Beispiel #1
0
static
#if LZO_ARCH_AVR
__lzo_noinline
#endif
lzo_bytep
store_run(lzo_bytep op, const lzo_bytep ii, lzo_uint r_len)
{
    assert(r_len > 0);

    /* code a long R0 run */
    if (r_len >= 512)
    {
        unsigned r_bits = 7;        /* 256 << 7 == 32768 */
        do {
            while (r_len >= (256u << r_bits))
            {
                r_len -= (256u << r_bits);
                *op++ = 0; *op++ = LZO_BYTE((R0FAST - R0MIN) + r_bits);
                MEMCPY8_DS(op, ii, (256u << r_bits));
            }
        } while (--r_bits > 0);
    }
    while (r_len >= R0FAST)
    {
        r_len -= R0FAST;
        *op++ = 0; *op++ = R0FAST - R0MIN;
        MEMCPY8_DS(op, ii, R0FAST);
    }

    if (r_len >= R0MIN)
    {
        /* code a short R0 run */
        *op++ = 0; *op++ = LZO_BYTE(r_len - R0MIN);
        MEMCPY_DS(op, ii, r_len);
    }
    else if (r_len > 0)
    {
        /* code a 'normal' run */
        *op++ = LZO_BYTE(r_len);
        MEMCPY_DS(op, ii, r_len);
    }

    assert(r_len == 0);
    return op;
}
Beispiel #2
0
lzo1a_decompress ( const lzo_byte *in , lzo_uint  in_len,
                         lzo_byte *out, lzo_uint *out_len,
                         lzo_voidp wrkmem )
{
#if defined(LZO_OPTIMIZE_GNUC_i386)
	register lzo_byte *op __asm__("%edi");
	register const lzo_byte *ip __asm__("%esi");
	register lzo_uint t __asm__("%ecx");
	register const lzo_byte *m_pos __asm__("%ebx");
#else
	register lzo_byte *op;
	register const lzo_byte *ip;
	register lzo_uint t;
	register const lzo_byte *m_pos;
#endif
	const lzo_byte * const ip_end = in + in_len;

	LZO_UNUSED(wrkmem);

#if defined(__LZO_QUERY_DECOMPRESS)
	if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
		return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);
