Example #1
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
			}
		}
Example #2
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
            }
        }