/*********************************************************************** // ************************************************************************/ 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]; } } } }
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; }
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; }
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 {
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; }
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; }
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 {
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); }