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)
411 hent = &hist_entries[hentno];
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];
742 if (
unlikely(sp > srcend || off == 0))
748 len =
Min(len, destend - dp);
765 memcpy(dp, dp - off, off);
795 memcpy(dp, dp - off, len);
817 if (check_complete && (dp != destend || sp != srcend))
823 return (
char *) dp -
dest;
844 int64 compressed_size;
853 compressed_size = ((int64) rawsize * 9 + 7) / 8;
863 compressed_size += 2;
869 compressed_size =
Min(compressed_size, total_compressed_size);
871 return (
int32) compressed_size;
int32 pglz_maximum_compressed_size(int32 rawsize, int32 total_compressed_size)
struct PGLZ_HistEntry * next
#define pglz_hist_add(_hs, _he, _hn, _recycle, _s, _e, _mask)
struct PGLZ_HistEntry PGLZ_HistEntry
static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE+1]
int32 pglz_decompress(const char *source, int32 slen, char *dest, int32 rawsize, bool check_complete)
static const PGLZ_Strategy strategy_default_data
#define pglz_out_tag(_ctrlp, _ctrlb, _ctrl, _buf, _len, _off)
static int16 hist_start[PGLZ_MAX_HISTORY_LISTS]
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)
int32 pglz_compress(const char *source, int32 slen, char *dest, const PGLZ_Strategy *strategy)
struct PGLZ_HistEntry * prev
#define pglz_out_literal(_ctrlp, _ctrlb, _ctrl, _buf, _byte)
#define PGLZ_MAX_HISTORY_LISTS
#define INVALID_ENTRY_PTR
#define pglz_hist_idx(_s, _e, _mask)
#define PGLZ_HISTORY_SIZE
static rewind_source * source
const PGLZ_Strategy *const PGLZ_strategy_always
static const PGLZ_Strategy strategy_always_data
const PGLZ_Strategy *const PGLZ_strategy_default