/***********************************************************************
// compress a block of data.
************************************************************************/
static NOINLINE unsigned
do_compress(const uint8_t* in, unsigned in_len,
            uint8_t* out, unsigned* out_len,
            void* wrkmem)
{
    register const uint8_t* ip;
    uint8_t* op;
    const uint8_t* const in_end = in + in_len;
    const uint8_t* const ip_end = in + in_len - M2_MAX_LEN - 5;
    const uint8_t* ii;
    const void* *const dict = (const void**) wrkmem;

    op = out;
    ip = in;
    ii = ip;

    ip += 4;
    for (;;) {
        register const uint8_t* m_pos;
        unsigned m_off;
        unsigned m_len;
        unsigned dindex;

        D_INDEX1(dindex,ip);
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
            goto literal;
#if 1
        if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
            goto try_match;
        D_INDEX2(dindex,ip);
#endif
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
            goto literal;
        if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
            goto try_match;
        goto literal;

try_match:
#if 1 && defined(LZO_UNALIGNED_OK_2)
        if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
#else
        if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
#endif
        {
        } else {
            if (m_pos[2] == ip[2]) {
#if 0
                if (m_off <= M2_MAX_OFFSET)
                    goto match;
                if (lit <= 3)
                    goto match;
                if (lit == 3) {			  /* better compression, but slower */
                    assert(op - 2 > out);
                    op[-2] |= (uint8_t)(3);
                    *op++ = *ii++;
                    *op++ = *ii++;
                    *op++ = *ii++;
                    goto code_match;
                }
                if (m_pos[3] == ip[3])
#endif
                    goto match;
            }
            else {
                /* still need a better way for finding M1 matches */
#if 0
                /* a M1 match */
#if 0
                if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
#else
                if (m_off <= M1_MAX_OFFSET && lit == 3)
#endif
                {
                    register unsigned t;

                    t = lit;
                    assert(op - 2 > out);
                    op[-2] |= (uint8_t)(t);
                    do *op++ = *ii++;
                    while (--t > 0);
                    assert(ii == ip);
                    m_off -= 1;
                    *op++ = (uint8_t)(M1_MARKER | ((m_off & 3) << 2));
                    *op++ = (uint8_t)(m_off >> 2);
                    ip += 2;
                    goto match_done;
                }
#endif
            }
        }

        /* a literal */
literal:
        UPDATE_I(dict, 0, dindex, ip, in);
        ++ip;
        if (ip >= ip_end)
            break;
        continue;

        /* a match */
match:
        UPDATE_I(dict, 0, dindex, ip, in);
        /* store current literal run */
        if (pd(ip, ii) > 0) {
            register unsigned t = pd(ip, ii);

            if (t <= 3) {
                assert(op - 2 > out);
                op[-2] |= (uint8_t)(t);
            }
            else if (t <= 18)
                *op++ = (uint8_t)(t - 3);
            else {
                register unsigned tt = t - 18;

                *op++ = 0;
                while (tt > 255) {
                    tt -= 255;
                    *op++ = 0;
                }
                assert(tt > 0);
                *op++ = (uint8_t)(tt);
            }
            do *op++ = *ii++;
            while (--t > 0);
        }

        /* code the match */
        assert(ii == ip);
        ip += 3;
        if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++
                || m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
#ifdef LZO1Y
                || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
                || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
#endif
           ) {
            --ip;
            m_len = pd(ip, ii);
            assert(m_len >= 3);
            assert(m_len <= M2_MAX_LEN);

            if (m_off <= M2_MAX_OFFSET) {
                m_off -= 1;
#if defined(LZO1X)
                *op++ = (uint8_t)(((m_len - 1) << 5) | ((m_off & 7) << 2));
                *op++ = (uint8_t)(m_off >> 3);
#elif defined(LZO1Y)
                *op++ = (uint8_t)(((m_len + 1) << 4) | ((m_off & 3) << 2));
                *op++ = (uint8_t)(m_off >> 2);
#endif
            }
            else if (m_off <= M3_MAX_OFFSET) {
Ejemplo n.º 2
0
static __lzo_noinline
int do_compress          ( const lzo_bytep in , lzo_uint  in_len,
                                 lzo_bytep out, lzo_uintp out_len,
                                 lzo_voidp wrkmem )
{
    const lzo_bytep ip;
    lzo_bytep op;
    const lzo_bytep const in_end = in + in_len;
    const lzo_bytep const ip_end = in + in_len - 9;
    const lzo_bytep ii;
    lzo_dict_p const dict = (lzo_dict_p) wrkmem;

    op = out;
    ip = in;
    ii = ip;

    ip++;
    for (;;)
    {
        const lzo_bytep m_pos;
        LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0);
        lzo_uint m_len;
        lzo_uint dindex;
        lzo_uint lit;

        DINDEX1(dindex,ip);
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET))
            goto literal;
#if 1
        if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
            goto try_match;
        DINDEX2(dindex,ip);
#endif
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET))
            goto literal;
        if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
            goto try_match;
        goto literal;


try_match:
#if 0 && (LZO_OPT_UNALIGNED16)
        if (UA_GET_NE16(m_pos) != UA_GET_NE16(ip))
#else
        if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
