lz4hc.c
Go to the documentation of this file.
1 /*
2  LZ4 HC - High Compression Mode of LZ4
3  Copyright (C) 2011-2017, Yann Collet.
4 
5  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are
9  met:
10 
11  * Redistributions of source code must retain the above copyright
12  notice, this list of conditions and the following disclaimer.
13  * Redistributions in binary form must reproduce the above
14  copyright notice, this list of conditions and the following disclaimer
15  in the documentation and/or other materials provided with the
16  distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30  You can contact the author at :
31  - LZ4 source repository : https://github.com/lz4/lz4
32  - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
33 */
34 /* note : lz4hc is not an independent module, it requires lz4.h/lz4.c for proper compilation */
35 
36 
37 /* *************************************
38 * Tuning Parameter
39 ***************************************/
40 
46 #ifndef LZ4HC_HEAPMODE
47 # define LZ4HC_HEAPMODE 1
48 #endif
49 
50 
51 /*=== Dependency ===*/
52 #include "lz4hc.h"
53 
54 
55 /*=== Common LZ4 definitions ===*/
56 #if defined(__GNUC__)
57 # pragma GCC diagnostic ignored "-Wunused-function"
58 #endif
59 #if defined (__clang__)
60 # pragma clang diagnostic ignored "-Wunused-function"
61 #endif
62 
63 #define LZ4_COMMONDEFS_ONLY
64 #include "lz4.c" /* LZ4_count, constants, mem */
65 
66 
67 /*=== Constants ===*/
68 #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
69 
70 
71 /*=== Macros ===*/
72 #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
73 #define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK] /* flexible, LZ4HC_MAXD dependent */
74 #define DELTANEXTU16(table, pos) table[(U16)(pos)] /* faster */
75 
76 static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)); }
77 
78 
79 
80 /**************************************
81 * HC Compression
82 **************************************/
83 static void LZ4HC_init (LZ4HC_CCtx_internal* hc4, const BYTE* start)
84 {
85  MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
86  MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
87  hc4->nextToUpdate = 64 KB;
88  hc4->base = start - 64 KB;
89  hc4->end = start;
90  hc4->dictBase = start - 64 KB;
91  hc4->dictLimit = 64 KB;
92  hc4->lowLimit = 64 KB;
93 }
94 
95 
96 /* Update chains up to ip (excluded) */
98 {
99  U16* const chainTable = hc4->chainTable;
100  U32* const hashTable = hc4->hashTable;
101  const BYTE* const base = hc4->base;
102  U32 const target = (U32)(ip - base);
103  U32 idx = hc4->nextToUpdate;
104 
105  while (idx < target) {
106  U32 const h = LZ4HC_hashPtr(base+idx);
107  size_t delta = idx - hashTable[h];
108  if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
109  DELTANEXTU16(chainTable, idx) = (U16)delta;
110  hashTable[h] = idx;
111  idx++;
112  }
113 
114  hc4->nextToUpdate = target;
115 }
116 
117 
118 FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_CCtx_internal* const hc4, /* Index table will be updated */
119  const BYTE* const ip, const BYTE* const iLimit,
120  const BYTE** matchpos,
121  const int maxNbAttempts)
122 {
123  U16* const chainTable = hc4->chainTable;
124  U32* const HashTable = hc4->hashTable;
125  const BYTE* const base = hc4->base;
126  const BYTE* const dictBase = hc4->dictBase;
127  const U32 dictLimit = hc4->dictLimit;
128  const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
129  U32 matchIndex;
130  int nbAttempts = maxNbAttempts;
131  size_t ml = 0;
132 
133  /* HC4 match finder */
134  LZ4HC_Insert(hc4, ip);
135  matchIndex = HashTable[LZ4HC_hashPtr(ip)];
136 
137  while ((matchIndex>=lowLimit) && (nbAttempts)) {
138  nbAttempts--;
139  if (matchIndex >= dictLimit) {
140  const BYTE* const match = base + matchIndex;
141  if ( (*(match+ml) == *(ip+ml)) /* can be longer */
142  && (LZ4_read32(match) == LZ4_read32(ip)) )
143  {
144  size_t const mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
145  if (mlt > ml) { ml = mlt; *matchpos = match; }
146  }
147  } else {
148  const BYTE* const match = dictBase + matchIndex;
149  if (LZ4_read32(match) == LZ4_read32(ip)) {
150  size_t mlt;
151  const BYTE* vLimit = ip + (dictLimit - matchIndex);
152  if (vLimit > iLimit) vLimit = iLimit;
153  mlt = LZ4_count(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
154  if ((ip+mlt == vLimit) && (vLimit < iLimit))
155  mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit);
156  if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; } /* virtual matchpos */
157  }
158  }
159  matchIndex -= DELTANEXTU16(chainTable, matchIndex);
160  }
161 
162  return (int)ml;
163 }
164 
165 
167  LZ4HC_CCtx_internal* hc4,
168  const BYTE* const ip,
169  const BYTE* const iLowLimit,
170  const BYTE* const iHighLimit,
171  int longest,
172  const BYTE** matchpos,
173  const BYTE** startpos,
174  const int maxNbAttempts)
175 {
176  U16* const chainTable = hc4->chainTable;
177  U32* const HashTable = hc4->hashTable;
178  const BYTE* const base = hc4->base;
179  const U32 dictLimit = hc4->dictLimit;
180  const BYTE* const lowPrefixPtr = base + dictLimit;
181  const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
182  const BYTE* const dictBase = hc4->dictBase;
183  int const delta = (int)(ip-iLowLimit);
184  int nbAttempts = maxNbAttempts;
185  U32 matchIndex;
186 
187 
188  /* First Match */
189  LZ4HC_Insert(hc4, ip);
190  matchIndex = HashTable[LZ4HC_hashPtr(ip)];
191 
192  while ((matchIndex>=lowLimit) && (nbAttempts)) {
193  nbAttempts--;
194  if (matchIndex >= dictLimit) {
195  const BYTE* const matchPtr = base + matchIndex;
196  if (*(iLowLimit + longest) == *(matchPtr - delta + longest)) {
197  if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
198  int mlt = MINMATCH + LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, iHighLimit);
199  int back = 0;
200 
201  while ( (ip+back > iLowLimit)
202  && (matchPtr+back > lowPrefixPtr)
203  && (ip[back-1] == matchPtr[back-1])) {
204  back--;
205  }
206 
207  mlt -= back;
208 
209  if (mlt > longest) {
210  longest = mlt;
211  *matchpos = matchPtr+back;
212  *startpos = ip+back;
213  } } }
214  } else {
215  const BYTE* const matchPtr = dictBase + matchIndex;
216  if (LZ4_read32(matchPtr) == LZ4_read32(ip)) {
217  int mlt;
218  int back=0;
219  const BYTE* vLimit = ip + (dictLimit - matchIndex);
220  if (vLimit > iHighLimit) vLimit = iHighLimit;
221  mlt = LZ4_count(ip+MINMATCH, matchPtr+MINMATCH, vLimit) + MINMATCH;
222  if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
223  mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit);
224  while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == matchPtr[back-1])) back--;
225  mlt -= back;
226  if (mlt > longest) { longest = mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
227  }
228  }
229  matchIndex -= DELTANEXTU16(chainTable, matchIndex);
230  }
231 
232  return longest;
233 }
234 
235 
236 typedef enum {
237  noLimit = 0,
241 
242 #ifndef LZ4HC_DEBUG
243 # define LZ4HC_DEBUG 0
244 #endif
245 
246 /* LZ4HC_encodeSequence() :
247  * @return : 0 if ok,
248  * 1 if buffer issue detected */
250  const BYTE** ip,
251  BYTE** op,
252  const BYTE** anchor,
253  int matchLength,
254  const BYTE* const match,
256  BYTE* oend)
257 {
258  size_t length;
259  BYTE* const token = (*op)++;
260 
261 #if LZ4HC_DEBUG
262  printf("literal : %u -- match : %u -- offset : %u\n",
263  (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));
264 #endif
265 
266  /* Encode Literal length */
267  length = (size_t)(*ip - *anchor);
268  if ((limit) && ((*op + (length >> 8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1; /* Check output limit */
269  if (length >= RUN_MASK) {
270  size_t len = length - RUN_MASK;
271  *token = (RUN_MASK << ML_BITS);
272  for(; len >= 255 ; len -= 255) *(*op)++ = 255;
273  *(*op)++ = (BYTE)len;
274  } else {
275  *token = (BYTE)(length << ML_BITS);
276  }
277 
278  /* Copy Literals */
279  LZ4_wildCopy(*op, *anchor, (*op) + length);
280  *op += length;
281 
282  /* Encode Offset */
283  LZ4_writeLE16(*op, (U16)(*ip-match)); *op += 2;
284 
285  /* Encode MatchLength */
286  length = (size_t)(matchLength - MINMATCH);
287  if ((limit) && (*op + (length >> 8) + (1 + LASTLITERALS) > oend)) return 1; /* Check output limit */
288  if (length >= ML_MASK) {
289  *token += ML_MASK;
290  length -= ML_MASK;
291  for(; length >= 510 ; length -= 510) { *(*op)++ = 255; *(*op)++ = 255; }
292  if (length >= 255) { length -= 255; *(*op)++ = 255; }
293  *(*op)++ = (BYTE)length;
294  } else {
295  *token += (BYTE)(length);
296  }
297 
298  /* Prepare next loop */
299  *ip += matchLength;
300  *anchor = *ip;
301 
302  return 0;
303 }
304 
305 /* btopt */
306 #include "lz4opt.h"
307 
308 
310  LZ4HC_CCtx_internal* const ctx,
311  const char* const source,
312  char* const dest,
313  int* srcSizePtr,
314  int const maxOutputSize,
315  unsigned maxNbAttempts,
317  )
318 {
319  const int inputSize = *srcSizePtr;
320 
321  const BYTE* ip = (const BYTE*) source;
322  const BYTE* anchor = ip;
323  const BYTE* const iend = ip + inputSize;
324  const BYTE* const mflimit = iend - MFLIMIT;
325  const BYTE* const matchlimit = (iend - LASTLITERALS);
326 
327  BYTE* optr = (BYTE*) dest;
328  BYTE* op = (BYTE*) dest;
329  BYTE* oend = op + maxOutputSize;
330 
331  int ml, ml2, ml3, ml0;
332  const BYTE* ref = NULL;
333  const BYTE* start2 = NULL;
334  const BYTE* ref2 = NULL;
335  const BYTE* start3 = NULL;
336  const BYTE* ref3 = NULL;
337  const BYTE* start0;
338  const BYTE* ref0;
339 
340  /* init */
341  *srcSizePtr = 0;
342  if (limit == limitedDestSize && maxOutputSize < 1) return 0; /* Impossible to store anything */
343  if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */
344 
345  ctx->end += inputSize;
346  if (limit == limitedDestSize) oend -= LASTLITERALS; /* Hack for support limitations LZ4 decompressor */
347  if (inputSize < LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
348 
349  ip++;
350 
351  /* Main Loop */
352  while (ip < mflimit) {
353  ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
354  if (!ml) { ip++; continue; }
355 
356  /* saved, in case we would skip too much */
357  start0 = ip;
358  ref0 = ref;
359  ml0 = ml;
360 
361 _Search2:
362  if (ip+ml < mflimit)
363  ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 0, matchlimit, ml, &ref2, &start2, maxNbAttempts);
364  else
365  ml2 = ml;
366 
367  if (ml2 == ml) { /* No better match */
368  optr = op;
369  if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow;
370  continue;
371  }
372 
373  if (start0 < ip) {
374  if (start2 < ip + ml0) { /* empirical */
375  ip = start0;
376  ref = ref0;
377  ml = ml0;
378  }
379  }
380 
381  /* Here, start0==ip */
382  if ((start2 - ip) < 3) { /* First Match too small : removed */
383  ml = ml2;
384  ip = start2;
385  ref =ref2;
386  goto _Search2;
387  }
388 
389 _Search3:
390  /* At this stage, we have :
391  * ml2 > ml1, and
392  * ip1+3 <= ip2 (usually < ip1+ml1) */
393  if ((start2 - ip) < OPTIMAL_ML) {
394  int correction;
395  int new_ml = ml;
396  if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
397  if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
398  correction = new_ml - (int)(start2 - ip);
399  if (correction > 0) {
400  start2 += correction;
401  ref2 += correction;
402  ml2 -= correction;
403  }
404  }
405  /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
406 
407  if (start2 + ml2 < mflimit)
408  ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
409  else
410  ml3 = ml2;
411 
412  if (ml3 == ml2) { /* No better match : 2 sequences to encode */
413  /* ip & ref are known; Now for ml */
414  if (start2 < ip+ml) ml = (int)(start2 - ip);
415  /* Now, encode 2 sequences */
416  optr = op;
417  if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow;
418  ip = start2;
419  optr = op;
420  if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) goto _dest_overflow;
421  continue;
422  }
423 
424  if (start3 < ip+ml+3) { /* Not enough space for match 2 : remove it */
425  if (start3 >= (ip+ml)) { /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
426  if (start2 < ip+ml) {
427  int correction = (int)(ip+ml - start2);
428  start2 += correction;
429  ref2 += correction;
430  ml2 -= correction;
431  if (ml2 < MINMATCH) {
432  start2 = start3;
433  ref2 = ref3;
434  ml2 = ml3;
435  }
436  }
437 
438  optr = op;
439  if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow;
440  ip = start3;
441  ref = ref3;
442  ml = ml3;
443 
444  start0 = start2;
445  ref0 = ref2;
446  ml0 = ml2;
447  goto _Search2;
448  }
449 
450  start2 = start3;
451  ref2 = ref3;
452  ml2 = ml3;
453  goto _Search3;
454  }
455 
456  /*
457  * OK, now we have 3 ascending matches; let's write at least the first one
458  * ip & ref are known; Now for ml
459  */
460  if (start2 < ip+ml) {
461  if ((start2 - ip) < (int)ML_MASK) {
462  int correction;
463  if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
464  if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
465  correction = ml - (int)(start2 - ip);
466  if (correction > 0) {
467  start2 += correction;
468  ref2 += correction;
469  ml2 -= correction;
470  }
471  } else {
472  ml = (int)(start2 - ip);
473  }
474  }
475  optr = op;
476  if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) goto _dest_overflow;
477 
478  ip = start2;
479  ref = ref2;
480  ml = ml2;
481 
482  start2 = start3;
483  ref2 = ref3;
484  ml2 = ml3;
485 
486  goto _Search3;
487  }
488 
489 _last_literals:
490  /* Encode Last Literals */
491  { size_t lastRunSize = (size_t)(iend - anchor); /* literals */
492  size_t litLength = (lastRunSize + 255 - RUN_MASK) / 255;
493  size_t const totalSize = 1 + litLength + lastRunSize;
494  if (limit == limitedDestSize) oend += LASTLITERALS; /* restore correct value */
495  if (limit && (op + totalSize > oend)) {
496  if (limit == limitedOutput) return 0; /* Check output limit */
497  /* adapt lastRunSize to fill 'dest' */
498  lastRunSize = (size_t)(oend - op) - 1;
499  litLength = (lastRunSize + 255 - RUN_MASK) / 255;
500  lastRunSize -= litLength;
501  }
502  ip = anchor + lastRunSize;
503 
504  if (lastRunSize >= RUN_MASK) {
505  size_t accumulator = lastRunSize - RUN_MASK;
506  *op++ = (RUN_MASK << ML_BITS);
507  for(; accumulator >= 255 ; accumulator -= 255) *op++ = 255;
508  *op++ = (BYTE) accumulator;
509  } else {
510  *op++ = (BYTE)(lastRunSize << ML_BITS);
511  }
512  memcpy(op, anchor, lastRunSize);
513  op += lastRunSize;
514  }
515 
516  /* End */
517  *srcSizePtr = (int) (((const char*)ip) - source);
518  return (int) (((char*)op)-dest);
519 
520 _dest_overflow:
521  if (limit == limitedDestSize) {
522  op = optr; /* restore correct out pointer */
523  goto _last_literals;
524  }
525  return 0;
526 }
527 
529 {
530  switch (compressionLevel) {
531  default: return 0; /* unused */
532  case 11: return 128;
533  case 12: return 1<<10;
534  }
535 }
536 
538  LZ4HC_CCtx_internal* const ctx,
539  const char* const src,
540  char* const dst,
541  int* const srcSizePtr,
542  int const dstCapacity,
543  int cLevel,
545  )
546 {
547  if (cLevel < 1) cLevel = LZ4HC_CLEVEL_DEFAULT; /* note : convention is different from lz4frame, maybe to reconsider */
548  if (cLevel > 9) {
549  if (limit == limitedDestSize) cLevel = 10;
550  switch (cLevel) {
551  case 10:
552  return LZ4HC_compress_hashChain(ctx, src, dst, srcSizePtr, dstCapacity, 1 << 12, limit);
553  case 11:
554  ctx->searchNum = LZ4HC_getSearchNum(cLevel);
555  return LZ4HC_compress_optimal(ctx, src, dst, *srcSizePtr, dstCapacity, limit, 128, 0);
556  default:
557  cLevel = 12;
558  /* fall-through */
559  case 12:
560  ctx->searchNum = LZ4HC_getSearchNum(cLevel);
561  return LZ4HC_compress_optimal(ctx, src, dst, *srcSizePtr, dstCapacity, limit, LZ4_OPT_NUM, 1);
562  }
563  }
564  return LZ4HC_compress_hashChain(ctx, src, dst, srcSizePtr, dstCapacity, 1 << (cLevel-1), limit); /* levels 1-9 */
565 }
566 
567 
568 int LZ4_sizeofStateHC(void) { return sizeof(LZ4_streamHC_t); }
569 
570 int LZ4_compress_HC_extStateHC (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel)
571 {
572  LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
573  if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0; /* Error : state is not aligned for pointers (32 or 64 bits) */
574  LZ4HC_init (ctx, (const BYTE*)src);
575  if (dstCapacity < LZ4_compressBound(srcSize))
576  return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, limitedOutput);
577  else
578  return LZ4HC_compress_generic (ctx, src, dst, &srcSize, dstCapacity, compressionLevel, noLimit);
579 }
580 
581 int LZ4_compress_HC(const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel)
582 {
583 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
584  LZ4_streamHC_t* const statePtr = (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t));
585 #else
587  LZ4_streamHC_t* const statePtr = &state;
588 #endif
589  int const cSize = LZ4_compress_HC_extStateHC(statePtr, src, dst, srcSize, dstCapacity, compressionLevel);
590 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
591  free(statePtr);
592 #endif
593  return cSize;
594 }
595 
596 /* LZ4_compress_HC_destSize() :
597  * currently, only compatible with Hash Chain implementation,
598  * hence limit compression level to LZ4HC_CLEVEL_OPT_MIN-1*/
599 int LZ4_compress_HC_destSize(void* LZ4HC_Data, const char* source, char* dest, int* sourceSizePtr, int targetDestSize, int cLevel)
600 {
601  LZ4HC_CCtx_internal* const ctx = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse;
602  LZ4HC_init(ctx, (const BYTE*) source);
603  return LZ4HC_compress_generic(ctx, source, dest, sourceSizePtr, targetDestSize, cLevel, limitedDestSize);
604 }
605 
606 
607 
608 /**************************************
609 * Streaming Functions
610 **************************************/
611 /* allocation */
613 int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; }
614 
615 
616 /* initialization */
618 {
619  LZ4_STATIC_ASSERT(sizeof(LZ4HC_CCtx_internal) <= sizeof(size_t) * LZ4_STREAMHCSIZE_SIZET); /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
620  LZ4_streamHCPtr->internal_donotuse.base = NULL;
621  if (compressionLevel > LZ4HC_CLEVEL_MAX) compressionLevel = LZ4HC_CLEVEL_MAX; /* cap compression level */
623  LZ4_streamHCPtr->internal_donotuse.searchNum = LZ4HC_getSearchNum(compressionLevel);
624 }
625 
626 int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
627 {
628  LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
629  if (dictSize > 64 KB) {
630  dictionary += dictSize - 64 KB;
631  dictSize = 64 KB;
632  }
633  LZ4HC_init (ctxPtr, (const BYTE*)dictionary);
634  ctxPtr->end = (const BYTE*)dictionary + dictSize;
635  if (ctxPtr->compressionLevel >= LZ4HC_CLEVEL_OPT_MIN)
636  LZ4HC_updateBinTree(ctxPtr, ctxPtr->end - MFLIMIT, ctxPtr->end - LASTLITERALS);
637  else
638  if (dictSize >= 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3);
639  return dictSize;
640 }
641 
642 
643 /* compression */
644 
645 static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal* ctxPtr, const BYTE* newBlock)
646 {
647  if (ctxPtr->compressionLevel >= LZ4HC_CLEVEL_OPT_MIN)
648  LZ4HC_updateBinTree(ctxPtr, ctxPtr->end - MFLIMIT, ctxPtr->end - LASTLITERALS);
649  else
650  if (ctxPtr->end >= ctxPtr->base + 4) LZ4HC_Insert (ctxPtr, ctxPtr->end-3); /* Referencing remaining dictionary content */
651 
652  /* Only one memory segment for extDict, so any previous extDict is lost at this stage */
653  ctxPtr->lowLimit = ctxPtr->dictLimit;
654  ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
655  ctxPtr->dictBase = ctxPtr->base;
656  ctxPtr->base = newBlock - ctxPtr->dictLimit;
657  ctxPtr->end = newBlock;
658  ctxPtr->nextToUpdate = ctxPtr->dictLimit; /* match referencing will resume from there */
659 }
660 
661 static int LZ4_compressHC_continue_generic (LZ4_streamHC_t* LZ4_streamHCPtr,
662  const char* src, char* dst,
663  int* srcSizePtr, int dstCapacity,
665 {
666  LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
667  /* auto-init if forgotten */
668  if (ctxPtr->base == NULL) LZ4HC_init (ctxPtr, (const BYTE*) src);
669 
670  /* Check overflow */
671  if ((size_t)(ctxPtr->end - ctxPtr->base) > 2 GB) {
672  size_t dictSize = (size_t)(ctxPtr->end - ctxPtr->base) - ctxPtr->dictLimit;
673  if (dictSize > 64 KB) dictSize = 64 KB;
674  LZ4_loadDictHC(LZ4_streamHCPtr, (const char*)(ctxPtr->end) - dictSize, (int)dictSize);
675  }
676 
677  /* Check if blocks follow each other */
678  if ((const BYTE*)src != ctxPtr->end) LZ4HC_setExternalDict(ctxPtr, (const BYTE*)src);
679 
680  /* Check overlapping input/dictionary space */
681  { const BYTE* sourceEnd = (const BYTE*) src + *srcSizePtr;
682  const BYTE* const dictBegin = ctxPtr->dictBase + ctxPtr->lowLimit;
683  const BYTE* const dictEnd = ctxPtr->dictBase + ctxPtr->dictLimit;
684  if ((sourceEnd > dictBegin) && ((const BYTE*)src < dictEnd)) {
685  if (sourceEnd > dictEnd) sourceEnd = dictEnd;
686  ctxPtr->lowLimit = (U32)(sourceEnd - ctxPtr->dictBase);
687  if (ctxPtr->dictLimit - ctxPtr->lowLimit < 4) ctxPtr->lowLimit = ctxPtr->dictLimit;
688  }
689  }
690 
691  return LZ4HC_compress_generic (ctxPtr, src, dst, srcSizePtr, dstCapacity, ctxPtr->compressionLevel, limit);
692 }
693 
694 int LZ4_compress_HC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int srcSize, int dstCapacity)
695 {
696  if (dstCapacity < LZ4_compressBound(srcSize))
697  return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, limitedOutput);
698  else
699  return LZ4_compressHC_continue_generic (LZ4_streamHCPtr, src, dst, &srcSize, dstCapacity, noLimit);
700 }
701 
702 int LZ4_compress_HC_continue_destSize (LZ4_streamHC_t* LZ4_streamHCPtr, const char* src, char* dst, int* srcSizePtr, int targetDestSize)
703 {
704  LZ4HC_CCtx_internal* const ctxPtr = &LZ4_streamHCPtr->internal_donotuse;
705  if (ctxPtr->compressionLevel >= LZ4HC_CLEVEL_OPT_MIN) LZ4HC_init(ctxPtr, (const BYTE*)src); /* not compatible with btopt implementation */
706  return LZ4_compressHC_continue_generic(LZ4_streamHCPtr, src, dst, srcSizePtr, targetDestSize, limitedDestSize);
707 }
708 
709 
710 
711 /* dictionary saving */
712 
713 int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
714 {
715  LZ4HC_CCtx_internal* const streamPtr = &LZ4_streamHCPtr->internal_donotuse;
716  int const prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
717  if (dictSize > 64 KB) dictSize = 64 KB;
718  if (dictSize < 4) dictSize = 0;
719  if (dictSize > prefixSize) dictSize = prefixSize;
720  memmove(safeBuffer, streamPtr->end - dictSize, dictSize);
721  { U32 const endIndex = (U32)(streamPtr->end - streamPtr->base);
722  streamPtr->end = (const BYTE*)safeBuffer + dictSize;
723  streamPtr->base = streamPtr->end - endIndex;
724  streamPtr->dictLimit = endIndex - dictSize;
725  streamPtr->lowLimit = endIndex - dictSize;
726  if (streamPtr->nextToUpdate < streamPtr->dictLimit) streamPtr->nextToUpdate = streamPtr->dictLimit;
727  }
728  return dictSize;
729 }
730 
731 
732 /***********************************
733 * Deprecated Functions
734 ***********************************/
735 /* These functions currently generate deprecation warnings */
736 /* Deprecated compression functions */
737 int LZ4_compressHC(const char* src, char* dst, int srcSize) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), 0); }
738 int LZ4_compressHC_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, 0); }
739 int LZ4_compressHC2(const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC (src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }
740 int LZ4_compressHC2_limitedOutput(const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC(src, dst, srcSize, maxDstSize, cLevel); }
741 int LZ4_compressHC_withStateHC (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, LZ4_compressBound(srcSize), 0); }
742 int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_extStateHC (state, src, dst, srcSize, maxDstSize, 0); }
743 int LZ4_compressHC2_withStateHC (void* state, const char* src, char* dst, int srcSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, LZ4_compressBound(srcSize), cLevel); }
744 int LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* src, char* dst, int srcSize, int maxDstSize, int cLevel) { return LZ4_compress_HC_extStateHC(state, src, dst, srcSize, maxDstSize, cLevel); }
745 int LZ4_compressHC_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, LZ4_compressBound(srcSize)); }
746 int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* ctx, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_HC_continue (ctx, src, dst, srcSize, maxDstSize); }
747 
748 
749 /* Deprecated streaming functions */
751 
753 {
754  LZ4HC_CCtx_internal *ctx = &((LZ4_streamHC_t*)state)->internal_donotuse;
755  if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */
756  LZ4HC_init(ctx, (const BYTE*)inputBuffer);
757  ctx->inputBuffer = (BYTE*)inputBuffer;
758  return 0;
759 }
760 
762 {
764  if (hc4 == NULL) return NULL; /* not enough memory */
765  LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer);
766  hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer;
767  return hc4;
768 }
769 
770 int LZ4_freeHC (void* LZ4HC_Data) { FREEMEM(LZ4HC_Data); return 0; }
771 
772 int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int cLevel)
773 {
774  return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, 0, cLevel, noLimit);
775 }
776 
777 int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* src, char* dst, int srcSize, int dstCapacity, int cLevel)
778 {
779  return LZ4HC_compress_generic (&((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse, src, dst, &srcSize, dstCapacity, cLevel, limitedOutput);
780 }
781 
782 char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
783 {
784  LZ4HC_CCtx_internal* const hc4 = &((LZ4_streamHC_t*)LZ4HC_Data)->internal_donotuse;
785  int const dictSize = LZ4_saveDictHC((LZ4_streamHC_t*)LZ4HC_Data, (char*)(hc4->inputBuffer), 64 KB);
786  return (char*)(hc4->inputBuffer + dictSize);
787 }
unsigned char * inputBuffer
Definition: lz4hc.h:168
int LZ4_freeHC(void *LZ4HC_Data)
Definition: lz4hc.c:770
static int LZ4HC_compress_optimal(LZ4HC_CCtx_internal *ctx, const char *const source, char *dest, int inputSize, int maxOutputSize, limitedOutput_directive limit, size_t sufficient_len, const int fullUpdate)
Definition: lz4opt.h:208
FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch(LZ4HC_CCtx_internal *hc4, const BYTE *const ip, const BYTE *const iLowLimit, const BYTE *const iHighLimit, int longest, const BYTE **matchpos, const BYTE **startpos, const int maxNbAttempts)
Definition: lz4hc.c:166
#define MINMATCH
Definition: lz4.c:262
#define LZ4HC_CLEVEL_DEFAULT
Definition: lz4hc.h:48
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:626
unsigned int U32
Definition: lz4.c:147
#define HASH_FUNCTION(i)
Definition: lz4hc.c:72
int LZ4_compressHC2_withStateHC(void *state, const char *src, char *dst, int srcSize, int cLevel)
Definition: lz4hc.c:743
int LZ4_compressHC(const char *src, char *dst, int srcSize)
Definition: lz4hc.c:737
#define LZ4HC_CLEVEL_MAX
Definition: lz4hc.h:50
static U32 LZ4HC_hashPtr(const void *ptr)
Definition: lz4hc.c:76
int LZ4_compressHC_withStateHC(void *state, const char *src, char *dst, int srcSize)
Definition: lz4hc.c:741
unsigned int dictLimit
Definition: lz4hc.h:169
#define LASTLITERALS
Definition: lz4.c:265
#define LZ4HC_CLEVEL_OPT_MIN
Definition: lz4hc.h:49
LZ4LIB_API char * inputBuffer
Definition: lz4.h:452
static int LZ4HC_getSearchNum(int compressionLevel)
Definition: lz4hc.c:528
int LZ4_compress_HC(const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:581
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
Definition: lz4hc.c:613
#define FREEMEM
Definition: lz4.c:128
void LZ4_resetStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:617
GLenum GLenum dst
Definition: glext.h:1751
LZ4HC_CCtx_internal internal_donotuse
Definition: lz4hc.h:182
#define LZ4_OPT_NUM
Definition: lz4opt.h:36
union LZ4_streamHC_u LZ4_streamHC_t
Definition: lz4hc.h:87
FORCE_INLINE int LZ4HC_encodeSequence(const BYTE **ip, BYTE **op, const BYTE **anchor, int matchLength, const BYTE *const match, limitedOutput_directive limit, BYTE *oend)
Definition: lz4hc.c:249
LZ4LIB_API char int int compressionLevel
Definition: lz4hc.h:203
#define MAX_DISTANCE
Definition: lz4.c:274
GLenum src
Definition: glext.h:1751
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
static void LZ4HC_setExternalDict(LZ4HC_CCtx_internal *ctxPtr, const BYTE *newBlock)
Definition: lz4hc.c:645
GLint limit
Definition: glext.h:9964
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:612
const unsigned char * dictBase
Definition: lz4hc.h:167
int LZ4_compressHC_limitedOutput_continue(LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize, int maxDstSize)
Definition: lz4hc.c:746
int LZ4_compressHC2_continue(void *LZ4HC_Data, const char *src, char *dst, int srcSize, int cLevel)
Definition: lz4hc.c:772
FORCE_INLINE int LZ4HC_InsertAndFindBestMatch(LZ4HC_CCtx_internal *const hc4, const BYTE *const ip, const BYTE *const iLimit, const BYTE **matchpos, const int maxNbAttempts)
Definition: lz4hc.c:118
unsigned int hashTable[LZ4HC_HASHTABLESIZE]
Definition: lz4hc.h:163
GLenum GLsizei len
Definition: glext.h:3285
#define FORCE_INLINE
Definition: lz4.c:109
int LZ4_compressHC_limitedOutput(const char *src, char *dst, int srcSize, int maxDstSize)
Definition: lz4hc.c:738
unsigned short U16
Definition: lz4.c:146
int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int targetDestSize)
Definition: lz4hc.c:702
limitedOutput_directive
Definition: lz4hc.c:236
int LZ4_compressHC2_limitedOutput_continue(void *LZ4HC_Data, const char *src, char *dst, int srcSize, int dstCapacity, int cLevel)
Definition: lz4hc.c:777
static int LZ4_compressHC_continue_generic(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int *srcSizePtr, int dstCapacity, limitedOutput_directive limit)
Definition: lz4hc.c:661
unsigned char BYTE
Definition: lz4.c:145
int LZ4_compress_HC_destSize(void *LZ4HC_Data, const char *source, char *dest, int *sourceSizePtr, int targetDestSize, int cLevel)
Definition: lz4hc.c:599
unsigned int lowLimit
Definition: lz4hc.h:170
#define ML_BITS
Definition: lz4.c:276
int LZ4_compressHC2_limitedOutput_withStateHC(void *state, const char *src, char *dst, int srcSize, int maxDstSize, int cLevel)
Definition: lz4hc.c:744
FORCE_INLINE void LZ4HC_updateBinTree(LZ4HC_CCtx_internal *ctx, const BYTE *const ip, const BYTE *const iHighLimit)
Definition: lz4opt.h:173
FORCE_INLINE void LZ4HC_Insert(LZ4HC_CCtx_internal *hc4, const BYTE *ip)
Definition: lz4hc.c:97
int LZ4_resetStreamStateHC(void *state, char *inputBuffer)
Definition: lz4hc.c:752
unsigned int nextToUpdate
Definition: lz4hc.h:171
static void LZ4HC_init(LZ4HC_CCtx_internal *hc4, const BYTE *start)
Definition: lz4hc.c:83
#define DELTANEXTU16(table, pos)
Definition: lz4hc.c:74
#define KB
Definition: lz4.c:269
Definition: lz4hc.c:237
#define MEM_INIT
Definition: lz4.c:130
GLenum target
Definition: glext.h:1565
static const int LZ4_minLength
Definition: lz4.c:267
int LZ4_sizeofStateHC(void)
Definition: lz4hc.c:568
void * LZ4_createHC(char *inputBuffer)
Definition: lz4hc.c:761
#define ALLOCATOR(n, s)
Definition: lz4.c:127
GLuint start
static void LZ4_writeLE16(void *memPtr, U16 value)
Definition: lz4.c:232
int LZ4_compressHC_continue(LZ4_streamHC_t *ctx, const char *src, char *dst, int srcSize)
Definition: lz4hc.c:745
static void LZ4_wildCopy(void *dstPtr, const void *srcPtr, void *dstEnd)
Definition: lz4.c:249
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:694
static U32 LZ4_read32(const void *memPtr)
Definition: lz4.c:199
#define LZ4_STATIC_ASSERT(c)
Definition: lz4.c:285
#define LZ4_MAX_INPUT_SIZE
Definition: lz4.h:152
unsigned int searchNum
Definition: lz4hc.h:172
LZ4LIB_API const char char int inputSize
Definition: lz4.h:440
const unsigned char * base
Definition: lz4hc.h:166
#define ML_MASK
Definition: lz4.c:277
static int LZ4HC_compress_generic(LZ4HC_CCtx_internal *const ctx, const char *const src, char *const dst, int *const srcSizePtr, int const dstCapacity, int cLevel, limitedOutput_directive limit)
Definition: lz4hc.c:537
int LZ4_compressHC2_limitedOutput(const char *src, char *dst, int srcSize, int maxDstSize, int cLevel)
Definition: lz4hc.c:740
LZ4LIB_API char int int maxDstSize
Definition: lz4.h:456
LZ4LIB_API char int int maxOutputSize
Definition: lz4.h:439
GLint ref
int LZ4_compressHC2(const char *src, char *dst, int srcSize, int cLevel)
Definition: lz4hc.c:739
GLsizei GLsizei GLchar * source
#define RUN_MASK
Definition: lz4.c:279
LZ4LIB_API char * dest
Definition: lz4.h:438
#define LZ4_STREAMHCSIZE_SIZET
Definition: lz4hc.h:179
int LZ4_sizeofStreamStateHC(void)
Definition: lz4hc.c:750
int LZ4_compressBound(int isize)
Definition: lz4.c:406
int LZ4_compress_HC_extStateHC(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:570
#define NULL
Definition: tinycthread.c:47
#define GB
Definition: lz4.c:271
GLenum GLuint GLenum GLsizei length
limitedOutput_directive
Definition: lz4.c:391
#define LZ4_STREAMHCSIZE
Definition: lz4hc.h:178
char * LZ4_slideInputBufferHC(void *LZ4HC_Data)
Definition: lz4hc.c:782
unsigned short chainTable[LZ4HC_MAXD]
Definition: lz4hc.h:164
static int LZ4HC_compress_hashChain(LZ4HC_CCtx_internal *const ctx, const char *const source, char *const dest, int *srcSizePtr, int const maxOutputSize, unsigned maxNbAttempts, limitedOutput_directive limit)
Definition: lz4hc.c:309
int LZ4_compressHC_limitedOutput_withStateHC(void *state, const char *src, char *dst, int srcSize, int maxDstSize)
Definition: lz4hc.c:742
#define OPTIMAL_ML
Definition: lz4hc.c:68
#define MFLIMIT
Definition: lz4.c:266
int compressionLevel
Definition: lz4hc.h:173
const unsigned char * end
Definition: lz4hc.h:165
static unsigned LZ4_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *pInLimit)
Definition: lz4.c:362
int LZ4_saveDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize)
Definition: lz4hc.c:713


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:21