Example #1
0
/***********************************************************************
//
************************************************************************/
static void swd_search(lzo_swd_p s, unsigned node, unsigned cnt)
{
	const uint8_t *p1;
	const uint8_t *p2;
	const uint8_t *px;
	unsigned m_len = s->m_len;
	const uint8_t *b  = s->b;
	const uint8_t *bp = s->b + s->bp;
	const uint8_t *bx = s->b + s->bp + s->look;
	unsigned char scan_end1;

	assert(s->m_len > 0);

	scan_end1 = bp[m_len - 1];
	for ( ; cnt-- > 0; node = s->succ3[node]) {
		p1 = bp;
		p2 = b + node;
		px = bx;

		assert(m_len < s->look);

		if (p2[m_len - 1] == scan_end1
		 && p2[m_len] == p1[m_len]
		 && p2[0] == p1[0]
		 && p2[1] == p1[1]
		) {
			unsigned i;
			assert(lzo_memcmp(bp, &b[node], 3) == 0);

			p1 += 2; p2 += 2;
			do {} while (++p1 < px && *p1 == *++p2);
			i = p1-bp;

			assert(lzo_memcmp(bp, &b[node], i) == 0);

#if defined(SWD_BEST_OFF)
			if (i < SWD_BEST_OFF) {
				if (s->best_pos[i] == 0)
					s->best_pos[i] = node + 1;
			}
#endif
			if (i > m_len) {
				s->m_len = m_len = i;
				s->m_pos = node;
				if (m_len == s->look)
					return;
				if (m_len >= SWD_F)
					return;
				if (m_len > (unsigned) s->best3[node])
					return;
				scan_end1 = bp[m_len - 1];
			}
		}
	}
}
Example #2
0
static int swd_search2(lzo_swd_p s)
{
	unsigned key;

	assert(s->look >= 2);
	assert(s->m_len > 0);

	key = s->head2[HEAD2(s->b, s->bp)];
	if (key == NIL2)
		return 0;
	assert(lzo_memcmp(&s->b[s->bp], &s->b[key], 2) == 0);
#if defined(SWD_BEST_OFF)
	if (s->best_pos[2] == 0)
		s->best_pos[2] = key + 1;
#endif

	if (s->m_len < 2) {
		s->m_len = 2;
		s->m_pos = key;
	}
	return 1;
}
Example #3
0
int do_file ( const char *in_name, int level )
{
    int r;
    lzo_bytep in;
    lzo_bytep out;
    lzo_bytep newb;
    lzo_bytep wrkmem;
    lzo_uint in_len;
    lzo_uint out_len;
    lzo_uint new_len;
    long l;
    FILE *f;

/*
 * Step 1: open the input file
 */
    f = fopen(in_name,"rb");
    if (f == 0)
    {
        printf("%s: cannot open file %s\n", progname, in_name);
        return 0;   /* no error */
    }
    fseek(f,0,SEEK_END);
    l = ftell(f);
    fseek(f,0,SEEK_SET);
    if (l <= 0)
    {
        printf("%s: %s: empty file -- skipping\n", progname, in_name);
        fclose(f);
        return 0;
    }
    in_len = (lzo_uint) l;

/*
 * Step 2: allocate compression buffers and read the file
 */
    in = (lzo_bytep) lzo_malloc(in_len);
    out = (lzo_bytep) lzo_malloc(in_len + in_len / 16 + 64 + 3);
    newb = (lzo_bytep) lzo_malloc(in_len);
    wrkmem = (lzo_bytep) lzo_malloc(LZO1X_999_MEM_COMPRESS);
    if (in == NULL || out == NULL || newb == NULL || wrkmem == NULL)
    {
        printf("%s: out of memory\n", progname);
        exit(1);
    }
    in_len = (lzo_uint) lzo_fread(f,in,in_len);
    fclose(f);

/*
 * Step 3: compress from `in' to `out' with LZO1X-999
 */
    r = lzo1x_999_compress_level(in,in_len,out,&out_len,wrkmem,
                                 dict, dict_len, 0, level);
    if (r != LZO_E_OK)
    {
        /* this should NEVER happen */
        printf("internal error - compression failed: %d\n", r);
        return 1;
    }

    print_file(in_name,in_len,out_len);

/*
 * Step 4: decompress again, now going from `out' to `newb'
 */
    new_len = in_len;
    r = lzo1x_decompress_dict_safe(out,out_len,newb,&new_len,NULL,dict,dict_len);
    if (r != LZO_E_OK)
    {
        /* this should NEVER happen */
        printf("internal error - decompression failed: %d\n", r);
        return 1;
    }

/*
 * Step 5: verify decompression
 */
    if (new_len != in_len || lzo_memcmp(in,newb,in_len) != 0)
    {
        /* this should NEVER happen */
        printf("internal error - decompression data error\n");
        return 1;
    }

    /* free buffers in reverse order to help malloc() */
    lzo_free(wrkmem);
    lzo_free(newb);
    lzo_free(out);
    lzo_free(in);
    return 0;
}
Example #4
0
lzo2a_999_compress_callback ( const lzo_byte *in , lzo_uint  in_len,
                                    lzo_byte *out, lzo_uintp out_len,
                                    lzo_voidp wrkmem,
                                    lzo_progress_callback_t cb,
                                    lzo_uint max_chain )
{
	lzo_byte *op;
	lzo_byte *bitp = 0;
	lzo_uint m_len, m_off;
	LZO_COMPRESS_T cc;
	LZO_COMPRESS_T * const c = &cc;
	lzo_swd_t * const swd = (lzo_swd_t *) wrkmem;
	int r;

	lzo_uint32 b = 0;		/* bit buffer */
	unsigned k = 0;			/* bits in bit buffer */

#if defined(__LZO_QUERY_COMPRESS)
	if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
		return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,1,lzo_sizeof(lzo_swd_t));