#endif
        {
        }
        else
        {
            if (m_pos[2] == ip[2])
            {
                m_pos += 3;
#if 0
                if (m_off <= M2_MAX_OFFSET)
                    goto match;
                if (lit <= 3)
                    goto match;
                if (lit == 3)           /* better compression, but slower */
                {
                    assert(op - 2 > out); op[-2] |= LZO_BYTE(3);
                    *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
                    goto code_match;
                }
                if (*m_pos == ip[3])
#endif
                    goto match;
            }
        }


    /* a literal */
literal:
        UPDATE_I(dict,0,dindex,ip,in);
        if (++ip >= ip_end)
            break;
        continue;


    /* a match */
match:
        UPDATE_I(dict,0,dindex,ip,in);
        /* store current literal run */
        lit = pd(ip,ii);
        if (lit > 0)
        {
            lzo_uint t = lit;

            if (t < 4 && op > out)
                op[-2] = LZO_BYTE(op[-2] | t);
            else if (t <= 31)
                *op++ = LZO_BYTE(t);
            else
            {
                lzo_uint tt = t - 31;

                *op++ = 0;
                while (tt > 255)
                {
                    tt -= 255;
                    UA_SET1(op, 0);
                    op++;
                }
                assert(tt > 0);
                *op++ = LZO_BYTE(tt);
            }
            do *op++ = *ii++; while (--t > 0);
        }
        assert(ii == ip);


        /* code the match */
        ip += 3;
        if (*m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++ ||
            *m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++)
        {
            --ip;
            m_len = pd(ip, ii);
            assert(m_len >= 3); assert(m_len <= 8);

            if (m_off <= M2_MAX_OFFSET)
            {
                m_off -= 1;
                *op++ = LZO_BYTE(((m_len - 2) << 5) | ((m_off & 7) << 2));
                *op++ = LZO_BYTE(m_off >> 3);
            }
            else if (m_len == 3 && m_off <= 2*M2_MAX_OFFSET && lit > 0)
Ejemplo n.º 3
0
static
int do_compress          ( const lzo_byte *in , lzo_uint  in_len,
                                 lzo_byte *out, lzo_uint *out_len,
                                 lzo_voidp wrkmem )
{
#if 1 && defined(__GNUC__) && defined(__i386__)
	register const lzo_byte *ip __asm__("%esi");
#else
	register const lzo_byte *ip;
#endif
	lzo_uint32 dv;
	lzo_byte *op;
	const lzo_byte * const in_end = in + in_len;
	const lzo_byte * const ip_end = in + in_len - 9;
	const lzo_byte *ii;
	const lzo_bytepp const dict = (const lzo_bytepp) wrkmem;

	op = out;
	ip = in;
	ii = ip;

	DVAL_FIRST(dv,ip);
	UPDATE_D(dict,cycle,dv,ip);
	ip++;
	DVAL_NEXT(dv,ip);


	while (1)
	{
#if 1 && defined(__GNUC__) && defined(__i386__)
		register const lzo_byte *m_pos __asm__("%edi");
#else
		register const lzo_byte *m_pos;
#endif
		lzo_uint m_len;
		lzo_ptrdiff_t m_off;
		lzo_uint lit;

		{
			lzo_uint dindex = DINDEX(dv,ip);
			m_pos = dict[dindex];
			UPDATE_I(dict,cycle,dindex,ip);
		}


		if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M3_MAX_OFFSET))
		{
		}
#if defined(LZO_UNALIGNED_OK_2)
		else if (* (lzo_ushortp) m_pos != * (lzo_ushortp) ip)
#else
		else if (m_pos[0] != ip[0] || m_pos[1] != ip[1]) 
#endif
		{
		}
		else
		{
			if (m_pos[2] == ip[2])
			{
				m_pos += 3;
				if (m_off <= M2_MAX_OFFSET)
					goto match;
#if 1
				if (ip - ii <= 3)
					goto match;
#else
				if (ip - ii == 3)		/* better compression, but slower */
					goto match;
#endif
				if (*m_pos == ip[3])
					goto match;
			}
		}


	/* a literal */
		++ip;
		if (ip >= ip_end)
			break;
		DVAL_NEXT(dv,ip);
		continue;


	/* a match */
match:

		/* store current literal run */
		lit = ip - ii;
		if (lit > 0)
		{
			register lzo_uint t = lit;

			if (t < 4 && op > out)
				op[-2] |= LZO_BYTE(t);
			else if (t <= 31)
				*op++ = LZO_BYTE(t);
			else
			{
				register lzo_uint tt = t - 31;

				*op++ = 0;
				while (tt > 255)
				{
					tt -= 255;
					*op++ = 0;
				}
				assert(tt > 0);
				*op++ = LZO_BYTE(tt);
			}
			do *op++ = *ii++; while (--t > 0);
		}
		assert(ii == ip);


		/* code the match */
		ip += 3;
		if (*m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++ ||
		    *m_pos++ != *ip++ || *m_pos++ != *ip++ || *m_pos++ != *ip++)
		{
			--ip;
			m_len = ip - ii;
			assert(m_len >= 3); assert(m_len <= 8);

			if (m_off <= M2_MAX_OFFSET)
			{
				m_off -= 1;
				*op++ = LZO_BYTE(((m_len - 2) << 5) | ((m_off & 7) << 2));
				*op++ = LZO_BYTE(m_off >> 3);
			}
			else if (m_len == 3 && m_off <= 2*M2_MAX_OFFSET && lit > 0)