27#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
38#if defined(__GNUC__) && (__GNUC__ > 2)
39#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
40#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
42#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
43#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
49#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
50#define FASTLZ_INLINE inline
51#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
52#define FASTLZ_INLINE __inline
60#if !defined(FASTLZ_STRICT_ALIGN)
61#define FASTLZ_STRICT_ALIGN
62#if defined(__i386__) || defined(__386)
63#undef FASTLZ_STRICT_ALIGN
64#elif defined(__i486__) || defined(__i586__) || defined(__i686__)
65#undef FASTLZ_STRICT_ALIGN
67#undef FASTLZ_STRICT_ALIGN
69#undef FASTLZ_STRICT_ALIGN
71#undef FASTLZ_STRICT_ALIGN
73#undef FASTLZ_STRICT_ALIGN
80typedef unsigned char flzuint8;
81typedef unsigned short flzuint16;
82typedef unsigned int flzuint32;
85int fastlz_compress(
const void* input,
int length,
void* output);
86int fastlz_compress_level(
int level,
const void* input,
int length,
void* output);
87int fastlz_decompress(
const void* input,
int length,
void* output,
int maxout);
91#define MAX_DISTANCE 8192
93#if !defined(FASTLZ_STRICT_ALIGN)
94#define FASTLZ_READU16(p) *((const flzuint16*)(p))
96#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
100#define HASH_SIZE (1<< HASH_LOG)
101#define HASH_MASK (HASH_SIZE-1)
102#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
105#define FASTLZ_LEVEL 1
107#undef FASTLZ_COMPRESSOR
108#undef FASTLZ_DECOMPRESSOR
109#define FASTLZ_COMPRESSOR fastlz1_compress
110#define FASTLZ_DECOMPRESSOR fastlz1_decompress
111static FASTLZ_INLINE
int FASTLZ_COMPRESSOR(
const void* input,
int length,
void* output);
112static FASTLZ_INLINE
int FASTLZ_DECOMPRESSOR(
const void* input,
int length,
void* output,
int maxout);
116#define FASTLZ_LEVEL 2
119#define MAX_DISTANCE 8191
120#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
122#undef FASTLZ_COMPRESSOR
123#undef FASTLZ_DECOMPRESSOR
124#define FASTLZ_COMPRESSOR fastlz2_compress
125#define FASTLZ_DECOMPRESSOR fastlz2_decompress
126static FASTLZ_INLINE
int FASTLZ_COMPRESSOR(
const void* input,
int length,
void* output);
127static FASTLZ_INLINE
int FASTLZ_DECOMPRESSOR(
const void* input,
int length,
void* output,
int maxout);
130int fastlz_compress(
const void* input,
int length,
void* output)
134 return fastlz1_compress(input, length, output);
137 return fastlz2_compress(input, length, output);
140int fastlz_decompress(
const void* input,
int length,
void* output,
int maxout)
143 int level = ((*(
const flzuint8*)input) >> 5) + 1;
146 return fastlz1_decompress(input, length, output, maxout);
148 return fastlz2_decompress(input, length, output, maxout);
154int fastlz_compress_level(
int level,
const void* input,
int length,
void* output)
157 return fastlz1_compress(input, length, output);
159 return fastlz2_compress(input, length, output);
166static FASTLZ_INLINE
int FASTLZ_COMPRESSOR(
const void* input,
int length,
void* output)
168 const flzuint8* ip = (
const flzuint8*) input;
169 const flzuint8* ip_bound = ip + length - 2;
170 const flzuint8* ip_limit = ip + length - 12;
171 flzuint8* op = (flzuint8*) output;
173 const flzuint8* htab[HASH_SIZE];
174 const flzuint8** hslot;
180 if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
187 while(ip <= ip_bound)
196 for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
206 while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
215 const flzuint8* anchor = ip;
219 if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
231 ref = anchor - 1 + 3;
237 HASH_FUNCTION(hval,ip);
242 distance = anchor - ref;
250 (distance >= MAX_DISTANCE) ||
252 (distance >= MAX_FARDISTANCE) ||
254 *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
259 if(distance >= MAX_DISTANCE)
261 if(*ip++ != *ref++ || *ip++!= *ref++)
280 if(*ref++ != x)
break;
else ip++;
286 if(*ref++ != *ip++)
break;
287 if(*ref++ != *ip++)
break;
288 if(*ref++ != *ip++)
break;
289 if(*ref++ != *ip++)
break;
290 if(*ref++ != *ip++)
break;
291 if(*ref++ != *ip++)
break;
292 if(*ref++ != *ip++)
break;
293 if(*ref++ != *ip++)
break;
295 if(*ref++ != *ip++)
break;
302 *(op-copy-1) = copy-1;
316 if(distance < MAX_DISTANCE)
320 *op++ = (len << 5) + (distance >> 8);
321 *op++ = (distance & 255);
325 *op++ = (7 << 5) + (distance >> 8);
326 for(len-=7; len >= 255; len-= 255)
329 *op++ = (distance & 255);
337 distance -= MAX_DISTANCE;
338 *op++ = (len << 5) + 31;
340 *op++ = distance >> 8;
341 *op++ = distance & 255;
345 distance -= MAX_DISTANCE;
346 *op++ = (7 << 5) + 31;
347 for(len-=7; len >= 255; len-= 255)
351 *op++ = distance >> 8;
352 *op++ = distance & 255;
357 if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
358 while(len > MAX_LEN-2)
360 *op++ = (7 << 5) + (distance >> 8);
361 *op++ = MAX_LEN - 2 - 7 -2;
362 *op++ = (distance & 255);
368 *op++ = (len << 5) + (distance >> 8);
369 *op++ = (distance & 255);
373 *op++ = (7 << 5) + (distance >> 8);
375 *op++ = (distance & 255);
380 HASH_FUNCTION(hval,ip);
382 HASH_FUNCTION(hval,ip);
394 if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
403 while(ip <= ip_bound)
416 *(op-copy-1) = copy-1;
422 *(flzuint8*)output |= (1 << 5);
425 return op - (flzuint8*)output;
428static FASTLZ_INLINE
int FASTLZ_DECOMPRESSOR(
const void* input,
int length,
void* output,
int maxout)
430 const flzuint8* ip = (
const flzuint8*) input;
431 const flzuint8* ip_limit = ip + length;
432 flzuint8* op = (flzuint8*) output;
433 flzuint8* op_limit = op + maxout;
434 flzuint32 ctrl = (*ip++) & 31;
439 const flzuint8* ref = op;
440 flzuint32 len = ctrl >> 5;
441 flzuint32 ofs = (ctrl & 31) << 8;
464 if(FASTLZ_UNEXPECT_CONDITIONAL(
code==255))
465 if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
469 ref = op - ofs - MAX_DISTANCE;
474 if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
477 if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
481 if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
489 flzuint8 b = ref[-1];
498#if !defined(FASTLZ_STRICT_ALIGN)
508#if !defined(FASTLZ_STRICT_ALIGN)
519 p = (
const flzuint16*) ref;
520 for(len>>=1; len > 4; len-=4)
539 if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
541 if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
546 for(--ctrl; ctrl; ctrl--)
549 loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
554 while(FASTLZ_EXPECT_CONDITIONAL(loop));
556 return op - (flzuint8*)output;
unsigned p
Definition tte.h:17