#endif

	op = out;
	ip = in;
	while (ip < ip_end)
	{
		t = *ip++;		/* get marker */
		LZO_STATS(lzo_stats->marker[t]++);

		if (t == 0)				/* a R0 literal run */
		{
			t = *ip++;
			if (t >= R0FAST - R0MIN)			/* a long R0 run */
			{
				t -= R0FAST - R0MIN;
				if (t == 0)
					t = R0FAST;
				else
				{
#if 0
					t = 256u << ((unsigned) t);
#else
					/* help the optimizer */
					lzo_uint tt = 256;
					do tt <<= 1; while (--t > 0);
					t = tt;
#endif
				}
				MEMCPY8_DS(op,ip,t);
				continue;
			}
			t += R0MIN;
			goto literal;
		}
		else if (t < R0MIN)		/* a short literal run */
		{
literal:
			MEMCPY_DS(op,ip,t);

		/* after a literal a match must follow */
			while (ip < ip_end)
			{
				t = *ip++;			/* get R1 marker */
				if (t >= R0MIN)
					goto match;

			/* R1 match - a context sensitive 3 byte match + 1 byte literal */
				assert((t & OMASK) == t);
				m_pos = op - MIN_OFFSET;
				m_pos -= t | (((lzo_uint) *ip++) << OBITS);
				assert(m_pos >= out); assert(m_pos < op);
				*op++ = *m_pos++;
				*op++ = *m_pos++;
				*op++ = *m_pos++;
				*op++ = *ip++;
			}
		}
		else					/* a match */
		{
match:
			/* get match offset */
			m_pos = op - MIN_OFFSET;
			m_pos -= (t & OMASK) | (((lzo_uint) *ip++) << OBITS);
			assert(m_pos >= out); assert(m_pos < op);

			/* get match len */
			if (t < ((MSIZE - 1) << OBITS))			/* a short match */
			{
				t >>= OBITS;
				*op++ = *m_pos++;
				*op++ = *m_pos++;
				MEMMOVE_DS(op,m_pos,t);
			}
			else									 /* a long match */
			{
#if (LBITS < 8)
				t = (MIN_MATCH_LONG - THRESHOLD) + ((lzo_uint)(*ip++) & LMASK);
#else
				t = (MIN_MATCH_LONG - THRESHOLD) + (lzo_uint)(*ip++);
#endif
				*op++ = *m_pos++;
				*op++ = *m_pos++;
				MEMMOVE_DS(op,m_pos,t);
#if (LBITS < 8)
				/* a very short literal following a long match */
				t = ip[-1] >> LBITS;
				if (t) do
					*op++ = *ip++;
				while (--t);
#endif
			}
		}
Beispiel #3
0
lzo1a_decompress ( const lzo_bytep in , lzo_uint  in_len,
                         lzo_bytep out, lzo_uintp out_len,
                         lzo_voidp wrkmem )
{
    register lzo_bytep op;
    register const lzo_bytep ip;
    register lzo_uint t;
    register const lzo_bytep m_pos;
    const lzo_bytep const ip_end = in + in_len;

    LZO_UNUSED(wrkmem);

    op = out;
    ip = in;
    while (ip < ip_end)
    {
        t = *ip++;      /* get marker */
        LZO_STATS(lzo_stats->marker[t]++);

        if (t == 0)             /* a R0 literal run */
        {
            t = *ip++;
            if (t >= R0FAST - R0MIN)            /* a long R0 run */
            {
                t -= R0FAST - R0MIN;
                if (t == 0)
                    t = R0FAST;
                else
                {
#if 0
                    t = 256u << ((unsigned) t);
#else
                    /* help the optimizer */
                    lzo_uint tt = 256;
                    do tt <<= 1; while (--t > 0);
                    t = tt;
#endif
                }
                MEMCPY8_DS(op,ip,t);
                continue;
            }
            t += R0MIN;
            goto literal;
        }
        else if (t < R0MIN)     /* a short literal run */
        {
literal:
            MEMCPY_DS(op,ip,t);

        /* after a literal a match must follow */
            while (ip < ip_end)
            {
                t = *ip++;          /* get R1 marker */
                if (t >= R0MIN)
                    goto match;

            /* R1 match - a context sensitive 3 byte match + 1 byte literal */
                assert((t & OMASK) == t);
                m_pos = op - MIN_OFFSET;
                m_pos -= t | (((lzo_uint) *ip++) << OBITS);
                assert(m_pos >= out); assert(m_pos < op);
                *op++ = m_pos[0];
                *op++ = m_pos[1];
                *op++ = m_pos[2];
                *op++ = *ip++;
            }
        }
        else                    /* a match */
        {
match:
            /* get match offset */
            m_pos = op - MIN_OFFSET;
            m_pos -= (t & OMASK) | (((lzo_uint) *ip++) << OBITS);
            assert(m_pos >= out); assert(m_pos < op);

            /* get match len */
            if (t < ((MSIZE - 1) << OBITS))         /* a short match */
            {
                t >>= OBITS;
                *op++ = *m_pos++;
                *op++ = *m_pos++;
                MEMCPY_DS(op,m_pos,t);
            }
            else                                     /* a long match */
            {
#if (LBITS < 8)
                t = (MIN_MATCH_LONG - THRESHOLD) + ((lzo_uint)(*ip++) & LMASK);
#else
                t = (MIN_MATCH_LONG - THRESHOLD) + (lzo_uint)(*ip++);
#endif
                *op++ = *m_pos++;
                *op++ = *m_pos++;
                MEMCPY_DS(op,m_pos,t);
#if (LBITS < 8)
                /* a very short literal following a long match */
                t = ip[-1] >> LBITS;
                if (t) do
                    *op++ = *ip++;
                while (--t);
#endif
            }
        }
Beispiel #4
0
lzo1_decompress  ( const lzo_bytep in , lzo_uint  in_len,
                         lzo_bytep out, lzo_uintp out_len,
                         lzo_voidp wrkmem )
{
    lzo_bytep op;
    const lzo_bytep ip;
    const lzo_bytep const ip_end = in + in_len;
    lzo_uint t;

    LZO_UNUSED(wrkmem);

    op = out;
    ip = in;
    while (ip < ip_end)
    {
        t = *ip++;  /* get marker */

        if (t < R0MIN)          /* a literal run */
        {
            if (t == 0)             /* a R0 literal run */
            {
                t = *ip++;
                if (t >= R0FAST - R0MIN)            /* a long R0 run */
                {
                    t -= R0FAST - R0MIN;
                    if (t == 0)
                        t = R0FAST;
                    else
                    {
#if 0
                        t = 256u << ((unsigned) t);
#else
                        /* help the optimizer */
                        lzo_uint tt = 256;
                        do tt <<= 1; while (--t > 0);
                        t = tt;
#endif
                    }
                    MEMCPY8_DS(op,ip,t);
                    continue;
                }
                t += R0MIN;
            }
            MEMCPY_DS(op,ip,t);
        }
        else                    /* a match */
        {
            lzo_uint tt;
            /* get match offset */
            const lzo_bytep m_pos = op - 1;
            m_pos -= (lzo_uint)(t & OMASK) | (((lzo_uint) *ip++) << OBITS);

            /* get match len */
            if (t >= ((MSIZE - 1) << OBITS))                /* all m-bits set */
                tt = (MIN_MATCH_LONG - THRESHOLD) + *ip++;  /* a long match */
            else
                tt = t >> OBITS;                            /* a short match */

            assert(m_pos >= out);
            assert(m_pos <  op);
            /* a half unrolled loop */
            *op++ = *m_pos++;
            *op++ = *m_pos++;
            MEMCPY_DS(op,m_pos,tt);
        }
    }

    *out_len = pd(op, out);

    /* the next line is the only check in the decompressor ! */
    return (ip == ip_end ? LZO_E_OK :
           (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
}