#endif

	/* sanity check */
	if (!lzo_assert(LZO2A_999_MEM_COMPRESS >= lzo_sizeof(lzo_swd_t)))
		return LZO_E_ERROR;

	c->init = 0;
	c->ip = c->in = in;
	c->in_end = in + in_len;
	c->cb = cb;
	c->m1 = c->m2 = c->m3 = c->m4 = 0;

	op = out;

	r = init_match(c,swd,NULL,0,0);
	if (r != 0)
		return r;
	if (max_chain > 0)
		swd->max_chain = max_chain;

	r = find_match(c,swd,0,0);
	if (r != 0)
		return r;
	while (c->look > 0)
	{
		int lazy_match_min_gain = 0;
		int extra1 = 0;
		int extra2 = 0;
		lzo_uint ahead = 0;

		LZO_UNUSED(extra1);

		m_len = c->m_len;
		m_off = c->m_off;

#if (N >= 8192)
		if (m_off >= 8192)
		{
			if (m_len < M3_MIN_LEN)
				m_len = 0;
			else
				lazy_match_min_gain = 1;
		}
		else
#endif
		if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
		{
			lazy_match_min_gain = 2;
			extra1 = 3;
			extra2 = 2;
		}
		else if (m_len >= 10)
			lazy_match_min_gain = 1;
		else if (m_len >= 3)
		{
			lazy_match_min_gain = 1;
			extra1 = 1;
		}
		else
			m_len = 0;


		/* try a lazy match */
		if (lazy_match_min_gain > 0 && c->look > m_len)
		{
			int lit = swd->b_char;

			r = find_match(c,swd,1,0);
			assert(r == 0);
			assert(c->look > 0);

#if (N >= 8192)
			if (m_off < 8192 && c->m_off >= 8192)
				lazy_match_min_gain += extra1;
			else
#endif
			if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
			{
				if (!(c->m_len >= M1_MIN_LEN &&
				      c->m_len <= M1_MAX_LEN && c->m_off <= 256))
					lazy_match_min_gain += extra2;
			}
			if (c->m_len >= M1_MIN_LEN &&
			    c->m_len <= M1_MAX_LEN && c->m_off <= 256)
			{
					lazy_match_min_gain -= 1;
			}

			if (lazy_match_min_gain < 1)
				lazy_match_min_gain = 1;

			if (c->m_len >= m_len + lazy_match_min_gain)
			{
				c->lazy++;
#if !defined(NDEBUG)
				m_len = c->m_len;
				m_off = c->m_off;
				assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off,
			                      m_len) == 0);
				assert(m_len >= 3 || (m_len >= 2 && m_off <= 256));
#endif
				/* code literal */
				putbit(0);
				putbyte(lit);
				c->lit_bytes++;
				continue;
			}
			else
				ahead = 1;
			assert(m_len > 0);
		}


		if (m_len == 0)
		{
			/* a literal */
			putbit(0);
			putbyte(swd->b_char);
			c->lit_bytes++;
			r = find_match(c,swd,1,0);
			assert(r == 0);
		}
		else
		{
			assert(m_len >= M1_MIN_LEN);
			assert(m_off > 0);
			assert(m_off <= N);

			/* 2 - code match */
			if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
			{
				putbit(1);
				putbit(0);
				putbits(2,m_len - M1_MIN_LEN);
				putbyte(m_off - 1);
				c->m1++;
			}
#if (N >= 8192)
			else if (m_off >= 8192)
			{
				unsigned len = m_len;
				assert(m_len >= M3_MIN_LEN);
				putbit(1);
				putbit(1);
				putbyte(m_off & 31);
				putbyte(m_off >> 5);
				putbit(1);
				len -= M3_MIN_LEN - 1;
				while (len > 255)
				{
					len -= 255;
					putbyte(0);
				}
				putbyte(len);
				c->m4++;
			}
#endif
			else
			{
				assert(m_len >= 3);

				putbit(1);
				putbit(1);
				if (m_len <= 9)
				{
					putbyte(((m_len - 2) << 5) | (m_off & 31));
					putbyte(m_off >> 5);
					c->m2++;
				}
				else
				{
Example #5
0
static
int process_file ( const compress_t *c, lzo_decompress_t decompress,
                   const char *method_name,
                   const char *file_name, lzo_uint l,
                   int t_loops, int c_loops, int d_loops )
{
	int i;
	unsigned blocks = 0;
	unsigned long compressed_len = 0;
	my_clock_t t_time = 0, c_time = 0, d_time = 0;
	my_clock_t t_start, c_start, d_start;
#ifdef USE_DUMP
	FILE *dump = NULL;

	if (opt_dump_compressed_data)
		dump = fopen(opt_dump_compressed_data,"wb");
#endif

/* process the file */

	t_start = my_clock();
	for (i = 0; i < t_loops; i++)
	{
		lzo_uint len, c_len, c_len_max, d_len = 0;
		lzo_byte *d = data;

		len = l;
		c_len = 0;
		blocks = 0;

		/* process blocks */
		if (len > 0 || opt_try_to_compress_0_bytes) do
		{
			int j;
			int r;

			const lzo_uint bl = len > opt_block_size ? opt_block_size : len;
			lzo_uint bl_overwrite = bl;
#if defined(__LZO_CHECKER)
			lzo_byte *dd = NULL;
			lzo_byte *b1 = NULL;
			lzo_byte *b2 = NULL;
			const lzo_uint b1_len = bl + bl / 64 + 16 + 3;
#else
			lzo_byte * const dd = d;
			lzo_byte * const b1 = block1;
			lzo_byte * const b2 = block2;
			const lzo_uint b1_len = sizeof(_block1) - 256;
			unsigned char random_byte;
			random_byte = (unsigned char) my_clock();
#endif

			blocks++;

			/* may overwrite 3 bytes past the end of the decompressed block */
			if (opt_use_asm_fast_decompressor)
				bl_overwrite += (lzo_uint) sizeof(int) - 1;

#if defined(__LZO_CHECKER)
			/* malloc a block of the exact size to detect any overrun */
			dd = malloc(bl_overwrite > 0 ? bl_overwrite : 1);
			b1 = malloc(b1_len);
			b2 = dd;
			if (dd == NULL || b1 == NULL)
			{
				perror("malloc");
				return EXIT_MEM;
			}
			if (bl > 0)
				memcpy(dd,d,bl);
#endif

		/* compress the block */
			c_len = c_len_max = 0;
			c_start = my_clock();
			for (j = r = 0; r == 0 && j < c_loops; j++)
			{
				c_len = b1_len;
				r = do_compress(c,dd,bl,b1,&c_len);
				if (r == 0 && c_len > c_len_max)
					c_len_max = c_len;
			}
			c_time += my_clock() - c_start;
			if (r != 0)
			{
				printf("  compression failed in block %d (%d) (%lu %lu)\n",
					blocks, r, (long)c_len, (long)bl);
				return EXIT_LZO_ERROR;
			}

		/* optimize the block */
			if (opt_optimize_compressed_data)
			{
				d_len = bl;
				r = do_optimize(c,b1,c_len,b2,&d_len);
				if (r != 0 || d_len != bl)
				{
					printf("  optimization failed in block %d (%d) "
						"(%lu %lu %lu)\n", blocks, r,
						(long)c_len, (long)d_len, (long)bl);
					return EXIT_LZO_ERROR;
				}
			}

#ifdef USE_DUMP
			/* dump compressed data to disk */
			if (dump)
			{
				lzo_fwrite(dump,b1,c_len);
				fflush(dump);
			}
#endif

		/* decompress the block and verify */
#if defined(__LZO_CHECKER)
			lzo_memset(b2,0,bl_overwrite);
#else
			init_mem_checker(b2,_block2,bl_overwrite,random_byte);
#endif
			d_start = my_clock();
			for (j = r = 0; r == 0 && j < d_loops; j++)
			{
				d_len = bl;
				r = do_decompress(c,decompress,b1,c_len,b2,&d_len);
				if (d_len != bl)
					break;
			}
			d_time += my_clock() - d_start;
			if (r != 0)
			{
				printf("  decompression failed in block %d (%d) "
					"(%lu %lu %lu)\n", blocks, r,
					(long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
			if (d_len != bl)
			{
				printf("  decompression size error in block %d (%lu %lu %lu)\n",
					blocks, (long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
			if (is_compressor(c))
			{
				if (lzo_memcmp(d,b2,bl) != 0)
				{
					lzo_uint x = 0;
					while (x < bl && b2[x] == d[x])
						x++;
					printf("  decompression data error in block %d at offset "
						"%lu (%lu %lu)\n", blocks, (long)x,
						(long)c_len, (long)d_len);
					if (opt_compute_adler32)
						printf("      checksum: 0x%08lx 0x%08lx\n",
							(long)adler_in, (long)adler_out);
#if 0
					printf("Orig:  ");
					r = (x >= 10) ? -10 : 0 - (int) x;
					for (j = r; j <= 10 && x + j < bl; j++)
						printf(" %02x", (int)d[x+j]);
					printf("\nDecomp:");
					for (j = r; j <= 10 && x + j < bl; j++)
						printf(" %02x", (int)b2[x+j]);
					printf("\n");
#endif
					return EXIT_LZO_ERROR;
				}
				if ((opt_compute_adler32 && adler_in != adler_out) ||
				    (opt_compute_crc32 && crc_in != crc_out))
				{
					printf("  checksum error in block %d (%lu %lu)\n",
						blocks, (long)c_len, (long)d_len);
					printf("      adler32: 0x%08lx 0x%08lx\n",
						(long)adler_in, (long)adler_out);
					printf("      crc32: 0x%08lx 0x%08lx\n",
						(long)crc_in, (long)crc_out);
					return EXIT_LZO_ERROR;
				}
			}

#if defined(__LZO_CHECKER)
			/* free in reverse order of allocations */
			free(b1);
			free(dd);
#else
			if (check_mem(b2,_block2,bl_overwrite,random_byte) != 0)
			{
				printf("  decompression overwrite error in block %d "
					"(%lu %lu %lu)\n",
					blocks, (long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
#endif

			d += bl;
			len -= bl;
			compressed_len += c_len_max;
		}
		while (len > 0);
	}
	t_time += my_clock() - t_start;

#ifdef USE_DUMP
	if (dump)
		fclose(dump);
	opt_dump_compressed_data = NULL;	/* only dump the first file */
#endif

	print_stats(method_name, file_name,
	            t_loops, c_loops, d_loops,
	            t_time, c_time, d_time,
	            compressed_len, l, blocks);

	return EXIT_OK;
}
Example #6
0
int do_file ( const char *in_name )
{
    int r;
    FILE *fp = NULL;
    long l;

    lzo_voidp wrkmem = NULL;

    lzo_bytep in = NULL;
    lzo_uint in_len;                /* uncompressed length */

    lzo_bytep out = NULL;
    lzo_uint out_len;               /* compressed length */

    lzo_bytep overlap = NULL;
    lzo_uint overhead;
    lzo_uint offset;

    lzo_uint new_len = 0;

/*
 * Step 1: open the input file
 */
    fp = fopen(in_name, "rb");
    if (fp == NULL)
    {
        printf("%s: %s: cannot open file\n", progname, in_name);
        goto next_file;
    }
    fseek(fp, 0, SEEK_END);
    l = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (l <= 0)
    {
        printf("%s: %s: empty file -- skipping\n", progname, in_name);
        goto next_file;
    }
    in_len = (lzo_uint) l;

/*
 * Step 2: allocate compression buffers and read the file
 */
    in = (lzo_bytep) xmalloc(in_len);
    out = (lzo_bytep) xmalloc(in_len + in_len / 16 + 64 + 3);
    wrkmem = (lzo_voidp) xmalloc(LZO1X_1_MEM_COMPRESS);
    in_len = (lzo_uint) lzo_fread(fp, in, in_len);
    fclose(fp); fp = NULL;
    printf("%s: %s: read %lu bytes\n", progname, in_name, (unsigned long) in_len);

    total_files++;
    total_in += (unsigned long) in_len;

/*
 * Step 3: compress from 'in' to 'out' with LZO1X-1
 */
    r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem);
    if (r != LZO_E_OK || out_len > in_len + in_len / 16 + 64 + 3)
    {
        /* this should NEVER happen */
        printf("internal error - compression failed: %d\n", r);
        exit(1);
    }
    printf("%-26s %8lu -> %8lu\n", "LZO1X-1:", (unsigned long) in_len, (unsigned long) out_len);


/***** Step 4: overlapping compression *****/

/*
 * Step 4a: allocate the 'overlap' buffer for overlapping compression
 */
    overhead  = in_len > 0xbfff ? 0xbfff : in_len;
    overhead += in_len / 16 + 64 + 3;
    overlap = (lzo_bytep) xmalloc(in_len + overhead);

/*
 * Step 4b: prepare data in 'overlap' buffer.
 *          copy uncompressed data at the top of the overlap buffer
 */
    /*** offset = in_len + overhead - in_len; ***/
    offset = overhead;
    lzo_memcpy(overlap + offset, in, in_len);

/*
 * Step 4c: do an in-place compression within the 'overlap' buffer
 */
    r = lzo1x_1_compress(overlap+offset,in_len,overlap,&new_len,wrkmem);
    if (r != LZO_E_OK)
    {
        /* this should NEVER happen */
        printf("overlapping compression failed: %d\n", r);
        exit(1);
    }

/*
 * Step 4d: verify overlapping compression
 */
    if (new_len != out_len || lzo_memcmp(out,overlap,out_len) != 0)
    {
        /* As compression is non-deterministic there can be a difference
         * in the representation of the compressed data (but this usually
         * happens very seldom). So we have to verify the overlapping
         * compression by doing a temporary decompression.
         */
        lzo_uint ll = in_len;
        lzo_bytep tmp = (lzo_bytep) xmalloc(ll);
        r = lzo1x_decompress_safe(overlap, new_len, tmp, &ll, NULL);
        if (r != LZO_E_OK || ll != in_len || lzo_memcmp(in, tmp, ll) != 0)
        {
            /* this should NEVER happen */
            printf("overlapping compression data error\n");
            exit(1);
        }
        lzo_free(tmp);
    }

    printf("overlapping compression:   %8lu -> %8lu    overhead: %7lu\n",
            (unsigned long) in_len, (unsigned long) new_len, (unsigned long) overhead);
    lzo_free(overlap); overlap = NULL;


/***** Step 5: overlapping decompression *****/

/*
 * Step 5a: allocate the 'overlap' buffer for in-place decompression
 */
    if (opt_overhead == 0 || out_len >= in_len)
        overhead = in_len / 16 + 64 + 3;
    else
        overhead = opt_overhead;
    overlap = (lzo_bytep) xmalloc(in_len + overhead);

/*
 * Step 5b: prepare data in 'overlap' buffer.
 *          copy compressed data at the top of the overlap buffer
 */
    offset = in_len + overhead - out_len;
    lzo_memcpy(overlap + offset, out, out_len);

/*
 * Step 5c: do an in-place decompression within the 'overlap' buffer
 */
    new_len = in_len;
    r = lzo1x_decompress(overlap+offset,out_len,overlap,&new_len,NULL);
    if (r != LZO_E_OK)
    {
        /* this may happen if overhead is too small */
        printf("overlapping decompression failed: %d - increase 'opt_overhead'\n", r);
        exit(1);
    }

/*
 * Step 5d: verify decompression
 */
    if (new_len != in_len || lzo_memcmp(in,overlap,in_len) != 0)
    {
        /* this may happen if overhead is too small */
        printf("overlapping decompression data error - increase 'opt_overhead'\n");
        exit(1);
    }
    printf("overlapping decompression: %8lu -> %8lu    overhead: %7lu\n",
            (unsigned long) out_len, (unsigned long) new_len, (unsigned long) overhead);
    lzo_free(overlap); overlap = NULL;


next_file:
    lzo_free(overlap);
    lzo_free(wrkmem);
    lzo_free(out);
    lzo_free(in);
    if (fp) fclose(fp);

    return 0;
}
Example #7
0
lzo2a_999_compress_callback(const lzo_bytep in , lzo_uint  in_len,
                            lzo_bytep out, lzo_uintp out_len,
                            lzo_voidp wrkmem,
                            lzo_callback_p cb,
                            lzo_uint max_chain)
{
    lzo_bytep op;
    lzo_bytep bitp = 0;
    lzo_uint m_len, m_off;
    LZO_COMPRESS_T cc;
    LZO_COMPRESS_T* const c = &cc;
    lzo_swd_p const swd = (lzo_swd_p) wrkmem;
    int r;

    lzo_uint32_t b = 0;     /* bit buffer */
    unsigned k = 0;         /* bits in bit buffer */

    /* sanity check */
    LZO_COMPILE_TIME_ASSERT(LZO2A_999_MEM_COMPRESS >= SIZEOF_LZO_SWD_T)

    c->init = 0;
    c->ip = c->in = in;
    c->in_end = in + in_len;
    c->cb = cb;
    c->m1 = c->m2 = c->m3 = c->m4 = 0;

    op = out;

    r = init_match(c, swd, NULL, 0, 0);

    if (r != 0)
        return r;

    if (max_chain > 0)
        swd->max_chain = max_chain;

    r = find_match(c, swd, 0, 0);

    if (r != 0)
        return r;

    while (c->look > 0)
    {
        lzo_uint lazy_match_min_gain = 0;
#if (SWD_N >= 8192)
        lzo_uint extra1 = 0;
#endif
        lzo_uint extra2 = 0;
        lzo_uint ahead = 0;

        m_len = c->m_len;
        m_off = c->m_off;

#if (SWD_N >= 8192)

        if (m_off >= 8192)
        {
            if (m_len < M3_MIN_LEN)
                m_len = 0;
            else
                lazy_match_min_gain = 1;
        }
        else
#endif
            if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
            {
                lazy_match_min_gain = 2;
#if (SWD_N >= 8192)
                extra1 = 3;
#endif
                extra2 = 2;
            }
            else if (m_len >= 10)
                lazy_match_min_gain = 1;
            else if (m_len >= 3)
            {
                lazy_match_min_gain = 1;
#if (SWD_N >= 8192)
                extra1 = 1;
#endif
            }
            else
                m_len = 0;


        /* try a lazy match */
        if (lazy_match_min_gain > 0 && c->look > m_len)
        {
            unsigned char lit = LZO_BYTE(swd->b_char);

            r = find_match(c, swd, 1, 0);
            assert(r == 0);
            LZO_UNUSED(r);
            assert(c->look > 0);

#if (SWD_N >= 8192)

            if (m_off < 8192 && c->m_off >= 8192)
                lazy_match_min_gain += extra1;
            else
#endif
                if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
                {
                    if (!(c->m_len >= M1_MIN_LEN &&
                            c->m_len <= M1_MAX_LEN && c->m_off <= 256))
                        lazy_match_min_gain += extra2;
                }

            if (c->m_len >= M1_MIN_LEN &&
                    c->m_len <= M1_MAX_LEN && c->m_off <= 256)
            {
                lazy_match_min_gain -= 1;
            }

            if ((lzo_int) lazy_match_min_gain < 1)
                lazy_match_min_gain = 1;

            if (c->m_len >= m_len + lazy_match_min_gain)
            {
                c->lazy++;
#if !defined(NDEBUG)
                m_len = c->m_len;
                m_off = c->m_off;
                assert(lzo_memcmp(c->ip - c->look, c->ip - c->look - m_off,
                                  m_len) == 0);
                assert(m_len >= 3 || (m_len >= 2 && m_off <= 256));
#endif
                /* code literal */
                putbit(0);
                putbyte(lit);
                c->lit_bytes++;
                continue;
            }
            else
                ahead = 1;

            assert(m_len > 0);
        }


        if (m_len == 0)
        {
            /* a literal */
            putbit(0);
            putbyte(swd->b_char);
            c->lit_bytes++;
            r = find_match(c, swd, 1, 0);
            assert(r == 0);
            LZO_UNUSED(r);
        }
        else
        {
            assert(m_len >= M1_MIN_LEN);
            assert(m_off > 0);
            assert(m_off <= SWD_N);

            /* 2 - code match */
            if (m_len >= M1_MIN_LEN && m_len <= M1_MAX_LEN && m_off <= 256)
            {
                putbit(1);
                putbit(0);
                putbits(2, m_len - M1_MIN_LEN);
                putbyte(m_off - 1);
                c->m1++;
            }

#if (SWD_N >= 8192)
            else if (m_off >= 8192)
            {
                unsigned len = m_len;
                assert(m_len >= M3_MIN_LEN);
                putbit(1);
                putbit(1);
                putbyte(m_off & 31);
                putbyte(m_off >> 5);
                putbit(1);
                len -= M3_MIN_LEN - 1;

                while (len > 255)
                {
                    len -= 255;
                    putbyte(0);
                }

                putbyte(len);
                c->m4++;
            }

#endif
            else
            {
                assert(m_len >= 3);

                putbit(1);
                putbit(1);

                if (m_len <= 9)
                {
                    putbyte(((m_len - 2) << 5) | (m_off & 31));
                    putbyte(m_off >> 5);
                    c->m2++;
                }
                else
                {
Example #8
0
static 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;
#if defined(__LZO_HASH_INCREMENTAL)
    lzo_xint dv;
#endif
    lzo_bytep op;
    const lzo_bytep m_pos;
    const lzo_bytep const ip_end = in+in_len - DVAL_LEN - MIN_MATCH_LONG;
    const lzo_bytep const in_end = in+in_len - DVAL_LEN;
    const lzo_bytep ii;
    lzo_dict_p const dict = (lzo_dict_p) wrkmem;

#if !defined(NDEBUG)
    const lzo_bytep m_pos_sav;
#endif

    op = out;
    ip = in;
    ii = ip;                /* point to start of literal run */
    if (in_len <= MIN_MATCH_LONG + DVAL_LEN + 1)
        goto the_end;

    /* init dictionary */
#if (LZO_DETERMINISTIC)
    BZERO8_PTR(wrkmem,sizeof(lzo_dict_t),D_SIZE);
#endif

    DVAL_FIRST(dv,ip);
    UPDATE_D(dict,0,dv,ip,in);
    ip++;
    DVAL_NEXT(dv,ip);

    do {
        LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0);
        lzo_uint dindex;

        DINDEX1(dindex,ip);
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS(m_pos,m_off,in,ip,MAX_OFFSET))
            goto literal;
        if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2])
            goto match;
        DINDEX2(dindex,ip);
        GINDEX(m_pos,m_off,dict,dindex,in);
        if (LZO_CHECK_MPOS(m_pos,m_off,in,ip,MAX_OFFSET))
            goto literal;
        if (m_pos[0] == ip[0] && m_pos[1] == ip[1] && m_pos[2] == ip[2])
            goto match;
        goto literal;


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

match:
        UPDATE_I(dict,0,dindex,ip,in);
#if !defined(NDEBUG) && (LZO_DICT_USE_PTR)
        m_pos_sav = m_pos;
#endif
        m_pos += 3;
        {
    /* we have found a match (of at least length 3) */
#if !defined(NDEBUG) && !(LZO_DICT_USE_PTR)
            assert((m_pos_sav = ip - m_off) == (m_pos - 3));
#endif
            /* 1) store the current literal run */
            if (pd(ip,ii) > 0)
            {
                lzo_uint t = pd(ip,ii);
#if 1
                /* OPTIMIZED: inline the copying of a short run */
                if (t < R0MIN)
                {
                    *op++ = LZO_BYTE(t);
                    MEMCPY_DS(op, ii, t);
                }
                else
#endif
                    op = store_run(op,ii,t);
            }

            /* 2a) compute match len */
            ii = ip;        /* point to start of current match */

            /* we already matched MIN_MATCH bytes,
             * m_pos also already advanced MIN_MATCH bytes */
            ip += MIN_MATCH;
            assert(m_pos < ip);

            /* try to match another MIN_MATCH_LONG - MIN_MATCH bytes
             * to see if we get a long match */

#define PS  *m_pos++ != *ip++

#if (MIN_MATCH_LONG - MIN_MATCH == 2)                   /* MBITS == 2 */
            if (PS || PS)
#elif (MIN_MATCH_LONG - MIN_MATCH == 6)                 /* MBITS == 3 */
            if (PS || PS || PS || PS || PS || PS)
#elif (MIN_MATCH_LONG - MIN_MATCH == 14)                /* MBITS == 4 */
            if (PS || PS || PS || PS || PS || PS || PS ||
                PS || PS || PS || PS || PS || PS || PS)
#elif (MIN_MATCH_LONG - MIN_MATCH == 30)                /* MBITS == 5 */
            if (PS || PS || PS || PS || PS || PS || PS || PS ||
                PS || PS || PS || PS || PS || PS || PS || PS ||
                PS || PS || PS || PS || PS || PS || PS || PS ||
                PS || PS || PS || PS || PS || PS)
#else
#  error "MBITS not yet implemented"
#endif
            {
                lzo_uint m_len;

            /* 2b) code a short match */
                    assert(pd(ip,m_pos) == m_off);
                --ip;   /* ran one too far, point back to non-match */
                m_len = pd(ip, ii);
                    assert(m_len >= MIN_MATCH_SHORT);
                    assert(m_len <= MAX_MATCH_SHORT);
                    assert(m_off > 0);
                    assert(m_off <= MAX_OFFSET);
                    assert(ii-m_off == m_pos_sav);
                    assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0);
                --m_off;
                /* code short match len + low offset bits */
                *op++ = LZO_BYTE(((m_len - THRESHOLD) << OBITS) |
                                 (m_off & OMASK));
                /* code high offset bits */
                *op++ = LZO_BYTE(m_off >> OBITS);


            /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */

#define SI      /* nothing */
#define DI      ++ii; DVAL_NEXT(dv,ii); UPDATE_D(dict,0,dv,ii,in);
#define XI      assert(ii < ip); ii = ip; DVAL_FIRST(dv,(ip));

#if (CLEVEL == 9) || (CLEVEL >= 7 && MBITS <= 4) || (CLEVEL >= 5 && MBITS <= 3)
            /* Insert the whole match (ii+1)..(ip-1) into dictionary.  */
                ++ii;
                do {
                    DVAL_NEXT(dv,ii);
                    UPDATE_D(dict,0,dv,ii,in);
                } while (++ii < ip);
                DVAL_NEXT(dv,ii);
                assert(ii == ip);
                DVAL_ASSERT(dv,ip);
#elif (CLEVEL >= 3)
                SI   DI DI   XI
#elif (CLEVEL >= 2)
                SI   DI      XI
#else
                             XI
#endif

            }
            else
            {
            /* we've found a long match - see how far we can still go */
                const lzo_bytep end;
                lzo_uint m_len;

                assert(ip <= in_end);
                assert(ii == ip - MIN_MATCH_LONG);

                if (pd(in_end,ip) <= (MAX_MATCH_LONG - MIN_MATCH_LONG))
                    end = in_end;
                else
                {
                    end = ip + (MAX_MATCH_LONG - MIN_MATCH_LONG);
                    assert(end < in_end);
                }

                while (ip < end  &&  *m_pos == *ip)
                    m_pos++, ip++;
                assert(ip <= in_end);

            /* 2b) code the long match */
                m_len = pd(ip, ii);
                    assert(m_len >= MIN_MATCH_LONG);
                    assert(m_len <= MAX_MATCH_LONG);
                    assert(m_off > 0);
                    assert(m_off <= MAX_OFFSET);
                    assert(ii-m_off == m_pos_sav);
                    assert(lzo_memcmp(m_pos_sav,ii,m_len) == 0);
                    assert(pd(ip,m_pos) == m_off);
                --m_off;
                /* code long match flag + low offset bits */
                *op++ = LZO_BYTE(((MSIZE - 1) << OBITS) | (m_off & OMASK));
                /* code high offset bits */
                *op++ = LZO_BYTE(m_off >> OBITS);
                /* code match len */
                *op++ = LZO_BYTE(m_len - MIN_MATCH_LONG);


            /* 2c) Insert phrases (beginning with ii+1) into the dictionary. */
#if (CLEVEL == 9)
            /* Insert the whole match (ii+1)..(ip-1) into dictionary.  */
            /* This is not recommended because it is slow. */
                ++ii;
                do {
                    DVAL_NEXT(dv,ii);
                    UPDATE_D(dict,0,dv,ii,in);
                } while (++ii < ip);
                DVAL_NEXT(dv,ii);
                assert(ii == ip);
                DVAL_ASSERT(dv,ip);
#elif (CLEVEL >= 8)
                SI   DI DI DI DI DI DI DI DI   XI
#elif (CLEVEL >= 7)
                SI   DI DI DI DI DI DI DI      XI
#elif (CLEVEL >= 6)
                SI   DI DI DI DI DI DI         XI
#elif (CLEVEL >= 5)
                SI   DI DI DI DI               XI
#elif (CLEVEL >= 4)
                SI   DI DI DI                  XI
#elif (CLEVEL >= 3)
                SI   DI DI                     XI
#elif (CLEVEL >= 2)
                SI   DI                        XI
#else
                                               XI
#endif
            }

            /* ii now points to the start of next literal run */
            assert(ii == ip);
        }