195 #define PGLZ_MAX_HISTORY_LISTS 8192
196 #define PGLZ_HISTORY_SIZE 4096
197 #define PGLZ_MAX_MATCH 273
262 #define INVALID_ENTRY 0
263 #define INVALID_ENTRY_PTR (&hist_entries[INVALID_ENTRY])
277 #define pglz_hist_idx(_s,_e, _mask) ( \
278 ((((_e) - (_s)) < 4) ? (int) (_s)[0] : \
279 (((_s)[0] << 6) ^ ((_s)[1] << 4) ^ \
280 ((_s)[2] << 2) ^ (_s)[3])) & (_mask) \
296 #define pglz_hist_add(_hs,_he,_hn,_recycle,_s,_e, _mask) \
298 int __hindex = pglz_hist_idx((_s),(_e), (_mask)); \
299 int16 *__myhsp = &(_hs)[__hindex]; \
300 PGLZ_HistEntry *__myhe = &(_he)[_hn]; \
302 if (__myhe->prev == NULL) \
303 (_hs)[__myhe->hindex] = __myhe->next - (_he); \
305 __myhe->prev->next = __myhe->next; \
306 if (__myhe->next != NULL) \
307 __myhe->next->prev = __myhe->prev; \
309 __myhe->next = &(_he)[*__myhsp]; \
310 __myhe->prev = NULL; \
311 __myhe->hindex = __hindex; \
312 __myhe->pos = (_s); \
321 (_he)[(*__myhsp)].prev = __myhe; \
323 if (++(_hn) >= PGLZ_HISTORY_SIZE + 1) { \
336 #define pglz_out_ctrl(__ctrlp,__ctrlb,__ctrl,__buf) \
338 if ((__ctrl & 0xff) == 0) \
340 *(__ctrlp) = __ctrlb; \
341 __ctrlp = (__buf)++; \
355 #define pglz_out_literal(_ctrlp,_ctrlb,_ctrl,_buf,_byte) \
357 pglz_out_ctrl(_ctrlp,_ctrlb,_ctrl,_buf); \
358 *(_buf)++ = (unsigned char)(_byte); \
371 #define pglz_out_tag(_ctrlp,_ctrlb,_ctrl,_buf,_len,_off) \
373 pglz_out_ctrl(_ctrlp,_ctrlb,_ctrl,_buf); \
378 (_buf)[0] = (unsigned char)((((_off) & 0xf00) >> 4) | 0x0f); \
379 (_buf)[1] = (unsigned char)(((_off) & 0xff)); \
380 (_buf)[2] = (unsigned char)((_len) - 18); \
383 (_buf)[0] = (unsigned char)((((_off) & 0xf00) >> 4) | ((_len) - 3)); \
384 (_buf)[1] = (unsigned char)((_off) & 0xff); \
400 int *lenp,
int *offp,
int good_match,
int good_drop,
int mask)
414 const char *ip =
input;
415 const char *hp = hent->
pos;
423 if (thisoff >= 0x0fff)
437 if (memcmp(ip, hp,
len) == 0)
480 if (
len >= good_match)
482 good_match -= (good_match * good_drop) / 100;
512 unsigned char *bp = (
unsigned char *)
dest;
513 unsigned char *bstart = bp;
515 bool hist_recycle =
false;
517 const char *dend =
source + slen;
518 unsigned char ctrl_dummy = 0;
519 unsigned char *ctrlp = &ctrl_dummy;
520 unsigned char ctrlb = 0;
521 unsigned char ctrl = 0;
522 bool found_match =
false;
536 if (strategy == NULL)
544 slen < strategy->min_input_size ||
554 else if (good_match < 17)
560 else if (good_drop > 100)
566 else if (need_rate > 99)
574 if (slen > (INT_MAX / 100))
577 result_max = (slen / 100) * (100 - need_rate);
580 result_max = (slen * (100 - need_rate)) / 100;
594 else if (slen < 1024)
618 if (bp - bstart >= result_max)
634 &match_off, good_match, good_drop, mask))
640 pglz_out_tag(ctrlp, ctrlb, ctrl, bp, match_len, match_off);
644 hist_next, hist_recycle,
658 hist_next, hist_recycle,
670 result_size = bp - bstart;
671 if (result_size >= result_max)
693 int32 rawsize,
bool check_complete)
695 const unsigned char *sp;
696 const unsigned char *srcend;
698 unsigned char *destend;
700 sp = (
const unsigned char *)
source;
701 srcend = ((
const unsigned char *)
source) + slen;
702 dp = (
unsigned char *)
dest;
703 destend = dp + rawsize;
705 while (sp < srcend && dp < destend)
711 unsigned char ctrl = *sp++;
714 for (ctrlc = 0; ctrlc < 8 && sp < srcend && dp < destend; ctrlc++)
730 len = (sp[0] & 0x0f) + 3;
731 off = ((sp[0] & 0xf0) << 4) | sp[1];
745 if (
unlikely(sp > srcend || off == 0 ||
746 off > (dp - (
unsigned char *)
dest)))
769 memcpy(dp, dp - off, off);
799 memcpy(dp, dp - off,
len);
821 if (check_complete && (dp != destend || sp != srcend))
827 return (
char *) dp -
dest;
848 int64 compressed_size;
857 compressed_size = ((int64) rawsize * 9 + 7) / 8;
867 compressed_size += 2;
873 compressed_size =
Min(compressed_size, total_compressed_size);
875 return (
int32) compressed_size;
const PGLZ_Strategy *const PGLZ_strategy_always
static int16 hist_start[PGLZ_MAX_HISTORY_LISTS]
const PGLZ_Strategy *const PGLZ_strategy_default
static int pglz_find_match(int16 *hstart, const char *input, const char *end, int *lenp, int *offp, int good_match, int good_drop, int mask)
#define INVALID_ENTRY_PTR
#define pglz_hist_idx(_s, _e, _mask)
static const PGLZ_Strategy strategy_default_data
struct PGLZ_HistEntry PGLZ_HistEntry
static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE+1]
static const PGLZ_Strategy strategy_always_data
#define pglz_out_tag(_ctrlp, _ctrlb, _ctrl, _buf, _len, _off)
#define PGLZ_MAX_HISTORY_LISTS
#define pglz_out_literal(_ctrlp, _ctrlb, _ctrl, _buf, _byte)
int32 pglz_decompress(const char *source, int32 slen, char *dest, int32 rawsize, bool check_complete)
#define PGLZ_HISTORY_SIZE
int32 pglz_compress(const char *source, int32 slen, char *dest, const PGLZ_Strategy *strategy)
#define pglz_hist_add(_hs, _he, _hn, _recycle, _s, _e, _mask)
int32 pglz_maximum_compressed_size(int32 rawsize, int32 total_compressed_size)
static rewind_source * source
struct PGLZ_HistEntry * next
struct PGLZ_HistEntry * prev