Rizin
unix-like reverse engineering framework and cli tools
lz4frame.c
Go to the documentation of this file.
1 /*
2  * LZ4 auto-framing library
3  * Copyright (C) 2011-2016, 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 homepage : http://www.lz4.org
32  * - LZ4 source repository : https://github.com/lz4/lz4
33  */
34 
35 /* LZ4F is a stand-alone API to create LZ4-compressed Frames
36  * in full conformance with specification v1.6.1 .
37  * This library rely upon memory management capabilities (malloc, free)
38  * provided either by <stdlib.h>,
39  * or redirected towards another library of user's choice
40  * (see Memory Routines below).
41  */
42 
43 
44 /*-************************************
45 * Compiler Options
46 **************************************/
47 #ifdef _MSC_VER /* Visual Studio */
48 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
49 #endif
50 
51 
52 /*-************************************
53 * Tuning parameters
54 **************************************/
55 /*
56  * LZ4F_HEAPMODE :
57  * Select how default compression functions will allocate memory for their hash table,
58  * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
59  */
60 #ifndef LZ4F_HEAPMODE
61 # define LZ4F_HEAPMODE 0
62 #endif
63 
64 
65 /*-************************************
66 * Memory routines
67 **************************************/
68 /*
69  * User may redirect invocations of
70  * malloc(), calloc() and free()
71  * towards another library or solution of their choice
72  * by modifying below section.
73  */
74 #ifndef LZ4_SRC_INCLUDED /* avoid redefinition when sources are coalesced */
75 # include <stdlib.h> /* malloc, calloc, free */
76 # define ALLOC(s) malloc(s)
77 # define ALLOC_AND_ZERO(s) calloc(1,(s))
78 # define FREEMEM(p) free(p)
79 #endif
80 
81 #include <string.h> /* memset, memcpy, memmove */
82 #ifndef LZ4_SRC_INCLUDED /* avoid redefinition when sources are coalesced */
83 # define MEM_INIT(p,v,s) memset((p),(v),(s))
84 #endif
85 
86 
87 /*-************************************
88 * Library declarations
89 **************************************/
90 #define LZ4F_STATIC_LINKING_ONLY
91 #include "lz4frame.h"
92 #define LZ4_STATIC_LINKING_ONLY
93 #include "lz4.h"
94 #define LZ4_HC_STATIC_LINKING_ONLY
95 #include "lz4hc.h"
96 #define XXH_STATIC_LINKING_ONLY
97 #include "xxhash.h"
98 
99 
100 /*-************************************
101 * Debug
102 **************************************/
103 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
104 # include <assert.h>
105 #else
106 # ifndef assert
107 # define assert(condition) ((void)0)
108 # endif
109 #endif
110 
111 #define LZ4F_STATIC_ASSERT(c) { enum { LZ4F_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
112 
113 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) && !defined(DEBUGLOG)
114 # include <stdio.h>
115 static int g_debuglog_enable = 1;
116 # define DEBUGLOG(l, ...) { \
117  if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
118  fprintf(stderr, __FILE__ ": "); \
119  fprintf(stderr, __VA_ARGS__); \
120  fprintf(stderr, " \n"); \
121  } }
122 #else
123 # define DEBUGLOG(l, ...) {} /* disabled */
124 #endif
125 
126 
127 /*-************************************
128 * Basic Types
129 **************************************/
130 #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
131 # include <stdint.h>
132  typedef uint8_t BYTE;
133  typedef uint16_t U16;
134  typedef uint32_t U32;
135  typedef int32_t S32;
136  typedef uint64_t U64;
137 #else
138  typedef unsigned char BYTE;
139  typedef unsigned short U16;
140  typedef unsigned int U32;
141  typedef signed int S32;
142  typedef unsigned long long U64;
143 #endif
144 
145 
146 /* unoptimized version; solves endianess & alignment issues */
147 static U32 LZ4F_readLE32 (const void* src)
148 {
149  const BYTE* const srcPtr = (const BYTE*)src;
150  U32 value32 = srcPtr[0];
151  value32 += ((U32)srcPtr[1])<< 8;
152  value32 += ((U32)srcPtr[2])<<16;
153  value32 += ((U32)srcPtr[3])<<24;
154  return value32;
155 }
156 
157 static void LZ4F_writeLE32 (void* dst, U32 value32)
158 {
159  BYTE* const dstPtr = (BYTE*)dst;
160  dstPtr[0] = (BYTE)value32;
161  dstPtr[1] = (BYTE)(value32 >> 8);
162  dstPtr[2] = (BYTE)(value32 >> 16);
163  dstPtr[3] = (BYTE)(value32 >> 24);
164 }
165 
166 static U64 LZ4F_readLE64 (const void* src)
167 {
168  const BYTE* const srcPtr = (const BYTE*)src;
169  U64 value64 = srcPtr[0];
170  value64 += ((U64)srcPtr[1]<<8);
171  value64 += ((U64)srcPtr[2]<<16);
172  value64 += ((U64)srcPtr[3]<<24);
173  value64 += ((U64)srcPtr[4]<<32);
174  value64 += ((U64)srcPtr[5]<<40);
175  value64 += ((U64)srcPtr[6]<<48);
176  value64 += ((U64)srcPtr[7]<<56);
177  return value64;
178 }
179 
180 static void LZ4F_writeLE64 (void* dst, U64 value64)
181 {
182  BYTE* const dstPtr = (BYTE*)dst;
183  dstPtr[0] = (BYTE)value64;
184  dstPtr[1] = (BYTE)(value64 >> 8);
185  dstPtr[2] = (BYTE)(value64 >> 16);
186  dstPtr[3] = (BYTE)(value64 >> 24);
187  dstPtr[4] = (BYTE)(value64 >> 32);
188  dstPtr[5] = (BYTE)(value64 >> 40);
189  dstPtr[6] = (BYTE)(value64 >> 48);
190  dstPtr[7] = (BYTE)(value64 >> 56);
191 }
192 
193 
194 /*-************************************
195 * Constants
196 **************************************/
197 #ifndef LZ4_SRC_INCLUDED /* avoid double definition */
198 # define KB *(1<<10)
199 # define MB *(1<<20)
200 # define GB *(1<<30)
201 #endif
202 
203 #define _1BIT 0x01
204 #define _2BITS 0x03
205 #define _3BITS 0x07
206 #define _4BITS 0x0F
207 #define _8BITS 0xFF
208 
209 #define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
210 #define LZ4F_MAGICNUMBER 0x184D2204U
211 #define LZ4F_BLOCKUNCOMPRESSED_FLAG 0x80000000U
212 #define LZ4F_BLOCKSIZEID_DEFAULT LZ4F_max64KB
213 
214 static const size_t minFHSize = LZ4F_HEADER_SIZE_MIN; /* 7 */
215 static const size_t maxFHSize = LZ4F_HEADER_SIZE_MAX; /* 19 */
216 static const size_t BHSize = LZ4F_BLOCK_HEADER_SIZE; /* block header : size, and compress flag */
217 static const size_t BFSize = LZ4F_BLOCK_CHECKSUM_SIZE; /* block footer : checksum (optional) */
218 
219 
220 /*-************************************
221 * Structures and local types
222 **************************************/
223 typedef struct LZ4F_cctx_s
224 {
228  const LZ4F_CDict* cdict;
229  size_t maxBlockSize;
233  size_t tmpInSize;
236  void* lz4CtxPtr;
237  U16 lz4CtxAlloc; /* sized for: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx */
238  U16 lz4CtxState; /* in use as: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx */
240 
241 
242 /*-************************************
243 * Error management
244 **************************************/
245 #define LZ4F_GENERATE_STRING(STRING) #STRING,
246 static const char* LZ4F_errorStrings[] = { LZ4F_LIST_ERRORS(LZ4F_GENERATE_STRING) };
247 
248 
250 {
251  return (code > (LZ4F_errorCode_t)(-LZ4F_ERROR_maxCode));
252 }
253 
255 {
256  static const char* codeError = "Unspecified error code";
257  if (LZ4F_isError(code)) return LZ4F_errorStrings[-(int)(code)];
258  return codeError;
259 }
260 
261 LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult)
262 {
263  if (!LZ4F_isError(functionResult)) return LZ4F_OK_NoError;
264  return (LZ4F_errorCodes)(-(ptrdiff_t)functionResult);
265 }
266 
267 static LZ4F_errorCode_t err0r(LZ4F_errorCodes code)
268 {
269  /* A compilation error here means sizeof(ptrdiff_t) is not large enough */
270  LZ4F_STATIC_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t));
271  return (LZ4F_errorCode_t)-(ptrdiff_t)code;
272 }
273 
274 unsigned LZ4F_getVersion(void) { return LZ4F_VERSION; }
275 
277 
278 size_t LZ4F_getBlockSize(unsigned blockSizeID)
279 {
280  static const size_t blockSizes[4] = { 64 KB, 256 KB, 1 MB, 4 MB };
281 
282  if (blockSizeID == 0) blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
283  if (blockSizeID < LZ4F_max64KB || blockSizeID > LZ4F_max4MB)
284  return err0r(LZ4F_ERROR_maxBlockSize_invalid);
285  blockSizeID -= LZ4F_max64KB;
286  return blockSizes[blockSizeID];
287 }
288 
289 /*-************************************
290 * Private functions
291 **************************************/
292 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
293 
294 static BYTE LZ4F_headerChecksum (const void* header, size_t length)
295 {
296  U32 const xxh = XXH32(header, length, 0);
297  return (BYTE)(xxh >> 8);
298 }
299 
300 
301 /*-************************************
302 * Simple-pass compression functions
303 **************************************/
305  const size_t srcSize)
306 {
307  LZ4F_blockSizeID_t proposedBSID = LZ4F_max64KB;
308  size_t maxBlockSize = 64 KB;
309  while (requestedBSID > proposedBSID) {
310  if (srcSize <= maxBlockSize)
311  return proposedBSID;
312  proposedBSID = (LZ4F_blockSizeID_t)((int)proposedBSID + 1);
313  maxBlockSize <<= 2;
314  }
315  return requestedBSID;
316 }
317 
325  const LZ4F_preferences_t* preferencesPtr,
326  size_t alreadyBuffered)
327 {
329  prefsNull.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; /* worst case */
330  prefsNull.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled; /* worst case */
331  { const LZ4F_preferences_t* const prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
332  U32 const flush = prefsPtr->autoFlush | (srcSize==0);
333  LZ4F_blockSizeID_t const blockID = prefsPtr->frameInfo.blockSizeID;
334  size_t const blockSize = LZ4F_getBlockSize(blockID);
335  size_t const maxBuffered = blockSize - 1;
336  size_t const bufferedSize = MIN(alreadyBuffered, maxBuffered);
337  size_t const maxSrcSize = srcSize + bufferedSize;
338  unsigned const nbFullBlocks = (unsigned)(maxSrcSize / blockSize);
339  size_t const partialBlockSize = maxSrcSize & (blockSize-1);
340  size_t const lastBlockSize = flush ? partialBlockSize : 0;
341  unsigned const nbBlocks = nbFullBlocks + (lastBlockSize>0);
342 
343  size_t const blockCRCSize = BFSize * prefsPtr->frameInfo.blockChecksumFlag;
344  size_t const frameEnd = BHSize + (prefsPtr->frameInfo.contentChecksumFlag*BFSize);
345 
346  return ((BHSize + blockCRCSize) * nbBlocks) +
347  (blockSize * nbFullBlocks) + lastBlockSize + frameEnd;
348  }
349 }
350 
351 size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr)
352 {
353  LZ4F_preferences_t prefs;
354  size_t const headerSize = maxFHSize; /* max header size, including optional fields */
355 
356  if (preferencesPtr!=NULL) prefs = *preferencesPtr;
357  else MEM_INIT(&prefs, 0, sizeof(prefs));
358  prefs.autoFlush = 1;
359 
360  return headerSize + LZ4F_compressBound_internal(srcSize, &prefs, 0);;
361 }
362 
363 
374  void* dstBuffer, size_t dstCapacity,
375  const void* srcBuffer, size_t srcSize,
376  const LZ4F_CDict* cdict,
377  const LZ4F_preferences_t* preferencesPtr)
378 {
379  LZ4F_preferences_t prefs;
381  BYTE* const dstStart = (BYTE*) dstBuffer;
382  BYTE* dstPtr = dstStart;
383  BYTE* const dstEnd = dstStart + dstCapacity;
384 
385  if (preferencesPtr!=NULL)
386  prefs = *preferencesPtr;
387  else
388  MEM_INIT(&prefs, 0, sizeof(prefs));
389  if (prefs.frameInfo.contentSize != 0)
390  prefs.frameInfo.contentSize = (U64)srcSize; /* auto-correct content size if selected (!=0) */
391 
393  prefs.autoFlush = 1;
395  prefs.frameInfo.blockMode = LZ4F_blockIndependent; /* only one block => no need for inter-block link */
396 
397  MEM_INIT(&options, 0, sizeof(options));
398  options.stableSrc = 1;
399 
400  if (dstCapacity < LZ4F_compressFrameBound(srcSize, &prefs)) /* condition to guarantee success */
401  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
402 
403  { size_t const headerSize = LZ4F_compressBegin_usingCDict(cctx, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
404  if (LZ4F_isError(headerSize)) return headerSize;
405  dstPtr += headerSize; /* header size */ }
406 
407  assert(dstEnd >= dstPtr);
408  { size_t const cSize = LZ4F_compressUpdate(cctx, dstPtr, (size_t)(dstEnd-dstPtr), srcBuffer, srcSize, &options);
409  if (LZ4F_isError(cSize)) return cSize;
410  dstPtr += cSize; }
411 
412  assert(dstEnd >= dstPtr);
413  { size_t const tailSize = LZ4F_compressEnd(cctx, dstPtr, (size_t)(dstEnd-dstPtr), &options); /* flush last block, and generate suffix */
414  if (LZ4F_isError(tailSize)) return tailSize;
415  dstPtr += tailSize; }
416 
417  assert(dstEnd >= dstStart);
418  return (size_t)(dstPtr - dstStart);
419 }
420 
421 
429 size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
430  const void* srcBuffer, size_t srcSize,
431  const LZ4F_preferences_t* preferencesPtr)
432 {
433  size_t result;
434 #if (LZ4F_HEAPMODE)
435  LZ4F_cctx_t *cctxPtr;
436  result = LZ4F_createCompressionContext(&cctxPtr, LZ4F_VERSION);
437  if (LZ4F_isError(result)) return result;
438 #else
439  LZ4F_cctx_t cctx;
440  LZ4_stream_t lz4ctx;
441  LZ4F_cctx_t *cctxPtr = &cctx;
442 
443  DEBUGLOG(4, "LZ4F_compressFrame");
444  MEM_INIT(&cctx, 0, sizeof(cctx));
445  cctx.version = LZ4F_VERSION;
446  cctx.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
447  if (preferencesPtr == NULL ||
448  preferencesPtr->compressionLevel < LZ4HC_CLEVEL_MIN)
449  {
450  LZ4_initStream(&lz4ctx, sizeof(lz4ctx));
451  cctxPtr->lz4CtxPtr = &lz4ctx;
452  cctxPtr->lz4CtxAlloc = 1;
453  cctxPtr->lz4CtxState = 1;
454  }
455 #endif
456 
457  result = LZ4F_compressFrame_usingCDict(cctxPtr, dstBuffer, dstCapacity,
458  srcBuffer, srcSize,
459  NULL, preferencesPtr);
460 
461 #if (LZ4F_HEAPMODE)
463 #else
464  if (preferencesPtr != NULL &&
465  preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN)
466  {
467  FREEMEM(cctxPtr->lz4CtxPtr);
468  }
469 #endif
470  return result;
471 }
472 
473 
474 /*-***************************************************
475 * Dictionary compression
476 *****************************************************/
477 
478 struct LZ4F_CDict_s {
479  void* dictContent;
482 }; /* typedef'd to LZ4F_CDict within lz4frame_static.h */
483 
490 LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
491 {
492  const char* dictStart = (const char*)dictBuffer;
493  LZ4F_CDict* cdict = (LZ4F_CDict*) ALLOC(sizeof(*cdict));
494  DEBUGLOG(4, "LZ4F_createCDict");
495  if (!cdict) return NULL;
496  if (dictSize > 64 KB) {
497  dictStart += dictSize - 64 KB;
498  dictSize = 64 KB;
499  }
500  cdict->dictContent = ALLOC(dictSize);
501  cdict->fastCtx = LZ4_createStream();
502  cdict->HCCtx = LZ4_createStreamHC();
503  if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
504  LZ4F_freeCDict(cdict);
505  return NULL;
506  }
507  memcpy(cdict->dictContent, dictStart, dictSize);
508  LZ4_loadDict (cdict->fastCtx, (const char*)cdict->dictContent, (int)dictSize);
510  LZ4_loadDictHC(cdict->HCCtx, (const char*)cdict->dictContent, (int)dictSize);
511  return cdict;
512 }
513 
514 void LZ4F_freeCDict(LZ4F_CDict* cdict)
515 {
516  if (cdict==NULL) return; /* support free on NULL */
517  FREEMEM(cdict->dictContent);
518  LZ4_freeStream(cdict->fastCtx);
519  LZ4_freeStreamHC(cdict->HCCtx);
520  FREEMEM(cdict);
521 }
522 
523 
524 /*-*********************************
525 * Advanced compression functions
526 ***********************************/
527 
536 LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx** LZ4F_compressionContextPtr, unsigned version)
537 {
538  LZ4F_cctx_t* const cctxPtr = (LZ4F_cctx_t*)ALLOC_AND_ZERO(sizeof(LZ4F_cctx_t));
539  if (cctxPtr==NULL) return err0r(LZ4F_ERROR_allocation_failed);
540 
541  cctxPtr->version = version;
542  cctxPtr->cStage = 0; /* Next stage : init stream */
543 
544  *LZ4F_compressionContextPtr = cctxPtr;
545 
546  return LZ4F_OK_NoError;
547 }
548 
549 
551 {
552  if (cctxPtr != NULL) { /* support free on NULL */
553  FREEMEM(cctxPtr->lz4CtxPtr); /* note: LZ4_streamHC_t and LZ4_stream_t are simple POD types */
554  FREEMEM(cctxPtr->tmpBuff);
555  FREEMEM(cctxPtr);
556  }
557 
558  return LZ4F_OK_NoError;
559 }
560 
561 
570 static void LZ4F_initStream(void* ctx,
571  const LZ4F_CDict* cdict,
572  int level,
573  LZ4F_blockMode_t blockMode) {
574  if (level < LZ4HC_CLEVEL_MIN) {
575  if (cdict != NULL || blockMode == LZ4F_blockLinked) {
576  /* In these cases, we will call LZ4_compress_fast_continue(),
577  * which needs an already reset context. Otherwise, we'll call a
578  * one-shot API. The non-continued APIs internally perform their own
579  * resets at the beginning of their calls, where they know what
580  * tableType they need the context to be in. So in that case this
581  * would be misguided / wasted work. */
583  }
584  LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL);
585  } else {
587  LZ4_attach_HC_dictionary((LZ4_streamHC_t *)ctx, cdict ? cdict->HCCtx : NULL);
588  }
589 }
590 
591 
599  void* dstBuffer, size_t dstCapacity,
600  const LZ4F_CDict* cdict,
601  const LZ4F_preferences_t* preferencesPtr)
602 {
603  LZ4F_preferences_t prefNull;
604  BYTE* const dstStart = (BYTE*)dstBuffer;
605  BYTE* dstPtr = dstStart;
606  BYTE* headerStart;
607 
608  if (dstCapacity < maxFHSize) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
609  MEM_INIT(&prefNull, 0, sizeof(prefNull));
610  if (preferencesPtr == NULL) preferencesPtr = &prefNull;
611  cctxPtr->prefs = *preferencesPtr;
612 
613  /* Ctx Management */
614  { U16 const ctxTypeID = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2;
615  if (cctxPtr->lz4CtxAlloc < ctxTypeID) {
616  FREEMEM(cctxPtr->lz4CtxPtr);
617  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
618  cctxPtr->lz4CtxPtr = LZ4_createStream();
619  } else {
620  cctxPtr->lz4CtxPtr = LZ4_createStreamHC();
621  }
622  if (cctxPtr->lz4CtxPtr == NULL)
623  return err0r(LZ4F_ERROR_allocation_failed);
624  cctxPtr->lz4CtxAlloc = ctxTypeID;
625  cctxPtr->lz4CtxState = ctxTypeID;
626  } else if (cctxPtr->lz4CtxState != ctxTypeID) {
627  /* otherwise, a sufficient buffer is allocated, but we need to
628  * reset it to the correct context type */
629  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
630  LZ4_initStream((LZ4_stream_t *) cctxPtr->lz4CtxPtr, sizeof (LZ4_stream_t));
631  } else {
634  }
635  cctxPtr->lz4CtxState = ctxTypeID;
636  }
637  }
638 
639  /* Buffer Management */
640  if (cctxPtr->prefs.frameInfo.blockSizeID == 0)
643 
644  { size_t const requiredBuffSize = preferencesPtr->autoFlush ?
645  ((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 64 KB : 0) : /* only needs past data up to window size */
646  cctxPtr->maxBlockSize + ((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 128 KB : 0);
647 
648  if (cctxPtr->maxBufferSize < requiredBuffSize) {
649  cctxPtr->maxBufferSize = 0;
650  FREEMEM(cctxPtr->tmpBuff);
651  cctxPtr->tmpBuff = (BYTE*)ALLOC_AND_ZERO(requiredBuffSize);
652  if (cctxPtr->tmpBuff == NULL) return err0r(LZ4F_ERROR_allocation_failed);
653  cctxPtr->maxBufferSize = requiredBuffSize;
654  } }
655  cctxPtr->tmpIn = cctxPtr->tmpBuff;
656  cctxPtr->tmpInSize = 0;
657  (void)XXH32_reset(&(cctxPtr->xxh), 0);
658 
659  /* context init */
660  cctxPtr->cdict = cdict;
661  if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
662  /* frame init only for blockLinked : blockIndependent will be init at each block */
664  }
665  if (preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN) {
666  LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
667  }
668 
669  /* Magic Number */
671  dstPtr += 4;
672  headerStart = dstPtr;
673 
674  /* FLG Byte */
675  *dstPtr++ = (BYTE)(((1 & _2BITS) << 6) /* Version('01') */
676  + ((cctxPtr->prefs.frameInfo.blockMode & _1BIT ) << 5)
677  + ((cctxPtr->prefs.frameInfo.blockChecksumFlag & _1BIT ) << 4)
678  + ((unsigned)(cctxPtr->prefs.frameInfo.contentSize > 0) << 3)
679  + ((cctxPtr->prefs.frameInfo.contentChecksumFlag & _1BIT ) << 2)
680  + (cctxPtr->prefs.frameInfo.dictID > 0) );
681  /* BD Byte */
682  *dstPtr++ = (BYTE)((cctxPtr->prefs.frameInfo.blockSizeID & _3BITS) << 4);
683  /* Optional Frame content size field */
684  if (cctxPtr->prefs.frameInfo.contentSize) {
685  LZ4F_writeLE64(dstPtr, cctxPtr->prefs.frameInfo.contentSize);
686  dstPtr += 8;
687  cctxPtr->totalInSize = 0;
688  }
689  /* Optional dictionary ID field */
690  if (cctxPtr->prefs.frameInfo.dictID) {
691  LZ4F_writeLE32(dstPtr, cctxPtr->prefs.frameInfo.dictID);
692  dstPtr += 4;
693  }
694  /* Header CRC Byte */
695  *dstPtr = LZ4F_headerChecksum(headerStart, (size_t)(dstPtr - headerStart));
696  dstPtr++;
697 
698  cctxPtr->cStage = 1; /* header written, now request input data block */
699  return (size_t)(dstPtr - dstStart);
700 }
701 
702 
711  void* dstBuffer, size_t dstCapacity,
712  const LZ4F_preferences_t* preferencesPtr)
713 {
714  return LZ4F_compressBegin_usingCDict(cctxPtr, dstBuffer, dstCapacity,
715  NULL, preferencesPtr);
716 }
717 
718 
719 /* LZ4F_compressBound() :
720  * @return minimum capacity of dstBuffer for a given srcSize to handle worst case scenario.
721  * LZ4F_preferences_t structure is optional : if NULL, preferences will be set to cover worst case scenario.
722  * This function cannot fail.
723  */
724 size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr)
725 {
726  if (preferencesPtr && preferencesPtr->autoFlush) {
727  return LZ4F_compressBound_internal(srcSize, preferencesPtr, 0);
728  }
729  return LZ4F_compressBound_internal(srcSize, preferencesPtr, (size_t)-1);
730 }
731 
732 
733 typedef int (*compressFunc_t)(void* ctx, const char* src, char* dst, int srcSize, int dstSize, int level, const LZ4F_CDict* cdict);
734 
735 
740 static size_t LZ4F_makeBlock(void* dst,
741  const void* src, size_t srcSize,
742  compressFunc_t compress, void* lz4ctx, int level,
743  const LZ4F_CDict* cdict,
744  LZ4F_blockChecksum_t crcFlag)
745 {
746  BYTE* const cSizePtr = (BYTE*)dst;
747  U32 cSize = (U32)compress(lz4ctx, (const char*)src, (char*)(cSizePtr+BHSize),
748  (int)(srcSize), (int)(srcSize-1),
749  level, cdict);
750  if (cSize == 0) { /* compression failed */
751  DEBUGLOG(5, "LZ4F_makeBlock: compression failed, creating a raw block (size %u)", (U32)srcSize);
752  cSize = (U32)srcSize;
753  LZ4F_writeLE32(cSizePtr, cSize | LZ4F_BLOCKUNCOMPRESSED_FLAG);
754  memcpy(cSizePtr+BHSize, src, srcSize);
755  } else {
756  LZ4F_writeLE32(cSizePtr, cSize);
757  }
758  if (crcFlag) {
759  U32 const crc32 = XXH32(cSizePtr+BHSize, cSize, 0); /* checksum of compressed data */
760  LZ4F_writeLE32(cSizePtr+BHSize+cSize, crc32);
761  }
762  return BHSize + cSize + ((U32)crcFlag)*BFSize;
763 }
764 
765 
766 static int LZ4F_compressBlock(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
767 {
768  int const acceleration = (level < 0) ? -level + 1 : 1;
770  if (cdict) {
771  return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
772  } else {
773  return LZ4_compress_fast_extState_fastReset(ctx, src, dst, srcSize, dstCapacity, acceleration);
774  }
775 }
776 
777 static int LZ4F_compressBlock_continue(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
778 {
779  int const acceleration = (level < 0) ? -level + 1 : 1;
780  (void)cdict; /* init once at beginning of frame */
781  return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
782 }
783 
784 static int LZ4F_compressBlockHC(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
785 {
787  if (cdict) {
788  return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
789  }
790  return LZ4_compress_HC_extStateHC_fastReset(ctx, src, dst, srcSize, dstCapacity, level);
791 }
792 
793 static int LZ4F_compressBlockHC_continue(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
794 {
795  (void)level; (void)cdict; /* init once at beginning of frame */
796  return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
797 }
798 
800 {
801  if (level < LZ4HC_CLEVEL_MIN) {
802  if (blockMode == LZ4F_blockIndependent) return LZ4F_compressBlock;
804  }
805  if (blockMode == LZ4F_blockIndependent) return LZ4F_compressBlockHC;
807 }
808 
809 static int LZ4F_localSaveDict(LZ4F_cctx_t* cctxPtr)
810 {
811  if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN)
812  return LZ4_saveDict ((LZ4_stream_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
813  return LZ4_saveDictHC ((LZ4_streamHC_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
814 }
815 
817 
826  void* dstBuffer, size_t dstCapacity,
827  const void* srcBuffer, size_t srcSize,
828  const LZ4F_compressOptions_t* compressOptionsPtr)
829 {
830  LZ4F_compressOptions_t cOptionsNull;
831  size_t const blockSize = cctxPtr->maxBlockSize;
832  const BYTE* srcPtr = (const BYTE*)srcBuffer;
833  const BYTE* const srcEnd = srcPtr + srcSize;
834  BYTE* const dstStart = (BYTE*)dstBuffer;
835  BYTE* dstPtr = dstStart;
836  LZ4F_lastBlockStatus lastBlockCompressed = notDone;
838 
839  DEBUGLOG(4, "LZ4F_compressUpdate (srcSize=%zu)", srcSize);
840 
841  if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
842  if (dstCapacity < LZ4F_compressBound_internal(srcSize, &(cctxPtr->prefs), cctxPtr->tmpInSize))
843  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
844  MEM_INIT(&cOptionsNull, 0, sizeof(cOptionsNull));
845  if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
846 
847  /* complete tmp buffer */
848  if (cctxPtr->tmpInSize > 0) { /* some data already within tmp buffer */
849  size_t const sizeToCopy = blockSize - cctxPtr->tmpInSize;
850  if (sizeToCopy > srcSize) {
851  /* add src to tmpIn buffer */
852  memcpy(cctxPtr->tmpIn + cctxPtr->tmpInSize, srcBuffer, srcSize);
853  srcPtr = srcEnd;
854  cctxPtr->tmpInSize += srcSize;
855  /* still needs some CRC */
856  } else {
857  /* complete tmpIn block and then compress it */
858  lastBlockCompressed = fromTmpBuffer;
859  memcpy(cctxPtr->tmpIn + cctxPtr->tmpInSize, srcBuffer, sizeToCopy);
860  srcPtr += sizeToCopy;
861 
862  dstPtr += LZ4F_makeBlock(dstPtr,
863  cctxPtr->tmpIn, blockSize,
864  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
865  cctxPtr->cdict,
867 
868  if (cctxPtr->prefs.frameInfo.blockMode==LZ4F_blockLinked) cctxPtr->tmpIn += blockSize;
869  cctxPtr->tmpInSize = 0;
870  }
871  }
872 
873  while ((size_t)(srcEnd - srcPtr) >= blockSize) {
874  /* compress full blocks */
875  lastBlockCompressed = fromSrcBuffer;
876  dstPtr += LZ4F_makeBlock(dstPtr,
877  srcPtr, blockSize,
878  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
879  cctxPtr->cdict,
881  srcPtr += blockSize;
882  }
883 
884  if ((cctxPtr->prefs.autoFlush) && (srcPtr < srcEnd)) {
885  /* compress remaining input < blockSize */
886  lastBlockCompressed = fromSrcBuffer;
887  dstPtr += LZ4F_makeBlock(dstPtr,
888  srcPtr, (size_t)(srcEnd - srcPtr),
889  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
890  cctxPtr->cdict,
892  srcPtr = srcEnd;
893  }
894 
895  /* preserve dictionary if necessary */
896  if ((cctxPtr->prefs.frameInfo.blockMode==LZ4F_blockLinked) && (lastBlockCompressed==fromSrcBuffer)) {
897  if (compressOptionsPtr->stableSrc) {
898  cctxPtr->tmpIn = cctxPtr->tmpBuff;
899  } else {
900  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
901  if (realDictSize==0) return err0r(LZ4F_ERROR_GENERIC);
902  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
903  }
904  }
905 
906  /* keep tmpIn within limits */
907  if ((cctxPtr->tmpIn + blockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize) /* necessarily LZ4F_blockLinked && lastBlockCompressed==fromTmpBuffer */
908  && !(cctxPtr->prefs.autoFlush))
909  {
910  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
911  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
912  }
913 
914  /* some input data left, necessarily < blockSize */
915  if (srcPtr < srcEnd) {
916  /* fill tmp buffer */
917  size_t const sizeToCopy = (size_t)(srcEnd - srcPtr);
918  memcpy(cctxPtr->tmpIn, srcPtr, sizeToCopy);
919  cctxPtr->tmpInSize = sizeToCopy;
920  }
921 
923  (void)XXH32_update(&(cctxPtr->xxh), srcBuffer, srcSize);
924 
925  cctxPtr->totalInSize += srcSize;
926  return (size_t)(dstPtr - dstStart);
927 }
928 
929 
938 size_t LZ4F_flush(LZ4F_cctx* cctxPtr,
939  void* dstBuffer, size_t dstCapacity,
940  const LZ4F_compressOptions_t* compressOptionsPtr)
941 {
942  BYTE* const dstStart = (BYTE*)dstBuffer;
943  BYTE* dstPtr = dstStart;
945 
946  if (cctxPtr->tmpInSize == 0) return 0; /* nothing to flush */
947  if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
948  if (dstCapacity < (cctxPtr->tmpInSize + BHSize + BFSize))
949  return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
950  (void)compressOptionsPtr; /* not yet useful */
951 
952  /* select compression function */
954 
955  /* compress tmp buffer */
956  dstPtr += LZ4F_makeBlock(dstPtr,
957  cctxPtr->tmpIn, cctxPtr->tmpInSize,
958  compress, cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel,
959  cctxPtr->cdict,
961  assert(((void)"flush overflows dstBuffer!", (size_t)(dstPtr - dstStart) <= dstCapacity));
962 
963  if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked)
964  cctxPtr->tmpIn += cctxPtr->tmpInSize;
965  cctxPtr->tmpInSize = 0;
966 
967  /* keep tmpIn within limits */
968  if ((cctxPtr->tmpIn + cctxPtr->maxBlockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize)) { /* necessarily LZ4F_blockLinked */
969  int const realDictSize = LZ4F_localSaveDict(cctxPtr);
970  cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
971  }
972 
973  return (size_t)(dstPtr - dstStart);
974 }
975 
976 
986 size_t LZ4F_compressEnd(LZ4F_cctx* cctxPtr,
987  void* dstBuffer, size_t dstCapacity,
988  const LZ4F_compressOptions_t* compressOptionsPtr)
989 {
990  BYTE* const dstStart = (BYTE*)dstBuffer;
991  BYTE* dstPtr = dstStart;
992 
993  size_t const flushSize = LZ4F_flush(cctxPtr, dstBuffer, dstCapacity, compressOptionsPtr);
994  DEBUGLOG(5,"LZ4F_compressEnd: dstCapacity=%u", (unsigned)dstCapacity);
995  if (LZ4F_isError(flushSize)) return flushSize;
996  dstPtr += flushSize;
997 
998  assert(flushSize <= dstCapacity);
999  dstCapacity -= flushSize;
1000 
1001  if (dstCapacity < 4) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
1002  LZ4F_writeLE32(dstPtr, 0);
1003  dstPtr += 4; /* endMark */
1004 
1006  U32 const xxh = XXH32_digest(&(cctxPtr->xxh));
1007  if (dstCapacity < 8) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
1008  DEBUGLOG(5,"Writing 32-bit content checksum");
1009  LZ4F_writeLE32(dstPtr, xxh);
1010  dstPtr+=4; /* content Checksum */
1011  }
1012 
1013  cctxPtr->cStage = 0; /* state is now re-usable (with identical preferences) */
1014  cctxPtr->maxBufferSize = 0; /* reuse HC context */
1015 
1016  if (cctxPtr->prefs.frameInfo.contentSize) {
1017  if (cctxPtr->prefs.frameInfo.contentSize != cctxPtr->totalInSize)
1018  return err0r(LZ4F_ERROR_frameSize_wrong);
1019  }
1020 
1021  return (size_t)(dstPtr - dstStart);
1022 }
1023 
1024 
1025 /*-***************************************************
1026 * Frame Decompression
1027 *****************************************************/
1028 
1029 typedef enum {
1040 
1041 struct LZ4F_dctx_s {
1049  size_t tmpInSize;
1050  size_t tmpInTarget;
1052  const BYTE* dict;
1053  size_t dictSize;
1055  size_t tmpOutSize;
1056  size_t tmpOutStart;
1060 }; /* typedef'd to LZ4F_dctx in lz4frame.h */
1061 
1062 
1069 LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** LZ4F_decompressionContextPtr, unsigned versionNumber)
1070 {
1071  LZ4F_dctx* const dctx = (LZ4F_dctx*)ALLOC_AND_ZERO(sizeof(LZ4F_dctx));
1072  if (dctx == NULL) { /* failed allocation */
1073  *LZ4F_decompressionContextPtr = NULL;
1074  return err0r(LZ4F_ERROR_allocation_failed);
1075  }
1076 
1077  dctx->version = versionNumber;
1078  *LZ4F_decompressionContextPtr = dctx;
1079  return LZ4F_OK_NoError;
1080 }
1081 
1083 {
1084  LZ4F_errorCode_t result = LZ4F_OK_NoError;
1085  if (dctx != NULL) { /* can accept NULL input, like free() */
1086  result = (LZ4F_errorCode_t)dctx->dStage;
1087  FREEMEM(dctx->tmpIn);
1088  FREEMEM(dctx->tmpOutBuffer);
1089  FREEMEM(dctx);
1090  }
1091  return result;
1092 }
1093 
1094 
1095 /*==--- Streaming Decompression operations ---==*/
1096 
1098 {
1099  dctx->dStage = dstage_getFrameHeader;
1100  dctx->dict = NULL;
1101  dctx->dictSize = 0;
1102 }
1103 
1104 
1113 static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize)
1114 {
1115  unsigned blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, dictIDFlag, blockSizeID;
1116  size_t frameHeaderSize;
1117  const BYTE* srcPtr = (const BYTE*)src;
1118 
1119  DEBUGLOG(5, "LZ4F_decodeHeader");
1120  /* need to decode header to get frameInfo */
1121  if (srcSize < minFHSize) return err0r(LZ4F_ERROR_frameHeader_incomplete); /* minimal frame header size */
1122  MEM_INIT(&(dctx->frameInfo), 0, sizeof(dctx->frameInfo));
1123 
1124  /* special case : skippable frames */
1125  if ((LZ4F_readLE32(srcPtr) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START) {
1127  if (src == (void*)(dctx->header)) {
1128  dctx->tmpInSize = srcSize;
1129  dctx->tmpInTarget = 8;
1131  return srcSize;
1132  } else {
1133  dctx->dStage = dstage_getSFrameSize;
1134  return 4;
1135  }
1136  }
1137 
1138  /* control magic number */
1139 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1140  if (LZ4F_readLE32(srcPtr) != LZ4F_MAGICNUMBER) {
1141  DEBUGLOG(4, "frame header error : unknown magic number");
1142  return err0r(LZ4F_ERROR_frameType_unknown);
1143  }
1144 #endif
1145  dctx->frameInfo.frameType = LZ4F_frame;
1146 
1147  /* Flags */
1148  { U32 const FLG = srcPtr[4];
1149  U32 const version = (FLG>>6) & _2BITS;
1150  blockChecksumFlag = (FLG>>4) & _1BIT;
1151  blockMode = (FLG>>5) & _1BIT;
1152  contentSizeFlag = (FLG>>3) & _1BIT;
1153  contentChecksumFlag = (FLG>>2) & _1BIT;
1154  dictIDFlag = FLG & _1BIT;
1155  /* validate */
1156  if (((FLG>>1)&_1BIT) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bit */
1157  if (version != 1) return err0r(LZ4F_ERROR_headerVersion_wrong); /* Version Number, only supported value */
1158  }
1159 
1160  /* Frame Header Size */
1161  frameHeaderSize = minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1162 
1163  if (srcSize < frameHeaderSize) {
1164  /* not enough input to fully decode frame header */
1165  if (srcPtr != dctx->header)
1166  memcpy(dctx->header, srcPtr, srcSize);
1167  dctx->tmpInSize = srcSize;
1168  dctx->tmpInTarget = frameHeaderSize;
1170  return srcSize;
1171  }
1172 
1173  { U32 const BD = srcPtr[5];
1174  blockSizeID = (BD>>4) & _3BITS;
1175  /* validate */
1176  if (((BD>>7)&_1BIT) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bit */
1177  if (blockSizeID < 4) return err0r(LZ4F_ERROR_maxBlockSize_invalid); /* 4-7 only supported values for the time being */
1178  if (((BD>>0)&_4BITS) != 0) return err0r(LZ4F_ERROR_reservedFlag_set); /* Reserved bits */
1179  }
1180 
1181  /* check header */
1182  assert(frameHeaderSize > 5);
1183 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1184  { BYTE const HC = LZ4F_headerChecksum(srcPtr+4, frameHeaderSize-5);
1185  if (HC != srcPtr[frameHeaderSize-1])
1186  return err0r(LZ4F_ERROR_headerChecksum_invalid);
1187  }
1188 #endif
1189 
1190  /* save */
1191  dctx->frameInfo.blockMode = (LZ4F_blockMode_t)blockMode;
1192  dctx->frameInfo.blockChecksumFlag = (LZ4F_blockChecksum_t)blockChecksumFlag;
1193  dctx->frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)contentChecksumFlag;
1194  dctx->frameInfo.blockSizeID = (LZ4F_blockSizeID_t)blockSizeID;
1195  dctx->maxBlockSize = LZ4F_getBlockSize(blockSizeID);
1196  if (contentSizeFlag)
1197  dctx->frameRemainingSize =
1198  dctx->frameInfo.contentSize = LZ4F_readLE64(srcPtr+6);
1199  if (dictIDFlag)
1200  dctx->frameInfo.dictID = LZ4F_readLE32(srcPtr + frameHeaderSize - 5);
1201 
1202  dctx->dStage = dstage_init;
1203 
1204  return frameHeaderSize;
1205 }
1206 
1207 
1212 size_t LZ4F_headerSize(const void* src, size_t srcSize)
1213 {
1214  if (src == NULL) return err0r(LZ4F_ERROR_srcPtr_wrong);
1215 
1216  /* minimal srcSize to determine header size */
1218  return err0r(LZ4F_ERROR_frameHeader_incomplete);
1219 
1220  /* special case : skippable frames */
1221  if ((LZ4F_readLE32(src) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START)
1222  return 8;
1223 
1224  /* control magic number */
1225 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1227  return err0r(LZ4F_ERROR_frameType_unknown);
1228 #endif
1229 
1230  /* Frame Header Size */
1231  { BYTE const FLG = ((const BYTE*)src)[4];
1232  U32 const contentSizeFlag = (FLG>>3) & _1BIT;
1233  U32 const dictIDFlag = FLG & _1BIT;
1234  return minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1235  }
1236 }
1237 
1254  LZ4F_frameInfo_t* frameInfoPtr,
1255  const void* srcBuffer, size_t* srcSizePtr)
1256 {
1258  if (dctx->dStage > dstage_storeFrameHeader) {
1259  /* frameInfo already decoded */
1260  size_t o=0, i=0;
1261  *srcSizePtr = 0;
1262  *frameInfoPtr = dctx->frameInfo;
1263  /* returns : recommended nb of bytes for LZ4F_decompress() */
1264  return LZ4F_decompress(dctx, NULL, &o, NULL, &i, NULL);
1265  } else {
1266  if (dctx->dStage == dstage_storeFrameHeader) {
1267  /* frame decoding already started, in the middle of header => automatic fail */
1268  *srcSizePtr = 0;
1269  return err0r(LZ4F_ERROR_frameDecoding_alreadyStarted);
1270  } else {
1271  size_t const hSize = LZ4F_headerSize(srcBuffer, *srcSizePtr);
1272  if (LZ4F_isError(hSize)) { *srcSizePtr=0; return hSize; }
1273  if (*srcSizePtr < hSize) {
1274  *srcSizePtr=0;
1275  return err0r(LZ4F_ERROR_frameHeader_incomplete);
1276  }
1277 
1278  { size_t decodeResult = LZ4F_decodeHeader(dctx, srcBuffer, hSize);
1279  if (LZ4F_isError(decodeResult)) {
1280  *srcSizePtr = 0;
1281  } else {
1282  *srcSizePtr = decodeResult;
1283  decodeResult = BHSize; /* block header size */
1284  }
1285  *frameInfoPtr = dctx->frameInfo;
1286  return decodeResult;
1287  } } }
1288 }
1289 
1290 
1291 /* LZ4F_updateDict() :
1292  * only used for LZ4F_blockLinked mode
1293  * Condition : dstPtr != NULL
1294  */
1295 static void LZ4F_updateDict(LZ4F_dctx* dctx,
1296  const BYTE* dstPtr, size_t dstSize, const BYTE* dstBufferStart,
1297  unsigned withinTmp)
1298 {
1299  assert(dstPtr != NULL);
1300  if (dctx->dictSize==0) {
1301  dctx->dict = (const BYTE*)dstPtr; /* priority to prefix mode */
1302  }
1303  assert(dctx->dict != NULL);
1304 
1305  if (dctx->dict + dctx->dictSize == dstPtr) { /* prefix mode, everything within dstBuffer */
1306  dctx->dictSize += dstSize;
1307  return;
1308  }
1309 
1310  assert(dstPtr >= dstBufferStart);
1311  if ((size_t)(dstPtr - dstBufferStart) + dstSize >= 64 KB) { /* history in dstBuffer becomes large enough to become dictionary */
1312  dctx->dict = (const BYTE*)dstBufferStart;
1313  dctx->dictSize = (size_t)(dstPtr - dstBufferStart) + dstSize;
1314  return;
1315  }
1316 
1317  assert(dstSize < 64 KB); /* if dstSize >= 64 KB, dictionary would be set into dstBuffer directly */
1318 
1319  /* dstBuffer does not contain whole useful history (64 KB), so it must be saved within tmpOutBuffer */
1320  assert(dctx->tmpOutBuffer != NULL);
1321 
1322  if (withinTmp && (dctx->dict == dctx->tmpOutBuffer)) { /* continue history within tmpOutBuffer */
1323  /* withinTmp expectation : content of [dstPtr,dstSize] is same as [dict+dictSize,dstSize], so we just extend it */
1324  assert(dctx->dict + dctx->dictSize == dctx->tmpOut + dctx->tmpOutStart);
1325  dctx->dictSize += dstSize;
1326  return;
1327  }
1328 
1329  if (withinTmp) { /* copy relevant dict portion in front of tmpOut within tmpOutBuffer */
1330  size_t const preserveSize = (size_t)(dctx->tmpOut - dctx->tmpOutBuffer);
1331  size_t copySize = 64 KB - dctx->tmpOutSize;
1332  const BYTE* const oldDictEnd = dctx->dict + dctx->dictSize - dctx->tmpOutStart;
1333  if (dctx->tmpOutSize > 64 KB) copySize = 0;
1334  if (copySize > preserveSize) copySize = preserveSize;
1335 
1336  memcpy(dctx->tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1337 
1338  dctx->dict = dctx->tmpOutBuffer;
1339  dctx->dictSize = preserveSize + dctx->tmpOutStart + dstSize;
1340  return;
1341  }
1342 
1343  if (dctx->dict == dctx->tmpOutBuffer) { /* copy dst into tmp to complete dict */
1344  if (dctx->dictSize + dstSize > dctx->maxBufferSize) { /* tmp buffer not large enough */
1345  size_t const preserveSize = 64 KB - dstSize;
1346  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - preserveSize, preserveSize);
1347  dctx->dictSize = preserveSize;
1348  }
1349  memcpy(dctx->tmpOutBuffer + dctx->dictSize, dstPtr, dstSize);
1350  dctx->dictSize += dstSize;
1351  return;
1352  }
1353 
1354  /* join dict & dest into tmp */
1355  { size_t preserveSize = 64 KB - dstSize;
1356  if (preserveSize > dctx->dictSize) preserveSize = dctx->dictSize;
1357  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - preserveSize, preserveSize);
1358  memcpy(dctx->tmpOutBuffer + preserveSize, dstPtr, dstSize);
1359  dctx->dict = dctx->tmpOutBuffer;
1360  dctx->dictSize = preserveSize + dstSize;
1361  }
1362 }
1363 
1364 
1365 
1385  void* dstBuffer, size_t* dstSizePtr,
1386  const void* srcBuffer, size_t* srcSizePtr,
1387  const LZ4F_decompressOptions_t* decompressOptionsPtr)
1388 {
1389  LZ4F_decompressOptions_t optionsNull;
1390  const BYTE* const srcStart = (const BYTE*)srcBuffer;
1391  const BYTE* const srcEnd = srcStart + *srcSizePtr;
1392  const BYTE* srcPtr = srcStart;
1393  BYTE* const dstStart = (BYTE*)dstBuffer;
1394  BYTE* const dstEnd = dstStart ? dstStart + *dstSizePtr : NULL;
1395  BYTE* dstPtr = dstStart;
1396  const BYTE* selectedIn = NULL;
1397  unsigned doAnotherStage = 1;
1398  size_t nextSrcSizeHint = 1;
1399 
1400 
1401  DEBUGLOG(5, "LZ4F_decompress : %p,%u => %p,%u",
1402  srcBuffer, (unsigned)*srcSizePtr, dstBuffer, (unsigned)*dstSizePtr);
1403  if (dstBuffer == NULL) assert(*dstSizePtr == 0);
1404  MEM_INIT(&optionsNull, 0, sizeof(optionsNull));
1405  if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
1406  *srcSizePtr = 0;
1407  *dstSizePtr = 0;
1408  assert(dctx != NULL);
1409 
1410  /* behaves as a state machine */
1411 
1412  while (doAnotherStage) {
1413 
1414  switch(dctx->dStage)
1415  {
1416 
1417  case dstage_getFrameHeader:
1418  DEBUGLOG(6, "dstage_getFrameHeader");
1419  if ((size_t)(srcEnd-srcPtr) >= maxFHSize) { /* enough to decode - shortcut */
1420  size_t const hSize = LZ4F_decodeHeader(dctx, srcPtr, (size_t)(srcEnd-srcPtr)); /* will update dStage appropriately */
1421  if (LZ4F_isError(hSize)) return hSize;
1422  srcPtr += hSize;
1423  break;
1424  }
1425  dctx->tmpInSize = 0;
1426  if (srcEnd-srcPtr == 0) return minFHSize; /* 0-size input */
1427  dctx->tmpInTarget = minFHSize; /* minimum size to decode header */
1429  /* fall-through */
1430 
1432  DEBUGLOG(6, "dstage_storeFrameHeader");
1433  { size_t const sizeToCopy = MIN(dctx->tmpInTarget - dctx->tmpInSize, (size_t)(srcEnd - srcPtr));
1434  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1435  dctx->tmpInSize += sizeToCopy;
1436  srcPtr += sizeToCopy;
1437  }
1438  if (dctx->tmpInSize < dctx->tmpInTarget) {
1439  nextSrcSizeHint = (dctx->tmpInTarget - dctx->tmpInSize) + BHSize; /* rest of header + nextBlockHeader */
1440  doAnotherStage = 0; /* not enough src data, ask for some more */
1441  break;
1442  }
1443  { size_t const hSize = LZ4F_decodeHeader(dctx, dctx->header, dctx->tmpInTarget); /* will update dStage appropriately */
1444  if (LZ4F_isError(hSize)) return hSize;
1445  }
1446  break;
1447 
1448  case dstage_init:
1449  DEBUGLOG(6, "dstage_init");
1450  if (dctx->frameInfo.contentChecksumFlag) (void)XXH32_reset(&(dctx->xxh), 0);
1451  /* internal buffers allocation */
1452  { size_t const bufferNeeded = dctx->maxBlockSize
1453  + ((dctx->frameInfo.blockMode==LZ4F_blockLinked) ? 128 KB : 0);
1454  if (bufferNeeded > dctx->maxBufferSize) { /* tmp buffers too small */
1455  dctx->maxBufferSize = 0; /* ensure allocation will be re-attempted on next entry*/
1456  FREEMEM(dctx->tmpIn);
1457  dctx->tmpIn = (BYTE*)ALLOC(dctx->maxBlockSize + BFSize /* block checksum */);
1458  if (dctx->tmpIn == NULL)
1459  return err0r(LZ4F_ERROR_allocation_failed);
1460  FREEMEM(dctx->tmpOutBuffer);
1461  dctx->tmpOutBuffer= (BYTE*)ALLOC(bufferNeeded);
1462  if (dctx->tmpOutBuffer== NULL)
1463  return err0r(LZ4F_ERROR_allocation_failed);
1464  dctx->maxBufferSize = bufferNeeded;
1465  } }
1466  dctx->tmpInSize = 0;
1467  dctx->tmpInTarget = 0;
1468  dctx->tmpOut = dctx->tmpOutBuffer;
1469  dctx->tmpOutStart = 0;
1470  dctx->tmpOutSize = 0;
1471 
1472  dctx->dStage = dstage_getBlockHeader;
1473  /* fall-through */
1474 
1475  case dstage_getBlockHeader:
1476  if ((size_t)(srcEnd - srcPtr) >= BHSize) {
1477  selectedIn = srcPtr;
1478  srcPtr += BHSize;
1479  } else {
1480  /* not enough input to read cBlockSize field */
1481  dctx->tmpInSize = 0;
1483  }
1484 
1485  if (dctx->dStage == dstage_storeBlockHeader) /* can be skipped */
1487  { size_t const remainingInput = (size_t)(srcEnd - srcPtr);
1488  size_t const wantedData = BHSize - dctx->tmpInSize;
1489  size_t const sizeToCopy = MIN(wantedData, remainingInput);
1490  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1491  srcPtr += sizeToCopy;
1492  dctx->tmpInSize += sizeToCopy;
1493 
1494  if (dctx->tmpInSize < BHSize) { /* not enough input for cBlockSize */
1495  nextSrcSizeHint = BHSize - dctx->tmpInSize;
1496  doAnotherStage = 0;
1497  break;
1498  }
1499  selectedIn = dctx->tmpIn;
1500  } /* if (dctx->dStage == dstage_storeBlockHeader) */
1501 
1502  /* decode block header */
1503  { U32 const blockHeader = LZ4F_readLE32(selectedIn);
1504  size_t const nextCBlockSize = blockHeader & 0x7FFFFFFFU;
1505  size_t const crcSize = dctx->frameInfo.blockChecksumFlag * BFSize;
1506  if (blockHeader==0) { /* frameEnd signal, no more block */
1507  DEBUGLOG(5, "end of frame");
1508  dctx->dStage = dstage_getSuffix;
1509  break;
1510  }
1511  if (nextCBlockSize > dctx->maxBlockSize) {
1512  return err0r(LZ4F_ERROR_maxBlockSize_invalid);
1513  }
1514  if (blockHeader & LZ4F_BLOCKUNCOMPRESSED_FLAG) {
1515  /* next block is uncompressed */
1516  dctx->tmpInTarget = nextCBlockSize;
1517  DEBUGLOG(5, "next block is uncompressed (size %u)", (U32)nextCBlockSize);
1518  if (dctx->frameInfo.blockChecksumFlag) {
1519  (void)XXH32_reset(&dctx->blockChecksum, 0);
1520  }
1521  dctx->dStage = dstage_copyDirect;
1522  break;
1523  }
1524  /* next block is a compressed block */
1525  dctx->tmpInTarget = nextCBlockSize + crcSize;
1526  dctx->dStage = dstage_getCBlock;
1527  if (dstPtr==dstEnd || srcPtr==srcEnd) {
1528  nextSrcSizeHint = BHSize + nextCBlockSize + crcSize;
1529  doAnotherStage = 0;
1530  }
1531  break;
1532  }
1533 
1534  case dstage_copyDirect: /* uncompressed block */
1535  DEBUGLOG(6, "dstage_copyDirect");
1536  { size_t sizeToCopy;
1537  if (dstPtr == NULL) {
1538  sizeToCopy = 0;
1539  } else {
1540  size_t const minBuffSize = MIN((size_t)(srcEnd-srcPtr), (size_t)(dstEnd-dstPtr));
1541  sizeToCopy = MIN(dctx->tmpInTarget, minBuffSize);
1542  memcpy(dstPtr, srcPtr, sizeToCopy);
1543  if (dctx->frameInfo.blockChecksumFlag) {
1544  (void)XXH32_update(&dctx->blockChecksum, srcPtr, sizeToCopy);
1545  }
1546  if (dctx->frameInfo.contentChecksumFlag)
1547  (void)XXH32_update(&dctx->xxh, srcPtr, sizeToCopy);
1548  if (dctx->frameInfo.contentSize)
1549  dctx->frameRemainingSize -= sizeToCopy;
1550 
1551  /* history management (linked blocks only)*/
1552  if (dctx->frameInfo.blockMode == LZ4F_blockLinked) {
1553  LZ4F_updateDict(dctx, dstPtr, sizeToCopy, dstStart, 0);
1554  } }
1555 
1556  srcPtr += sizeToCopy;
1557  dstPtr += sizeToCopy;
1558  if (sizeToCopy == dctx->tmpInTarget) { /* all done */
1559  if (dctx->frameInfo.blockChecksumFlag) {
1560  dctx->tmpInSize = 0;
1562  } else
1563  dctx->dStage = dstage_getBlockHeader; /* new block */
1564  break;
1565  }
1566  dctx->tmpInTarget -= sizeToCopy; /* need to copy more */
1567  }
1568  nextSrcSizeHint = dctx->tmpInTarget +
1569  +(dctx->frameInfo.blockChecksumFlag ? BFSize : 0)
1570  + BHSize /* next header size */;
1571  doAnotherStage = 0;
1572  break;
1573 
1574  /* check block checksum for recently transferred uncompressed block */
1576  DEBUGLOG(6, "dstage_getBlockChecksum");
1577  { const void* crcSrc;
1578  if ((srcEnd-srcPtr >= 4) && (dctx->tmpInSize==0)) {
1579  crcSrc = srcPtr;
1580  srcPtr += 4;
1581  } else {
1582  size_t const stillToCopy = 4 - dctx->tmpInSize;
1583  size_t const sizeToCopy = MIN(stillToCopy, (size_t)(srcEnd-srcPtr));
1584  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1585  dctx->tmpInSize += sizeToCopy;
1586  srcPtr += sizeToCopy;
1587  if (dctx->tmpInSize < 4) { /* all input consumed */
1588  doAnotherStage = 0;
1589  break;
1590  }
1591  crcSrc = dctx->header;
1592  }
1593  { U32 const readCRC = LZ4F_readLE32(crcSrc);
1594  U32 const calcCRC = XXH32_digest(&dctx->blockChecksum);
1595 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1596  DEBUGLOG(6, "compare block checksum");
1597  if (readCRC != calcCRC) {
1598  DEBUGLOG(4, "incorrect block checksum: %08X != %08X",
1599  readCRC, calcCRC);
1600  return err0r(LZ4F_ERROR_blockChecksum_invalid);
1601  }
1602 #else
1603  (void)readCRC;
1604  (void)calcCRC;
1605 #endif
1606  } }
1607  dctx->dStage = dstage_getBlockHeader; /* new block */
1608  break;
1609 
1610  case dstage_getCBlock:
1611  DEBUGLOG(6, "dstage_getCBlock");
1612  if ((size_t)(srcEnd-srcPtr) < dctx->tmpInTarget) {
1613  dctx->tmpInSize = 0;
1614  dctx->dStage = dstage_storeCBlock;
1615  break;
1616  }
1617  /* input large enough to read full block directly */
1618  selectedIn = srcPtr;
1619  srcPtr += dctx->tmpInTarget;
1620 
1621  if (0) /* always jump over next block */
1622  case dstage_storeCBlock:
1623  { size_t const wantedData = dctx->tmpInTarget - dctx->tmpInSize;
1624  size_t const inputLeft = (size_t)(srcEnd-srcPtr);
1625  size_t const sizeToCopy = MIN(wantedData, inputLeft);
1626  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1627  dctx->tmpInSize += sizeToCopy;
1628  srcPtr += sizeToCopy;
1629  if (dctx->tmpInSize < dctx->tmpInTarget) { /* need more input */
1630  nextSrcSizeHint = (dctx->tmpInTarget - dctx->tmpInSize)
1631  + (dctx->frameInfo.blockChecksumFlag ? BFSize : 0)
1632  + BHSize /* next header size */;
1633  doAnotherStage = 0;
1634  break;
1635  }
1636  selectedIn = dctx->tmpIn;
1637  }
1638 
1639  /* At this stage, input is large enough to decode a block */
1640  if (dctx->frameInfo.blockChecksumFlag) {
1641  dctx->tmpInTarget -= 4;
1642  assert(selectedIn != NULL); /* selectedIn is defined at this stage (either srcPtr, or dctx->tmpIn) */
1643  { U32 const readBlockCrc = LZ4F_readLE32(selectedIn + dctx->tmpInTarget);
1644  U32 const calcBlockCrc = XXH32(selectedIn, dctx->tmpInTarget, 0);
1645 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1646  if (readBlockCrc != calcBlockCrc)
1647  return err0r(LZ4F_ERROR_blockChecksum_invalid);
1648 #else
1649  (void)readBlockCrc;
1650  (void)calcBlockCrc;
1651 #endif
1652  } }
1653 
1654  if ((size_t)(dstEnd-dstPtr) >= dctx->maxBlockSize) {
1655  const char* dict = (const char*)dctx->dict;
1656  size_t dictSize = dctx->dictSize;
1657  int decodedSize;
1658  assert(dstPtr != NULL);
1659  if (dict && dictSize > 1 GB) {
1660  /* the dictSize param is an int, avoid truncation / sign issues */
1661  dict += dictSize - 64 KB;
1662  dictSize = 64 KB;
1663  }
1664  /* enough capacity in `dst` to decompress directly there */
1665  decodedSize = LZ4_decompress_safe_usingDict(
1666  (const char*)selectedIn, (char*)dstPtr,
1667  (int)dctx->tmpInTarget, (int)dctx->maxBlockSize,
1668  dict, (int)dictSize);
1669  if (decodedSize < 0) return err0r(LZ4F_ERROR_GENERIC); /* decompression failed */
1670  if (dctx->frameInfo.contentChecksumFlag)
1671  XXH32_update(&(dctx->xxh), dstPtr, (size_t)decodedSize);
1672  if (dctx->frameInfo.contentSize)
1673  dctx->frameRemainingSize -= (size_t)decodedSize;
1674 
1675  /* dictionary management */
1676  if (dctx->frameInfo.blockMode==LZ4F_blockLinked) {
1677  LZ4F_updateDict(dctx, dstPtr, (size_t)decodedSize, dstStart, 0);
1678  }
1679 
1680  dstPtr += decodedSize;
1681  dctx->dStage = dstage_getBlockHeader;
1682  break;
1683  }
1684 
1685  /* not enough place into dst : decode into tmpOut */
1686  /* ensure enough place for tmpOut */
1687  if (dctx->frameInfo.blockMode == LZ4F_blockLinked) {
1688  if (dctx->dict == dctx->tmpOutBuffer) {
1689  if (dctx->dictSize > 128 KB) {
1690  memcpy(dctx->tmpOutBuffer, dctx->dict + dctx->dictSize - 64 KB, 64 KB);
1691  dctx->dictSize = 64 KB;
1692  }
1693  dctx->tmpOut = dctx->tmpOutBuffer + dctx->dictSize;
1694  } else { /* dict not within tmp */
1695  size_t const reservedDictSpace = MIN(dctx->dictSize, 64 KB);
1696  dctx->tmpOut = dctx->tmpOutBuffer + reservedDictSpace;
1697  } }
1698 
1699  /* Decode block */
1700  { const char* dict = (const char*)dctx->dict;
1701  size_t dictSize = dctx->dictSize;
1702  int decodedSize;
1703  if (dict && dictSize > 1 GB) {
1704  /* the dictSize param is an int, avoid truncation / sign issues */
1705  dict += dictSize - 64 KB;
1706  dictSize = 64 KB;
1707  }
1708  decodedSize = LZ4_decompress_safe_usingDict(
1709  (const char*)selectedIn, (char*)dctx->tmpOut,
1710  (int)dctx->tmpInTarget, (int)dctx->maxBlockSize,
1711  dict, (int)dictSize);
1712  if (decodedSize < 0) /* decompression failed */
1713  return err0r(LZ4F_ERROR_decompressionFailed);
1714  if (dctx->frameInfo.contentChecksumFlag)
1715  XXH32_update(&(dctx->xxh), dctx->tmpOut, (size_t)decodedSize);
1716  if (dctx->frameInfo.contentSize)
1717  dctx->frameRemainingSize -= (size_t)decodedSize;
1718  dctx->tmpOutSize = (size_t)decodedSize;
1719  dctx->tmpOutStart = 0;
1720  dctx->dStage = dstage_flushOut;
1721  }
1722  /* fall-through */
1723 
1724  case dstage_flushOut: /* flush decoded data from tmpOut to dstBuffer */
1725  DEBUGLOG(6, "dstage_flushOut");
1726  if (dstPtr != NULL) {
1727  size_t const sizeToCopy = MIN(dctx->tmpOutSize - dctx->tmpOutStart, (size_t)(dstEnd-dstPtr));
1728  memcpy(dstPtr, dctx->tmpOut + dctx->tmpOutStart, sizeToCopy);
1729 
1730  /* dictionary management */
1731  if (dctx->frameInfo.blockMode == LZ4F_blockLinked)
1732  LZ4F_updateDict(dctx, dstPtr, sizeToCopy, dstStart, 1 /*withinTmp*/);
1733 
1734  dctx->tmpOutStart += sizeToCopy;
1735  dstPtr += sizeToCopy;
1736  }
1737  if (dctx->tmpOutStart == dctx->tmpOutSize) { /* all flushed */
1738  dctx->dStage = dstage_getBlockHeader; /* get next block */
1739  break;
1740  }
1741  /* could not flush everything : stop there, just request a block header */
1742  doAnotherStage = 0;
1743  nextSrcSizeHint = BHSize;
1744  break;
1745 
1746  case dstage_getSuffix:
1747  if (dctx->frameRemainingSize)
1748  return err0r(LZ4F_ERROR_frameSize_wrong); /* incorrect frame size decoded */
1749  if (!dctx->frameInfo.contentChecksumFlag) { /* no checksum, frame is completed */
1750  nextSrcSizeHint = 0;
1752  doAnotherStage = 0;
1753  break;
1754  }
1755  if ((srcEnd - srcPtr) < 4) { /* not enough size for entire CRC */
1756  dctx->tmpInSize = 0;
1757  dctx->dStage = dstage_storeSuffix;
1758  } else {
1759  selectedIn = srcPtr;
1760  srcPtr += 4;
1761  }
1762 
1763  if (dctx->dStage == dstage_storeSuffix) /* can be skipped */
1764  case dstage_storeSuffix:
1765  { size_t const remainingInput = (size_t)(srcEnd - srcPtr);
1766  size_t const wantedData = 4 - dctx->tmpInSize;
1767  size_t const sizeToCopy = MIN(wantedData, remainingInput);
1768  memcpy(dctx->tmpIn + dctx->tmpInSize, srcPtr, sizeToCopy);
1769  srcPtr += sizeToCopy;
1770  dctx->tmpInSize += sizeToCopy;
1771  if (dctx->tmpInSize < 4) { /* not enough input to read complete suffix */
1772  nextSrcSizeHint = 4 - dctx->tmpInSize;
1773  doAnotherStage=0;
1774  break;
1775  }
1776  selectedIn = dctx->tmpIn;
1777  } /* if (dctx->dStage == dstage_storeSuffix) */
1778 
1779  /* case dstage_checkSuffix: */ /* no direct entry, avoid initialization risks */
1780  { U32 const readCRC = LZ4F_readLE32(selectedIn);
1781  U32 const resultCRC = XXH32_digest(&(dctx->xxh));
1782 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1783  if (readCRC != resultCRC)
1784  return err0r(LZ4F_ERROR_contentChecksum_invalid);
1785 #else
1786  (void)readCRC;
1787  (void)resultCRC;
1788 #endif
1789  nextSrcSizeHint = 0;
1791  doAnotherStage = 0;
1792  break;
1793  }
1794 
1795  case dstage_getSFrameSize:
1796  if ((srcEnd - srcPtr) >= 4) {
1797  selectedIn = srcPtr;
1798  srcPtr += 4;
1799  } else {
1800  /* not enough input to read cBlockSize field */
1801  dctx->tmpInSize = 4;
1802  dctx->tmpInTarget = 8;
1804  }
1805 
1806  if (dctx->dStage == dstage_storeSFrameSize)
1808  { size_t const sizeToCopy = MIN(dctx->tmpInTarget - dctx->tmpInSize,
1809  (size_t)(srcEnd - srcPtr) );
1810  memcpy(dctx->header + dctx->tmpInSize, srcPtr, sizeToCopy);
1811  srcPtr += sizeToCopy;
1812  dctx->tmpInSize += sizeToCopy;
1813  if (dctx->tmpInSize < dctx->tmpInTarget) {
1814  /* not enough input to get full sBlockSize; wait for more */
1815  nextSrcSizeHint = dctx->tmpInTarget - dctx->tmpInSize;
1816  doAnotherStage = 0;
1817  break;
1818  }
1819  selectedIn = dctx->header + 4;
1820  } /* if (dctx->dStage == dstage_storeSFrameSize) */
1821 
1822  /* case dstage_decodeSFrameSize: */ /* no direct entry */
1823  { size_t const SFrameSize = LZ4F_readLE32(selectedIn);
1824  dctx->frameInfo.contentSize = SFrameSize;
1825  dctx->tmpInTarget = SFrameSize;
1826  dctx->dStage = dstage_skipSkippable;
1827  break;
1828  }
1829 
1830  case dstage_skipSkippable:
1831  { size_t const skipSize = MIN(dctx->tmpInTarget, (size_t)(srcEnd-srcPtr));
1832  srcPtr += skipSize;
1833  dctx->tmpInTarget -= skipSize;
1834  doAnotherStage = 0;
1835  nextSrcSizeHint = dctx->tmpInTarget;
1836  if (nextSrcSizeHint) break; /* still more to skip */
1837  /* frame fully skipped : prepare context for a new frame */
1839  break;
1840  }
1841  } /* switch (dctx->dStage) */
1842  } /* while (doAnotherStage) */
1843 
1844  /* preserve history within tmp whenever necessary */
1845  LZ4F_STATIC_ASSERT((unsigned)dstage_init == 2);
1846  if ( (dctx->frameInfo.blockMode==LZ4F_blockLinked) /* next block will use up to 64KB from previous ones */
1847  && (dctx->dict != dctx->tmpOutBuffer) /* dictionary is not already within tmp */
1848  && (dctx->dict != NULL) /* dictionary exists */
1849  && (!decompressOptionsPtr->stableDst) /* cannot rely on dst data to remain there for next call */
1850  && ((unsigned)(dctx->dStage)-2 < (unsigned)(dstage_getSuffix)-2) ) /* valid stages : [init ... getSuffix[ */
1851  {
1852  if (dctx->dStage == dstage_flushOut) {
1853  size_t const preserveSize = (size_t)(dctx->tmpOut - dctx->tmpOutBuffer);
1854  size_t copySize = 64 KB - dctx->tmpOutSize;
1855  const BYTE* oldDictEnd = dctx->dict + dctx->dictSize - dctx->tmpOutStart;
1856  if (dctx->tmpOutSize > 64 KB) copySize = 0;
1857  if (copySize > preserveSize) copySize = preserveSize;
1858  assert(dctx->tmpOutBuffer != NULL);
1859 
1860  memcpy(dctx->tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1861 
1862  dctx->dict = dctx->tmpOutBuffer;
1863  dctx->dictSize = preserveSize + dctx->tmpOutStart;
1864  } else {
1865  const BYTE* const oldDictEnd = dctx->dict + dctx->dictSize;
1866  size_t const newDictSize = MIN(dctx->dictSize, 64 KB);
1867 
1868  memcpy(dctx->tmpOutBuffer, oldDictEnd - newDictSize, newDictSize);
1869 
1870  dctx->dict = dctx->tmpOutBuffer;
1871  dctx->dictSize = newDictSize;
1872  dctx->tmpOut = dctx->tmpOutBuffer + newDictSize;
1873  }
1874  }
1875 
1876  *srcSizePtr = (size_t)(srcPtr - srcStart);
1877  *dstSizePtr = (size_t)(dstPtr - dstStart);
1878  return nextSrcSizeHint;
1879 }
1880 
1887  void* dstBuffer, size_t* dstSizePtr,
1888  const void* srcBuffer, size_t* srcSizePtr,
1889  const void* dict, size_t dictSize,
1890  const LZ4F_decompressOptions_t* decompressOptionsPtr)
1891 {
1892  if (dctx->dStage <= dstage_init) {
1893  dctx->dict = (const BYTE*)dict;
1894  dctx->dictSize = dictSize;
1895  }
1896  return LZ4F_decompress(dctx, dstBuffer, dstSizePtr,
1897  srcBuffer, srcSizePtr,
1898  decompressOptionsPtr);
1899 }
static char * version
Definition: acr.h:4
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
#define FLG(x)
Definition: esil.c:10
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static const char struct stat static buf struct stat static buf static vhangup int options
Definition: sflib.h:145
static void struct sockaddr socklen_t static fromlen static backlog static fork char char char static envp int struct rusage static rusage struct utsname static buf struct sembuf unsigned
Definition: sflib.h:97
XXH_PUBLIC_API unsigned int XXH32_digest(const XXH32_state_t *state_in)
Definition: xxhash.c:546
XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed)
Definition: xxhash.c:392
XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed)
Definition: xxhash.c:437
XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *state_in, const void *input, size_t len)
Definition: xxhash.c:515
struct XXH32_state_s XXH32_state_t
Definition: xxhash.h:172
unsigned long long U64
Definition: lz4.c:290
int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize)
Definition: lz4.c:1475
LZ4_stream_t * LZ4_createStream(void)
Definition: lz4.c:1423
int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxOutputSize, const char *dictStart, int dictSize)
Definition: lz4.c:2404
LZ4_stream_t * LZ4_initStream(void *buffer, size_t size)
Definition: lz4.c:1443
unsigned char BYTE
Definition: lz4.c:286
void LZ4_resetStream_fast(LZ4_stream_t *ctx)
Definition: lz4.c:1461
int LZ4_freeStream(LZ4_stream_t *LZ4_stream)
Definition: lz4.c:1465
int LZ4_saveDict(LZ4_stream_t *LZ4_dict, char *safeBuffer, int dictSize)
Definition: lz4.c:1668
int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
Definition: lz4.c:1565
unsigned int U32
Definition: lz4.c:288
int LZ4_compress_fast_extState_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int acceleration)
Definition: lz4.c:1316
unsigned short U16
Definition: lz4.c:287
void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream)
Definition: lz4.c:1517
char int srcSize
Definition: lz4.h:697
char * dst
Definition: lz4.h:724
#define _2BITS
Definition: lz4frame.c:204
LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx *dctx)
Definition: lz4frame.c:1082
struct LZ4F_cctx_s LZ4F_cctx_t
static size_t LZ4F_makeBlock(void *dst, const void *src, size_t srcSize, compressFunc_t compress, void *lz4ctx, int level, const LZ4F_CDict *cdict, LZ4F_blockChecksum_t crcFlag)
Definition: lz4frame.c:740
static void LZ4F_writeLE32(void *dst, U32 value32)
Definition: lz4frame.c:157
#define _3BITS
Definition: lz4frame.c:205
static LZ4F_blockSizeID_t LZ4F_optimalBSID(const LZ4F_blockSizeID_t requestedBSID, const size_t srcSize)
Definition: lz4frame.c:304
unsigned long long U64
Definition: lz4frame.c:142
size_t LZ4F_compressBegin(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:710
static size_t LZ4F_compressBound_internal(size_t srcSize, const LZ4F_preferences_t *preferencesPtr, size_t alreadyBuffered)
Definition: lz4frame.c:324
size_t LZ4F_getBlockSize(unsigned blockSizeID)
Definition: lz4frame.c:278
size_t LZ4F_compressUpdate(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:825
#define MIN(a, b)
Definition: lz4frame.c:292
dStage_t
Definition: lz4frame.c:1029
@ dstage_skipSkippable
Definition: lz4frame.c:1038
@ dstage_getCBlock
Definition: lz4frame.c:1034
@ dstage_getSuffix
Definition: lz4frame.c:1036
@ dstage_getFrameHeader
Definition: lz4frame.c:1030
@ dstage_getSFrameSize
Definition: lz4frame.c:1037
@ dstage_storeSFrameSize
Definition: lz4frame.c:1037
@ dstage_storeSuffix
Definition: lz4frame.c:1036
@ dstage_getBlockChecksum
Definition: lz4frame.c:1033
@ dstage_init
Definition: lz4frame.c:1031
@ dstage_storeBlockHeader
Definition: lz4frame.c:1032
@ dstage_storeCBlock
Definition: lz4frame.c:1034
@ dstage_storeFrameHeader
Definition: lz4frame.c:1030
@ dstage_copyDirect
Definition: lz4frame.c:1033
@ dstage_flushOut
Definition: lz4frame.c:1035
@ dstage_getBlockHeader
Definition: lz4frame.c:1032
unsigned char BYTE
Definition: lz4frame.c:138
int LZ4F_compressionLevel_max(void)
Definition: lz4frame.c:276
static U32 LZ4F_readLE32(const void *src)
Definition: lz4frame.c:147
signed int S32
Definition: lz4frame.c:141
LZ4F_CDict * LZ4F_createCDict(const void *dictBuffer, size_t dictSize)
Definition: lz4frame.c:490
static void LZ4F_updateDict(LZ4F_dctx *dctx, const BYTE *dstPtr, size_t dstSize, const BYTE *dstBufferStart, unsigned withinTmp)
Definition: lz4frame.c:1295
size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:351
size_t LZ4F_flush(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:938
static const size_t minFHSize
Definition: lz4frame.c:214
size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx *cctx, void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:373
size_t LZ4F_decompress_usingDict(LZ4F_dctx *dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const void *dict, size_t dictSize, const LZ4F_decompressOptions_t *decompressOptionsPtr)
Definition: lz4frame.c:1886
static int LZ4F_compressBlockHC(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:784
static int LZ4F_compressBlock(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:766
static const size_t BHSize
Definition: lz4frame.c:216
size_t LZ4F_decompress(LZ4F_dctx *dctx, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const LZ4F_decompressOptions_t *decompressOptionsPtr)
Definition: lz4frame.c:1384
static const size_t maxFHSize
Definition: lz4frame.c:215
#define LZ4F_MAGIC_SKIPPABLE_START
Definition: lz4frame.c:209
#define LZ4F_BLOCKUNCOMPRESSED_FLAG
Definition: lz4frame.c:211
static int LZ4F_compressBlockHC_continue(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:793
static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int level)
Definition: lz4frame.c:799
size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:724
static const char * LZ4F_errorStrings[]
Definition: lz4frame.c:246
static size_t LZ4F_decodeHeader(LZ4F_dctx *dctx, const void *src, size_t srcSize)
Definition: lz4frame.c:1113
#define DEBUGLOG(l,...)
Definition: lz4frame.c:123
LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx *cctxPtr)
Definition: lz4frame.c:550
static LZ4F_errorCode_t err0r(LZ4F_errorCodes code)
Definition: lz4frame.c:267
#define LZ4F_BLOCKSIZEID_DEFAULT
Definition: lz4frame.c:212
#define ALLOC(s)
Definition: lz4frame.c:76
#define FREEMEM(p)
Definition: lz4frame.c:78
unsigned LZ4F_getVersion(void)
Definition: lz4frame.c:274
unsigned LZ4F_isError(LZ4F_errorCode_t code)
Definition: lz4frame.c:249
LZ4F_errorCode_t LZ4F_getFrameInfo(LZ4F_dctx *dctx, LZ4F_frameInfo_t *frameInfoPtr, const void *srcBuffer, size_t *srcSizePtr)
Definition: lz4frame.c:1253
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx **LZ4F_decompressionContextPtr, unsigned versionNumber)
Definition: lz4frame.c:1069
#define LZ4F_MAGICNUMBER
Definition: lz4frame.c:210
#define ALLOC_AND_ZERO(s)
Definition: lz4frame.c:77
#define MEM_INIT(p, v, s)
Definition: lz4frame.c:83
static int LZ4F_compressBlock_continue(void *ctx, const char *src, char *dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:777
void LZ4F_resetDecompressionContext(LZ4F_dctx *dctx)
Definition: lz4frame.c:1097
size_t LZ4F_compressFrame(void *dstBuffer, size_t dstCapacity, const void *srcBuffer, size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:429
LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_cctx **LZ4F_compressionContextPtr, unsigned version)
Definition: lz4frame.c:536
unsigned int U32
Definition: lz4frame.c:140
static U64 LZ4F_readLE64(const void *src)
Definition: lz4frame.c:166
static void LZ4F_writeLE64(void *dst, U64 value64)
Definition: lz4frame.c:180
static int LZ4F_localSaveDict(LZ4F_cctx_t *cctxPtr)
Definition: lz4frame.c:809
#define assert(condition)
Definition: lz4frame.c:107
static BYTE LZ4F_headerChecksum(const void *header, size_t length)
Definition: lz4frame.c:294
LZ4F_errorCodes LZ4F_getErrorCode(size_t functionResult)
Definition: lz4frame.c:261
void LZ4F_freeCDict(LZ4F_CDict *cdict)
Definition: lz4frame.c:514
unsigned short U16
Definition: lz4frame.c:139
const char * LZ4F_getErrorName(LZ4F_errorCode_t code)
Definition: lz4frame.c:254
#define LZ4F_STATIC_ASSERT(c)
Definition: lz4frame.c:111
#define _1BIT
Definition: lz4frame.c:203
size_t LZ4F_compressEnd(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_compressOptions_t *compressOptionsPtr)
Definition: lz4frame.c:986
static void LZ4F_initStream(void *ctx, const LZ4F_CDict *cdict, int level, LZ4F_blockMode_t blockMode)
Definition: lz4frame.c:570
#define _4BITS
Definition: lz4frame.c:206
static const size_t BFSize
Definition: lz4frame.c:217
size_t LZ4F_headerSize(const void *src, size_t srcSize)
Definition: lz4frame.c:1212
size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx *cctxPtr, void *dstBuffer, size_t dstCapacity, const LZ4F_CDict *cdict, const LZ4F_preferences_t *preferencesPtr)
Definition: lz4frame.c:598
#define LZ4F_GENERATE_STRING(STRING)
Definition: lz4frame.c:245
LZ4F_lastBlockStatus
Definition: lz4frame.c:816
@ fromSrcBuffer
Definition: lz4frame.c:816
@ notDone
Definition: lz4frame.c:816
@ fromTmpBuffer
Definition: lz4frame.c:816
int(* compressFunc_t)(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level, const LZ4F_CDict *cdict)
Definition: lz4frame.c:733
LZ4F_blockMode_t
Definition: lz4frame.h:138
@ LZ4F_blockLinked
Definition: lz4frame.h:139
@ LZ4F_blockIndependent
Definition: lz4frame.h:140
#define LZ4F_MIN_SIZE_TO_KNOW_HEADER_LENGTH
Definition: lz4frame.h:374
size_t LZ4F_errorCode_t
Definition: lz4frame.h:103
#define LZ4F_HEADER_SIZE_MAX
Definition: lz4frame.h:260
#define LZ4F_BLOCK_HEADER_SIZE
Definition: lz4frame.h:263
LZ4F_blockSizeID_t
Definition: lz4frame.h:123
@ LZ4F_max64KB
Definition: lz4frame.h:125
@ LZ4F_max4MB
Definition: lz4frame.h:128
#define LZ4F_HEADER_SIZE_MIN
Definition: lz4frame.h:259
#define LZ4F_INIT_PREFERENCES
Definition: lz4frame.h:200
#define LZ4F_BLOCK_CHECKSUM_SIZE
Definition: lz4frame.h:266
LZ4F_contentChecksum_t
Definition: lz4frame.h:145
@ LZ4F_contentChecksumEnabled
Definition: lz4frame.h:147
@ LZ4F_skippableFrame
Definition: lz4frame.h:159
@ LZ4F_frame
Definition: lz4frame.h:158
LZ4F_blockChecksum_t
Definition: lz4frame.h:152
@ LZ4F_blockChecksumEnabled
Definition: lz4frame.h:154
#define LZ4F_VERSION
Definition: lz4frame.h:242
void LZ4_favorDecompressionSpeed(LZ4_streamHC_t *LZ4_streamHCPtr, int favor)
Definition: lz4hc.c:1049
void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
Definition: lz4hc.c:1077
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1027
int LZ4_saveDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, char *safeBuffer, int dictSize)
Definition: lz4hc.c:1158
LZ4_streamHC_t * LZ4_initStreamHC(void *buffer, size_t size)
Definition: lz4hc.c:1003
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
Definition: lz4hc.c:994
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:1138
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:985
int LZ4_compress_HC_extStateHC_fastReset(void *state, const char *src, char *dst, int srcSize, int dstCapacity, int compressionLevel)
Definition: lz4hc.c:935
void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1041
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:1056
#define LZ4HC_CLEVEL_DEFAULT
Definition: lz4hc.h:48
#define LZ4HC_CLEVEL_MAX
Definition: lz4hc.h:50
#define LZ4HC_CLEVEL_MIN
Definition: lz4hc.h:47
#define header(is_bt, len_min, ret_op)
#define BD(a, b)
Definition: print.c:1148
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
int int32_t
Definition: sftypes.h:33
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
int ptrdiff_t
Definition: sftypes.h:68
void * dictContent
Definition: lz4frame.c:479
LZ4_stream_t * fastCtx
Definition: lz4frame.c:480
LZ4_streamHC_t * HCCtx
Definition: lz4frame.c:481
BYTE * tmpBuff
Definition: lz4frame.c:231
U16 lz4CtxState
Definition: lz4frame.c:238
size_t tmpInSize
Definition: lz4frame.c:233
U32 cStage
Definition: lz4frame.c:227
U16 lz4CtxAlloc
Definition: lz4frame.c:237
const LZ4F_CDict * cdict
Definition: lz4frame.c:228
U64 totalInSize
Definition: lz4frame.c:234
size_t maxBufferSize
Definition: lz4frame.c:230
U32 version
Definition: lz4frame.c:226
LZ4F_preferences_t prefs
Definition: lz4frame.c:225
size_t maxBlockSize
Definition: lz4frame.c:229
void * lz4CtxPtr
Definition: lz4frame.c:236
BYTE * tmpIn
Definition: lz4frame.c:232
XXH32_state_t xxh
Definition: lz4frame.c:235
size_t dictSize
Definition: lz4frame.c:1053
const BYTE * dict
Definition: lz4frame.c:1052
size_t maxBufferSize
Definition: lz4frame.c:1047
size_t maxBlockSize
Definition: lz4frame.c:1046
dStage_t dStage
Definition: lz4frame.c:1044
size_t tmpInSize
Definition: lz4frame.c:1049
BYTE * tmpIn
Definition: lz4frame.c:1048
size_t tmpOutSize
Definition: lz4frame.c:1055
XXH32_state_t blockChecksum
Definition: lz4frame.c:1058
size_t tmpOutStart
Definition: lz4frame.c:1056
BYTE header[LZ4F_HEADER_SIZE_MAX]
Definition: lz4frame.c:1059
LZ4F_frameInfo_t frameInfo
Definition: lz4frame.c:1042
BYTE * tmpOutBuffer
Definition: lz4frame.c:1051
XXH32_state_t xxh
Definition: lz4frame.c:1057
size_t tmpInTarget
Definition: lz4frame.c:1050
BYTE * tmpOut
Definition: lz4frame.c:1054
U64 frameRemainingSize
Definition: lz4frame.c:1045
LZ4F_contentChecksum_t contentChecksumFlag
Definition: lz4frame.h:178
unsigned dictID
Definition: lz4frame.h:181
unsigned long long contentSize
Definition: lz4frame.h:180
LZ4F_frameType_t frameType
Definition: lz4frame.h:179
LZ4F_blockChecksum_t blockChecksumFlag
Definition: lz4frame.h:182
LZ4F_blockMode_t blockMode
Definition: lz4frame.h:177
LZ4F_blockSizeID_t blockSizeID
Definition: lz4frame.h:176
LZ4F_frameInfo_t frameInfo
Definition: lz4frame.h:193
unsigned favorDecSpeed
Definition: lz4frame.h:196
unsigned autoFlush
Definition: lz4frame.h:195
Definition: inftree9.h:24
#define KB
Definition: unum.c:91
#define GB
Definition: unum.c:93
#define MB
Definition: unum.c:92
static int level
Definition: vmenus.c:2424
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:1063