From eeb31eed39c97791a2a204b68e528185be48ae0d Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 9 Mar 2017 11:44:25 -0800 Subject: [PATCH 001/400] s/ZSTD_btopt2/ZSTD_btultra/g --- doc/zstd_manual.html | 2 +- lib/compress/zstd_compress.c | 42 ++++++++++++++++++------------------ lib/zstd.h | 2 +- programs/zstd.1 | 4 ++-- tests/paramgrill.c | 20 ++++++++--------- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 77e8974de..8be0e6863 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -277,7 +277,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);

Advanced types


 
-
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy;   /* from faster to stronger */
+
typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
 

typedef struct {
     unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index 450e5970a..f0cef80a6 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -154,7 +154,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
       U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
       CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
     CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
-    if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
+    if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) return ERROR(compressionParameter_unsupported);
     return 0;
 }
 
@@ -211,7 +211,7 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
     size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<workSpaceSize < neededSpace) {
                 ZSTD_free(zc->workSpace, zc->customMem);
                 zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
@@ -305,7 +305,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
         zc->frameContentSize = frameContentSize;
         { int i; for (i=0; irep[i] = repStartValue[i]; }
 
-        if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
+        if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btultra)) {
             zc->seqStore.litFreq = (U32*)ptr;
             zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
@@ -2258,7 +2258,7 @@ static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t src
 #endif
 }
 
-static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static void ZSTD_compressBlock_btultra(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
 {
 #ifdef ZSTD_OPT_H_91842398743
     ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
@@ -2278,7 +2278,7 @@ static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, si
 #endif
 }
 
-static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+static void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
 {
 #ifdef ZSTD_OPT_H_91842398743
     ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
@@ -2294,8 +2294,8 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr
 static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
 {
     static const ZSTD_blockCompressor blockCompressor[2][8] = {
-        { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
-        { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
+        { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra },
+        { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict }
     };
 
     return blockCompressor[extDict][(U32)strat];
@@ -2539,7 +2539,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
 
     case ZSTD_btlazy2:
     case ZSTD_btopt:
-    case ZSTD_btopt2:
+    case ZSTD_btultra:
         ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
         break;
 
@@ -3270,9 +3270,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
     { 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
     { 23, 23, 22,  6,  5, 32, ZSTD_btopt   },  /* level 18 */
     { 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
-    { 25, 25, 23,  7,  3, 64, ZSTD_btopt2  },  /* level 20 */
-    { 26, 26, 23,  7,  3,256, ZSTD_btopt2  },  /* level 21 */
-    { 27, 27, 25,  9,  3,512, ZSTD_btopt2  },  /* level 22 */
+    { 25, 25, 23,  7,  3, 64, ZSTD_btultra  },  /* level 20 */
+    { 26, 26, 23,  7,  3,256, ZSTD_btultra  },  /* level 21 */
+    { 27, 27, 25,  9,  3,512, ZSTD_btultra  },  /* level 22 */
 },
 {   /* for srcSize <= 256 KB */
     /* W,  C,  H,  S,  L,  T, strat */
@@ -3296,9 +3296,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
     { 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
     { 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
     { 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
-    { 18, 19, 18, 11,  3,512, ZSTD_btopt2  },  /* level 20.*/
-    { 18, 19, 18, 12,  3,512, ZSTD_btopt2  },  /* level 21.*/
-    { 18, 19, 18, 13,  3,512, ZSTD_btopt2  },  /* level 22.*/
+    { 18, 19, 18, 11,  3,512, ZSTD_btultra  },  /* level 20.*/
+    { 18, 19, 18, 12,  3,512, ZSTD_btultra  },  /* level 21.*/
+    { 18, 19, 18, 13,  3,512, ZSTD_btultra  },  /* level 22.*/
 },
 {   /* for srcSize <= 128 KB */
     /* W,  C,  H,  S,  L,  T, strat */
@@ -3322,9 +3322,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
     { 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
     { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
     { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
-    { 17, 18, 17,  9,  3,256, ZSTD_btopt2  },  /* level 20.*/
-    { 17, 18, 17, 10,  3,256, ZSTD_btopt2  },  /* level 21.*/
-    { 17, 18, 17, 11,  3,512, ZSTD_btopt2  },  /* level 22.*/
+    { 17, 18, 17,  9,  3,256, ZSTD_btultra  },  /* level 20.*/
+    { 17, 18, 17, 10,  3,256, ZSTD_btultra  },  /* level 21.*/
+    { 17, 18, 17, 11,  3,512, ZSTD_btultra  },  /* level 22.*/
 },
 {   /* for srcSize <= 16 KB */
     /* W,  C,  H,  S,  L,  T, strat */
@@ -3348,9 +3348,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
     { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
     { 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
     { 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
-    { 14, 15, 15,  8,  3,256, ZSTD_btopt2  },  /* level 20.*/
-    { 14, 15, 15,  9,  3,256, ZSTD_btopt2  },  /* level 21.*/
-    { 14, 15, 15, 10,  3,256, ZSTD_btopt2  },  /* level 22.*/
+    { 14, 15, 15,  8,  3,256, ZSTD_btultra  },  /* level 20.*/
+    { 14, 15, 15,  9,  3,256, ZSTD_btultra  },  /* level 21.*/
+    { 14, 15, 15, 10,  3,256, ZSTD_btultra  },  /* level 22.*/
 },
 };
 
diff --git a/lib/zstd.h b/lib/zstd.h
index 0b48b7ec6..94b31a8e5 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -368,7 +368,7 @@ static const size_t ZSTD_skippableHeaderSize = 8;  /* magic number + skippable f
 
 
 /*--- Advanced types ---*/
-typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy;   /* from faster to stronger */
+typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
 
 typedef struct {
     unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
diff --git a/programs/zstd.1 b/programs/zstd.1
index 684fb868a..2e4875fb9 100644
--- a/programs/zstd.1
+++ b/programs/zstd.1
@@ -310,7 +310,7 @@ The list of available \fIoptions\fR:
 Specify a strategy used by a match finder.
 .IP ""
 There are 8 strategies numbered from 0 to 7, from faster to stronger:
-0=ZSTD_fast, 1=ZSTD_dfast, 2=ZSTD_greedy, 3=ZSTD_lazy, 4=ZSTD_lazy2, 5=ZSTD_btlazy2, 6=ZSTD_btopt, 7=ZSTD_btopt2.
+0=ZSTD_fast, 1=ZSTD_dfast, 2=ZSTD_greedy, 3=ZSTD_lazy, 4=ZSTD_lazy2, 5=ZSTD_btlazy2, 6=ZSTD_btopt, 7=ZSTD_btultra.
 .IP ""
 
 .TP
@@ -389,7 +389,7 @@ The minimum \fIslen\fR is 3 and the maximum is 7.
 Specify the minimum match length that causes a match finder to interrupt searching of better matches.
 .IP ""
 The bigger minimum match length usually improves compression ratio but decreases compression speed.
-This option is used only with ZSTD_btopt and ZSTD_btopt2 strategies.
+This option is used only with ZSTD_btopt and ZSTD_btultra strategies.
 .IP ""
 The minimum \fItlen\fR is 4 and the maximum is 999.
 .IP ""
diff --git a/tests/paramgrill.c b/tests/paramgrill.c
index 5eabcba2b..39aa8c595 100644
--- a/tests/paramgrill.c
+++ b/tests/paramgrill.c
@@ -296,14 +296,14 @@ static size_t BMK_benchParam(BMK_result_t* resultPtr,
 }
 
 
-const char* g_stratName[] = { "ZSTD_fast   ",
-                              "ZSTD_dfast  ",
-                              "ZSTD_greedy ",
-                              "ZSTD_lazy   ",
-                              "ZSTD_lazy2  ",
-                              "ZSTD_btlazy2",
-                              "ZSTD_btopt  ",
-                              "ZSTD_btopt2 "};
+const char* g_stratName[] = { "ZSTD_fast    ",
+                              "ZSTD_dfast   ",
+                              "ZSTD_greedy  ",
+                              "ZSTD_lazy    ",
+                              "ZSTD_lazy2   ",
+                              "ZSTD_btlazy2 ",
+                              "ZSTD_btopt   ",
+                              "ZSTD_btultra "};
 
 static void BMK_printWinner(FILE* f, U32 cLevel, BMK_result_t result, ZSTD_compressionParameters params, size_t srcSize)
 {
@@ -443,7 +443,7 @@ static ZSTD_compressionParameters* sanitizeParams(ZSTD_compressionParameters par
         g_params.chainLog = 0, g_params.searchLog = 0;
     if (params.strategy == ZSTD_dfast)
         g_params.searchLog = 0;
-    if (params.strategy != ZSTD_btopt && params.strategy != ZSTD_btopt2)
+    if (params.strategy != ZSTD_btopt && params.strategy != ZSTD_btultra)
         g_params.targetLength = 0;
     return &g_params;
 }
@@ -549,7 +549,7 @@ static ZSTD_compressionParameters randomParams(void)
         p.windowLog  = FUZ_rand(&g_rand) % (ZSTD_WINDOWLOG_MAX+1 - ZSTD_WINDOWLOG_MIN) + ZSTD_WINDOWLOG_MIN;
         p.searchLength=FUZ_rand(&g_rand) % (ZSTD_SEARCHLENGTH_MAX+1 - ZSTD_SEARCHLENGTH_MIN) + ZSTD_SEARCHLENGTH_MIN;
         p.targetLength=FUZ_rand(&g_rand) % (ZSTD_TARGETLENGTH_MAX+1 - ZSTD_TARGETLENGTH_MIN) + ZSTD_TARGETLENGTH_MIN;
-        p.strategy   = (ZSTD_strategy) (FUZ_rand(&g_rand) % (ZSTD_btopt2 +1));
+        p.strategy   = (ZSTD_strategy) (FUZ_rand(&g_rand) % (ZSTD_btultra +1));
         validated = !ZSTD_isError(ZSTD_checkCParams(p));
     }
     return p;

From f35ef5c8e9de43ff09dd1a281c1e0f3a773675d9 Mon Sep 17 00:00:00 2001
From: Nick Terrell 
Date: Thu, 9 Mar 2017 12:51:33 -0800
Subject: [PATCH 002/400] Whitespace only: tabs to spaces

---
 lib/common/bitstream.h       |  4 ++--
 lib/common/mem.h             |  2 +-
 lib/common/threading.c       |  1 -
 lib/compress/fse_compress.c  | 16 ++++++++--------
 lib/compress/zstd_compress.c |  8 ++++----
 lib/compress/zstd_opt.h      |  8 ++++----
 6 files changed, 19 insertions(+), 20 deletions(-)

diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h
index d3873002e..0e3d2fc55 100644
--- a/lib/common/bitstream.h
+++ b/lib/common/bitstream.h
@@ -376,8 +376,8 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
               if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
 MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
 {
-	if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
-		return BIT_DStream_overflow;
+    if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
+        return BIT_DStream_overflow;
 
     if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
         bitD->ptr -= bitD->bitsConsumed >> 3;
diff --git a/lib/common/mem.h b/lib/common/mem.h
index 7a3f72141..1e28fec46 100644
--- a/lib/common/mem.h
+++ b/lib/common/mem.h
@@ -120,7 +120,7 @@ MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
 /* currently only defined for gcc and icc */
 #if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
-	__pragma( pack(push, 1) )
+    __pragma( pack(push, 1) )
     typedef union { U16 u16; U32 u32; U64 u64; size_t st; } unalign;
     __pragma( pack(pop) )
 #else
diff --git a/lib/common/threading.c b/lib/common/threading.c
index 32d58796a..141376c56 100644
--- a/lib/common/threading.c
+++ b/lib/common/threading.c
@@ -1,4 +1,3 @@
-
 /**
  * Copyright (c) 2016 Tino Reichardt
  * All rights reserved.
diff --git a/lib/compress/fse_compress.c b/lib/compress/fse_compress.c
index 6708fb9d7..881bd27ab 100644
--- a/lib/compress/fse_compress.c
+++ b/lib/compress/fse_compress.c
@@ -476,20 +476,20 @@ void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
 /* provides the minimum logSize to safely represent a distribution */
 static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
 {
-	U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
-	U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
-	U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
-	return minBits;
+    U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
+    U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
+    U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
+    return minBits;
 }
 
 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
 {
-	U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
+    U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
     U32 tableLog = maxTableLog;
-	U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
+    U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
-	if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
-	if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
+    if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
+    if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
     if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
     if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
     return tableLog;
diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
index f0cef80a6..4a6c49d6e 100644
--- a/lib/compress/zstd_compress.c
+++ b/lib/compress/zstd_compress.c
@@ -1462,8 +1462,8 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
 
         if (ip <= ilimit) {
             /* Fill Table */
-			hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
-			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
+            hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
+            hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
             hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
             hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
             /* check immediate repcode */
@@ -1588,7 +1588,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
             match = dictBase + matchIndex;
             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
             if (matchIndex+matchLength >= dictLimit)
-				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
+                match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
         }
 
         if (matchLength > bestLength) {
@@ -1667,7 +1667,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
             match = dictBase + matchIndex;
             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
             if (matchIndex+matchLength >= dictLimit)
-				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
+                match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
         }
 
         if (matchLength > bestLength) {
diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
index ac418b61c..2c4014325 100644
--- a/lib/compress/zstd_opt.h
+++ b/lib/compress/zstd_opt.h
@@ -175,10 +175,10 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
     }
 
     /* match offset */
-	{   BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
-		seqStorePtr->offCodeSum++;
-		seqStorePtr->offCodeFreq[offCode]++;
-	}
+    {   BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
+        seqStorePtr->offCodeSum++;
+        seqStorePtr->offCodeFreq[offCode]++;
+    }
 
     /* match Length */
     {   const BYTE ML_deltaCode = 36;

From c3ba15e48f89071b2f2ab5aa137b5c5774709e3a Mon Sep 17 00:00:00 2001
From: Sean Purcell 
Date: Mon, 10 Apr 2017 16:22:35 -0700
Subject: [PATCH 003/400] Seekable compression demo

---
 doc/zstd_manual.html                 | 107 +++++++++
 examples/.gitignore                  |   2 +
 examples/Makefile                    |   9 +-
 examples/seekable_compression.c      | 126 ++++++++++
 examples/seekable_decompression.c    | 175 ++++++++++++++
 lib/common/error_private.c           |   2 +
 lib/common/seekable.h                |  23 ++
 lib/common/zstd_errors.h             |   2 +
 lib/compress/zstdseek_compress.c     | 265 ++++++++++++++++++++
 lib/decompress/zstdseek_decompress.c | 347 +++++++++++++++++++++++++++
 lib/zstd.h                           | 117 +++++++++
 11 files changed, 1174 insertions(+), 1 deletion(-)
 create mode 100644 examples/seekable_compression.c
 create mode 100644 examples/seekable_decompression.c
 create mode 100644 lib/common/seekable.h
 create mode 100644 lib/compress/zstdseek_compress.c
 create mode 100644 lib/decompress/zstdseek_decompress.c

diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
index a66f0a49c..a47b7142a 100644
--- a/doc/zstd_manual.html
+++ b/doc/zstd_manual.html
@@ -28,6 +28,9 @@
 
  • Buffer-less streaming compression (synchronous mode)
  • Buffer-less streaming decompression (synchronous mode)
  • Block functions
  • +
  • Seekable Format
  • +
  • Seekable compression - HowTo
  • +
  • Seekable decompression - HowTo

  • Introduction

    @@ -660,5 +663,109 @@ size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, cons
     size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
     

    +

    Seekable Format

    +  The seekable format splits the compressed data into a series of "chunks",
    +  each compressed individually so that decompression of a section in the
    +  middle of an archive only requires zstd to decompress at most a chunk's
    +  worth of extra data, instead of the entire archive.
    +
    + +

    Seekable compression - HowTo

      A ZSTD_seekable_CStream object is required to tracking streaming operation.
    +  Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/
    +  release resources.
    +
    +  Streaming objects are reusable to avoid allocation and deallocation,
    +  to start a new compression operation call ZSTD_seekable_initCStream() on the
    +  compressor.
    +
    +  Data streamed to the seekable compressor will automatically be split into
    +  chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()),
    +  or if none is provided, will be cut off whenver ZSTD_endChunk() is called
    +  or when the default maximum chunk size is reached (approximately 4GB).
    +
    +  Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object
    +  for a new compression operation.
    +  `maxChunkSize` indicates the size at which to automatically start a new
    +  seekable frame.  `maxChunkSize == 0` implies the default maximum size.
    +  @return : a size hint for input to provide for compression, or an error code
    +            checkable with ZSTD_isError()
    +
    +  Use ZSTD_seekable_compressStream() repetitively to consume input stream.
    +  The function will automatically update both `pos` fields.
    +  Note that it may not consume the entire input, in which case `pos < size`,
    +  and it's up to the caller to present again remaining data.
    +  @return : a size hint, preferred nb of bytes to use as input for next
    +            function call or an error code, which can be tested using
    +            ZSTD_isError().
    +            Note 1 : it's just a hint, to help latency a little, any other
    +                     value will work fine.
    +            Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize()
    +
    +  At any time, call ZSTD_seekable_endChunk() to end the current chunk and
    +  start a new one.
    +
    +  ZSTD_endStream() will end the current chunk, and then write the seek table
    +  so that decompressors can efficiently find compressed chunks.
    +  ZSTD_endStream() may return a number > 0 if it was unable to flush all the
    +  necessary data to `output`.  In this case, it should be called again until
    +  all remaining data is flushed out and 0 is returned.
    +
    + +

    Seekable compressor management

    ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void);
    +size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs);
    +

    +

    Seekable compression functions

    size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, unsigned maxChunkSize);
    +size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
    +size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    +size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    +

    +

    Seekable decompression - HowTo

      A ZSTD_seekable_DStream object is required to tracking streaming operation.
    +  Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/
    +  release resources.
    +
    +  Streaming objects are reusable to avoid allocation and deallocation,
    +  to start a new compression operation call ZSTD_seekable_initDStream() on the
    +  compressor.
    +
    +  Use ZSTD_seekable_loadSeekTable() to load the seek table from a file.
    +  `src` should point to a block of data read from the end of the file,
    +  i.e. `src + srcSize` should always be the end of the file.
    +  @return : 0 if the table was loaded successfully, or if `srcSize` was too
    +            small, a size hint for how much data to provide.
    +            An error code may also be returned, checkable with ZSTD_isError()
    +
    +  Use ZSTD_initDStream to prepare for a new decompression operation using the
    +  seektable loaded with ZSTD_seekable_loadSeekTable().
    +  Data in the range [rangeStart, rangeEnd) will be decompressed.
    +
    +  Call ZSTD_seekable_decompressStream() repetitively to consume input stream.
    +  @return : There are a number of possible return codes for this function
    +           - 0, the decompression operation has completed.
    +           - An error code checkable with ZSTD_isError
    +             + If this error code is ZSTD_error_needSeek, the user should seek
    +               to the file position provided by ZSTD_seekable_getSeekOffset()
    +               and indicate this to the stream with
    +               ZSTD_seekable_updateOffset(), before resuming decompression
    +             + Otherwise, this is a regular decompression error and the input
    +               file is likely corrupted or the API was incorrectly used.
    +           - A size hint, the preferred nb of bytes to provide as input to the
    +             next function call to improve latency.
    +
    +  ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper
    +  functions to indicate where the user should seek their file stream to, when
    +  a different position is required to continue decompression.
    +  Note that ZSTD_seekable_updateOffset will error if given an offset other
    +  than the one requested from ZSTD_seekable_getSeekOffset().
    +
    + +

    Seekable decompressor management

    ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void);
    +size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds);
    +

    +

    Seekable decompression functions

    size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize);
    +size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd);
    +size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
    +unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds);
    +size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset);
    +

    diff --git a/examples/.gitignore b/examples/.gitignore index 0711813d3..c6b2a9f42 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -6,6 +6,8 @@ dictionary_decompression streaming_compression streaming_decompression multiple_streaming_compression +seekable_compression +seekable_decompression #test artefact tmp* diff --git a/examples/Makefile b/examples/Makefile index b84983f08..88cc10d24 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -18,7 +18,8 @@ default: all all: simple_compression simple_decompression \ dictionary_compression dictionary_decompression \ streaming_compression streaming_decompression \ - multiple_streaming_compression + multiple_streaming_compression \ + seekable_compression simple_compression : simple_compression.c $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ @@ -41,6 +42,12 @@ multiple_streaming_compression : multiple_streaming_compression.c streaming_decompression : streaming_decompression.c $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ +seekable_compression : seekable_compression.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +seekable_decompression : seekable_decompression.c + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ + clean: @rm -f core *.o tmp* result* *.zst \ simple_compression simple_decompression \ diff --git a/examples/seekable_compression.c b/examples/seekable_compression.c new file mode 100644 index 000000000..5ab36c3cb --- /dev/null +++ b/examples/seekable_compression.c @@ -0,0 +1,126 @@ +/** + * Copyright 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + +#include // malloc, free, exit, atoi +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc:"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned chunkSize) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + size_t const buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */ + void* const buffIn = malloc_orDie(buffInSize); + size_t const buffOutSize = ZSTD_CStreamOutSize(); /* can always flush a full block */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_seekable_CStream* const cstream = ZSTD_seekable_createCStream(); + if (cstream==NULL) { fprintf(stderr, "ZSTD_seekable_createCStream() error \n"); exit(10); } + size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, chunkSize); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t read, toRead = buffInSize; + while( (read = fread_orDie(buffIn, toRead, fin)) ) { + ZSTD_inBuffer input = { buffIn, read, 0 }; + while (input.pos < input.size) { + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + toRead = ZSTD_seekable_compressStream(cstream, &output , &input); /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */ + if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); } + if (toRead > buffInSize) toRead = buffInSize; /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/ + fwrite_orDie(buffOut, output.pos, fout); + } + } + + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + while (1) { + size_t const remainingToFlush = ZSTD_seekable_endStream(cstream, &output); /* close stream */ + fwrite_orDie(buffOut, output.pos, fout); + if (!remainingToFlush) break; + } + + ZSTD_seekable_freeCStream(cstream); + fclose_orDie(fout); + fclose_orDie(fin); + free(buffIn); + free(buffOut); +} + +static const char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (const char*)outSpace; +} + +int main(int argc, const char** argv) { + const char* const exeName = argv[0]; + if (argc!=3) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE CHUNK_SIZE\n", exeName); + return 1; + } + + { const char* const inFileName = argv[1]; + unsigned const chunkSize = (unsigned)atoi(argv[2]); + + const char* const outFileName = createOutFilename_orDie(inFileName); + compressFile_orDie(inFileName, outFileName, 5, chunkSize); + } +} diff --git a/examples/seekable_decompression.c b/examples/seekable_decompression.c new file mode 100644 index 000000000..97563c3de --- /dev/null +++ b/examples/seekable_decompression.c @@ -0,0 +1,175 @@ +/** + * Copyright 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + + +#include // malloc, exit +#include // fprintf, perror, feof +#include // strerror +#include // errno +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include + + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(1); +} + +static void* realloc_orDie(void* ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) return ptr; + /* error */ + perror("realloc"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) { + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + + +static void decompressFile_orDie(const char* fname, unsigned startOffset, unsigned endOffset) +{ + FILE* const fin = fopen_orDie(fname, "rb"); + size_t const buffInSize = ZSTD_DStreamInSize(); + void* const buffIn = malloc_orDie(buffInSize); + FILE* const fout = stdout; + size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ + void* const buffOut = malloc_orDie(buffOutSize); + + ZSTD_seekable_DStream* const dstream = ZSTD_seekable_createDStream(); + if (dstream==NULL) { fprintf(stderr, "ZSTD_seekable_createDStream() error \n"); exit(10); } + + { size_t sizeNeeded = 0; + void* buffSeekTable = NULL; + + do { + sizeNeeded = ZSTD_seekable_loadSeekTable(dstream, buffSeekTable, sizeNeeded); + if (!sizeNeeded) break; + + if (ZSTD_isError(sizeNeeded)) { + fprintf(stderr, "ZSTD_seekable_loadSeekTable() error : %s \n", + ZSTD_getErrorName(sizeNeeded)); + exit(11); + } + + fseek_orDie(fin, -(long) sizeNeeded, SEEK_END); + buffSeekTable = realloc_orDie(buffSeekTable, sizeNeeded); + fread_orDie(buffSeekTable, sizeNeeded, fin); + } while (sizeNeeded > 0); + + free(buffSeekTable); + } + + /* In more complex scenarios, a file may consist of multiple appended frames (ex : pzstd). + * The following example decompresses only the first frame. + * It is compatible with other provided streaming examples */ + size_t const initResult = ZSTD_seekable_initDStream(dstream, startOffset, endOffset); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initDStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t result, read, toRead = 0; + + do { + read = fread_orDie(buffIn, toRead, fin); + { ZSTD_inBuffer input = { buffIn, read, 0 }; + ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; + result = ZSTD_seekable_decompressStream(dstream, &output, &input); + + if (ZSTD_isError(result)) { + if (ZSTD_getErrorCode(result) == ZSTD_error_needSeek) { + unsigned long long const offset = ZSTD_seekable_getSeekOffset(dstream); + fseek_orDie(fin, offset, SEEK_SET); + ZSTD_seekable_updateOffset(dstream, offset); + toRead = 0; + } else { + fprintf(stderr, + "ZSTD_seekable_decompressStream() error : %s \n", + ZSTD_getErrorName(result)); + exit(12); + } + } else { + toRead = result; + } + fwrite_orDie(buffOut, output.pos, fout); + } + } while (result > 0); + + ZSTD_seekable_freeDStream(dstream); + fclose_orDie(fin); + fclose_orDie(fout); + free(buffIn); + free(buffOut); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=4) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE\n", exeName); + return 1; + } + + { + const char* const inFilename = argv[1]; + unsigned const startOffset = (unsigned) atoi(argv[2]); + unsigned const endOffset = (unsigned) atoi(argv[3]); + decompressFile_orDie(inFilename, startOffset, endOffset); + } + return 0; +} diff --git a/lib/common/error_private.c b/lib/common/error_private.c index 44ae20104..4084edca6 100644 --- a/lib/common/error_private.c +++ b/lib/common/error_private.c @@ -38,6 +38,8 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; case PREFIX(dictionary_wrong): return "Dictionary mismatch"; case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; + case PREFIX(chunkIndex_tooLarge): return "Chunk index is too large"; + case PREFIX(needSeek): return "Wrong file position, a seek is required to continue"; case PREFIX(maxCode): default: return notErrorCode; } diff --git a/lib/common/seekable.h b/lib/common/seekable.h new file mode 100644 index 000000000..ab11a4388 --- /dev/null +++ b/lib/common/seekable.h @@ -0,0 +1,23 @@ +#ifndef SEEKABLE_H +#define SEEKABLE_H + +#if defined (__cplusplus) +extern "C" { +#endif + +#include "zstd_internal.h" + +static const unsigned ZSTD_seekTableFooterSize = 9; + +#define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 + +#define ZSTD_SEEKABLE_MAXCHUNKS 0x8000000U + +/* 0xFE03F607 is the largest number x such that ZSTD_compressBound(x) fits in a 32-bit integer */ +#define ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE 0xFE03F607 + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/lib/common/zstd_errors.h b/lib/common/zstd_errors.h index 3d579d969..13a5608e0 100644 --- a/lib/common/zstd_errors.h +++ b/lib/common/zstd_errors.h @@ -58,6 +58,8 @@ typedef enum { ZSTD_error_dictionary_corrupted, ZSTD_error_dictionary_wrong, ZSTD_error_dictionaryCreation_failed, + ZSTD_error_chunkIndex_tooLarge, + ZSTD_error_needSeek, ZSTD_error_maxCode } ZSTD_ErrorCode; diff --git a/lib/compress/zstdseek_compress.c b/lib/compress/zstdseek_compress.c new file mode 100644 index 000000000..284724e58 --- /dev/null +++ b/lib/compress/zstdseek_compress.c @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include /* malloc, free */ + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#include "zstd_internal.h" /* includes zstd.h */ +#include "seekable.h" + +typedef struct { + U32 cSize; + U32 dSize; + U32 checksum; +} chunklogEntry_t; + +typedef struct { + chunklogEntry_t* entries; + U32 size; + U32 capacity; +} chunklog_t; + +struct ZSTD_seekable_CStream_s { + ZSTD_CStream* cstream; + chunklog_t chunklog; + + U32 chunkCSize; + U32 chunkDSize; + + XXH64_state_t xxhState; + + U32 maxChunkSize; + + int checksumFlag; +}; + +ZSTD_seekable_CStream* ZSTD_seekable_createCStream() +{ + ZSTD_seekable_CStream* zcs = malloc(sizeof(ZSTD_seekable_CStream)); + + if (zcs == NULL) return NULL; + + memset(zcs, 0, sizeof(*zcs)); + + zcs->cstream = ZSTD_createCStream(); + if (zcs->cstream == NULL) goto failed1; + + { size_t const CHUNKLOG_STARTING_CAPACITY = 16; + zcs->chunklog.entries = + malloc(sizeof(chunklogEntry_t) * CHUNKLOG_STARTING_CAPACITY); + if (zcs->chunklog.entries == NULL) goto failed2; + zcs->chunklog.capacity = CHUNKLOG_STARTING_CAPACITY; + } + + return zcs; + +failed2: + ZSTD_freeCStream(zcs->cstream); +failed1: + free(zcs); + return NULL; +} + +size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs) +{ + if (zcs == NULL) return 0; /* support free on NULL */ + ZSTD_freeCStream(zcs->cstream); + free(zcs->chunklog.entries); + free(zcs); + + return 0; +} + +size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, + int compressionLevel, + U32 maxChunkSize) +{ + zcs->chunklog.size = 0; + zcs->chunkCSize = 0; + zcs->chunkDSize = 0; + + if (maxChunkSize > ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE) { + return ERROR(compressionParameter_unsupported); + } + + zcs->maxChunkSize = maxChunkSize + ? maxChunkSize + : ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE; + + zcs->checksumFlag = 0; + if (zcs->checksumFlag) { + XXH64_reset(&zcs->xxhState, 0); + } + + return ZSTD_initCStream(zcs->cstream, compressionLevel); +} + +static size_t ZSTD_seekable_logChunk(ZSTD_seekable_CStream* zcs) +{ + if (zcs->chunklog.size == ZSTD_SEEKABLE_MAXCHUNKS) + return ERROR(chunkIndex_tooLarge); + + zcs->chunklog.entries[zcs->chunklog.size] = (chunklogEntry_t) + { + .cSize = zcs->chunkCSize, + .dSize = zcs->chunkDSize, + }; + if (zcs->checksumFlag) + zcs->chunklog.entries[zcs->chunklog.size].checksum = + XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU; + + zcs->chunklog.size++; + if (zcs->chunklog.size == zcs->chunklog.capacity) { + size_t const newCapacity = zcs->chunklog.capacity * 2; + chunklogEntry_t* const newEntries = realloc(zcs->chunklog.entries, + sizeof(chunklogEntry_t) * newCapacity); + + if (newEntries == NULL) return ERROR(memory_allocation); + + zcs->chunklog.entries = newEntries; + zcs->chunklog.capacity = newCapacity; + } + + return 0; +} + +size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +{ + size_t const prevOutPos = output->pos; + size_t ret = ZSTD_endStream(zcs->cstream, output); + + zcs->chunkCSize += output->pos - prevOutPos; + + /* need to flush before doing the rest */ + if (ret) return ret; + + /* frame done */ + + /* store the chunk data for later */ + ret = ZSTD_seekable_logChunk(zcs); + if (ret) return ret; + + /* reset for the next chunk */ + zcs->chunkCSize = 0; + zcs->chunkDSize = 0; + + ZSTD_resetCStream(zcs->cstream, 0); + if (zcs->checksumFlag) + XXH64_reset(&zcs->xxhState, 0); + + return 0; +} + +size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + const BYTE* const inBase = (const BYTE*) input->src + input->pos; + size_t inLen = input->size - input->pos; + + inLen = MIN(inLen, (size_t)(zcs->maxChunkSize - zcs->chunkDSize)); + + if (inLen > 0) { + ZSTD_inBuffer inTmp = { inBase, inLen, 0 }; + size_t const prevOutPos = output->pos; + + size_t const ret = ZSTD_compressStream(zcs->cstream, output, &inTmp); + + if (zcs->checksumFlag) { + XXH64_update(&zcs->xxhState, inBase, inTmp.pos); + } + + zcs->chunkCSize += output->pos - prevOutPos; + zcs->chunkDSize += inTmp.pos; + + input->pos += inTmp.pos; + + if (ZSTD_isError(ret)) return ret; + } + + if (zcs->maxChunkSize == zcs->chunkDSize) { + size_t const ret = ZSTD_seekable_endChunk(zcs, output); + if (ZSTD_isError(ret)) return ret; + } + + return (size_t)(zcs->maxChunkSize - zcs->chunkDSize); +} + +static size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream* zcs) +{ + size_t const sizePerChunk = 8 + (zcs->checksumFlag?4:0); + size_t const seekTableLen = ZSTD_skippableHeaderSize + + sizePerChunk * zcs->chunklog.size + + ZSTD_seekTableFooterSize; + + return seekTableLen; +} + +static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +{ + BYTE* op = (BYTE*) output->dst; + + /* repurpose + * zcs->chunkDSize: the current index in the table and + * zcs->chunkCSize: the amount of the table written so far */ + + size_t const sizePerChunk = 8 + (zcs->checksumFlag?4:0); + size_t const seekTableLen = ZSD_seekable_seekTableSize(zcs); + + if (zcs->chunkCSize == 0) { + if (output->size - output->pos < 4) return seekTableLen - zcs->chunkCSize; + MEM_writeLE32(op + output->pos, ZSTD_MAGIC_SKIPPABLE_START); + output->pos += 4; + zcs->chunkCSize += 4; + } + if (zcs->chunkCSize == 4) { + if (output->size - output->pos < 4) return seekTableLen - zcs->chunkCSize; + MEM_writeLE32(op + output->pos, seekTableLen - ZSTD_skippableHeaderSize); + output->pos += 4; + zcs->chunkCSize += 4; + } + + while (zcs->chunkDSize < zcs->chunklog.size) { + if (output->size - output->pos < sizePerChunk) return seekTableLen - zcs->chunkCSize; + MEM_writeLE32(op + output->pos + 0, zcs->chunklog.entries[zcs->chunkDSize].cSize); + MEM_writeLE32(op + output->pos + 4, zcs->chunklog.entries[zcs->chunkDSize].dSize); + if (zcs->checksumFlag) { + MEM_writeLE32(op + output->pos + 8, zcs->chunklog.entries[zcs->chunkDSize].checksum); + } + output->pos += sizePerChunk; + zcs->chunkCSize += sizePerChunk; + zcs->chunkDSize++; + } + + if (output->size - output->pos < ZSTD_seekTableFooterSize) return seekTableLen - zcs->chunkCSize; + MEM_writeLE32(op + output->pos, zcs->chunklog.size); + { BYTE sfd = 0; + sfd |= (zcs->checksumFlag) << 7; + + op[output->pos + 4] = sfd; + } + MEM_writeLE32(op + output->pos + 5, ZSTD_SEEKABLE_MAGICNUMBER); + + output->pos += ZSTD_seekTableFooterSize; + zcs->chunkCSize += ZSTD_seekTableFooterSize; + + if (zcs->chunkCSize != seekTableLen) return ERROR(GENERIC); + return 0; +} + +size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +{ + if (zcs->chunkDSize) { + const size_t endChunk = ZSTD_seekable_endChunk(zcs, output); + /* return an accurate size hint */ + if (endChunk) return endChunk + ZSTD_seekable_seekTableLen(zcs); + } + + return ZSTD_seekable_writeSeekTable(zcs, output); +} diff --git a/lib/decompress/zstdseek_decompress.c b/lib/decompress/zstdseek_decompress.c new file mode 100644 index 000000000..e76b4c612 --- /dev/null +++ b/lib/decompress/zstdseek_decompress.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include /* malloc, free */ + +#define XXH_STATIC_LINKING_ONLY +#include "xxhash.h" + +#include "zstd_internal.h" /* includes zstd.h */ +#include "seekable.h" + +typedef struct { + U64 cOffset; + U64 dOffset; + U32 checksum; +} seekEntry_t; + +typedef struct { + seekEntry_t* entries; + size_t tableLen; + + int checksumFlag; +} seekTable_t; + +static U32 ZSTD_seekable_offsetToChunk(const seekTable_t* table, U64 pos) +{ + U32 lo = 0; + U32 hi = table->tableLen; + + while (lo + 1 < hi) { + U32 mid = lo + ((hi - lo) >> 1); + if (table->entries[mid].dOffset <= pos) { + lo = mid; + } else { + hi = mid; + } + } + return lo; +} + +enum ZSTD_seekable_DStream_stage { + zsds_init, + zsds_seek, + zsds_decompress, + zsds_done, +}; + +struct ZSTD_seekable_DStream_s { + ZSTD_DStream* dstream; + seekTable_t seekTable; + + U32 curChunk; + U64 compressedOffset; + U64 decompressedOffset; + + U64 targetStart; + U64 targetEnd; + + U64 nextSeek; + + enum ZSTD_seekable_DStream_stage stage; + + XXH64_state_t xxhState; +}; + +ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void) +{ + ZSTD_seekable_DStream* zds = malloc(sizeof(ZSTD_seekable_DStream)); + + if (zds == NULL) return NULL; + + memset(zds, 0, sizeof(*zds)); + + zds->dstream = ZSTD_createDStream(); + if (zds->dstream == NULL) { + free(zds); + return NULL; + } + + return zds; +} + +size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds) +{ + if (zds == NULL) return 0; + ZSTD_freeDStream(zds->dstream); + free(zds->seekTable.entries); + free(zds); + + return 0; +} + +size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize) +{ + const BYTE* ip = (const BYTE*)src + srcSize; + + U32 numChunks; + int checksumFlag; + + U32 sizePerEntry; + + if (srcSize < ZSTD_seekTableFooterSize) + return ZSTD_seekTableFooterSize; + + if (MEM_readLE32(ip - 4) != ZSTD_SEEKABLE_MAGICNUMBER) { + return ERROR(prefix_unknown); + } + + { + BYTE const sfd = ip[-5]; + checksumFlag = sfd >> 7; + + numChunks = MEM_readLE32(ip-9); + + sizePerEntry = 8 + (checksumFlag?4:0); + } + + { U32 const tableSize = sizePerEntry * numChunks; + U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_skippableHeaderSize; + + const BYTE* base = ip - frameSize; + + if (srcSize < frameSize) return frameSize; + + if ((MEM_readLE32(base) & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) { + return ERROR(prefix_unknown); + } + if (MEM_readLE32(base+4) + ZSTD_skippableHeaderSize != frameSize) { + return ERROR(prefix_unknown); + } + + { /* Allocate an extra entry at the end so that we can do size + * computations on the last element without special case */ + seekEntry_t* entries = malloc(sizeof(seekEntry_t) * (numChunks + 1)); + const BYTE* tableBase = base + ZSTD_skippableHeaderSize; + + U32 idx; + size_t pos; + + U64 cOffset = 0; + U64 dOffset = 0; + + if (!entries) { + free(entries); + return ERROR(memory_allocation); + } + + for (idx = 0, pos = 0; idx < numChunks; idx++) { + entries[idx].cOffset = cOffset; + entries[idx].dOffset = dOffset; + + cOffset += MEM_readLE32(tableBase + pos); pos += 4; + dOffset += MEM_readLE32(tableBase + pos); pos += 4; + if (checksumFlag) { + entries[idx].checksum = MEM_readLE32(tableBase + pos); + pos += 4; + } + } + entries[numChunks].cOffset = cOffset; + entries[numChunks].dOffset = dOffset; + + zds->seekTable.entries = entries; + zds->seekTable.tableLen = numChunks; + zds->seekTable.checksumFlag = checksumFlag; + return 0; + } + } +} + +size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64 rangeEnd) +{ + /* restrict range to the end of the file, and not before the range start */ + rangeEnd = MIN(rangeEnd, zds->seekTable.entries[zds->seekTable.tableLen].dOffset); + rangeEnd = MAX(rangeEnd, rangeStart); + + zds->targetStart = rangeStart; + zds->targetEnd = rangeEnd; + zds->stage = zsds_seek; + + /* force a seek first */ + zds->curChunk = (U32) -1; + zds->compressedOffset = (U64) -1; + zds->decompressedOffset = (U64) -1; + + if (zds->seekTable.checksumFlag) { + XXH64_reset(&zds->xxhState, 0); + } + + { const size_t ret = ZSTD_initDStream(zds->dstream); + if (ZSTD_isError(ret)) return ret; } + return 0; +} + +U64 ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds) +{ + return zds->nextSeek; +} + +size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, U64 offset) +{ + if (zds->stage != zsds_seek) { + return ERROR(stage_wrong); + } + if (offset != zds->nextSeek) { + return ERROR(needSeek); + } + + zds->stage = zsds_decompress; + zds->compressedOffset = offset; + return 0; +} + +size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + const seekTable_t* const jt = &zds->seekTable; + while (1) { + switch (zds->stage) { + case zsds_init: + return ERROR(init_missing); + case zsds_decompress: { + BYTE* const outBase = (BYTE*)output->dst + output->pos; + size_t const outLen = output->size - output->pos; + while (zds->decompressedOffset < zds->targetStart) { + U64 const toDecompress = + zds->targetStart - zds->decompressedOffset; + size_t const prevInputPos = input->pos; + + ZSTD_outBuffer outTmp = { + .dst = outBase, + .size = (size_t)MIN((U64)outLen, toDecompress), + .pos = 0}; + + size_t const ret = + ZSTD_decompressStream(zds->dstream, &outTmp, input); + + if (ZSTD_isError(ret)) return ret; + if (ret == 0) { + /* should not happen at this stage */ + return ERROR(corruption_detected); + } + + zds->compressedOffset += input->pos - prevInputPos; + zds->decompressedOffset += outTmp.pos; + + if (zds->seekTable.checksumFlag) { + XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos); + } + + if (input->pos == input->size) { + /* need more input */ + return MIN( + ZSTD_DStreamInSize(), + (size_t)(zds->seekTable.entries[zds->curChunk + 1] + .cOffset - + zds->compressedOffset)); + } + } + + /* do actual decompression */ + { + U64 const toDecompress = + MIN(zds->targetEnd, + jt->entries[zds->curChunk + 1].dOffset) - + zds->decompressedOffset; + size_t const prevInputPos = input->pos; + + ZSTD_outBuffer outTmp = { + .dst = outBase, + .size = (size_t)MIN((U64)outLen, toDecompress), + .pos = 0}; + + size_t const ret = + ZSTD_decompressStream(zds->dstream, &outTmp, input); + + if (ZSTD_isError(ret)) return ret; + + zds->compressedOffset += input->pos - prevInputPos; + zds->decompressedOffset += outTmp.pos; + + output->pos += outTmp.pos; + + if (zds->seekTable.checksumFlag) { + XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos); + if (ret == 0) { + /* verify the checksum */ + U32 const digest = XXH64_digest(&zds->xxhState); + if (digest != jt->entries[zds->curChunk].checksum) { + return ERROR(checksum_wrong); + } + + XXH64_reset(&zds->xxhState, 0); + } + } + + if (zds->decompressedOffset == zds->targetEnd) { + /* done */ + zds->stage = zsds_done; + return 0; + } + + if (ret == 0) { + /* frame is done */ + ZSTD_resetDStream(zds->dstream); + zds->stage = zsds_seek; + break; + } + + /* need more input */ + return MIN( + ZSTD_DStreamInSize(), + (size_t)(zds->seekTable.entries[zds->curChunk + 1] + .cOffset - + zds->compressedOffset)); + } + } + case zsds_seek: { + U32 targetChunk; + if (zds->decompressedOffset < zds->targetStart || + zds->decompressedOffset >= zds->targetEnd) { + /* haven't started yet */ + targetChunk = ZSTD_seekable_offsetToChunk(jt, zds->targetStart); + } else { + targetChunk = ZSTD_seekable_offsetToChunk(jt, zds->decompressedOffset); + } + + zds->curChunk = targetChunk; + + if (zds->compressedOffset == jt->entries[targetChunk].cOffset) { + zds->stage = zsds_decompress; + break; + } + + zds->nextSeek = jt->entries[targetChunk].cOffset; + zds->decompressedOffset = jt->entries[targetChunk].dOffset; + return ERROR(needSeek); + } + case zsds_done: + return 0; + } + } +} diff --git a/lib/zstd.h b/lib/zstd.h index 6066db45e..5bbd1b742 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -776,6 +776,123 @@ ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCa ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */ +/*-**************************************************************************** +* Seekable Format +* +* The seekable format splits the compressed data into a series of "chunks", +* each compressed individually so that decompression of a section in the +* middle of an archive only requires zstd to decompress at most a chunk's +* worth of extra data, instead of the entire archive. +******************************************************************************/ + +typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream; +typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; + +/*-**************************************************************************** +* Seekable compression - HowTo +* A ZSTD_seekable_CStream object is required to tracking streaming operation. +* Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/ +* release resources. +* +* Streaming objects are reusable to avoid allocation and deallocation, +* to start a new compression operation call ZSTD_seekable_initCStream() on the +* compressor. +* +* Data streamed to the seekable compressor will automatically be split into +* chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()), +* or if none is provided, will be cut off whenver ZSTD_endChunk() is called +* or when the default maximum chunk size is reached (approximately 4GB). +* +* Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object +* for a new compression operation. +* `maxChunkSize` indicates the size at which to automatically start a new +* seekable frame. `maxChunkSize == 0` implies the default maximum size. +* @return : a size hint for input to provide for compression, or an error code +* checkable with ZSTD_isError() +* +* Use ZSTD_seekable_compressStream() repetitively to consume input stream. +* The function will automatically update both `pos` fields. +* Note that it may not consume the entire input, in which case `pos < size`, +* and it's up to the caller to present again remaining data. +* @return : a size hint, preferred nb of bytes to use as input for next +* function call or an error code, which can be tested using +* ZSTD_isError(). +* Note 1 : it's just a hint, to help latency a little, any other +* value will work fine. +* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() +* +* At any time, call ZSTD_seekable_endChunk() to end the current chunk and +* start a new one. +* +* ZSTD_endStream() will end the current chunk, and then write the seek table +* so that decompressors can efficiently find compressed chunks. +* ZSTD_endStream() may return a number > 0 if it was unable to flush all the +* necessary data to `output`. In this case, it should be called again until +* all remaining data is flushed out and 0 is returned. +******************************************************************************/ + +/*===== Seekable compressor management =====*/ +ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void); +ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs); + +/*===== Seekable compression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, unsigned maxChunkSize); +ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); +ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); + +/*-**************************************************************************** +* Seekable decompression - HowTo +* A ZSTD_seekable_DStream object is required to tracking streaming operation. +* Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/ +* release resources. +* +* Streaming objects are reusable to avoid allocation and deallocation, +* to start a new compression operation call ZSTD_seekable_initDStream() on the +* compressor. +* +* Use ZSTD_seekable_loadSeekTable() to load the seek table from a file. +* `src` should point to a block of data read from the end of the file, +* i.e. `src + srcSize` should always be the end of the file. +* @return : 0 if the table was loaded successfully, or if `srcSize` was too +* small, a size hint for how much data to provide. +* An error code may also be returned, checkable with ZSTD_isError() +* +* Use ZSTD_initDStream to prepare for a new decompression operation using the +* seektable loaded with ZSTD_seekable_loadSeekTable(). +* Data in the range [rangeStart, rangeEnd) will be decompressed. +* +* Call ZSTD_seekable_decompressStream() repetitively to consume input stream. +* @return : There are a number of possible return codes for this function +* - 0, the decompression operation has completed. +* - An error code checkable with ZSTD_isError +* + If this error code is ZSTD_error_needSeek, the user should seek +* to the file position provided by ZSTD_seekable_getSeekOffset() +* and indicate this to the stream with +* ZSTD_seekable_updateOffset(), before resuming decompression +* + Otherwise, this is a regular decompression error and the input +* file is likely corrupted or the API was incorrectly used. +* - A size hint, the preferred nb of bytes to provide as input to the +* next function call to improve latency. +* +* ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper +* functions to indicate where the user should seek their file stream to, when +* a different position is required to continue decompression. +* Note that ZSTD_seekable_updateOffset will error if given an offset other +* than the one requested from ZSTD_seekable_getSeekOffset(). +******************************************************************************/ + +/*===== Seekable decompressor management =====*/ +ZSTDLIB_API ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void); +ZSTDLIB_API size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds); + +/*===== Seekable decompression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd); +ZSTDLIB_API size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds); +ZSTDLIB_API size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset); + #endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ #if defined (__cplusplus) From a3b7c2260404a85d0d72db37d4a627b9c2caf058 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Tue, 11 Apr 2017 11:40:34 -0700 Subject: [PATCH 004/400] Make seekable streams work w/ small buffers, misc fixes --- doc/zstd_manual.html | 4 +- examples/seekable_compression.c | 9 ++- examples/seekable_decompression.c | 2 + lib/compress/zstdseek_compress.c | 94 +++++++++++++++++++--------- lib/decompress/zstdseek_decompress.c | 52 +++++++++------ lib/zstd.h | 4 +- 6 files changed, 110 insertions(+), 55 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index a47b7142a..0fa5c5d78 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -687,6 +687,8 @@ size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSiz for a new compression operation. `maxChunkSize` indicates the size at which to automatically start a new seekable frame. `maxChunkSize == 0` implies the default maximum size. + `checksumFlag` indicates whether or not the seek table should include chunk + checksums on the uncompressed data for verification. @return : a size hint for input to provide for compression, or an error code checkable with ZSTD_isError() @@ -714,7 +716,7 @@ size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSiz

    Seekable compressor management

    ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void);
     size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs);
     

    -

    Seekable compression functions

    size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, unsigned maxChunkSize);
    +

    Seekable compression functions

    size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize);
     size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
     size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
     size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    diff --git a/examples/seekable_compression.c b/examples/seekable_compression.c
    index 5ab36c3cb..f4bceb10c 100644
    --- a/examples/seekable_compression.c
    +++ b/examples/seekable_compression.c
    @@ -68,7 +68,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve
     
         ZSTD_seekable_CStream* const cstream = ZSTD_seekable_createCStream();
         if (cstream==NULL) { fprintf(stderr, "ZSTD_seekable_createCStream() error \n"); exit(10); }
    -    size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, chunkSize);
    +    size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, 1, chunkSize);
         if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); }
     
         size_t read, toRead = buffInSize;
    @@ -77,15 +77,16 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve
             while (input.pos < input.size) {
                 ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
                 toRead = ZSTD_seekable_compressStream(cstream, &output , &input);   /* toRead is guaranteed to be <= ZSTD_CStreamInSize() */
    -            if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); }
    +            if (ZSTD_isError(toRead)) { fprintf(stderr, "ZSTD_seekable_compressStream() error : %s \n", ZSTD_getErrorName(toRead)); exit(12); }
                 if (toRead > buffInSize) toRead = buffInSize;   /* Safely handle case when `buffInSize` is manually changed to a value < ZSTD_CStreamInSize()*/
                 fwrite_orDie(buffOut, output.pos, fout);
             }
         }
     
    -    ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
         while (1) {
    +        ZSTD_outBuffer output = { buffOut, buffOutSize, 0 };
             size_t const remainingToFlush = ZSTD_seekable_endStream(cstream, &output);   /* close stream */
    +        if (ZSTD_isError(remainingToFlush)) { fprintf(stderr, "ZSTD_seekable_endStream() error : %s \n", ZSTD_getErrorName(remainingToFlush)); exit(13); }
             fwrite_orDie(buffOut, output.pos, fout);
             if (!remainingToFlush) break;
         }
    @@ -123,4 +124,6 @@ int main(int argc, const char** argv) {
             const char* const outFileName = createOutFilename_orDie(inFileName);
             compressFile_orDie(inFileName, outFileName, 5, chunkSize);
         }
    +
    +    return 0;
     }
    diff --git a/examples/seekable_decompression.c b/examples/seekable_decompression.c
    index 97563c3de..641e0429f 100644
    --- a/examples/seekable_decompression.c
    +++ b/examples/seekable_decompression.c
    @@ -143,6 +143,7 @@ static void decompressFile_orDie(const char* fname, unsigned startOffset, unsign
                     toRead = result;
                 }
                 fwrite_orDie(buffOut, output.pos, fout);
    +            if (toRead > buffInSize) toRead = buffInSize;
             }
         } while (result > 0);
     
    @@ -171,5 +172,6 @@ int main(int argc, const char** argv)
             unsigned const endOffset = (unsigned) atoi(argv[3]);
             decompressFile_orDie(inFilename, startOffset, endOffset);
         }
    +
         return 0;
     }
    diff --git a/lib/compress/zstdseek_compress.c b/lib/compress/zstdseek_compress.c
    index 284724e58..f9e108afc 100644
    --- a/lib/compress/zstdseek_compress.c
    +++ b/lib/compress/zstdseek_compress.c
    @@ -39,6 +39,8 @@ struct ZSTD_seekable_CStream_s {
         U32 maxChunkSize;
     
         int checksumFlag;
    +
    +    int writingSeekTable;
     };
     
     ZSTD_seekable_CStream* ZSTD_seekable_createCStream()
    @@ -52,6 +54,7 @@ ZSTD_seekable_CStream* ZSTD_seekable_createCStream()
         zcs->cstream = ZSTD_createCStream();
         if (zcs->cstream == NULL) goto failed1;
     
    +    /* allocate some initial space */
         {   size_t const CHUNKLOG_STARTING_CAPACITY = 16;
             zcs->chunklog.entries =
                     malloc(sizeof(chunklogEntry_t) * CHUNKLOG_STARTING_CAPACITY);
    @@ -70,7 +73,7 @@ failed1:
     
     size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs)
     {
    -    if (zcs == NULL) return 0; /* support free on NULL */
    +    if (zcs == NULL) return 0; /* support free on null */
         ZSTD_freeCStream(zcs->cstream);
         free(zcs->chunklog.entries);
         free(zcs);
    @@ -80,12 +83,14 @@ size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs)
     
     size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs,
                                      int compressionLevel,
    +                                 int checksumFlag,
                                      U32 maxChunkSize)
     {
         zcs->chunklog.size = 0;
         zcs->chunkCSize = 0;
         zcs->chunkDSize = 0;
     
    +    /* make sure maxChunkSize has a reasonable value */
         if (maxChunkSize > ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE) {
             return ERROR(compressionParameter_unsupported);
         }
    @@ -94,11 +99,13 @@ size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs,
                                     ? maxChunkSize
                                     : ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE;
     
    -    zcs->checksumFlag = 0;
    +    zcs->checksumFlag = checksumFlag;
         if (zcs->checksumFlag) {
             XXH64_reset(&zcs->xxhState, 0);
         }
     
    +    zcs->writingSeekTable = 0;
    +
         return ZSTD_initCStream(zcs->cstream, compressionLevel);
     }
     
    @@ -114,10 +121,13 @@ static size_t ZSTD_seekable_logChunk(ZSTD_seekable_CStream* zcs)
             };
         if (zcs->checksumFlag)
             zcs->chunklog.entries[zcs->chunklog.size].checksum =
    +                /* take lower 32 bits of digest */
                     XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU;
     
         zcs->chunklog.size++;
    +    /* grow the buffer if required */
         if (zcs->chunklog.size == zcs->chunklog.capacity) {
    +        /* exponential size increase for constant amortized runtime */
             size_t const newCapacity = zcs->chunklog.capacity * 2;
             chunklogEntry_t* const newEntries = realloc(zcs->chunklog.entries,
                     sizeof(chunklogEntry_t) * newCapacity);
    @@ -134,6 +144,7 @@ static size_t ZSTD_seekable_logChunk(ZSTD_seekable_CStream* zcs)
     size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output)
     {
         size_t const prevOutPos = output->pos;
    +    /* end the frame */
         size_t ret = ZSTD_endStream(zcs->cstream, output);
     
         zcs->chunkCSize += output->pos - prevOutPos;
    @@ -165,6 +176,7 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer*
     
         inLen = MIN(inLen, (size_t)(zcs->maxChunkSize - zcs->chunkDSize));
     
    +    /* if we haven't finished flushing the last chunk, don't start writing a new one */
         if (inLen > 0) {
             ZSTD_inBuffer inTmp = { inBase, inLen, 0 };
             size_t const prevOutPos = output->pos;
    @@ -184,8 +196,12 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer*
         }
     
         if (zcs->maxChunkSize == zcs->chunkDSize) {
    +        /* log the chunk and start over */
             size_t const ret = ZSTD_seekable_endChunk(zcs, output);
             if (ZSTD_isError(ret)) return ret;
    +
    +        /* get the client ready for the next chunk */
    +        return (size_t)zcs->maxChunkSize;
         }
     
         return (size_t)(zcs->maxChunkSize - zcs->chunkDSize);
    @@ -204,62 +220,78 @@ static size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream* zcs)
     static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output)
     {
         BYTE* op = (BYTE*) output->dst;
    +    BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */
     
         /* repurpose
          * zcs->chunkDSize: the current index in the table and
    -     * zcs->chunkCSize: the amount of the table written so far */
    +     * zcs->chunkCSize: the amount of the table written so far
    +     *
    +     * This function is written this way so that if it has to return early
    +     * because of a small buffer, it can keep going where it left off.
    +     */
     
         size_t const sizePerChunk = 8 + (zcs->checksumFlag?4:0);
    -    size_t const seekTableLen = ZSD_seekable_seekTableSize(zcs);
    +    size_t const seekTableLen = ZSTD_seekable_seekTableSize(zcs);
     
    -    if (zcs->chunkCSize == 0) {
    -        if (output->size - output->pos < 4) return seekTableLen - zcs->chunkCSize;
    -        MEM_writeLE32(op + output->pos, ZSTD_MAGIC_SKIPPABLE_START);
    -        output->pos += 4;
    -        zcs->chunkCSize += 4;
    -    }
    -    if (zcs->chunkCSize == 4) {
    -        if (output->size - output->pos < 4) return seekTableLen - zcs->chunkCSize;
    -        MEM_writeLE32(op + output->pos, seekTableLen - ZSTD_skippableHeaderSize);
    -        output->pos += 4;
    -        zcs->chunkCSize += 4;
    -    }
    +#define st_write32(x, o)                                                       \
    +    do {                                                                       \
    +        if (zcs->chunkCSize < (o) + 4) {                                       \
    +            size_t const lenWrite = MIN(output->size - output->pos,            \
    +                                        (o) + 4 - zcs->chunkCSize);            \
    +            MEM_writeLE32(tmp, (x));                                           \
    +            memcpy(op + output->pos, tmp + (zcs->chunkCSize - (o)), lenWrite); \
    +            zcs->chunkCSize += lenWrite;                                       \
    +            output->pos += lenWrite;                                           \
    +            if (lenWrite < 4) return seekTableLen - zcs->chunkCSize;           \
    +        }                                                                      \
    +    } while (0)
    +
    +    st_write32(ZSTD_MAGIC_SKIPPABLE_START, 0);
    +    st_write32(seekTableLen - ZSTD_skippableHeaderSize, 4);
     
         while (zcs->chunkDSize < zcs->chunklog.size) {
    -        if (output->size - output->pos < sizePerChunk) return seekTableLen - zcs->chunkCSize;
    -        MEM_writeLE32(op + output->pos + 0, zcs->chunklog.entries[zcs->chunkDSize].cSize);
    -        MEM_writeLE32(op + output->pos + 4, zcs->chunklog.entries[zcs->chunkDSize].dSize);
    +        st_write32(zcs->chunklog.entries[zcs->chunkDSize].cSize,
    +                   ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize);
    +        st_write32(zcs->chunklog.entries[zcs->chunkDSize].dSize,
    +                   ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize + 4);
             if (zcs->checksumFlag) {
    -            MEM_writeLE32(op + output->pos + 8, zcs->chunklog.entries[zcs->chunkDSize].checksum);
    +            st_write32(zcs->chunklog.entries[zcs->chunkDSize].checksum,
    +                       ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize + 8);
             }
    -        output->pos += sizePerChunk;
    -        zcs->chunkCSize += sizePerChunk;
    +
             zcs->chunkDSize++;
         }
     
    -    if (output->size - output->pos < ZSTD_seekTableFooterSize) return seekTableLen - zcs->chunkCSize;
    -    MEM_writeLE32(op + output->pos, zcs->chunklog.size);
    -    {   BYTE sfd = 0;
    +    st_write32(zcs->chunklog.size, seekTableLen - ZSTD_seekTableFooterSize);
    +
    +    if (output->size - output->pos < 1) return seekTableLen - zcs->chunkCSize;
    +    if (zcs->chunkCSize < seekTableLen - 4) {
    +        BYTE sfd = 0;
             sfd |= (zcs->checksumFlag) << 7;
     
    -        op[output->pos + 4] = sfd;
    +        op[output->pos] = sfd;
    +        output->pos++;
    +        zcs->chunkCSize++;
         }
    -    MEM_writeLE32(op + output->pos + 5, ZSTD_SEEKABLE_MAGICNUMBER);
     
    -    output->pos += ZSTD_seekTableFooterSize;
    -    zcs->chunkCSize += ZSTD_seekTableFooterSize;
    +    st_write32(ZSTD_SEEKABLE_MAGICNUMBER, seekTableLen - 4);
     
         if (zcs->chunkCSize != seekTableLen) return ERROR(GENERIC);
         return 0;
    +
    +#undef st_write32
     }
     
     size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    if (zcs->chunkDSize) {
    +    if (!zcs->writingSeekTable && zcs->chunkDSize) {
             const size_t endChunk = ZSTD_seekable_endChunk(zcs, output);
    +        if (ZSTD_isError(endChunk)) return endChunk;
             /* return an accurate size hint */
    -        if (endChunk) return endChunk + ZSTD_seekable_seekTableLen(zcs);
    +        if (endChunk) return endChunk + ZSTD_seekable_seekTableSize(zcs);
         }
     
    +    zcs->writingSeekTable = 1;
    +
         return ZSTD_seekable_writeSeekTable(zcs, output);
     }
    diff --git a/lib/decompress/zstdseek_decompress.c b/lib/decompress/zstdseek_decompress.c
    index e76b4c612..5e303f26b 100644
    --- a/lib/decompress/zstdseek_decompress.c
    +++ b/lib/decompress/zstdseek_decompress.c
    @@ -28,6 +28,10 @@ typedef struct {
         int checksumFlag;
     } seekTable_t;
     
    +/** ZSTD_seekable_offsetToChunk() :
    + *  Performs a binary search to find the last chunk with a decompressed offset
    + *  <= pos
    + *  @return : the chunk's index */
     static U32 ZSTD_seekable_offsetToChunk(const seekTable_t* table, U64 pos)
     {
         U32 lo = 0;
    @@ -44,8 +48,9 @@ static U32 ZSTD_seekable_offsetToChunk(const seekTable_t* table, U64 pos)
         return lo;
     }
     
    +/* Stream decompressor state machine stages */
     enum ZSTD_seekable_DStream_stage {
    -    zsds_init,
    +    zsds_init = 0,
         zsds_seek,
         zsds_decompress,
         zsds_done,
    @@ -75,6 +80,7 @@ ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void)
     
         if (zds == NULL) return NULL;
     
    +    /* also initializes stage to zsds_init */
         memset(zds, 0, sizeof(*zds));
     
         zds->dstream = ZSTD_createDStream();
    @@ -88,7 +94,7 @@ ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void)
     
     size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds)
     {
    -    if (zds == NULL) return 0;
    +    if (zds == NULL) return 0; /* support free on null */
         ZSTD_freeDStream(zds->dstream);
         free(zds->seekTable.entries);
         free(zds);
    @@ -105,6 +111,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src,
     
         U32 sizePerEntry;
     
    +    /* footer is fixed size */
         if (srcSize < ZSTD_seekTableFooterSize)
             return ZSTD_seekTableFooterSize;
     
    @@ -112,15 +119,13 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src,
             return ERROR(prefix_unknown);
         }
     
    -    {
    -        BYTE const sfd = ip[-5];
    +    {   BYTE const sfd = ip[-5];
             checksumFlag = sfd >> 7;
    -
    -        numChunks = MEM_readLE32(ip-9);
    -
    -        sizePerEntry = 8 + (checksumFlag?4:0);
         }
     
    +    numChunks = MEM_readLE32(ip-9);
    +    sizePerEntry = 8 + (checksumFlag?4:0);
    +
         {   U32 const tableSize = sizePerEntry * numChunks;
             U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_skippableHeaderSize;
     
    @@ -151,6 +156,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src,
                     return ERROR(memory_allocation);
                 }
     
    +            /* compute cumulative positions */
                 for (idx = 0, pos = 0; idx < numChunks; idx++) {
                     entries[idx].cOffset = cOffset;
                     entries[idx].dOffset = dOffset;
    @@ -175,7 +181,8 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src,
     
     size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64 rangeEnd)
     {
    -    /* restrict range to the end of the file, and not before the range start */
    +    /* restrict range to the end of the file, of non-negative size */
    +    rangeStart = MIN(rangeStart, zds->seekTable.entries[zds->seekTable.tableLen].dOffset);
         rangeEnd = MIN(rangeEnd, zds->seekTable.entries[zds->seekTable.tableLen].dOffset);
         rangeEnd = MAX(rangeEnd, rangeStart);
     
    @@ -192,6 +199,8 @@ size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64
             XXH64_reset(&zds->xxhState, 0);
         }
     
    +    if (rangeStart == rangeEnd) zds->stage = zsds_done;
    +
         {   const size_t ret = ZSTD_initDStream(zds->dstream);
             if (ZSTD_isError(ret)) return ret; }
         return 0;
    @@ -222,7 +231,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
         while (1) {
             switch (zds->stage) {
             case zsds_init:
    -            return ERROR(init_missing);
    +            return ERROR(init_missing); /* ZSTD_seekable_initDStream should be called first */
             case zsds_decompress: {
                 BYTE* const outBase = (BYTE*)output->dst + output->pos;
                 size_t const outLen = output->size - output->pos;
    @@ -248,7 +257,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
                     zds->compressedOffset += input->pos - prevInputPos;
                     zds->decompressedOffset += outTmp.pos;
     
    -                if (zds->seekTable.checksumFlag) {
    +                if (jt->checksumFlag) {
                         XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos);
                     }
     
    @@ -256,7 +265,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
                         /* need more input */
                         return MIN(
                                 ZSTD_DStreamInSize(),
    -                            (size_t)(zds->seekTable.entries[zds->curChunk + 1]
    +                            (size_t)(jt->entries[zds->curChunk + 1]
                                                  .cOffset -
                                          zds->compressedOffset));
                     }
    @@ -285,11 +294,11 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
     
                     output->pos += outTmp.pos;
     
    -                if (zds->seekTable.checksumFlag) {
    +                if (jt->checksumFlag) {
                         XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos);
                         if (ret == 0) {
                             /* verify the checksum */
    -                        U32 const digest = XXH64_digest(&zds->xxhState);
    +                        U32 const digest = XXH64_digest(&zds->xxhState) & 0xFFFFFFFFU;
                             if (digest != jt->entries[zds->curChunk].checksum) {
                                 return ERROR(checksum_wrong);
                             }
    @@ -306,17 +315,21 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
     
                     if (ret == 0) {
                         /* frame is done */
    +                    /* make sure this lines up with the expected frame border */
    +                    if (zds->decompressedOffset !=
    +                                jt->entries[zds->curChunk + 1].dOffset ||
    +                        zds->compressedOffset !=
    +                                jt->entries[zds->curChunk + 1].cOffset)
    +                        return ERROR(corruption_detected);
                         ZSTD_resetDStream(zds->dstream);
                         zds->stage = zsds_seek;
                         break;
                     }
     
                     /* need more input */
    -                return MIN(
    -                        ZSTD_DStreamInSize(),
    -                        (size_t)(zds->seekTable.entries[zds->curChunk + 1]
    -                                         .cOffset -
    -                                 zds->compressedOffset));
    +                return MIN(ZSTD_DStreamInSize(), (size_t)(
    +                        jt->entries[zds->curChunk + 1].cOffset -
    +                        zds->compressedOffset));
                 }
             }
             case zsds_seek: {
    @@ -338,6 +351,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer
     
                 zds->nextSeek = jt->entries[targetChunk].cOffset;
                 zds->decompressedOffset = jt->entries[targetChunk].dOffset;
    +            /* signal to user that a seek is required */
                 return ERROR(needSeek);
             }
             case zsds_done:
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 5bbd1b742..748a98270 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -807,6 +807,8 @@ typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream;
     *  for a new compression operation.
     *  `maxChunkSize` indicates the size at which to automatically start a new
     *  seekable frame.  `maxChunkSize == 0` implies the default maximum size.
    +*  `checksumFlag` indicates whether or not the seek table should include chunk
    +*  checksums on the uncompressed data for verification.
     *  @return : a size hint for input to provide for compression, or an error code
     *            checkable with ZSTD_isError()
     *
    @@ -836,7 +838,7 @@ ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void);
     ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs);
     
     /*===== Seekable compression functions =====*/
    -ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, unsigned maxChunkSize);
    +ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize);
     ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
     ZSTDLIB_API size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
     ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    
    From 45f3bc4801ebb27dc118346a7bc761b715e478b9 Mon Sep 17 00:00:00 2001
    From: Sean Purcell 
    Date: Tue, 11 Apr 2017 13:50:05 -0700
    Subject: [PATCH 005/400] Add format specification
    
    ---
     doc/zstd_seekable_compression_format.md | 107 ++++++++++++++++++++++++
     lib/decompress/zstdseek_decompress.c    |   5 ++
     2 files changed, 112 insertions(+)
     create mode 100644 doc/zstd_seekable_compression_format.md
    
    diff --git a/doc/zstd_seekable_compression_format.md b/doc/zstd_seekable_compression_format.md
    new file mode 100644
    index 000000000..fd0593f9a
    --- /dev/null
    +++ b/doc/zstd_seekable_compression_format.md
    @@ -0,0 +1,107 @@
    +# Zstandard Seekable Format
    +
    +### Notices
    +
    +Copyright (c) 2017-present Facebook, Inc.
    +
    +Permission is granted to copy and distribute this document
    +for any purpose and without charge,
    +including translations into other languages
    +and incorporation into compilations,
    +provided that the copyright notice and this notice are preserved,
    +and that any substantive changes or deletions from the original
    +are clearly marked.
    +Distribution of this document is unlimited.
    +
    +### Version
    +0.1.0 (11/04/17)
    +
    +## Introduction
    +This document defines a format for compressed data to be stored so that subranges of the data can be efficiently decompressed without requiring the entire document to be decompressed.
    +This is done by splitting up the input data into chunks,
    +each of which are compressed independently,
    +and so can be decompressed independently.
    +Decompression then takes advantage of a provided 'seek table', which allows the decompressor to immediately jump to the desired data.  This is done in a way that is compatible with the original Zstandard format by placing the seek table in a Zstandard skippable frame.
    +
    +### Overall conventions
    +In this document:
    +- square brackets i.e. `[` and `]` are used to indicate optional fields or parameters.
    +- the naming convention for identifiers is `Mixed_Case_With_Underscores`
    +- All numeric fields are little-endian unless specified otherwise
    +
    +## Format
    +
    +The format consists of a number of chunks (Zstandard compressed frames and skippable frames), followed by a final skippable frame at the end containing the seek table.
    +
    +### Seek Table Format
    +The structure of the seek table frame is as follows:
    +
    +|`Skippable_Magic_Number`|`Frame_Size`|`[Seek_Table_Entries]`|`Seek_Table_Footer`|
    +|------------------------|------------|----------------------|-------------------|
    +| 4 bytes                | 4 bytes    | 8-12 bytes each      | 9 bytes           |
    +
    +__`Skippable_Magic_Number`__
    +
    +Value : 0x184D2A5?, which means any value from 0x184D2A50 to 0x184D2A5F.
    +All 16 values are valid to identify a skippable frame.
    +This is for compatibility with [Zstandard skippable frames].
    +
    +__`Frame_Size`__
    +
    +The total size of the skippable frame, not including the `Skippable_Magic_Number` or `Frame_Size`.  This is for compatibility with [Zstandard skippable frames].
    +
    +[Zstandard skippable frames]: https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#skippable-frames
    +
    +#### `Seek_Table_Footer`
    +The seek table footer format is as follows:
    +
    +|`Number_Of_Chunks`|`Seek_Table_Descriptor`|`Seekable_Magic_Number`|
    +|------------------|-----------------------|-----------------------|
    +| 4 bytes          | 1 byte                | 4 bytes               |
    +
    +__`Number_Of_Chunks`__
    +
    +The number of stored chunks in the data.
    +
    +__`Seek_Table_Descriptor`__
    +
    +A bitfield describing the format of the seek table.
    +
    +| Bit number | Field name                |
    +| ---------- | ----------                |
    +| 7          | `Checksum_Flag`           |
    +| 6-2        | `Reserved_Bits`           |
    +| 1-0        | `Unused_Bits`             |
    +
    +While only `Checksum_Flag` currently exists, there are 7 other bits in this field that can be used for future changes to the format,
    +for example the addition of inline dictionaries.
    +
    +__`Checksum_Flag`__
    +
    +If the checksum flag is set, each of the seek table entries contains a 4 byte checksum of the uncompressed data contained in its chunk.
    +
    +`Reserved_Bits` are not currently used but may be used in the future for breaking changes, so a compliant decoder should ensure they are set to 0.  `Unused_Bits` may be used in the future for non-breaking changes, so a compliant decoder should not interpret these bits.
    +
    +#### __`Seek_Table_Entries`__
    +
    +`Seek_Table_Entries` consists of `Number_Of_Chunks` (one for each chunk in the data, not including the seek table frame) entries of the following form, in sequence:
    +
    +|`Compressed_Size`|`Decompressed_Size`|`[Checksum]`|
    +|-----------------|-------------------|------------|
    +| 4 bytes         | 4 bytes           | 4 bytes    |
    +
    +__`Compressed_Size`__
    +
    +The compressed size of the chunk.
    +The cumulative sum of the `Compressed_Size` fields of chunks `0` to `i` gives the offset in the compressed file of chunk `i+1`.
    +
    +__`Decompressed_Size`__
    +
    +The size of the decompressed data contained in the chunk.  For skippable or otherwise empty frames, this value is 0.
    +
    +__`Checksum`__
    +
    +Only present if `Checksum_Flag` is set in the `Seek_Table_Descriptor`.  Value : the least significant 32 bits of the XXH64 digest of the uncompressed data, stored in little-endian format.
    +
    +## Version Changes
    +- 0.1.0: initial version
    diff --git a/lib/decompress/zstdseek_decompress.c b/lib/decompress/zstdseek_decompress.c
    index 5e303f26b..92901befa 100644
    --- a/lib/decompress/zstdseek_decompress.c
    +++ b/lib/decompress/zstdseek_decompress.c
    @@ -121,6 +121,11 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src,
     
         {   BYTE const sfd = ip[-5];
             checksumFlag = sfd >> 7;
    +
    +        /* check reserved bits */
    +        if ((checksumFlag >> 2) & 0x1f) {
    +            return ERROR(corruption_detected);
    +        }
         }
     
         numChunks = MEM_readLE32(ip-9);
    
    From b13da709e854f8639061da48c2d58fa1ba4ded54 Mon Sep 17 00:00:00 2001
    From: Sean Purcell 
    Date: Tue, 11 Apr 2017 13:53:43 -0700
    Subject: [PATCH 006/400] Fixes
    
    ---
     doc/README.md        |  2 ++
     doc/zstd_manual.html | 14 +++++++++++---
     examples/Makefile    |  2 +-
     3 files changed, 14 insertions(+), 4 deletions(-)
    
    diff --git a/doc/README.md b/doc/README.md
    index 47cfe3617..0aee04280 100644
    --- a/doc/README.md
    +++ b/doc/README.md
    @@ -17,4 +17,6 @@ __`zstd_manual.html`__ : Documentation on the functions found in `zstd.h`.
     See [http://zstd.net/zstd_manual.html](http://zstd.net/zstd_manual.html) for
     the manual released with the latest official `zstd` release.
     
    +__`zstd_seekable_compression_format.md`__ : This document defines the Zstandard
    +format for seekable compression.
     
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 0fa5c5d78..c7017d12c 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -500,14 +500,22 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     

    Advanced streaming functions

    
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    +size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< size of CStream is variable, depending primarily on compression level */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    -size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);  /**< re-use compression parameters from previous init; skip dictionary loading stage; zcs must be init at least once before. note: pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
    -size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
     

    +
    size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
    +

    start a new compression job, using same parameters from previous job. + This is typically useful to skip dictionary loading stage, since it will re-use it in-place.. + Note that zcs must be init at least once before using ZSTD_resetCStream(). + pledgedSrcSize==0 means "srcSize unknown". + If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end. + @return : 0, or an error code (which can be tested using ZSTD_isError()) +


    +

    Advanced Streaming decompression functions

    typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
     size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
    @@ -556,7 +564,7 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
     size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
     size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**<  note: if pledgedSrcSize can be 0, indicating unknown size.  if it is non-zero, it must be accurate.  for 0 size frames, use compressBegin_advanced */
    -size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize can be 0, indicating unknown size.  if it is non-zero, it must be accurate.  for 0 size frames, use compressBegin_advanced */
    +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize); /**< note: fail if cdict==NULL. pledgedSrcSize can be 0, indicating unknown size.  For 0 size frames, use compressBegin_advanced */
     size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     

    diff --git a/examples/Makefile b/examples/Makefile index 88cc10d24..2f649eaef 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -19,7 +19,7 @@ all: simple_compression simple_decompression \ dictionary_compression dictionary_decompression \ streaming_compression streaming_decompression \ multiple_streaming_compression \ - seekable_compression + seekable_compression seekable_decompression simple_compression : simple_compression.c $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ From d048fefef72d9664a6ca90ae62ee7a07eef3fcba Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Tue, 11 Apr 2017 14:38:56 -0700 Subject: [PATCH 007/400] Move seekable format content to /contrib --- contrib/seekable_format/examples/.gitignore | 2 + contrib/seekable_format/examples/Makefile | 35 +++++ .../examples/seekable_compression | Bin 0 -> 2557127 bytes .../examples}/seekable_compression.c | 2 + .../examples}/seekable_decompression.c | 2 + contrib/seekable_format/zstd_seekable.h | 140 ++++++++++++++++++ .../zstd_seekable_compression_format.md | 0 .../seekable_format}/zstdseek_compress.c | 3 +- .../seekable_format}/zstdseek_decompress.c | 3 +- doc/README.md | 3 - doc/zstd_manual.html | 109 -------------- examples/.gitignore | 2 - examples/Makefile | 9 +- lib/common/seekable.h | 23 --- lib/zstd.h | 119 --------------- 15 files changed, 186 insertions(+), 266 deletions(-) create mode 100644 contrib/seekable_format/examples/.gitignore create mode 100644 contrib/seekable_format/examples/Makefile create mode 100755 contrib/seekable_format/examples/seekable_compression rename {examples => contrib/seekable_format/examples}/seekable_compression.c (99%) rename {examples => contrib/seekable_format/examples}/seekable_decompression.c (99%) create mode 100644 contrib/seekable_format/zstd_seekable.h rename {doc => contrib/seekable_format}/zstd_seekable_compression_format.md (100%) rename {lib/compress => contrib/seekable_format}/zstdseek_compress.c (99%) rename {lib/decompress => contrib/seekable_format}/zstdseek_decompress.c (99%) delete mode 100644 lib/common/seekable.h diff --git a/contrib/seekable_format/examples/.gitignore b/contrib/seekable_format/examples/.gitignore new file mode 100644 index 000000000..4ded45619 --- /dev/null +++ b/contrib/seekable_format/examples/.gitignore @@ -0,0 +1,2 @@ +seekable_compression +seekable_decompression diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile new file mode 100644 index 000000000..c560eb075 --- /dev/null +++ b/contrib/seekable_format/examples/Makefile @@ -0,0 +1,35 @@ +# ################################################################ +# Copyright (c) 2017-present, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. +# ################################################################ + +# This Makefile presumes libzstd is built, using `make` in / or /lib/ + +LDFLAGS += -L../../../lib/ -lzstd +CPPFLAGS += -I../ -I../../../lib -I../../../lib/common + +CFLAGS = -O3 +CFLAGS += -g + +SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c + +.PHONY: default all clean test + +default: all + +all: seekable_compression seekable_decompression + +seekable_compression : seekable_compression.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(SEEKABLE_OBJS) $^ $(LDFLAGS) -o $@ + +seekable_decompression : seekable_decompression.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(SEEKABLE_OBJS) $^ $(LDFLAGS) -o $@ + +clean: + @rm -f core *.o tmp* result* *.zst \ + seekable_compression seekable_decompression + @echo Cleaning completed diff --git a/contrib/seekable_format/examples/seekable_compression b/contrib/seekable_format/examples/seekable_compression new file mode 100755 index 0000000000000000000000000000000000000000..88e1d2949b157168b81cc7c090cc29dd439dd425 GIT binary patch literal 2557127 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

    k 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Ýld#aKOKu0y>2SGAQ!0?lrO% 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

    l@=tsJO*@a8pg?%n}%79@9XMpyTl$r?0J4{C<< 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�--e=b^B{W(F}#O=5l?7-ErKiF2r2v=}r90*oi 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%0DYtShamWeCsL90A1 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

    ys-=iL0%5^& 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 -6`fY<9r9 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

    5ATz&4;>_ks%1iMEInv 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

  • Buffer-less streaming compression (synchronous mode)
  • Buffer-less streaming decompression (synchronous mode)
  • Block functions
  • -
  • Seekable Format
  • -
  • Seekable compression - HowTo
  • -
  • Seekable decompression - HowTo

  • Introduction

    @@ -671,111 +668,5 @@ size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, cons
     size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
     

    -

    Seekable Format

    -  The seekable format splits the compressed data into a series of "chunks",
    -  each compressed individually so that decompression of a section in the
    -  middle of an archive only requires zstd to decompress at most a chunk's
    -  worth of extra data, instead of the entire archive.
    -
    - -

    Seekable compression - HowTo

      A ZSTD_seekable_CStream object is required to tracking streaming operation.
    -  Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/
    -  release resources.
    -
    -  Streaming objects are reusable to avoid allocation and deallocation,
    -  to start a new compression operation call ZSTD_seekable_initCStream() on the
    -  compressor.
    -
    -  Data streamed to the seekable compressor will automatically be split into
    -  chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()),
    -  or if none is provided, will be cut off whenver ZSTD_endChunk() is called
    -  or when the default maximum chunk size is reached (approximately 4GB).
    -
    -  Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object
    -  for a new compression operation.
    -  `maxChunkSize` indicates the size at which to automatically start a new
    -  seekable frame.  `maxChunkSize == 0` implies the default maximum size.
    -  `checksumFlag` indicates whether or not the seek table should include chunk
    -  checksums on the uncompressed data for verification.
    -  @return : a size hint for input to provide for compression, or an error code
    -            checkable with ZSTD_isError()
    -
    -  Use ZSTD_seekable_compressStream() repetitively to consume input stream.
    -  The function will automatically update both `pos` fields.
    -  Note that it may not consume the entire input, in which case `pos < size`,
    -  and it's up to the caller to present again remaining data.
    -  @return : a size hint, preferred nb of bytes to use as input for next
    -            function call or an error code, which can be tested using
    -            ZSTD_isError().
    -            Note 1 : it's just a hint, to help latency a little, any other
    -                     value will work fine.
    -            Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize()
    -
    -  At any time, call ZSTD_seekable_endChunk() to end the current chunk and
    -  start a new one.
    -
    -  ZSTD_endStream() will end the current chunk, and then write the seek table
    -  so that decompressors can efficiently find compressed chunks.
    -  ZSTD_endStream() may return a number > 0 if it was unable to flush all the
    -  necessary data to `output`.  In this case, it should be called again until
    -  all remaining data is flushed out and 0 is returned.
    -
    - -

    Seekable compressor management

    ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void);
    -size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs);
    -

    -

    Seekable compression functions

    size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize);
    -size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
    -size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    -size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output);
    -

    -

    Seekable decompression - HowTo

      A ZSTD_seekable_DStream object is required to tracking streaming operation.
    -  Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/
    -  release resources.
    -
    -  Streaming objects are reusable to avoid allocation and deallocation,
    -  to start a new compression operation call ZSTD_seekable_initDStream() on the
    -  compressor.
    -
    -  Use ZSTD_seekable_loadSeekTable() to load the seek table from a file.
    -  `src` should point to a block of data read from the end of the file,
    -  i.e. `src + srcSize` should always be the end of the file.
    -  @return : 0 if the table was loaded successfully, or if `srcSize` was too
    -            small, a size hint for how much data to provide.
    -            An error code may also be returned, checkable with ZSTD_isError()
    -
    -  Use ZSTD_initDStream to prepare for a new decompression operation using the
    -  seektable loaded with ZSTD_seekable_loadSeekTable().
    -  Data in the range [rangeStart, rangeEnd) will be decompressed.
    -
    -  Call ZSTD_seekable_decompressStream() repetitively to consume input stream.
    -  @return : There are a number of possible return codes for this function
    -           - 0, the decompression operation has completed.
    -           - An error code checkable with ZSTD_isError
    -             + If this error code is ZSTD_error_needSeek, the user should seek
    -               to the file position provided by ZSTD_seekable_getSeekOffset()
    -               and indicate this to the stream with
    -               ZSTD_seekable_updateOffset(), before resuming decompression
    -             + Otherwise, this is a regular decompression error and the input
    -               file is likely corrupted or the API was incorrectly used.
    -           - A size hint, the preferred nb of bytes to provide as input to the
    -             next function call to improve latency.
    -
    -  ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper
    -  functions to indicate where the user should seek their file stream to, when
    -  a different position is required to continue decompression.
    -  Note that ZSTD_seekable_updateOffset will error if given an offset other
    -  than the one requested from ZSTD_seekable_getSeekOffset().
    -
    - -

    Seekable decompressor management

    ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void);
    -size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds);
    -

    -

    Seekable decompression functions

    size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize);
    -size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd);
    -size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
    -unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds);
    -size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset);
    -

    diff --git a/examples/.gitignore b/examples/.gitignore index c6b2a9f42..0711813d3 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -6,8 +6,6 @@ dictionary_decompression streaming_compression streaming_decompression multiple_streaming_compression -seekable_compression -seekable_decompression #test artefact tmp* diff --git a/examples/Makefile b/examples/Makefile index 2f649eaef..b84983f08 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -18,8 +18,7 @@ default: all all: simple_compression simple_decompression \ dictionary_compression dictionary_decompression \ streaming_compression streaming_decompression \ - multiple_streaming_compression \ - seekable_compression seekable_decompression + multiple_streaming_compression simple_compression : simple_compression.c $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ @@ -42,12 +41,6 @@ multiple_streaming_compression : multiple_streaming_compression.c streaming_decompression : streaming_decompression.c $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -seekable_compression : seekable_compression.c - $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ - -seekable_decompression : seekable_decompression.c - $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ - clean: @rm -f core *.o tmp* result* *.zst \ simple_compression simple_decompression \ diff --git a/lib/common/seekable.h b/lib/common/seekable.h deleted file mode 100644 index ab11a4388..000000000 --- a/lib/common/seekable.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef SEEKABLE_H -#define SEEKABLE_H - -#if defined (__cplusplus) -extern "C" { -#endif - -#include "zstd_internal.h" - -static const unsigned ZSTD_seekTableFooterSize = 9; - -#define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 - -#define ZSTD_SEEKABLE_MAXCHUNKS 0x8000000U - -/* 0xFE03F607 is the largest number x such that ZSTD_compressBound(x) fits in a 32-bit integer */ -#define ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE 0xFE03F607 - -#if defined (__cplusplus) -} -#endif - -#endif diff --git a/lib/zstd.h b/lib/zstd.h index 748a98270..6066db45e 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -776,125 +776,6 @@ ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCa ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */ -/*-**************************************************************************** -* Seekable Format -* -* The seekable format splits the compressed data into a series of "chunks", -* each compressed individually so that decompression of a section in the -* middle of an archive only requires zstd to decompress at most a chunk's -* worth of extra data, instead of the entire archive. -******************************************************************************/ - -typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream; -typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; - -/*-**************************************************************************** -* Seekable compression - HowTo -* A ZSTD_seekable_CStream object is required to tracking streaming operation. -* Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/ -* release resources. -* -* Streaming objects are reusable to avoid allocation and deallocation, -* to start a new compression operation call ZSTD_seekable_initCStream() on the -* compressor. -* -* Data streamed to the seekable compressor will automatically be split into -* chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()), -* or if none is provided, will be cut off whenver ZSTD_endChunk() is called -* or when the default maximum chunk size is reached (approximately 4GB). -* -* Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object -* for a new compression operation. -* `maxChunkSize` indicates the size at which to automatically start a new -* seekable frame. `maxChunkSize == 0` implies the default maximum size. -* `checksumFlag` indicates whether or not the seek table should include chunk -* checksums on the uncompressed data for verification. -* @return : a size hint for input to provide for compression, or an error code -* checkable with ZSTD_isError() -* -* Use ZSTD_seekable_compressStream() repetitively to consume input stream. -* The function will automatically update both `pos` fields. -* Note that it may not consume the entire input, in which case `pos < size`, -* and it's up to the caller to present again remaining data. -* @return : a size hint, preferred nb of bytes to use as input for next -* function call or an error code, which can be tested using -* ZSTD_isError(). -* Note 1 : it's just a hint, to help latency a little, any other -* value will work fine. -* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() -* -* At any time, call ZSTD_seekable_endChunk() to end the current chunk and -* start a new one. -* -* ZSTD_endStream() will end the current chunk, and then write the seek table -* so that decompressors can efficiently find compressed chunks. -* ZSTD_endStream() may return a number > 0 if it was unable to flush all the -* necessary data to `output`. In this case, it should be called again until -* all remaining data is flushed out and 0 is returned. -******************************************************************************/ - -/*===== Seekable compressor management =====*/ -ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void); -ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs); - -/*===== Seekable compression functions =====*/ -ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize); -ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); -ZSTDLIB_API size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); -ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); - -/*-**************************************************************************** -* Seekable decompression - HowTo -* A ZSTD_seekable_DStream object is required to tracking streaming operation. -* Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/ -* release resources. -* -* Streaming objects are reusable to avoid allocation and deallocation, -* to start a new compression operation call ZSTD_seekable_initDStream() on the -* compressor. -* -* Use ZSTD_seekable_loadSeekTable() to load the seek table from a file. -* `src` should point to a block of data read from the end of the file, -* i.e. `src + srcSize` should always be the end of the file. -* @return : 0 if the table was loaded successfully, or if `srcSize` was too -* small, a size hint for how much data to provide. -* An error code may also be returned, checkable with ZSTD_isError() -* -* Use ZSTD_initDStream to prepare for a new decompression operation using the -* seektable loaded with ZSTD_seekable_loadSeekTable(). -* Data in the range [rangeStart, rangeEnd) will be decompressed. -* -* Call ZSTD_seekable_decompressStream() repetitively to consume input stream. -* @return : There are a number of possible return codes for this function -* - 0, the decompression operation has completed. -* - An error code checkable with ZSTD_isError -* + If this error code is ZSTD_error_needSeek, the user should seek -* to the file position provided by ZSTD_seekable_getSeekOffset() -* and indicate this to the stream with -* ZSTD_seekable_updateOffset(), before resuming decompression -* + Otherwise, this is a regular decompression error and the input -* file is likely corrupted or the API was incorrectly used. -* - A size hint, the preferred nb of bytes to provide as input to the -* next function call to improve latency. -* -* ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper -* functions to indicate where the user should seek their file stream to, when -* a different position is required to continue decompression. -* Note that ZSTD_seekable_updateOffset will error if given an offset other -* than the one requested from ZSTD_seekable_getSeekOffset(). -******************************************************************************/ - -/*===== Seekable decompressor management =====*/ -ZSTDLIB_API ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void); -ZSTDLIB_API size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds); - -/*===== Seekable decompression functions =====*/ -ZSTDLIB_API size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd); -ZSTDLIB_API size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); -ZSTDLIB_API unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds); -ZSTDLIB_API size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset); - #endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */ #if defined (__cplusplus) From e80f1d74b32ae32859fb845e032983f50be88433 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Wed, 12 Apr 2017 10:57:38 -0700 Subject: [PATCH 008/400] Address PR comments and minor fixes --- contrib/seekable_format/examples/Makefile | 8 ++++---- .../examples/seekable_compression | Bin 2557127 -> 0 bytes .../zstd_seekable_compression_format.md | 15 ++++++++++++--- contrib/seekable_format/zstdseek_compress.c | 2 +- contrib/seekable_format/zstdseek_decompress.c | 4 ++-- doc/README.md | 1 + 6 files changed, 20 insertions(+), 10 deletions(-) delete mode 100755 contrib/seekable_format/examples/seekable_compression diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile index c560eb075..b57774ef3 100644 --- a/contrib/seekable_format/examples/Makefile +++ b/contrib/seekable_format/examples/Makefile @@ -23,11 +23,11 @@ default: all all: seekable_compression seekable_decompression -seekable_compression : seekable_compression.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(SEEKABLE_OBJS) $^ $(LDFLAGS) -o $@ +seekable_compression : seekable_compression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -seekable_decompression : seekable_decompression.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(SEEKABLE_OBJS) $^ $(LDFLAGS) -o $@ +seekable_decompression : seekable_decompression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ clean: @rm -f core *.o tmp* result* *.zst \ diff --git a/contrib/seekable_format/examples/seekable_compression b/contrib/seekable_format/examples/seekable_compression deleted file mode 100755 index 88e1d2949b157168b81cc7c090cc29dd439dd425..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2557127 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

    k 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Ýld#aKOKu0y>2SGAQ!0?lrO% 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

    l@=tsJO*@a8pg?%n}%79@9XMpyTl$r?0J4{C<< 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�--e=b^B{W(F}#O=5l?7-ErKiF2r2v=}r90*oi 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%0DYtShamWeCsL90A1 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

    ys-=iL0%5^& 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 -6`fY<9r9 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

    5ATz&4;>_ks%1iMEInv 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 z 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 diff --git a/contrib/seekable_format/zstd_seekable_compression_format.md b/contrib/seekable_format/zstd_seekable_compression_format.md index fd0593f9a..cc98150ce 100644 --- a/contrib/seekable_format/zstd_seekable_compression_format.md +++ b/contrib/seekable_format/zstd_seekable_compression_format.md @@ -42,13 +42,16 @@ The structure of the seek table frame is as follows: __`Skippable_Magic_Number`__ -Value : 0x184D2A5?, which means any value from 0x184D2A50 to 0x184D2A5F. -All 16 values are valid to identify a skippable frame. +Value : 0x184D2A5E. This is for compatibility with [Zstandard skippable frames]. +Since it is legal for other Zstandard skippable frames to use the same +magic number, it is not recommended for a decoder to recognize frames +solely on this. __`Frame_Size`__ -The total size of the skippable frame, not including the `Skippable_Magic_Number` or `Frame_Size`. This is for compatibility with [Zstandard skippable frames]. +The total size of the skippable frame, not including the `Skippable_Magic_Number` or `Frame_Size`. +This is for compatibility with [Zstandard skippable frames]. [Zstandard skippable frames]: https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#skippable-frames @@ -59,6 +62,12 @@ The seek table footer format is as follows: |------------------|-----------------------|-----------------------| | 4 bytes | 1 byte | 4 bytes | +__`Seekable_Magic_Number`__ + +Value : 0x8F92EAB1. +This value must be the last bytes present in the compressed file so that decoders +can efficiently find it and determine if there is an actual seek table present. + __`Number_Of_Chunks`__ The number of stored chunks in the data. diff --git a/contrib/seekable_format/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c index 2504287cd..44dd4afca 100644 --- a/contrib/seekable_format/zstdseek_compress.c +++ b/contrib/seekable_format/zstdseek_compress.c @@ -247,7 +247,7 @@ static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outB } \ } while (0) - st_write32(ZSTD_MAGIC_SKIPPABLE_START, 0); + st_write32(ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0); st_write32(seekTableLen - ZSTD_skippableHeaderSize, 4); while (zcs->chunkDSize < zcs->chunklog.size) { diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index 3cb851ea5..2b97480f5 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -39,7 +39,7 @@ static U32 ZSTD_seekable_offsetToChunk(const seekTable_t* table, U64 pos) U32 hi = table->tableLen; while (lo + 1 < hi) { - U32 mid = lo + ((hi - lo) >> 1); + U32 const mid = lo + ((hi - lo) >> 1); if (table->entries[mid].dOffset <= pos) { lo = mid; } else { @@ -139,7 +139,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, if (srcSize < frameSize) return frameSize; - if ((MEM_readLE32(base) & 0xFFFFFFF0U) != ZSTD_MAGIC_SKIPPABLE_START) { + if (MEM_readLE32(base) != (ZSTD_MAGIC_SKIPPABLE_START | 0xE)) { return ERROR(prefix_unknown); } if (MEM_readLE32(base+4) + ZSTD_skippableHeaderSize != frameSize) { diff --git a/doc/README.md b/doc/README.md index 6f761b33e..47cfe3617 100644 --- a/doc/README.md +++ b/doc/README.md @@ -17,3 +17,4 @@ __`zstd_manual.html`__ : Documentation on the functions found in `zstd.h`. See [http://zstd.net/zstd_manual.html](http://zstd.net/zstd_manual.html) for the manual released with the latest official `zstd` release. + From 5ee1135f306a94df1c65889e13b3c70d4d4e6ef7 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Wed, 12 Apr 2017 11:06:00 -0700 Subject: [PATCH 009/400] s/chunk/frame/ --- .../examples/seekable_compression.c | 10 +- contrib/seekable_format/zstd_seekable.h | 36 ++-- .../zstd_seekable_compression_format.md | 20 +-- contrib/seekable_format/zstdseek_compress.c | 160 +++++++++--------- contrib/seekable_format/zstdseek_decompress.c | 54 +++--- lib/common/error_private.c | 2 +- lib/common/zstd_errors.h | 2 +- 7 files changed, 142 insertions(+), 142 deletions(-) diff --git a/contrib/seekable_format/examples/seekable_compression.c b/contrib/seekable_format/examples/seekable_compression.c index 8d3fe8576..a33952d93 100644 --- a/contrib/seekable_format/examples/seekable_compression.c +++ b/contrib/seekable_format/examples/seekable_compression.c @@ -59,7 +59,7 @@ static size_t fclose_orDie(FILE* file) exit(6); } -static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned chunkSize) +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize) { FILE* const fin = fopen_orDie(fname, "rb"); FILE* const fout = fopen_orDie(outName, "wb"); @@ -70,7 +70,7 @@ static void compressFile_orDie(const char* fname, const char* outName, int cLeve ZSTD_seekable_CStream* const cstream = ZSTD_seekable_createCStream(); if (cstream==NULL) { fprintf(stderr, "ZSTD_seekable_createCStream() error \n"); exit(10); } - size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, 1, chunkSize); + size_t const initResult = ZSTD_seekable_initCStream(cstream, cLevel, 1, frameSize); if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initCStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } size_t read, toRead = buffInSize; @@ -116,15 +116,15 @@ int main(int argc, const char** argv) { if (argc!=3) { printf("wrong arguments\n"); printf("usage:\n"); - printf("%s FILE CHUNK_SIZE\n", exeName); + printf("%s FILE FRAME_SIZE\n", exeName); return 1; } { const char* const inFileName = argv[1]; - unsigned const chunkSize = (unsigned)atoi(argv[2]); + unsigned const frameSize = (unsigned)atoi(argv[2]); const char* const outFileName = createOutFilename_orDie(inFileName); - compressFile_orDie(inFileName, outFileName, 5, chunkSize); + compressFile_orDie(inFileName, outFileName, 5, frameSize); } return 0; diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index 959b1bd0f..f389ec973 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -9,17 +9,17 @@ static const unsigned ZSTD_seekTableFooterSize = 9; #define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 -#define ZSTD_SEEKABLE_MAXCHUNKS 0x8000000U +#define ZSTD_SEEKABLE_MAXFRAMES 0x8000000U /* 0xFE03F607 is the largest number x such that ZSTD_compressBound(x) fits in a 32-bit integer */ -#define ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE 0xFE03F607 +#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0xFE03F607 /*-**************************************************************************** * Seekable Format * -* The seekable format splits the compressed data into a series of "chunks", +* The seekable format splits the compressed data into a series of "frames", * each compressed individually so that decompression of a section in the -* middle of an archive only requires zstd to decompress at most a chunk's +* middle of an archive only requires zstd to decompress at most a frame's * worth of extra data, instead of the entire archive. ******************************************************************************/ @@ -37,15 +37,15 @@ typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; * compressor. * * Data streamed to the seekable compressor will automatically be split into -* chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()), -* or if none is provided, will be cut off whenver ZSTD_endChunk() is called -* or when the default maximum chunk size is reached (approximately 4GB). +* frames of size `maxFrameSize` (provided in ZSTD_seekable_initCStream()), +* or if none is provided, will be cut off whenver ZSTD_endFrame() is called +* or when the default maximum frame size is reached (approximately 4GB). * * Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object * for a new compression operation. -* `maxChunkSize` indicates the size at which to automatically start a new -* seekable frame. `maxChunkSize == 0` implies the default maximum size. -* `checksumFlag` indicates whether or not the seek table should include chunk +* `maxFrameSize` indicates the size at which to automatically start a new +* seekable frame. `maxFrameSize == 0` implies the default maximum size. +* `checksumFlag` indicates whether or not the seek table should include frame * checksums on the uncompressed data for verification. * @return : a size hint for input to provide for compression, or an error code * checkable with ZSTD_isError() @@ -61,14 +61,14 @@ typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; * value will work fine. * Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() * -* At any time, call ZSTD_seekable_endChunk() to end the current chunk and +* At any time, call ZSTD_seekable_endFrame() to end the current frame and * start a new one. * -* ZSTD_endStream() will end the current chunk, and then write the seek table -* so that decompressors can efficiently find compressed chunks. -* ZSTD_endStream() may return a number > 0 if it was unable to flush all the -* necessary data to `output`. In this case, it should be called again until -* all remaining data is flushed out and 0 is returned. +* ZSTD_seekable_endStream() will end the current frame, and then write the seek +* table so that decompressors can efficiently find compressed frames. +* ZSTD_seekable_endStream() may return a number > 0 if it was unable to flush +* all the necessary data to `output`. In this case, it should be called again +* until all remaining data is flushed out and 0 is returned. ******************************************************************************/ /*===== Seekable compressor management =====*/ @@ -76,9 +76,9 @@ ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void); ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs); /*===== Seekable compression functions =====*/ -ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize); +ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxFrameSize); ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); -ZSTDLIB_API size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); +ZSTDLIB_API size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); /*-**************************************************************************** diff --git a/contrib/seekable_format/zstd_seekable_compression_format.md b/contrib/seekable_format/zstd_seekable_compression_format.md index cc98150ce..bf3080f7b 100644 --- a/contrib/seekable_format/zstd_seekable_compression_format.md +++ b/contrib/seekable_format/zstd_seekable_compression_format.md @@ -18,7 +18,7 @@ Distribution of this document is unlimited. ## Introduction This document defines a format for compressed data to be stored so that subranges of the data can be efficiently decompressed without requiring the entire document to be decompressed. -This is done by splitting up the input data into chunks, +This is done by splitting up the input data into frames, each of which are compressed independently, and so can be decompressed independently. Decompression then takes advantage of a provided 'seek table', which allows the decompressor to immediately jump to the desired data. This is done in a way that is compatible with the original Zstandard format by placing the seek table in a Zstandard skippable frame. @@ -31,7 +31,7 @@ In this document: ## Format -The format consists of a number of chunks (Zstandard compressed frames and skippable frames), followed by a final skippable frame at the end containing the seek table. +The format consists of a number of frames (Zstandard compressed frames and skippable frames), followed by a final skippable frame at the end containing the seek table. ### Seek Table Format The structure of the seek table frame is as follows: @@ -58,7 +58,7 @@ This is for compatibility with [Zstandard skippable frames]. #### `Seek_Table_Footer` The seek table footer format is as follows: -|`Number_Of_Chunks`|`Seek_Table_Descriptor`|`Seekable_Magic_Number`| +|`Number_Of_Frames`|`Seek_Table_Descriptor`|`Seekable_Magic_Number`| |------------------|-----------------------|-----------------------| | 4 bytes | 1 byte | 4 bytes | @@ -68,9 +68,9 @@ Value : 0x8F92EAB1. This value must be the last bytes present in the compressed file so that decoders can efficiently find it and determine if there is an actual seek table present. -__`Number_Of_Chunks`__ +__`Number_Of_Frames`__ -The number of stored chunks in the data. +The number of stored frames in the data. __`Seek_Table_Descriptor`__ @@ -87,13 +87,13 @@ for example the addition of inline dictionaries. __`Checksum_Flag`__ -If the checksum flag is set, each of the seek table entries contains a 4 byte checksum of the uncompressed data contained in its chunk. +If the checksum flag is set, each of the seek table entries contains a 4 byte checksum of the uncompressed data contained in its frame. `Reserved_Bits` are not currently used but may be used in the future for breaking changes, so a compliant decoder should ensure they are set to 0. `Unused_Bits` may be used in the future for non-breaking changes, so a compliant decoder should not interpret these bits. #### __`Seek_Table_Entries`__ -`Seek_Table_Entries` consists of `Number_Of_Chunks` (one for each chunk in the data, not including the seek table frame) entries of the following form, in sequence: +`Seek_Table_Entries` consists of `Number_Of_Frames` (one for each frame in the data, not including the seek table frame) entries of the following form, in sequence: |`Compressed_Size`|`Decompressed_Size`|`[Checksum]`| |-----------------|-------------------|------------| @@ -101,12 +101,12 @@ If the checksum flag is set, each of the seek table entries contains a 4 byte ch __`Compressed_Size`__ -The compressed size of the chunk. -The cumulative sum of the `Compressed_Size` fields of chunks `0` to `i` gives the offset in the compressed file of chunk `i+1`. +The compressed size of the frame. +The cumulative sum of the `Compressed_Size` fields of frames `0` to `i` gives the offset in the compressed file of frame `i+1`. __`Decompressed_Size`__ -The size of the decompressed data contained in the chunk. For skippable or otherwise empty frames, this value is 0. +The size of the decompressed data contained in the frame. For skippable or otherwise empty frames, this value is 0. __`Checksum`__ diff --git a/contrib/seekable_format/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c index 44dd4afca..df4feff28 100644 --- a/contrib/seekable_format/zstdseek_compress.c +++ b/contrib/seekable_format/zstdseek_compress.c @@ -20,24 +20,24 @@ typedef struct { U32 cSize; U32 dSize; U32 checksum; -} chunklogEntry_t; +} framelogEntry_t; typedef struct { - chunklogEntry_t* entries; + framelogEntry_t* entries; U32 size; U32 capacity; -} chunklog_t; +} framelog_t; struct ZSTD_seekable_CStream_s { ZSTD_CStream* cstream; - chunklog_t chunklog; + framelog_t framelog; - U32 chunkCSize; - U32 chunkDSize; + U32 frameCSize; + U32 frameDSize; XXH64_state_t xxhState; - U32 maxChunkSize; + U32 maxFrameSize; int checksumFlag; @@ -56,11 +56,11 @@ ZSTD_seekable_CStream* ZSTD_seekable_createCStream() if (zcs->cstream == NULL) goto failed1; /* allocate some initial space */ - { size_t const CHUNKLOG_STARTING_CAPACITY = 16; - zcs->chunklog.entries = - malloc(sizeof(chunklogEntry_t) * CHUNKLOG_STARTING_CAPACITY); - if (zcs->chunklog.entries == NULL) goto failed2; - zcs->chunklog.capacity = CHUNKLOG_STARTING_CAPACITY; + { size_t const FRAMELOG_STARTING_CAPACITY = 16; + zcs->framelog.entries = + malloc(sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); + if (zcs->framelog.entries == NULL) goto failed2; + zcs->framelog.capacity = FRAMELOG_STARTING_CAPACITY; } return zcs; @@ -76,7 +76,7 @@ size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs) { if (zcs == NULL) return 0; /* support free on null */ ZSTD_freeCStream(zcs->cstream); - free(zcs->chunklog.entries); + free(zcs->framelog.entries); free(zcs); return 0; @@ -85,20 +85,20 @@ size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs) size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, - U32 maxChunkSize) + U32 maxFrameSize) { - zcs->chunklog.size = 0; - zcs->chunkCSize = 0; - zcs->chunkDSize = 0; + zcs->framelog.size = 0; + zcs->frameCSize = 0; + zcs->frameDSize = 0; - /* make sure maxChunkSize has a reasonable value */ - if (maxChunkSize > ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE) { + /* make sure maxFrameSize has a reasonable value */ + if (maxFrameSize > ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE) { return ERROR(compressionParameter_unsupported); } - zcs->maxChunkSize = maxChunkSize - ? maxChunkSize - : ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE; + zcs->maxFrameSize = maxFrameSize + ? maxFrameSize + : ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE; zcs->checksumFlag = checksumFlag; if (zcs->checksumFlag) { @@ -110,58 +110,58 @@ size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, return ZSTD_initCStream(zcs->cstream, compressionLevel); } -static size_t ZSTD_seekable_logChunk(ZSTD_seekable_CStream* zcs) +static size_t ZSTD_seekable_logFrame(ZSTD_seekable_CStream* zcs) { - if (zcs->chunklog.size == ZSTD_SEEKABLE_MAXCHUNKS) - return ERROR(chunkIndex_tooLarge); + if (zcs->framelog.size == ZSTD_SEEKABLE_MAXFRAMES) + return ERROR(frameIndex_tooLarge); - zcs->chunklog.entries[zcs->chunklog.size] = (chunklogEntry_t) + zcs->framelog.entries[zcs->framelog.size] = (framelogEntry_t) { - .cSize = zcs->chunkCSize, - .dSize = zcs->chunkDSize, + .cSize = zcs->frameCSize, + .dSize = zcs->frameDSize, }; if (zcs->checksumFlag) - zcs->chunklog.entries[zcs->chunklog.size].checksum = + zcs->framelog.entries[zcs->framelog.size].checksum = /* take lower 32 bits of digest */ XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU; - zcs->chunklog.size++; + zcs->framelog.size++; /* grow the buffer if required */ - if (zcs->chunklog.size == zcs->chunklog.capacity) { + if (zcs->framelog.size == zcs->framelog.capacity) { /* exponential size increase for constant amortized runtime */ - size_t const newCapacity = zcs->chunklog.capacity * 2; - chunklogEntry_t* const newEntries = realloc(zcs->chunklog.entries, - sizeof(chunklogEntry_t) * newCapacity); + size_t const newCapacity = zcs->framelog.capacity * 2; + framelogEntry_t* const newEntries = realloc(zcs->framelog.entries, + sizeof(framelogEntry_t) * newCapacity); if (newEntries == NULL) return ERROR(memory_allocation); - zcs->chunklog.entries = newEntries; - zcs->chunklog.capacity = newCapacity; + zcs->framelog.entries = newEntries; + zcs->framelog.capacity = newCapacity; } return 0; } -size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) { size_t const prevOutPos = output->pos; /* end the frame */ size_t ret = ZSTD_endStream(zcs->cstream, output); - zcs->chunkCSize += output->pos - prevOutPos; + zcs->frameCSize += output->pos - prevOutPos; /* need to flush before doing the rest */ if (ret) return ret; /* frame done */ - /* store the chunk data for later */ - ret = ZSTD_seekable_logChunk(zcs); + /* store the frame data for later */ + ret = ZSTD_seekable_logFrame(zcs); if (ret) return ret; - /* reset for the next chunk */ - zcs->chunkCSize = 0; - zcs->chunkDSize = 0; + /* reset for the next frame */ + zcs->frameCSize = 0; + zcs->frameDSize = 0; ZSTD_resetCStream(zcs->cstream, 0); if (zcs->checksumFlag) @@ -175,9 +175,9 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* const BYTE* const inBase = (const BYTE*) input->src + input->pos; size_t inLen = input->size - input->pos; - inLen = MIN(inLen, (size_t)(zcs->maxChunkSize - zcs->chunkDSize)); + inLen = MIN(inLen, (size_t)(zcs->maxFrameSize - zcs->frameDSize)); - /* if we haven't finished flushing the last chunk, don't start writing a new one */ + /* if we haven't finished flushing the last frame, don't start writing a new one */ if (inLen > 0) { ZSTD_inBuffer inTmp = { inBase, inLen, 0 }; size_t const prevOutPos = output->pos; @@ -188,31 +188,31 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* XXH64_update(&zcs->xxhState, inBase, inTmp.pos); } - zcs->chunkCSize += output->pos - prevOutPos; - zcs->chunkDSize += inTmp.pos; + zcs->frameCSize += output->pos - prevOutPos; + zcs->frameDSize += inTmp.pos; input->pos += inTmp.pos; if (ZSTD_isError(ret)) return ret; } - if (zcs->maxChunkSize == zcs->chunkDSize) { - /* log the chunk and start over */ - size_t const ret = ZSTD_seekable_endChunk(zcs, output); + if (zcs->maxFrameSize == zcs->frameDSize) { + /* log the frame and start over */ + size_t const ret = ZSTD_seekable_endFrame(zcs, output); if (ZSTD_isError(ret)) return ret; - /* get the client ready for the next chunk */ - return (size_t)zcs->maxChunkSize; + /* get the client ready for the next frame */ + return (size_t)zcs->maxFrameSize; } - return (size_t)(zcs->maxChunkSize - zcs->chunkDSize); + return (size_t)(zcs->maxFrameSize - zcs->frameDSize); } static size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream* zcs) { - size_t const sizePerChunk = 8 + (zcs->checksumFlag?4:0); + size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); size_t const seekTableLen = ZSTD_skippableHeaderSize + - sizePerChunk * zcs->chunklog.size + + sizePerFrame * zcs->framelog.size + ZSTD_seekTableFooterSize; return seekTableLen; @@ -224,60 +224,60 @@ static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outB BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */ /* repurpose - * zcs->chunkDSize: the current index in the table and - * zcs->chunkCSize: the amount of the table written so far + * zcs->frameDSize: the current index in the table and + * zcs->frameCSize: the amount of the table written so far * * This function is written this way so that if it has to return early * because of a small buffer, it can keep going where it left off. */ - size_t const sizePerChunk = 8 + (zcs->checksumFlag?4:0); + size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); size_t const seekTableLen = ZSTD_seekable_seekTableSize(zcs); #define st_write32(x, o) \ do { \ - if (zcs->chunkCSize < (o) + 4) { \ + if (zcs->frameCSize < (o) + 4) { \ size_t const lenWrite = MIN(output->size - output->pos, \ - (o) + 4 - zcs->chunkCSize); \ + (o) + 4 - zcs->frameCSize); \ MEM_writeLE32(tmp, (x)); \ - memcpy(op + output->pos, tmp + (zcs->chunkCSize - (o)), lenWrite); \ - zcs->chunkCSize += lenWrite; \ + memcpy(op + output->pos, tmp + (zcs->frameCSize - (o)), lenWrite); \ + zcs->frameCSize += lenWrite; \ output->pos += lenWrite; \ - if (lenWrite < 4) return seekTableLen - zcs->chunkCSize; \ + if (lenWrite < 4) return seekTableLen - zcs->frameCSize; \ } \ } while (0) st_write32(ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0); st_write32(seekTableLen - ZSTD_skippableHeaderSize, 4); - while (zcs->chunkDSize < zcs->chunklog.size) { - st_write32(zcs->chunklog.entries[zcs->chunkDSize].cSize, - ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize); - st_write32(zcs->chunklog.entries[zcs->chunkDSize].dSize, - ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize + 4); + while (zcs->frameDSize < zcs->framelog.size) { + st_write32(zcs->framelog.entries[zcs->frameDSize].cSize, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize); + st_write32(zcs->framelog.entries[zcs->frameDSize].dSize, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize + 4); if (zcs->checksumFlag) { - st_write32(zcs->chunklog.entries[zcs->chunkDSize].checksum, - ZSTD_skippableHeaderSize + sizePerChunk * zcs->chunkDSize + 8); + st_write32(zcs->framelog.entries[zcs->frameDSize].checksum, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize + 8); } - zcs->chunkDSize++; + zcs->frameDSize++; } - st_write32(zcs->chunklog.size, seekTableLen - ZSTD_seekTableFooterSize); + st_write32(zcs->framelog.size, seekTableLen - ZSTD_seekTableFooterSize); - if (output->size - output->pos < 1) return seekTableLen - zcs->chunkCSize; - if (zcs->chunkCSize < seekTableLen - 4) { + if (output->size - output->pos < 1) return seekTableLen - zcs->frameCSize; + if (zcs->frameCSize < seekTableLen - 4) { BYTE sfd = 0; sfd |= (zcs->checksumFlag) << 7; op[output->pos] = sfd; output->pos++; - zcs->chunkCSize++; + zcs->frameCSize++; } st_write32(ZSTD_SEEKABLE_MAGICNUMBER, seekTableLen - 4); - if (zcs->chunkCSize != seekTableLen) return ERROR(GENERIC); + if (zcs->frameCSize != seekTableLen) return ERROR(GENERIC); return 0; #undef st_write32 @@ -285,11 +285,11 @@ static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outB size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) { - if (!zcs->writingSeekTable && zcs->chunkDSize) { - const size_t endChunk = ZSTD_seekable_endChunk(zcs, output); - if (ZSTD_isError(endChunk)) return endChunk; + if (!zcs->writingSeekTable && zcs->frameDSize) { + const size_t endFrame = ZSTD_seekable_endFrame(zcs, output); + if (ZSTD_isError(endFrame)) return endFrame; /* return an accurate size hint */ - if (endChunk) return endChunk + ZSTD_seekable_seekTableSize(zcs); + if (endFrame) return endFrame + ZSTD_seekable_seekTableSize(zcs); } zcs->writingSeekTable = 1; diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index 2b97480f5..add62c762 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -29,11 +29,11 @@ typedef struct { int checksumFlag; } seekTable_t; -/** ZSTD_seekable_offsetToChunk() : - * Performs a binary search to find the last chunk with a decompressed offset +/** ZSTD_seekable_offsetToFrame() : + * Performs a binary search to find the last frame with a decompressed offset * <= pos - * @return : the chunk's index */ -static U32 ZSTD_seekable_offsetToChunk(const seekTable_t* table, U64 pos) + * @return : the frame's index */ +static U32 ZSTD_seekable_offsetToFrame(const seekTable_t* table, U64 pos) { U32 lo = 0; U32 hi = table->tableLen; @@ -61,7 +61,7 @@ struct ZSTD_seekable_DStream_s { ZSTD_DStream* dstream; seekTable_t seekTable; - U32 curChunk; + U32 curFrame; U64 compressedOffset; U64 decompressedOffset; @@ -107,7 +107,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, { const BYTE* ip = (const BYTE*)src + srcSize; - U32 numChunks; + U32 numFrames; int checksumFlag; U32 sizePerEntry; @@ -129,10 +129,10 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, } } - numChunks = MEM_readLE32(ip-9); + numFrames = MEM_readLE32(ip-9); sizePerEntry = 8 + (checksumFlag?4:0); - { U32 const tableSize = sizePerEntry * numChunks; + { U32 const tableSize = sizePerEntry * numFrames; U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_skippableHeaderSize; const BYTE* base = ip - frameSize; @@ -148,7 +148,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, { /* Allocate an extra entry at the end so that we can do size * computations on the last element without special case */ - seekEntry_t* entries = malloc(sizeof(seekEntry_t) * (numChunks + 1)); + seekEntry_t* entries = malloc(sizeof(seekEntry_t) * (numFrames + 1)); const BYTE* tableBase = base + ZSTD_skippableHeaderSize; U32 idx; @@ -163,7 +163,7 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, } /* compute cumulative positions */ - for (idx = 0, pos = 0; idx < numChunks; idx++) { + for (idx = 0, pos = 0; idx < numFrames; idx++) { entries[idx].cOffset = cOffset; entries[idx].dOffset = dOffset; @@ -174,11 +174,11 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, pos += 4; } } - entries[numChunks].cOffset = cOffset; - entries[numChunks].dOffset = dOffset; + entries[numFrames].cOffset = cOffset; + entries[numFrames].dOffset = dOffset; zds->seekTable.entries = entries; - zds->seekTable.tableLen = numChunks; + zds->seekTable.tableLen = numFrames; zds->seekTable.checksumFlag = checksumFlag; return 0; } @@ -197,7 +197,7 @@ size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64 zds->stage = zsds_seek; /* force a seek first */ - zds->curChunk = (U32) -1; + zds->curFrame = (U32) -1; zds->compressedOffset = (U64) -1; zds->decompressedOffset = (U64) -1; @@ -271,7 +271,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer /* need more input */ return MIN( ZSTD_DStreamInSize(), - (size_t)(jt->entries[zds->curChunk + 1] + (size_t)(jt->entries[zds->curFrame + 1] .cOffset - zds->compressedOffset)); } @@ -281,7 +281,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer { U64 const toDecompress = MIN(zds->targetEnd, - jt->entries[zds->curChunk + 1].dOffset) - + jt->entries[zds->curFrame + 1].dOffset) - zds->decompressedOffset; size_t const prevInputPos = input->pos; @@ -305,7 +305,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer if (ret == 0) { /* verify the checksum */ U32 const digest = XXH64_digest(&zds->xxhState) & 0xFFFFFFFFU; - if (digest != jt->entries[zds->curChunk].checksum) { + if (digest != jt->entries[zds->curFrame].checksum) { return ERROR(checksum_wrong); } @@ -323,9 +323,9 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer /* frame is done */ /* make sure this lines up with the expected frame border */ if (zds->decompressedOffset != - jt->entries[zds->curChunk + 1].dOffset || + jt->entries[zds->curFrame + 1].dOffset || zds->compressedOffset != - jt->entries[zds->curChunk + 1].cOffset) + jt->entries[zds->curFrame + 1].cOffset) return ERROR(corruption_detected); ZSTD_resetDStream(zds->dstream); zds->stage = zsds_seek; @@ -334,29 +334,29 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer /* need more input */ return MIN(ZSTD_DStreamInSize(), (size_t)( - jt->entries[zds->curChunk + 1].cOffset - + jt->entries[zds->curFrame + 1].cOffset - zds->compressedOffset)); } } case zsds_seek: { - U32 targetChunk; + U32 targetFrame; if (zds->decompressedOffset < zds->targetStart || zds->decompressedOffset >= zds->targetEnd) { /* haven't started yet */ - targetChunk = ZSTD_seekable_offsetToChunk(jt, zds->targetStart); + targetFrame = ZSTD_seekable_offsetToFrame(jt, zds->targetStart); } else { - targetChunk = ZSTD_seekable_offsetToChunk(jt, zds->decompressedOffset); + targetFrame = ZSTD_seekable_offsetToFrame(jt, zds->decompressedOffset); } - zds->curChunk = targetChunk; + zds->curFrame = targetFrame; - if (zds->compressedOffset == jt->entries[targetChunk].cOffset) { + if (zds->compressedOffset == jt->entries[targetFrame].cOffset) { zds->stage = zsds_decompress; break; } - zds->nextSeek = jt->entries[targetChunk].cOffset; - zds->decompressedOffset = jt->entries[targetChunk].dOffset; + zds->nextSeek = jt->entries[targetFrame].cOffset; + zds->decompressedOffset = jt->entries[targetFrame].dOffset; /* signal to user that a seek is required */ return ERROR(needSeek); } diff --git a/lib/common/error_private.c b/lib/common/error_private.c index 4084edca6..f32c6abda 100644 --- a/lib/common/error_private.c +++ b/lib/common/error_private.c @@ -38,7 +38,7 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(dictionary_corrupted): return "Dictionary is corrupted"; case PREFIX(dictionary_wrong): return "Dictionary mismatch"; case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; - case PREFIX(chunkIndex_tooLarge): return "Chunk index is too large"; + case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; case PREFIX(needSeek): return "Wrong file position, a seek is required to continue"; case PREFIX(maxCode): default: return notErrorCode; diff --git a/lib/common/zstd_errors.h b/lib/common/zstd_errors.h index 13a5608e0..d11c1ba21 100644 --- a/lib/common/zstd_errors.h +++ b/lib/common/zstd_errors.h @@ -58,7 +58,7 @@ typedef enum { ZSTD_error_dictionary_corrupted, ZSTD_error_dictionary_wrong, ZSTD_error_dictionaryCreation_failed, - ZSTD_error_chunkIndex_tooLarge, + ZSTD_error_frameIndex_tooLarge, ZSTD_error_needSeek, ZSTD_error_maxCode } ZSTD_ErrorCode; From 2785b28e05d715a99fa66beee12bf47422fb8601 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Wed, 12 Apr 2017 14:09:13 -0700 Subject: [PATCH 010/400] Reduce the limit on frame decompressed size to 2 GB --- contrib/seekable_format/zstd_seekable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index f389ec973..2e148ebf3 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -11,8 +11,8 @@ static const unsigned ZSTD_seekTableFooterSize = 9; #define ZSTD_SEEKABLE_MAXFRAMES 0x8000000U -/* 0xFE03F607 is the largest number x such that ZSTD_compressBound(x) fits in a 32-bit integer */ -#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0xFE03F607 +/* Limit the maximum size to avoid any potential issues storing the compressed size */ +#define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x80000000U /*-**************************************************************************** * Seekable Format From 9626cf1ac636edd84341ada6419302335185bf7d Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 13 Apr 2017 17:47:55 -0700 Subject: [PATCH 011/400] Address @terrelln's comments --- contrib/seekable_format/examples/Makefile | 2 +- contrib/seekable_format/zstd_seekable.h | 9 +- contrib/seekable_format/zstdseek_compress.c | 129 +++++++++++------- contrib/seekable_format/zstdseek_decompress.c | 49 ++++--- 4 files changed, 109 insertions(+), 80 deletions(-) diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile index b57774ef3..fcd1d9146 100644 --- a/contrib/seekable_format/examples/Makefile +++ b/contrib/seekable_format/examples/Makefile @@ -12,7 +12,7 @@ LDFLAGS += -L../../../lib/ -lzstd CPPFLAGS += -I../ -I../../../lib -I../../../lib/common -CFLAGS = -O3 +CFLAGS ?= -O3 CFLAGS += -g SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index 2e148ebf3..3ab4f185e 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -38,8 +38,8 @@ typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; * * Data streamed to the seekable compressor will automatically be split into * frames of size `maxFrameSize` (provided in ZSTD_seekable_initCStream()), -* or if none is provided, will be cut off whenver ZSTD_endFrame() is called -* or when the default maximum frame size is reached (approximately 4GB). +* or if none is provided, will be cut off whenever ZSTD_seekable_endFrame() is +* called or when the default maximum frame size (2GB) is reached. * * Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object * for a new compression operation. @@ -59,7 +59,6 @@ typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; * ZSTD_isError(). * Note 1 : it's just a hint, to help latency a little, any other * value will work fine. -* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() * * At any time, call ZSTD_seekable_endFrame() to end the current frame and * start a new one. @@ -98,8 +97,8 @@ ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outB * small, a size hint for how much data to provide. * An error code may also be returned, checkable with ZSTD_isError() * -* Use ZSTD_initDStream to prepare for a new decompression operation using the -* seektable loaded with ZSTD_seekable_loadSeekTable(). +* Use ZSTD_seekable_initDStream to prepare for a new decompression operation +* using the seektable loaded with ZSTD_seekable_loadSeekTable(). * Data in the range [rangeStart, rangeEnd) will be decompressed. * * Call ZSTD_seekable_decompressStream() repetitively to consume input stream. diff --git a/contrib/seekable_format/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c index df4feff28..2d1698bee 100644 --- a/contrib/seekable_format/zstdseek_compress.c +++ b/contrib/seekable_format/zstdseek_compress.c @@ -13,9 +13,22 @@ #define XXH_NAMESPACE ZSTD_ #include "xxhash.h" -#include "zstd_internal.h" /* includes zstd.h */ +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" +#include "mem.h" #include "zstd_seekable.h" +#define CHECK_Z(f) { size_t const ret = (f); if (ret != 0) return ret; } + +#undef ERROR +#define ERROR(name) ((size_t)-ZSTD_error_##name) + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + typedef struct { U32 cSize; U32 dSize; @@ -42,6 +55,8 @@ struct ZSTD_seekable_CStream_s { int checksumFlag; int writingSeekTable; + U32 seekTablePos; + U32 seekTableIndex; }; ZSTD_seekable_CStream* ZSTD_seekable_createCStream() @@ -57,8 +72,8 @@ ZSTD_seekable_CStream* ZSTD_seekable_createCStream() /* allocate some initial space */ { size_t const FRAMELOG_STARTING_CAPACITY = 16; - zcs->framelog.entries = - malloc(sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); + zcs->framelog.entries = (framelogEntry_t*)malloc( + sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); if (zcs->framelog.entries == NULL) goto failed2; zcs->framelog.capacity = FRAMELOG_STARTING_CAPACITY; } @@ -105,6 +120,8 @@ size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, XXH64_reset(&zcs->xxhState, 0); } + zcs->seekTablePos = 0; + zcs->seekTableIndex = 0; zcs->writingSeekTable = 0; return ZSTD_initCStream(zcs->cstream, compressionLevel); @@ -115,17 +132,6 @@ static size_t ZSTD_seekable_logFrame(ZSTD_seekable_CStream* zcs) if (zcs->framelog.size == ZSTD_SEEKABLE_MAXFRAMES) return ERROR(frameIndex_tooLarge); - zcs->framelog.entries[zcs->framelog.size] = (framelogEntry_t) - { - .cSize = zcs->frameCSize, - .dSize = zcs->frameDSize, - }; - if (zcs->checksumFlag) - zcs->framelog.entries[zcs->framelog.size].checksum = - /* take lower 32 bits of digest */ - XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU; - - zcs->framelog.size++; /* grow the buffer if required */ if (zcs->framelog.size == zcs->framelog.capacity) { /* exponential size increase for constant amortized runtime */ @@ -139,6 +145,15 @@ static size_t ZSTD_seekable_logFrame(ZSTD_seekable_CStream* zcs) zcs->framelog.capacity = newCapacity; } + zcs->framelog.entries[zcs->framelog.size] = (framelogEntry_t){ + zcs->frameCSize, zcs->frameDSize, + }; + if (zcs->checksumFlag) + zcs->framelog.entries[zcs->framelog.size].checksum = + XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU; /* take lower 32 bits of digest */ + + zcs->framelog.size++; + return 0; } @@ -208,7 +223,7 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* return (size_t)(zcs->maxFrameSize - zcs->frameDSize); } -static size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream* zcs) +static inline size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream const* zcs) { size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); size_t const seekTableLen = ZSTD_skippableHeaderSize + @@ -218,14 +233,29 @@ static size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream* zcs) return seekTableLen; } +static inline size_t ZSTD_stwrite32(ZSTD_seekable_CStream* zcs, + ZSTD_outBuffer* output, U32 const value, + U32 const offset) +{ + if (zcs->seekTablePos < offset + 4) { + BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */ + size_t const lenWrite = + MIN(output->size - output->pos, offset + 4 - zcs->seekTablePos); + MEM_writeLE32(tmp, value); + memcpy((BYTE*)output->dst + output->pos, + tmp + (zcs->seekTablePos - offset), lenWrite); + output->pos += lenWrite; + zcs->seekTablePos += lenWrite; + + if (lenWrite < 4) return ZSTD_seekable_seekTableSize(zcs) - zcs->seekTablePos; + } + return 0; +} + static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) { - BYTE* op = (BYTE*) output->dst; - BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */ - - /* repurpose - * zcs->frameDSize: the current index in the table and - * zcs->frameCSize: the amount of the table written so far + /* seekTableIndex: the current index in the table and + * seekTableSize: the amount of the table written so far * * This function is written this way so that if it has to return early * because of a small buffer, it can keep going where it left off. @@ -234,53 +264,48 @@ static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outB size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); size_t const seekTableLen = ZSTD_seekable_seekTableSize(zcs); -#define st_write32(x, o) \ - do { \ - if (zcs->frameCSize < (o) + 4) { \ - size_t const lenWrite = MIN(output->size - output->pos, \ - (o) + 4 - zcs->frameCSize); \ - MEM_writeLE32(tmp, (x)); \ - memcpy(op + output->pos, tmp + (zcs->frameCSize - (o)), lenWrite); \ - zcs->frameCSize += lenWrite; \ - output->pos += lenWrite; \ - if (lenWrite < 4) return seekTableLen - zcs->frameCSize; \ - } \ - } while (0) + CHECK_Z(ZSTD_stwrite32(zcs, output, ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0)); + CHECK_Z(ZSTD_stwrite32(zcs, output, seekTableLen - ZSTD_skippableHeaderSize, + 4)); - st_write32(ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0); - st_write32(seekTableLen - ZSTD_skippableHeaderSize, 4); + while (zcs->seekTableIndex < zcs->framelog.size) { + CHECK_Z(ZSTD_stwrite32( + zcs, output, zcs->framelog.entries[zcs->seekTableIndex].cSize, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex)); + + CHECK_Z(ZSTD_stwrite32( + zcs, output, zcs->framelog.entries[zcs->seekTableIndex].dSize, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex + 4)); - while (zcs->frameDSize < zcs->framelog.size) { - st_write32(zcs->framelog.entries[zcs->frameDSize].cSize, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize); - st_write32(zcs->framelog.entries[zcs->frameDSize].dSize, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize + 4); if (zcs->checksumFlag) { - st_write32(zcs->framelog.entries[zcs->frameDSize].checksum, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->frameDSize + 8); + CHECK_Z(ZSTD_stwrite32( + zcs, output, + zcs->framelog.entries[zcs->seekTableIndex].checksum, + ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex + + 8)); } - zcs->frameDSize++; + zcs->seekTableIndex++; } - st_write32(zcs->framelog.size, seekTableLen - ZSTD_seekTableFooterSize); + CHECK_Z(ZSTD_stwrite32(zcs, output, zcs->framelog.size, + seekTableLen - ZSTD_seekTableFooterSize)); - if (output->size - output->pos < 1) return seekTableLen - zcs->frameCSize; - if (zcs->frameCSize < seekTableLen - 4) { + if (output->size - output->pos < 1) return seekTableLen - zcs->seekTablePos; + if (zcs->seekTablePos < seekTableLen - 4) { BYTE sfd = 0; sfd |= (zcs->checksumFlag) << 7; - op[output->pos] = sfd; + ((BYTE*)output->dst)[output->pos] = sfd; output->pos++; - zcs->frameCSize++; + zcs->seekTablePos++; } - st_write32(ZSTD_SEEKABLE_MAGICNUMBER, seekTableLen - 4); + CHECK_Z(ZSTD_stwrite32(zcs, output, ZSTD_SEEKABLE_MAGICNUMBER, + seekTableLen - 4)); - if (zcs->frameCSize != seekTableLen) return ERROR(GENERIC); + if (zcs->seekTablePos != seekTableLen) return ERROR(GENERIC); return 0; - -#undef st_write32 } size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index add62c762..87a140c02 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -13,9 +13,20 @@ #define XXH_NAMESPACE ZSTD_ #include "xxhash.h" -#include "zstd_internal.h" /* includes zstd.h */ +#define ZSTD_STATIC_LINKING_ONLY +#include "zstd.h" +#include "zstd_errors.h" +#include "mem.h" /* includes zstd.h */ #include "zstd_seekable.h" +#undef ERROR +#define ERROR(name) ((size_t)-ZSTD_error_##name) + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + typedef struct { U64 cOffset; U64 dOffset; @@ -107,11 +118,8 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, { const BYTE* ip = (const BYTE*)src + srcSize; - U32 numFrames; int checksumFlag; - U32 sizePerEntry; - /* footer is fixed size */ if (srcSize < ZSTD_seekTableFooterSize) return ZSTD_seekTableFooterSize; @@ -129,10 +137,9 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, } } - numFrames = MEM_readLE32(ip-9); - sizePerEntry = 8 + (checksumFlag?4:0); - - { U32 const tableSize = sizePerEntry * numFrames; + { U32 const numFrames = MEM_readLE32(ip-9); + U32 const sizePerEntry = 8 + (checksumFlag?4:0); + U32 const tableSize = sizePerEntry * numFrames; U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_skippableHeaderSize; const BYTE* base = ip - frameSize; @@ -148,7 +155,8 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, { /* Allocate an extra entry at the end so that we can do size * computations on the last element without special case */ - seekEntry_t* entries = malloc(sizeof(seekEntry_t) * (numFrames + 1)); + seekEntry_t* entries = + (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1)); const BYTE* tableBase = base + ZSTD_skippableHeaderSize; U32 idx; @@ -167,8 +175,10 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, entries[idx].cOffset = cOffset; entries[idx].dOffset = dOffset; - cOffset += MEM_readLE32(tableBase + pos); pos += 4; - dOffset += MEM_readLE32(tableBase + pos); pos += 4; + cOffset += MEM_readLE32(tableBase + pos); + pos += 4; + dOffset += MEM_readLE32(tableBase + pos); + pos += 4; if (checksumFlag) { entries[idx].checksum = MEM_readLE32(tableBase + pos); pos += 4; @@ -188,18 +198,17 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64 rangeEnd) { /* restrict range to the end of the file, of non-negative size */ - rangeStart = MIN(rangeStart, zds->seekTable.entries[zds->seekTable.tableLen].dOffset); rangeEnd = MIN(rangeEnd, zds->seekTable.entries[zds->seekTable.tableLen].dOffset); - rangeEnd = MAX(rangeEnd, rangeStart); + rangeStart = MIN(rangeStart, rangeEnd); zds->targetStart = rangeStart; zds->targetEnd = rangeEnd; zds->stage = zsds_seek; /* force a seek first */ - zds->curFrame = (U32) -1; - zds->compressedOffset = (U64) -1; - zds->decompressedOffset = (U64) -1; + zds->curFrame = (U32)-1; + zds->compressedOffset = (U64)-1; + zds->decompressedOffset = (U64)-1; if (zds->seekTable.checksumFlag) { XXH64_reset(&zds->xxhState, 0); @@ -247,9 +256,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer size_t const prevInputPos = input->pos; ZSTD_outBuffer outTmp = { - .dst = outBase, - .size = (size_t)MIN((U64)outLen, toDecompress), - .pos = 0}; + outBase, (size_t)MIN((U64)outLen, toDecompress), 0}; size_t const ret = ZSTD_decompressStream(zds->dstream, &outTmp, input); @@ -286,9 +293,7 @@ size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer size_t const prevInputPos = input->pos; ZSTD_outBuffer outTmp = { - .dst = outBase, - .size = (size_t)MIN((U64)outLen, toDecompress), - .pos = 0}; + outBase, (size_t)MIN((U64)outLen, toDecompress), 0}; size_t const ret = ZSTD_decompressStream(zds->dstream, &outTmp, input); From 0f7bd772e62866077cb3d72665b600de3a7bae57 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Tue, 18 Apr 2017 16:47:28 -0700 Subject: [PATCH 012/400] Update seekable API to simplify IO --- .../examples/seekable_decompression.c | 72 +-- contrib/seekable_format/zstd_seekable.h | 109 ++-- contrib/seekable_format/zstdseek_decompress.c | 538 ++++++++++-------- lib/common/error_private.c | 2 +- lib/common/zstd_errors.h | 2 +- 5 files changed, 397 insertions(+), 326 deletions(-) diff --git a/contrib/seekable_format/examples/seekable_decompression.c b/contrib/seekable_format/examples/seekable_decompression.c index b134b87b6..d18def7cd 100644 --- a/contrib/seekable_format/examples/seekable_decompression.c +++ b/contrib/seekable_format/examples/seekable_decompression.c @@ -17,6 +17,7 @@ #include "zstd_seekable.h" +#define MIN(a, b) ((a) < (b) ? (a) : (b)) static void* malloc_orDie(size_t size) { @@ -85,74 +86,31 @@ static void fseek_orDie(FILE* file, long int offset, int origin) { static void decompressFile_orDie(const char* fname, unsigned startOffset, unsigned endOffset) { FILE* const fin = fopen_orDie(fname, "rb"); - size_t const buffInSize = ZSTD_DStreamInSize(); - void* const buffIn = malloc_orDie(buffInSize); FILE* const fout = stdout; size_t const buffOutSize = ZSTD_DStreamOutSize(); /* Guarantee to successfully flush at least one complete compressed block in all circumstances. */ void* const buffOut = malloc_orDie(buffOutSize); - ZSTD_seekable_DStream* const dstream = ZSTD_seekable_createDStream(); - if (dstream==NULL) { fprintf(stderr, "ZSTD_seekable_createDStream() error \n"); exit(10); } + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } - { size_t sizeNeeded = 0; - void* buffSeekTable = NULL; + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } - do { - sizeNeeded = ZSTD_seekable_loadSeekTable(dstream, buffSeekTable, sizeNeeded); - if (!sizeNeeded) break; + while (startOffset < endOffset) { + size_t const result = ZSTD_seekable_decompress(seekable, buffOut, MIN(endOffset - startOffset, buffOutSize), startOffset); - if (ZSTD_isError(sizeNeeded)) { - fprintf(stderr, "ZSTD_seekable_loadSeekTable() error : %s \n", - ZSTD_getErrorName(sizeNeeded)); - exit(11); - } - - fseek_orDie(fin, -(long) sizeNeeded, SEEK_END); - buffSeekTable = realloc_orDie(buffSeekTable, sizeNeeded); - fread_orDie(buffSeekTable, sizeNeeded, fin); - } while (sizeNeeded > 0); - - free(buffSeekTable); + if (ZSTD_isError(result)) { + fprintf(stderr, "ZSTD_seekable_decompress() error : %s \n", + ZSTD_getErrorName(result)); + exit(12); + } + fwrite_orDie(buffOut, result, fout); + startOffset += result; } - /* In more complex scenarios, a file may consist of multiple appended frames (ex : pzstd). - * The following example decompresses only the first frame. - * It is compatible with other provided streaming examples */ - size_t const initResult = ZSTD_seekable_initDStream(dstream, startOffset, endOffset); - if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_initDStream() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } - - size_t result, read, toRead = 0; - - do { - read = fread_orDie(buffIn, toRead, fin); - { ZSTD_inBuffer input = { buffIn, read, 0 }; - ZSTD_outBuffer output = { buffOut, buffOutSize, 0 }; - result = ZSTD_seekable_decompressStream(dstream, &output, &input); - - if (ZSTD_isError(result)) { - if (ZSTD_getErrorCode(result) == ZSTD_error_needSeek) { - unsigned long long const offset = ZSTD_seekable_getSeekOffset(dstream); - fseek_orDie(fin, offset, SEEK_SET); - ZSTD_seekable_updateOffset(dstream, offset); - toRead = 0; - } else { - fprintf(stderr, - "ZSTD_seekable_decompressStream() error : %s \n", - ZSTD_getErrorName(result)); - exit(12); - } - } else { - toRead = result; - } - fwrite_orDie(buffOut, output.pos, fout); - if (toRead > buffInSize) toRead = buffInSize; - } - } while (result > 0); - - ZSTD_seekable_freeDStream(dstream); + ZSTD_seekable_free(seekable); fclose_orDie(fin); fclose_orDie(fout); - free(buffIn); free(buffOut); } diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index 3ab4f185e..54b50fa50 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -5,6 +5,8 @@ extern "C" { #endif +#include + static const unsigned ZSTD_seekTableFooterSize = 9; #define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 @@ -14,6 +16,8 @@ static const unsigned ZSTD_seekTableFooterSize = 9; /* Limit the maximum size to avoid any potential issues storing the compressed size */ #define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x80000000U +#define ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (0ULL-2) + /*-**************************************************************************** * Seekable Format * @@ -24,7 +28,7 @@ static const unsigned ZSTD_seekTableFooterSize = 9; ******************************************************************************/ typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream; -typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; +typedef struct ZSTD_seekable_s ZSTD_seekable; /*-**************************************************************************** * Seekable compression - HowTo @@ -82,55 +86,76 @@ ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outB /*-**************************************************************************** * Seekable decompression - HowTo -* A ZSTD_seekable_DStream object is required to tracking streaming operation. -* Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/ -* release resources. +* A ZSTD_seekable object is required to tracking the seekTable. * -* Streaming objects are reusable to avoid allocation and deallocation, -* to start a new compression operation call ZSTD_seekable_initDStream() on the -* compressor. +* Call ZSTD_seekable_init* to initialize a ZSTD_seekable object with the +* the seek table provided in the input. +* There are three modes for ZSTD_seekable_init: +* - ZSTD_seekable_initBuff() : An in-memory API. The data contained in +* `src` should be the entire seekable file, including the seek table. +* `src` should be kept alive and unmodified until the ZSTD_seekable object +* is freed or reset. +* - ZSTD_seekable_initFile() : A simplified file API using stdio. fread and +* fseek will be used to access the required data for building the seek +* table and doing decompression operations. `src` should not be closed +* or modified until the ZSTD_seekable object is freed or reset. +* - ZSTD_seekable_initAdvanced() : A general API allowing the client to +* provide its own read and seek callbacks. +* + ZSTD_seekable_read() : read exactly `n` bytes into `buffer`. +* Premature EOF should be treated as an error. +* + ZSTD_seekable_seek() : seek the read head to `offset` from `origin`, +* where origin is either SEEK_SET (beginning of +* file), or SEEK_END (end of file). +* Both functions should return a non-negative value in case of success, and a +* negative value in case of failure. If implementing using this API and +* stdio, be careful with files larger than 4GB and fseek. All of these +* functions return an error code checkable with ZSTD_isError(). * -* Use ZSTD_seekable_loadSeekTable() to load the seek table from a file. -* `src` should point to a block of data read from the end of the file, -* i.e. `src + srcSize` should always be the end of the file. -* @return : 0 if the table was loaded successfully, or if `srcSize` was too -* small, a size hint for how much data to provide. -* An error code may also be returned, checkable with ZSTD_isError() +* Call ZSTD_seekable_decompress to decompress `dstSize` bytes at decompressed +* offset `offset`. ZSTD_seekable_decompress may have to decompress the entire +* prefix of the frame before the desired data if it has not already processed +* this section. If ZSTD_seekable_decompress is called multiple times for a +* consecutive range of data, it will efficiently retain the decompressor object +* and avoid redecompressing frame prefixes. The return value is the number of +* bytes decompressed, or an error code checkable with ZSTD_isError(). * -* Use ZSTD_seekable_initDStream to prepare for a new decompression operation -* using the seektable loaded with ZSTD_seekable_loadSeekTable(). -* Data in the range [rangeStart, rangeEnd) will be decompressed. -* -* Call ZSTD_seekable_decompressStream() repetitively to consume input stream. -* @return : There are a number of possible return codes for this function -* - 0, the decompression operation has completed. -* - An error code checkable with ZSTD_isError -* + If this error code is ZSTD_error_needSeek, the user should seek -* to the file position provided by ZSTD_seekable_getSeekOffset() -* and indicate this to the stream with -* ZSTD_seekable_updateOffset(), before resuming decompression -* + Otherwise, this is a regular decompression error and the input -* file is likely corrupted or the API was incorrectly used. -* - A size hint, the preferred nb of bytes to provide as input to the -* next function call to improve latency. -* -* ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper -* functions to indicate where the user should seek their file stream to, when -* a different position is required to continue decompression. -* Note that ZSTD_seekable_updateOffset will error if given an offset other -* than the one requested from ZSTD_seekable_getSeekOffset(). +* The seek table access functions can be used to obtain the data contained +* in the seek table. If frameIndex is larger than the value returned by +* ZSTD_seekable_getNumFrames(), they will return error codes checkable with +* ZSTD_isError(). Note that since the offset access functions return +* unsigned long long instead of size_t, in this case they will instead return +* the value ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE. ******************************************************************************/ /*===== Seekable decompressor management =====*/ -ZSTDLIB_API ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void); -ZSTDLIB_API size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds); +ZSTDLIB_API ZSTD_seekable* ZSTD_seekable_create(void); +ZSTDLIB_API size_t ZSTD_seekable_free(ZSTD_seekable* zs); /*===== Seekable decompression functions =====*/ -ZSTDLIB_API size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize); -ZSTDLIB_API size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd); -ZSTDLIB_API size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); -ZSTDLIB_API unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds); -ZSTDLIB_API size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset); +ZSTDLIB_API size_t ZSTD_seekable_initBuff(ZSTD_seekable* zs, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_seekable_initFile(ZSTD_seekable* zs, FILE* src); +ZSTDLIB_API size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned long long offset); +ZSTDLIB_API size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned frameIndex); + +/*===== Seek Table access functions =====*/ +ZSTDLIB_API unsigned ZSTD_seekable_getNumFrames(ZSTD_seekable* const zs); +ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameCompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex); +ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameDecompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekable_getFrameCompressedSize(ZSTD_seekable* const zs, unsigned frameIndex); +ZSTDLIB_API size_t ZSTD_seekable_getFrameDecompressedSize(ZSTD_seekable* const zs, unsigned frameIndex); + +ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrame(ZSTD_seekable* const zs, unsigned long long offset); + +/*===== Seekable advanced I/O API =====*/ +typedef int(ZSTD_seekable_read)(void* opaque, void* buffer, size_t n); +typedef int(ZSTD_seekable_seek)(void* opaque, long long offset, int origin); +typedef struct { + void* opaque; + ZSTD_seekable_read* read; + ZSTD_seekable_seek* seek; +} ZSTD_seekable_customFile; + +ZSTDLIB_API size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile src); #if defined (__cplusplus) } diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index 87a140c02..9bcfea91b 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -7,7 +7,54 @@ * of patent rights can be found in the PATENTS file in the same directory. */ +/* ********************************************************* +* Turn on Large Files support (>4GB) for 32-bit Linux/Unix +***********************************************************/ +#if !defined(__64BIT__) || defined(__MINGW32__) /* No point defining Large file for 64 bit but MinGW-w64 requires it */ +# if !defined(_FILE_OFFSET_BITS) +# define _FILE_OFFSET_BITS 64 /* turn off_t into a 64-bit type for ftello, fseeko */ +# endif +# if !defined(_LARGEFILE_SOURCE) /* obsolete macro, replaced with _FILE_OFFSET_BITS */ +# define _LARGEFILE_SOURCE 1 /* Large File Support extension (LFS) - fseeko, ftello */ +# endif +# if defined(_AIX) || defined(__hpux) +# define _LARGE_FILES /* Large file support on 32-bits AIX and HP-UX */ +# endif +#endif + +/* ************************************************************ +* Avoid fseek()'s 2GiB barrier with MSVC, MacOS, *BSD, MinGW +***************************************************************/ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +# define LONG_SEEK _fseeki64 +#elif !defined(__64BIT__) && (PLATFORM_POSIX_VERSION >= 200112L) /* No point defining Large file for 64 bit */ +# define LONG_SEEK fseeko +#elif defined(__MINGW32__) && !defined(__STRICT_ANSI__) && !defined(__NO_MINGW_LFS) && defined(__MSVCRT__) +# define LONG_SEEK fseeko64 +#elif defined(_WIN32) && !defined(__DJGPP__) +# include + static int LONG_SEEK(FILE* file, __int64 offset, int origin) { + LARGE_INTEGER off; + DWORD method; + off.QuadPart = offset; + if (origin == SEEK_END) + method = FILE_END; + else if (origin == SEEK_CUR) + method = FILE_CURRENT; + else + method = FILE_BEGIN; + + if (SetFilePointerEx((HANDLE) _get_osfhandle(_fileno(file)), off, NULL, method)) + return 0; + else + return -1; + } +#else +# define LONG_SEEK fseek +#endif + #include /* malloc, free */ +#include /* FILE* */ #define XXH_STATIC_LINKING_ONLY #define XXH_NAMESPACE ZSTD_ @@ -16,17 +63,74 @@ #define ZSTD_STATIC_LINKING_ONLY #include "zstd.h" #include "zstd_errors.h" -#include "mem.h" /* includes zstd.h */ +#include "mem.h" #include "zstd_seekable.h" #undef ERROR #define ERROR(name) ((size_t)-ZSTD_error_##name) +#define CHECK_IO(f) { int const errcod = (f); if (errcod < 0) return ERROR(seekableIO); } + #undef MIN #undef MAX #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +/* Special-case callbacks for FILE* and in-memory modes, so that we can treat + * them the same way as the advanced API */ +static int ZSTD_seekable_read_FILE(void* opaque, void* buffer, size_t n) +{ + size_t const result = fread(buffer, 1, n, (FILE*)opaque); + if (result != n) { + return -1; + } + return 0; +} + +static int ZSTD_seekable_seek_FILE(void* opaque, S64 offset, int origin) +{ + int const ret = LONG_SEEK((FILE*)opaque, offset, origin); + if (ret) return ret; + return fflush((FILE*)opaque); +} + +typedef struct { + const void *ptr; + size_t size; + size_t pos; +} buffWrapper_t; + +static int ZSTD_seekable_read_buff(void* opaque, void* buffer, size_t n) +{ + buffWrapper_t* buff = (buffWrapper_t*) opaque; + if (buff->size + n > buff->pos) return -1; + memcpy(buffer, (const BYTE*)buff->ptr + buff->pos, n); + buff->pos += n; + return 0; +} + +static int ZSTD_seekable_seek_buff(void* opaque, S64 offset, int origin) +{ + buffWrapper_t* buff = (buffWrapper_t*) opaque; + unsigned long long newOffset; + switch (origin) { + case SEEK_SET: + newOffset = offset; + break; + case SEEK_CUR: + newOffset = (unsigned long long)buff->pos + offset; + break; + case SEEK_END: + newOffset = (unsigned long long)buff->size - offset; + break; + } + if (newOffset < 0 || newOffset > buff->size) { + return -1; + } + buff->pos = newOffset; + return 0; +} + typedef struct { U64 cOffset; U64 dOffset; @@ -40,18 +144,70 @@ typedef struct { int checksumFlag; } seekTable_t; +#define SEEKABLE_BUFF_SIZE ZSTD_BLOCKSIZE_ABSOLUTEMAX + +struct ZSTD_seekable_s { + ZSTD_DStream* dstream; + seekTable_t seekTable; + ZSTD_seekable_customFile src; + + U64 decompressedOffset; + U32 curFrame; + + BYTE inBuff[SEEKABLE_BUFF_SIZE]; /* need to do our own input buffering */ + BYTE outBuff[SEEKABLE_BUFF_SIZE]; /* so we can efficiently decompress the + starts of chunks before we get to the + desired section */ + ZSTD_inBuffer in; /* maintain continuity across ZSTD_seekable_decompress operations */ + buffWrapper_t buffWrapper; /* for `src.opaque` in in-memory mode */ + + XXH64_state_t xxhState; +}; + +ZSTD_seekable* ZSTD_seekable_create(void) +{ + ZSTD_seekable* zs = malloc(sizeof(ZSTD_seekable)); + + if (zs == NULL) return NULL; + + /* also initializes stage to zsds_init */ + memset(zs, 0, sizeof(*zs)); + + zs->dstream = ZSTD_createDStream(); + if (zs->dstream == NULL) { + free(zs); + return NULL; + } + + return zs; +} + +size_t ZSTD_seekable_free(ZSTD_seekable* zs) +{ + if (zs == NULL) return 0; /* support free on null */ + ZSTD_freeDStream(zs->dstream); + free(zs->seekTable.entries); + free(zs); + + return 0; +} + /** ZSTD_seekable_offsetToFrame() : * Performs a binary search to find the last frame with a decompressed offset * <= pos * @return : the frame's index */ -static U32 ZSTD_seekable_offsetToFrame(const seekTable_t* table, U64 pos) +U32 ZSTD_seekable_offsetToFrame(ZSTD_seekable* const zs, U64 pos) { U32 lo = 0; - U32 hi = table->tableLen; + U32 hi = zs->seekTable.tableLen; + + if (pos >= zs->seekTable.entries[zs->seekTable.tableLen].dOffset) { + return zs->seekTable.tableLen; + } while (lo + 1 < hi) { U32 const mid = lo + ((hi - lo) >> 1); - if (table->entries[mid].dOffset <= pos) { + if (zs->seekTable.entries[mid].dOffset <= pos) { lo = mid; } else { hi = mid; @@ -60,75 +216,50 @@ static U32 ZSTD_seekable_offsetToFrame(const seekTable_t* table, U64 pos) return lo; } -/* Stream decompressor state machine stages */ -enum ZSTD_seekable_DStream_stage { - zsds_init = 0, - zsds_seek, - zsds_decompress, - zsds_done, -}; - -struct ZSTD_seekable_DStream_s { - ZSTD_DStream* dstream; - seekTable_t seekTable; - - U32 curFrame; - U64 compressedOffset; - U64 decompressedOffset; - - U64 targetStart; - U64 targetEnd; - - U64 nextSeek; - - enum ZSTD_seekable_DStream_stage stage; - - XXH64_state_t xxhState; -}; - -ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void) +U32 ZSTD_seekable_getNumFrames(ZSTD_seekable* const zs) { - ZSTD_seekable_DStream* zds = malloc(sizeof(ZSTD_seekable_DStream)); - - if (zds == NULL) return NULL; - - /* also initializes stage to zsds_init */ - memset(zds, 0, sizeof(*zds)); - - zds->dstream = ZSTD_createDStream(); - if (zds->dstream == NULL) { - free(zds); - return NULL; - } - - return zds; + return zs->seekTable.tableLen; } -size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds) +U64 ZSTD_seekable_getFrameCompressedOffset(ZSTD_seekable* const zs, U32 frameIndex) { - if (zds == NULL) return 0; /* support free on null */ - ZSTD_freeDStream(zds->dstream); - free(zds->seekTable.entries); - free(zds); - - return 0; + if (frameIndex >= zs->seekTable.tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE; + return zs->seekTable.entries[frameIndex].cOffset; } -size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize) +U64 ZSTD_seekable_getFrameDecompressedOffset(ZSTD_seekable* const zs, U32 frameIndex) { - const BYTE* ip = (const BYTE*)src + srcSize; + if (frameIndex >= zs->seekTable.tableLen) return ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE; + return zs->seekTable.entries[frameIndex].dOffset; +} +size_t ZSTD_seekable_getFrameCompressedSize(ZSTD_seekable* const zs, U32 frameIndex) +{ + if (frameIndex >= zs->seekTable.tableLen) return ERROR(frameIndex_tooLarge); + return zs->seekTable.entries[frameIndex + 1].cOffset - + zs->seekTable.entries[frameIndex].cOffset; +} + +size_t ZSTD_seekable_getFrameDecompressedSize(ZSTD_seekable* const zs, U32 frameIndex) +{ + if (frameIndex > zs->seekTable.tableLen) return ERROR(frameIndex_tooLarge); + return zs->seekTable.entries[frameIndex + 1].dOffset - + zs->seekTable.entries[frameIndex].dOffset; +} + +static size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable* zs) +{ int checksumFlag; + ZSTD_seekable_customFile src = zs->src; + /* read the footer, fixed size */ + CHECK_IO(src.seek(src.opaque, -(int)ZSTD_seekTableFooterSize, SEEK_END)); + CHECK_IO(src.read(src.opaque, zs->inBuff, ZSTD_seekTableFooterSize)); - /* footer is fixed size */ - if (srcSize < ZSTD_seekTableFooterSize) - return ZSTD_seekTableFooterSize; - - if (MEM_readLE32(ip - 4) != ZSTD_SEEKABLE_MAGICNUMBER) { + if (MEM_readLE32(zs->inBuff + 5) != ZSTD_SEEKABLE_MAGICNUMBER) { return ERROR(prefix_unknown); } - { BYTE const sfd = ip[-5]; + { BYTE const sfd = zs->inBuff[4]; checksumFlag = sfd >> 7; /* check reserved bits */ @@ -137,30 +268,36 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, } } - { U32 const numFrames = MEM_readLE32(ip-9); + { U32 const numFrames = MEM_readLE32(zs->inBuff); U32 const sizePerEntry = 8 + (checksumFlag?4:0); U32 const tableSize = sizePerEntry * numFrames; U32 const frameSize = tableSize + ZSTD_seekTableFooterSize + ZSTD_skippableHeaderSize; - const BYTE* base = ip - frameSize; + U32 remaining = frameSize - ZSTD_seekTableFooterSize; /* don't need to re-read footer */ + { + U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE); - if (srcSize < frameSize) return frameSize; + CHECK_IO(src.seek(src.opaque, -(S64)frameSize, SEEK_END)); + CHECK_IO(src.read(src.opaque, zs->inBuff, toRead)); - if (MEM_readLE32(base) != (ZSTD_MAGIC_SKIPPABLE_START | 0xE)) { + remaining -= toRead; + } + + if (MEM_readLE32(zs->inBuff) != (ZSTD_MAGIC_SKIPPABLE_START | 0xE)) { return ERROR(prefix_unknown); } - if (MEM_readLE32(base+4) + ZSTD_skippableHeaderSize != frameSize) { + if (MEM_readLE32(zs->inBuff+4) + ZSTD_skippableHeaderSize != frameSize) { return ERROR(prefix_unknown); } { /* Allocate an extra entry at the end so that we can do size * computations on the last element without special case */ - seekEntry_t* entries = - (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1)); - const BYTE* tableBase = base + ZSTD_skippableHeaderSize; + seekEntry_t* entries = (seekEntry_t*)malloc(sizeof(seekEntry_t) * (numFrames + 1)); + const BYTE* tableBase = zs->inBuff + ZSTD_skippableHeaderSize; + + U32 idx = 0; + U32 pos = 8; - U32 idx; - size_t pos; U64 cOffset = 0; U64 dOffset = 0; @@ -171,202 +308,153 @@ size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, } /* compute cumulative positions */ - for (idx = 0, pos = 0; idx < numFrames; idx++) { + for (; idx < numFrames; idx++) { + if (pos + sizePerEntry > SEEKABLE_BUFF_SIZE) { + U32 const toRead = MIN(remaining, SEEKABLE_BUFF_SIZE); + U32 const offset = SEEKABLE_BUFF_SIZE - pos; + memmove(zs->inBuff, zs->inBuff + pos, offset); /* move any data we haven't read yet */ + CHECK_IO(src.read(src.opaque, zs->inBuff+offset, toRead)); + remaining -= toRead; + pos = 0; + } entries[idx].cOffset = cOffset; entries[idx].dOffset = dOffset; - cOffset += MEM_readLE32(tableBase + pos); + cOffset += MEM_readLE32(zs->inBuff + pos); pos += 4; - dOffset += MEM_readLE32(tableBase + pos); + dOffset += MEM_readLE32(zs->inBuff + pos); pos += 4; if (checksumFlag) { - entries[idx].checksum = MEM_readLE32(tableBase + pos); + entries[idx].checksum = MEM_readLE32(zs->inBuff + pos); pos += 4; } } entries[numFrames].cOffset = cOffset; entries[numFrames].dOffset = dOffset; - zds->seekTable.entries = entries; - zds->seekTable.tableLen = numFrames; - zds->seekTable.checksumFlag = checksumFlag; + zs->seekTable.entries = entries; + zs->seekTable.tableLen = numFrames; + zs->seekTable.checksumFlag = checksumFlag; return 0; } } } -size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, U64 rangeStart, U64 rangeEnd) +size_t ZSTD_seekable_initBuff(ZSTD_seekable* zs, const void* src, size_t srcSize) { - /* restrict range to the end of the file, of non-negative size */ - rangeEnd = MIN(rangeEnd, zds->seekTable.entries[zds->seekTable.tableLen].dOffset); - rangeStart = MIN(rangeStart, rangeEnd); + zs->buffWrapper = (buffWrapper_t){src, srcSize, 0}; + { ZSTD_seekable_customFile srcFile = {&zs->buffWrapper, + &ZSTD_seekable_read_buff, + &ZSTD_seekable_seek_buff}; + return ZSTD_seekable_initAdvanced(zs, srcFile); } +} - zds->targetStart = rangeStart; - zds->targetEnd = rangeEnd; - zds->stage = zsds_seek; +size_t ZSTD_seekable_initFile(ZSTD_seekable* zs, FILE* src) +{ + ZSTD_seekable_customFile srcFile = {src, &ZSTD_seekable_read_FILE, + &ZSTD_seekable_seek_FILE}; + return ZSTD_seekable_initAdvanced(zs, srcFile); +} - /* force a seek first */ - zds->curFrame = (U32)-1; - zds->compressedOffset = (U64)-1; - zds->decompressedOffset = (U64)-1; +size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile src) +{ + zs->src = src; - if (zds->seekTable.checksumFlag) { - XXH64_reset(&zds->xxhState, 0); - } + { const size_t seekTableInit = ZSTD_seekable_loadSeekTable(zs); + if (ZSTD_isError(seekTableInit)) return seekTableInit; } - if (rangeStart == rangeEnd) zds->stage = zsds_done; + zs->decompressedOffset = (U64)-1; + zs->curFrame = (U32)-1; - { const size_t ret = ZSTD_initDStream(zds->dstream); - if (ZSTD_isError(ret)) return ret; } + { const size_t dstreamInit = ZSTD_initDStream(zs->dstream); + if (ZSTD_isError(dstreamInit)) return dstreamInit; } return 0; } -U64 ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds) +size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, U64 offset) { - return zds->nextSeek; -} + U32 targetFrame = ZSTD_seekable_offsetToFrame(zs, offset); + do { + /* check if we can continue from a previous decompress job */ + if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) { + zs->decompressedOffset = zs->seekTable.entries[targetFrame].dOffset; + zs->curFrame = targetFrame; -size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, U64 offset) -{ - if (zds->stage != zsds_seek) { - return ERROR(stage_wrong); - } - if (offset != zds->nextSeek) { - return ERROR(needSeek); - } + CHECK_IO(zs->src.seek(zs->src.opaque, + zs->seekTable.entries[targetFrame].cOffset, + SEEK_SET)); + zs->in = (ZSTD_inBuffer){zs->inBuff, 0, 0}; + XXH64_reset(&zs->xxhState, 0); + ZSTD_resetDStream(zs->dstream); + } - zds->stage = zsds_decompress; - zds->compressedOffset = offset; - return 0; -} + while (zs->decompressedOffset < offset + len) { + size_t toRead; + ZSTD_outBuffer outTmp; + size_t prevOutPos; + if (zs->decompressedOffset < offset) { + /* dummy decompressions until we get to the target offset */ + outTmp = (ZSTD_outBuffer){zs->outBuff, MIN(SEEKABLE_BUFF_SIZE, offset - zs->decompressedOffset), 0}; + } else { + outTmp = (ZSTD_outBuffer){dst, len, zs->decompressedOffset - offset}; + } -size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input) -{ - const seekTable_t* const jt = &zds->seekTable; - while (1) { - switch (zds->stage) { - case zsds_init: - return ERROR(init_missing); /* ZSTD_seekable_initDStream should be called first */ - case zsds_decompress: { - BYTE* const outBase = (BYTE*)output->dst + output->pos; - size_t const outLen = output->size - output->pos; - while (zds->decompressedOffset < zds->targetStart) { - U64 const toDecompress = - zds->targetStart - zds->decompressedOffset; - size_t const prevInputPos = input->pos; + prevOutPos = outTmp.pos; + toRead = ZSTD_decompressStream(zs->dstream, &outTmp, &zs->in); + if (ZSTD_isError(toRead)) { + return toRead; + } - ZSTD_outBuffer outTmp = { - outBase, (size_t)MIN((U64)outLen, toDecompress), 0}; + if (zs->seekTable.checksumFlag) { + XXH64_update(&zs->xxhState, outTmp.dst, outTmp.pos); + } + zs->decompressedOffset += outTmp.pos - prevOutPos; - size_t const ret = - ZSTD_decompressStream(zds->dstream, &outTmp, input); + if (toRead == 0) { + /* frame complete */ - if (ZSTD_isError(ret)) return ret; - if (ret == 0) { - /* should not happen at this stage */ + /* verify checksum */ + if (zs->seekTable.checksumFlag && + (XXH64_digest(&zs->xxhState) & 0xFFFFFFFFU) != + zs->seekTable.entries[targetFrame].checksum) { return ERROR(corruption_detected); } - zds->compressedOffset += input->pos - prevInputPos; - zds->decompressedOffset += outTmp.pos; - - if (jt->checksumFlag) { - XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos); + if (zs->decompressedOffset < offset + len) { + /* go back to the start and force a reset of the stream */ + targetFrame = ZSTD_seekable_offsetToFrame(zs, zs->decompressedOffset); } - - if (input->pos == input->size) { - /* need more input */ - return MIN( - ZSTD_DStreamInSize(), - (size_t)(jt->entries[zds->curFrame + 1] - .cOffset - - zds->compressedOffset)); - } - } - - /* do actual decompression */ - { - U64 const toDecompress = - MIN(zds->targetEnd, - jt->entries[zds->curFrame + 1].dOffset) - - zds->decompressedOffset; - size_t const prevInputPos = input->pos; - - ZSTD_outBuffer outTmp = { - outBase, (size_t)MIN((U64)outLen, toDecompress), 0}; - - size_t const ret = - ZSTD_decompressStream(zds->dstream, &outTmp, input); - - if (ZSTD_isError(ret)) return ret; - - zds->compressedOffset += input->pos - prevInputPos; - zds->decompressedOffset += outTmp.pos; - - output->pos += outTmp.pos; - - if (jt->checksumFlag) { - XXH64_update(&zds->xxhState, outTmp.dst, outTmp.pos); - if (ret == 0) { - /* verify the checksum */ - U32 const digest = XXH64_digest(&zds->xxhState) & 0xFFFFFFFFU; - if (digest != jt->entries[zds->curFrame].checksum) { - return ERROR(checksum_wrong); - } - - XXH64_reset(&zds->xxhState, 0); - } - } - - if (zds->decompressedOffset == zds->targetEnd) { - /* done */ - zds->stage = zsds_done; - return 0; - } - - if (ret == 0) { - /* frame is done */ - /* make sure this lines up with the expected frame border */ - if (zds->decompressedOffset != - jt->entries[zds->curFrame + 1].dOffset || - zds->compressedOffset != - jt->entries[zds->curFrame + 1].cOffset) - return ERROR(corruption_detected); - ZSTD_resetDStream(zds->dstream); - zds->stage = zsds_seek; - break; - } - - /* need more input */ - return MIN(ZSTD_DStreamInSize(), (size_t)( - jt->entries[zds->curFrame + 1].cOffset - - zds->compressedOffset)); - } - } - case zsds_seek: { - U32 targetFrame; - if (zds->decompressedOffset < zds->targetStart || - zds->decompressedOffset >= zds->targetEnd) { - /* haven't started yet */ - targetFrame = ZSTD_seekable_offsetToFrame(jt, zds->targetStart); - } else { - targetFrame = ZSTD_seekable_offsetToFrame(jt, zds->decompressedOffset); - } - - zds->curFrame = targetFrame; - - if (zds->compressedOffset == jt->entries[targetFrame].cOffset) { - zds->stage = zsds_decompress; break; } - zds->nextSeek = jt->entries[targetFrame].cOffset; - zds->decompressedOffset = jt->entries[targetFrame].dOffset; - /* signal to user that a seek is required */ - return ERROR(needSeek); + /* read in more data if we're done with this buffer */ + if (zs->in.pos == zs->in.size) { + toRead = MIN(toRead, SEEKABLE_BUFF_SIZE); + CHECK_IO(zs->src.read(zs->src.opaque, zs->inBuff, toRead)); + zs->in.size = toRead; + zs->in.pos = 0; + } } - case zsds_done: - return 0; + } while (zs->decompressedOffset != offset + len); + + return len; +} + +size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, U32 frameIndex) +{ + if (frameIndex >= zs->seekTable.tableLen) { + return ERROR(frameIndex_tooLarge); + } + + { + size_t const decompressedSize = + zs->seekTable.entries[frameIndex + 1].dOffset - + zs->seekTable.entries[frameIndex].dOffset; + if (dstSize < decompressedSize) { + return ERROR(dstSize_tooSmall); } + return ZSTD_seekable_decompress( + zs, dst, zs->seekTable.entries[frameIndex].dOffset, + decompressedSize); } } diff --git a/lib/common/error_private.c b/lib/common/error_private.c index f32c6abda..c94ea181c 100644 --- a/lib/common/error_private.c +++ b/lib/common/error_private.c @@ -39,7 +39,7 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(dictionary_wrong): return "Dictionary mismatch"; case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples"; case PREFIX(frameIndex_tooLarge): return "Frame index is too large"; - case PREFIX(needSeek): return "Wrong file position, a seek is required to continue"; + case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking"; case PREFIX(maxCode): default: return notErrorCode; } diff --git a/lib/common/zstd_errors.h b/lib/common/zstd_errors.h index d11c1ba21..de0fc8984 100644 --- a/lib/common/zstd_errors.h +++ b/lib/common/zstd_errors.h @@ -59,7 +59,7 @@ typedef enum { ZSTD_error_dictionary_wrong, ZSTD_error_dictionaryCreation_failed, ZSTD_error_frameIndex_tooLarge, - ZSTD_error_needSeek, + ZSTD_error_seekableIO, ZSTD_error_maxCode } ZSTD_ErrorCode; From 35186e65b04eb9844b63e15d1f5d1ed58bb497e6 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 20 Apr 2017 16:48:54 -0700 Subject: [PATCH 013/400] Address comments and make sure all prototypes are rendered by gen_html --- contrib/seekable_format/zstd_seekable.h | 7 ++----- contrib/seekable_format/zstdseek_decompress.c | 8 ++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index 54b50fa50..71b4c0be7 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -16,8 +16,6 @@ static const unsigned ZSTD_seekTableFooterSize = 9; /* Limit the maximum size to avoid any potential issues storing the compressed size */ #define ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE 0x80000000U -#define ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (0ULL-2) - /*-**************************************************************************** * Seekable Format * @@ -137,14 +135,14 @@ ZSTDLIB_API size_t ZSTD_seekable_initFile(ZSTD_seekable* zs, FILE* src); ZSTDLIB_API size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned long long offset); ZSTDLIB_API size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSize, unsigned frameIndex); +#define ZSTD_SEEKABLE_FRAMEINDEX_TOOLARGE (0ULL-2) /*===== Seek Table access functions =====*/ ZSTDLIB_API unsigned ZSTD_seekable_getNumFrames(ZSTD_seekable* const zs); ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameCompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex); ZSTDLIB_API unsigned long long ZSTD_seekable_getFrameDecompressedOffset(ZSTD_seekable* const zs, unsigned frameIndex); ZSTDLIB_API size_t ZSTD_seekable_getFrameCompressedSize(ZSTD_seekable* const zs, unsigned frameIndex); ZSTDLIB_API size_t ZSTD_seekable_getFrameDecompressedSize(ZSTD_seekable* const zs, unsigned frameIndex); - -ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrame(ZSTD_seekable* const zs, unsigned long long offset); +ZSTDLIB_API unsigned ZSTD_seekable_offsetToFrameIndex(ZSTD_seekable* const zs, unsigned long long offset); /*===== Seekable advanced I/O API =====*/ typedef int(ZSTD_seekable_read)(void* opaque, void* buffer, size_t n); @@ -154,7 +152,6 @@ typedef struct { ZSTD_seekable_read* read; ZSTD_seekable_seek* seek; } ZSTD_seekable_customFile; - ZSTDLIB_API size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile src); #if defined (__cplusplus) diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index 9bcfea91b..a9e87577b 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -192,11 +192,11 @@ size_t ZSTD_seekable_free(ZSTD_seekable* zs) return 0; } -/** ZSTD_seekable_offsetToFrame() : +/** ZSTD_seekable_offsetToFrameIndex() : * Performs a binary search to find the last frame with a decompressed offset * <= pos * @return : the frame's index */ -U32 ZSTD_seekable_offsetToFrame(ZSTD_seekable* const zs, U64 pos) +U32 ZSTD_seekable_offsetToFrameIndex(ZSTD_seekable* const zs, U64 pos) { U32 lo = 0; U32 hi = zs->seekTable.tableLen; @@ -373,7 +373,7 @@ size_t ZSTD_seekable_initAdvanced(ZSTD_seekable* zs, ZSTD_seekable_customFile sr size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, U64 offset) { - U32 targetFrame = ZSTD_seekable_offsetToFrame(zs, offset); + U32 targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, offset); do { /* check if we can continue from a previous decompress job */ if (targetFrame != zs->curFrame || offset != zs->decompressedOffset) { @@ -422,7 +422,7 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, U64 of if (zs->decompressedOffset < offset + len) { /* go back to the start and force a reset of the stream */ - targetFrame = ZSTD_seekable_offsetToFrame(zs, zs->decompressedOffset); + targetFrame = ZSTD_seekable_offsetToFrameIndex(zs, zs->decompressedOffset); } break; } From 11dc940e726012c8341679eeba44b6a876a49466 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Fri, 21 Apr 2017 12:23:06 -0700 Subject: [PATCH 014/400] Add parallel processing example for seekable API --- contrib/seekable_format/examples/.gitignore | 1 + contrib/seekable_format/examples/Makefile | 7 +- .../examples/parallel_processing.c | 195 ++++++++++++++++++ .../examples/seekable_decompression.c | 2 +- contrib/seekable_format/zstdseek_decompress.c | 7 +- 5 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 contrib/seekable_format/examples/parallel_processing.c diff --git a/contrib/seekable_format/examples/.gitignore b/contrib/seekable_format/examples/.gitignore index 4ded45619..1e1661d80 100644 --- a/contrib/seekable_format/examples/.gitignore +++ b/contrib/seekable_format/examples/.gitignore @@ -1,2 +1,3 @@ seekable_compression seekable_decompression +parallel_processing diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile index fcd1d9146..a77143889 100644 --- a/contrib/seekable_format/examples/Makefile +++ b/contrib/seekable_format/examples/Makefile @@ -21,7 +21,7 @@ SEEKABLE_OBJS = ../zstdseek_compress.c ../zstdseek_decompress.c default: all -all: seekable_compression seekable_decompression +all: seekable_compression seekable_decompression parallel_processing seekable_compression : seekable_compression.c $(SEEKABLE_OBJS) $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ @@ -29,7 +29,10 @@ seekable_compression : seekable_compression.c $(SEEKABLE_OBJS) seekable_decompression : seekable_decompression.c $(SEEKABLE_OBJS) $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ +parallel_processing : parallel_processing.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -pthread + clean: @rm -f core *.o tmp* result* *.zst \ - seekable_compression seekable_decompression + seekable_compression seekable_decompression parallel_processing @echo Cleaning completed diff --git a/contrib/seekable_format/examples/parallel_processing.c b/contrib/seekable_format/examples/parallel_processing.c new file mode 100644 index 000000000..cf2d0d2af --- /dev/null +++ b/contrib/seekable_format/examples/parallel_processing.c @@ -0,0 +1,195 @@ +/** + * Copyright 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + +/* + * A simple demo that sums up all the bytes in the file in parallel using + * seekable decompression and the zstd thread pool + */ + +#include // malloc, exit +#include // fprintf, perror, feof +#include // strerror +#include // errno +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include +#if defined(WIN32) || defined(_WIN32) +# include +# define SLEEP(x) Sleep(x) +#else +# include +# define SLEEP(x) usleep(x * 1000) +#endif + +#include "pool.h" // use zstd thread pool for demo + +#include "zstd_seekable.h" + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc"); + exit(1); +} + +static void* realloc_orDie(void* ptr, size_t size) +{ + ptr = realloc(ptr, size); + if (ptr) return ptr; + /* error */ + perror("realloc"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) { + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + +static const char* filename; + +struct sum_job { + const char* fname; + unsigned long long sum; + unsigned frameNb; + int done; +}; + +static void sumFrame(void* opaque) +{ + struct sum_job* job = (struct sum_job*)opaque; + job->done = 0; + + FILE* const fin = fopen_orDie(job->fname, "rb"); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t const frameSize = ZSTD_seekable_getFrameDecompressedSize(seekable, job->frameNb); + unsigned char* data = malloc_orDie(frameSize); + + size_t result = ZSTD_seekable_decompressFrame(seekable, data, frameSize, job->frameNb); + if (ZSTD_isError(result)) { fprintf(stderr, "ZSTD_seekable_decompressFrame() error : %s \n", ZSTD_getErrorName(result)); exit(12); } + + unsigned long long sum = 0; + size_t i; + for (i = 0; i < frameSize; i++) { + sum += data[i]; + } + job->sum = sum; + job->done = 1; + + fclose(fin); + ZSTD_seekable_free(seekable); + free(data); +} + +static void sumFile_orDie(const char* fname, int nbThreads) +{ + POOL_ctx* pool = POOL_create(nbThreads, nbThreads); + if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); } + + FILE* const fin = fopen_orDie(fname, "rb"); + + ZSTD_seekable* const seekable = ZSTD_seekable_create(); + if (seekable==NULL) { fprintf(stderr, "ZSTD_seekable_create() error \n"); exit(10); } + + size_t const initResult = ZSTD_seekable_initFile(seekable, fin); + if (ZSTD_isError(initResult)) { fprintf(stderr, "ZSTD_seekable_init() error : %s \n", ZSTD_getErrorName(initResult)); exit(11); } + + size_t const numFrames = ZSTD_seekable_getNumFrames(seekable); + struct sum_job* jobs = (struct sum_job*)malloc(numFrames * sizeof(struct sum_job)); + + size_t i; + for (i = 0; i < numFrames; i++) { + jobs[i] = (struct sum_job){ fname, 0, i, 0 }; + POOL_add(pool, sumFrame, &jobs[i]); + } + + unsigned long long total = 0; + + for (i = 0; i < numFrames; i++) { + while (!jobs[i].done) SLEEP(5); /* wake up every 5 milliseconds to check */ + total += jobs[i].sum; + } + + printf("Sum: %llu\n", total); + + POOL_free(pool); + ZSTD_seekable_free(seekable); + fclose(fin); + free(jobs); +} + + +int main(int argc, const char** argv) +{ + const char* const exeName = argv[0]; + + if (argc!=3) { + fprintf(stderr, "wrong arguments\n"); + fprintf(stderr, "usage:\n"); + fprintf(stderr, "%s FILE NB_THREADS\n", exeName); + return 1; + } + + { + const char* const inFilename = argv[1]; + int const nbThreads = atoi(argv[2]); + sumFile_orDie(inFilename, nbThreads); + } + + return 0; +} diff --git a/contrib/seekable_format/examples/seekable_decompression.c b/contrib/seekable_format/examples/seekable_decompression.c index d18def7cd..b765a7591 100644 --- a/contrib/seekable_format/examples/seekable_decompression.c +++ b/contrib/seekable_format/examples/seekable_decompression.c @@ -122,7 +122,7 @@ int main(int argc, const char** argv) if (argc!=4) { fprintf(stderr, "wrong arguments\n"); fprintf(stderr, "usage:\n"); - fprintf(stderr, "%s FILE\n", exeName); + fprintf(stderr, "%s FILE START END\n", exeName); return 1; } diff --git a/contrib/seekable_format/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c index a9e87577b..4a8b4e568 100644 --- a/contrib/seekable_format/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -406,7 +406,8 @@ size_t ZSTD_seekable_decompress(ZSTD_seekable* zs, void* dst, size_t len, U64 of } if (zs->seekTable.checksumFlag) { - XXH64_update(&zs->xxhState, outTmp.dst, outTmp.pos); + XXH64_update(&zs->xxhState, (BYTE*)outTmp.dst + prevOutPos, + outTmp.pos - prevOutPos); } zs->decompressedOffset += outTmp.pos - prevOutPos; @@ -454,7 +455,7 @@ size_t ZSTD_seekable_decompressFrame(ZSTD_seekable* zs, void* dst, size_t dstSiz return ERROR(dstSize_tooSmall); } return ZSTD_seekable_decompress( - zs, dst, zs->seekTable.entries[frameIndex].dOffset, - decompressedSize); + zs, dst, decompressedSize, + zs->seekTable.entries[frameIndex].dOffset); } } From 470993c9b11dff9fcf1f457b297edbbeef00565f Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Fri, 28 Apr 2017 12:17:09 -0700 Subject: [PATCH 015/400] Add raw seek table construction API and parallel compression example --- contrib/seekable_format/examples/.gitignore | 1 + contrib/seekable_format/examples/Makefile | 8 +- .../examples/parallel_compression.c | 214 ++++++++++++++++++ .../examples/parallel_processing.c | 2 - contrib/seekable_format/zstd_seekable.h | 23 ++ contrib/seekable_format/zstdseek_compress.c | 185 +++++++++------ 6 files changed, 358 insertions(+), 75 deletions(-) create mode 100644 contrib/seekable_format/examples/parallel_compression.c diff --git a/contrib/seekable_format/examples/.gitignore b/contrib/seekable_format/examples/.gitignore index 1e1661d80..df2f9ab07 100644 --- a/contrib/seekable_format/examples/.gitignore +++ b/contrib/seekable_format/examples/.gitignore @@ -1,3 +1,4 @@ seekable_compression seekable_decompression parallel_processing +parallel_compression diff --git a/contrib/seekable_format/examples/Makefile b/contrib/seekable_format/examples/Makefile index a77143889..625e1fcc8 100644 --- a/contrib/seekable_format/examples/Makefile +++ b/contrib/seekable_format/examples/Makefile @@ -9,7 +9,7 @@ # This Makefile presumes libzstd is built, using `make` in / or /lib/ -LDFLAGS += -L../../../lib/ -lzstd +LDFLAGS += ../../../lib/libzstd.a CPPFLAGS += -I../ -I../../../lib -I../../../lib/common CFLAGS ?= -O3 @@ -32,7 +32,11 @@ seekable_decompression : seekable_decompression.c $(SEEKABLE_OBJS) parallel_processing : parallel_processing.c $(SEEKABLE_OBJS) $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -pthread +parallel_compression : parallel_compression.c $(SEEKABLE_OBJS) + $(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@ -pthread + clean: @rm -f core *.o tmp* result* *.zst \ - seekable_compression seekable_decompression parallel_processing + seekable_compression seekable_decompression \ + parallel_processing parallel_compression @echo Cleaning completed diff --git a/contrib/seekable_format/examples/parallel_compression.c b/contrib/seekable_format/examples/parallel_compression.c new file mode 100644 index 000000000..89a13185f --- /dev/null +++ b/contrib/seekable_format/examples/parallel_compression.c @@ -0,0 +1,214 @@ +/** + * Copyright 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the license found in the + * LICENSE-examples file in the root directory of this source tree. + */ + +#include // malloc, free, exit, atoi +#include // fprintf, perror, feof, fopen, etc. +#include // strlen, memset, strcat +#define ZSTD_STATIC_LINKING_ONLY +#include // presumes zstd library is installed +#include +#if defined(WIN32) || defined(_WIN32) +# include +# define SLEEP(x) Sleep(x) +#else +# include +# define SLEEP(x) usleep(x * 1000) +#endif + +#define XXH_NAMESPACE ZSTD_ +#include "xxhash.h" + +#include "pool.h" // use zstd thread pool for demo + +#include "zstd_seekable.h" + +static void* malloc_orDie(size_t size) +{ + void* const buff = malloc(size); + if (buff) return buff; + /* error */ + perror("malloc:"); + exit(1); +} + +static FILE* fopen_orDie(const char *filename, const char *instruction) +{ + FILE* const inFile = fopen(filename, instruction); + if (inFile) return inFile; + /* error */ + perror(filename); + exit(3); +} + +static size_t fread_orDie(void* buffer, size_t sizeToRead, FILE* file) +{ + size_t const readSize = fread(buffer, 1, sizeToRead, file); + if (readSize == sizeToRead) return readSize; /* good */ + if (feof(file)) return readSize; /* good, reached end of file */ + /* error */ + perror("fread"); + exit(4); +} + +static size_t fwrite_orDie(const void* buffer, size_t sizeToWrite, FILE* file) +{ + size_t const writtenSize = fwrite(buffer, 1, sizeToWrite, file); + if (writtenSize == sizeToWrite) return sizeToWrite; /* good */ + /* error */ + perror("fwrite"); + exit(5); +} + +static size_t fclose_orDie(FILE* file) +{ + if (!fclose(file)) return 0; + /* error */ + perror("fclose"); + exit(6); +} + +static void fseek_orDie(FILE* file, long int offset, int origin) +{ + if (!fseek(file, offset, origin)) { + if (!fflush(file)) return; + } + /* error */ + perror("fseek"); + exit(7); +} + +static long int ftell_orDie(FILE* file) +{ + long int off = ftell(file); + if (off != -1) return off; + /* error */ + perror("ftell"); + exit(8); +} + +struct job { + const void* src; + size_t srcSize; + void* dst; + size_t dstSize; + + unsigned checksum; + + int compressionLevel; + int done; +}; + +static void compressFrame(void* opaque) +{ + struct job* job = opaque; + + job->checksum = XXH64(job->src, job->srcSize, 0); + + size_t ret = ZSTD_compress(job->dst, job->dstSize, job->src, job->srcSize, job->compressionLevel); + if (ZSTD_isError(ret)) { + fprintf(stderr, "ZSTD_compress() error : %s \n", ZSTD_getErrorName(ret)); + exit(20); + } + + job->dstSize = ret; + job->done = 1; +} + +static void compressFile_orDie(const char* fname, const char* outName, int cLevel, unsigned frameSize, int nbThreads) +{ + POOL_ctx* pool = POOL_create(nbThreads, nbThreads); + if (pool == NULL) { fprintf(stderr, "POOL_create() error \n"); exit(9); } + + FILE* const fin = fopen_orDie(fname, "rb"); + FILE* const fout = fopen_orDie(outName, "wb"); + + if (ZSTD_compressBound(frameSize) > 0xFFFFFFFFU) { fprintf(stderr, "Frame size too large \n"); exit(10); } + unsigned dstSize = ZSTD_compressBound(frameSize); + + + fseek_orDie(fin, 0, SEEK_END); + long int length = ftell_orDie(fin); + fseek_orDie(fin, 0, SEEK_SET); + + size_t numFrames = (length + frameSize - 1) / frameSize; + + struct job* jobs = malloc_orDie(sizeof(struct job) * numFrames); + + size_t i; + for(i = 0; i < numFrames; i++) { + void* in = malloc_orDie(frameSize); + void* out = malloc_orDie(dstSize); + + size_t inSize = fread_orDie(in, frameSize, fin); + + jobs[i].src = in; + jobs[i].srcSize = inSize; + jobs[i].dst = out; + jobs[i].dstSize = dstSize; + jobs[i].compressionLevel = cLevel; + jobs[i].done = 0; + POOL_add(pool, compressFrame, &jobs[i]); + } + + ZSTD_frameLog* fl = ZSTD_seekable_createFrameLog(1); + if (fl == NULL) { fprintf(stderr, "ZSTD_seekable_createFrameLog() failed \n"); exit(11); } + for (i = 0; i < numFrames; i++) { + while (!jobs[i].done) SLEEP(5); /* wake up every 5 milliseconds to check */ + fwrite_orDie(jobs[i].dst, jobs[i].dstSize, fout); + free((void*)jobs[i].src); + free(jobs[i].dst); + + size_t ret = ZSTD_seekable_logFrame(fl, jobs[i].dstSize, jobs[i].srcSize, jobs[i].checksum); + if (ZSTD_isError(ret)) { fprintf(stderr, "ZSTD_seekable_logFrame() error : %s \n", ZSTD_getErrorName(ret)); } + } + + { unsigned char seekTableBuff[1024]; + ZSTD_outBuffer out = {seekTableBuff, 1024, 0}; + while (ZSTD_seekable_writeSeekTable(fl, &out) != 0) { + fwrite_orDie(seekTableBuff, out.pos, fout); + out.pos = 0; + } + fwrite_orDie(seekTableBuff, out.pos, fout); + } + + ZSTD_seekable_freeFrameLog(fl); + free(jobs); + fclose_orDie(fout); + fclose_orDie(fin); +} + +static const char* createOutFilename_orDie(const char* filename) +{ + size_t const inL = strlen(filename); + size_t const outL = inL + 5; + void* outSpace = malloc_orDie(outL); + memset(outSpace, 0, outL); + strcat(outSpace, filename); + strcat(outSpace, ".zst"); + return (const char*)outSpace; +} + +int main(int argc, const char** argv) { + const char* const exeName = argv[0]; + if (argc!=4) { + printf("wrong arguments\n"); + printf("usage:\n"); + printf("%s FILE FRAME_SIZE NB_THREADS\n", exeName); + return 1; + } + + { const char* const inFileName = argv[1]; + unsigned const frameSize = (unsigned)atoi(argv[2]); + int const nbThreads = atoi(argv[3]); + + const char* const outFileName = createOutFilename_orDie(inFileName); + compressFile_orDie(inFileName, outFileName, 5, frameSize, nbThreads); + } + + return 0; +} diff --git a/contrib/seekable_format/examples/parallel_processing.c b/contrib/seekable_format/examples/parallel_processing.c index cf2d0d2af..cea4d5364 100644 --- a/contrib/seekable_format/examples/parallel_processing.c +++ b/contrib/seekable_format/examples/parallel_processing.c @@ -95,8 +95,6 @@ static void fseek_orDie(FILE* file, long int offset, int origin) { exit(7); } -static const char* filename; - struct sum_job { const char* fname; unsigned long long sum; diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h index 71b4c0be7..438ac2014 100644 --- a/contrib/seekable_format/zstd_seekable.h +++ b/contrib/seekable_format/zstd_seekable.h @@ -82,6 +82,29 @@ ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD ZSTDLIB_API size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); +/*= Raw seek table API + * These functions allow for the seek table to be constructed directly. + * This table can then be appended to a file of concatenated frames. + * This allows the frames to be compressed independently, even in parallel, + * and compiled together afterward into a seekable archive. + * + * Use ZSTD_seekable_createFrameLog() to allocate and initialize a tracking + * structure. + * + * Call ZSTD_seekable_logFrame() once for each frame in the archive. + * checksum is optional, and will not be used if checksumFlag was 0 when the + * frame log was created. If present, it should be the least significant 32 + * bits of the XXH64 hash of the uncompressed data. + * + * Call ZSTD_seekable_writeSeekTable to serialize the data into a seek table. + * If the entire table was written, the return value will be 0. Otherwise, + * it will be equal to the number of bytes left to write. */ +typedef struct ZSTD_frameLog_s ZSTD_frameLog; +ZSTDLIB_API ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag); +ZSTDLIB_API size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl); +ZSTDLIB_API size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl, unsigned compressedSize, unsigned decompressedSize, unsigned checksum); +ZSTDLIB_API size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output); + /*-**************************************************************************** * Seekable decompression - HowTo * A ZSTD_seekable object is required to tracking the seekTable. diff --git a/contrib/seekable_format/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c index 2d1698bee..5fe26ed28 100644 --- a/contrib/seekable_format/zstdseek_compress.c +++ b/contrib/seekable_format/zstdseek_compress.c @@ -35,15 +35,21 @@ typedef struct { U32 checksum; } framelogEntry_t; -typedef struct { +struct ZSTD_frameLog_s { framelogEntry_t* entries; U32 size; U32 capacity; + + int checksumFlag; + + /* for use when streaming out the seek table */ + U32 seekTablePos; + U32 seekTableIndex; } framelog_t; struct ZSTD_seekable_CStream_s { ZSTD_CStream* cstream; - framelog_t framelog; + ZSTD_frameLog framelog; U32 frameCSize; U32 frameDSize; @@ -52,13 +58,52 @@ struct ZSTD_seekable_CStream_s { U32 maxFrameSize; - int checksumFlag; - int writingSeekTable; - U32 seekTablePos; - U32 seekTableIndex; }; +size_t ZSTD_seekable_frameLog_allocVec(ZSTD_frameLog* fl) +{ + /* allocate some initial space */ + size_t const FRAMELOG_STARTING_CAPACITY = 16; + fl->entries = (framelogEntry_t*)malloc( + sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); + if (fl->entries == NULL) return ERROR(memory_allocation); + fl->capacity = FRAMELOG_STARTING_CAPACITY; + + return 0; +} + +size_t ZSTD_seekable_frameLog_freeVec(ZSTD_frameLog* fl) +{ + if (fl != NULL) free(fl->entries); + return 0; +} + +ZSTD_frameLog* ZSTD_seekable_createFrameLog(int checksumFlag) +{ + ZSTD_frameLog* fl = malloc(sizeof(ZSTD_frameLog)); + if (fl == NULL) return NULL; + + if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(fl))) { + free(fl); + return NULL; + } + + fl->checksumFlag = checksumFlag; + fl->seekTablePos = 0; + fl->seekTableIndex = 0; + fl->size = 0; + + return fl; +} + +size_t ZSTD_seekable_freeFrameLog(ZSTD_frameLog* fl) +{ + ZSTD_seekable_frameLog_freeVec(fl); + free(fl); + return 0; +} + ZSTD_seekable_CStream* ZSTD_seekable_createCStream() { ZSTD_seekable_CStream* zcs = malloc(sizeof(ZSTD_seekable_CStream)); @@ -70,13 +115,7 @@ ZSTD_seekable_CStream* ZSTD_seekable_createCStream() zcs->cstream = ZSTD_createCStream(); if (zcs->cstream == NULL) goto failed1; - /* allocate some initial space */ - { size_t const FRAMELOG_STARTING_CAPACITY = 16; - zcs->framelog.entries = (framelogEntry_t*)malloc( - sizeof(framelogEntry_t) * FRAMELOG_STARTING_CAPACITY); - if (zcs->framelog.entries == NULL) goto failed2; - zcs->framelog.capacity = FRAMELOG_STARTING_CAPACITY; - } + if (ZSTD_isError(ZSTD_seekable_frameLog_allocVec(&zcs->framelog))) goto failed2; return zcs; @@ -91,7 +130,7 @@ size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs) { if (zcs == NULL) return 0; /* support free on null */ ZSTD_freeCStream(zcs->cstream); - free(zcs->framelog.entries); + ZSTD_seekable_frameLog_freeVec(&zcs->framelog); free(zcs); return 0; @@ -115,44 +154,43 @@ size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, ? maxFrameSize : ZSTD_SEEKABLE_MAX_FRAME_DECOMPRESSED_SIZE; - zcs->checksumFlag = checksumFlag; - if (zcs->checksumFlag) { + zcs->framelog.checksumFlag = checksumFlag; + if (zcs->framelog.checksumFlag) { XXH64_reset(&zcs->xxhState, 0); } - zcs->seekTablePos = 0; - zcs->seekTableIndex = 0; + zcs->framelog.seekTablePos = 0; + zcs->framelog.seekTableIndex = 0; zcs->writingSeekTable = 0; return ZSTD_initCStream(zcs->cstream, compressionLevel); } -static size_t ZSTD_seekable_logFrame(ZSTD_seekable_CStream* zcs) +size_t ZSTD_seekable_logFrame(ZSTD_frameLog* fl, + unsigned compressedSize, + unsigned decompressedSize, + unsigned checksum) { - if (zcs->framelog.size == ZSTD_SEEKABLE_MAXFRAMES) + if (fl->size == ZSTD_SEEKABLE_MAXFRAMES) return ERROR(frameIndex_tooLarge); /* grow the buffer if required */ - if (zcs->framelog.size == zcs->framelog.capacity) { + if (fl->size == fl->capacity) { /* exponential size increase for constant amortized runtime */ - size_t const newCapacity = zcs->framelog.capacity * 2; - framelogEntry_t* const newEntries = realloc(zcs->framelog.entries, + size_t const newCapacity = fl->capacity * 2; + framelogEntry_t* const newEntries = realloc(fl->entries, sizeof(framelogEntry_t) * newCapacity); if (newEntries == NULL) return ERROR(memory_allocation); - zcs->framelog.entries = newEntries; - zcs->framelog.capacity = newCapacity; + fl->entries = newEntries; + fl->capacity = newCapacity; } - zcs->framelog.entries[zcs->framelog.size] = (framelogEntry_t){ - zcs->frameCSize, zcs->frameDSize, + fl->entries[fl->size] = (framelogEntry_t){ + compressedSize, decompressedSize, checksum }; - if (zcs->checksumFlag) - zcs->framelog.entries[zcs->framelog.size].checksum = - XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU; /* take lower 32 bits of digest */ - - zcs->framelog.size++; + fl->size++; return 0; } @@ -171,7 +209,11 @@ size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output /* frame done */ /* store the frame data for later */ - ret = ZSTD_seekable_logFrame(zcs); + ret = ZSTD_seekable_logFrame( + &zcs->framelog, zcs->frameCSize, zcs->frameDSize, + zcs->framelog.checksumFlag + ? XXH64_digest(&zcs->xxhState) & 0xFFFFFFFFU + : 0); if (ret) return ret; /* reset for the next frame */ @@ -179,7 +221,7 @@ size_t ZSTD_seekable_endFrame(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output zcs->frameDSize = 0; ZSTD_resetCStream(zcs->cstream, 0); - if (zcs->checksumFlag) + if (zcs->framelog.checksumFlag) XXH64_reset(&zcs->xxhState, 0); return 0; @@ -199,7 +241,7 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* size_t const ret = ZSTD_compressStream(zcs->cstream, output, &inTmp); - if (zcs->checksumFlag) { + if (zcs->framelog.checksumFlag) { XXH64_update(&zcs->xxhState, inBase, inTmp.pos); } @@ -223,36 +265,36 @@ size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* return (size_t)(zcs->maxFrameSize - zcs->frameDSize); } -static inline size_t ZSTD_seekable_seekTableSize(ZSTD_seekable_CStream const* zcs) +static inline size_t ZSTD_seekable_seekTableSize(const ZSTD_frameLog* fl) { - size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); + size_t const sizePerFrame = 8 + (fl->checksumFlag?4:0); size_t const seekTableLen = ZSTD_skippableHeaderSize + - sizePerFrame * zcs->framelog.size + + sizePerFrame * fl->size + ZSTD_seekTableFooterSize; return seekTableLen; } -static inline size_t ZSTD_stwrite32(ZSTD_seekable_CStream* zcs, +static inline size_t ZSTD_stwrite32(ZSTD_frameLog* fl, ZSTD_outBuffer* output, U32 const value, U32 const offset) { - if (zcs->seekTablePos < offset + 4) { + if (fl->seekTablePos < offset + 4) { BYTE tmp[4]; /* so that we can work with buffers too small to write a whole word to */ size_t const lenWrite = - MIN(output->size - output->pos, offset + 4 - zcs->seekTablePos); + MIN(output->size - output->pos, offset + 4 - fl->seekTablePos); MEM_writeLE32(tmp, value); memcpy((BYTE*)output->dst + output->pos, - tmp + (zcs->seekTablePos - offset), lenWrite); + tmp + (fl->seekTablePos - offset), lenWrite); output->pos += lenWrite; - zcs->seekTablePos += lenWrite; + fl->seekTablePos += lenWrite; - if (lenWrite < 4) return ZSTD_seekable_seekTableSize(zcs) - zcs->seekTablePos; + if (lenWrite < 4) return ZSTD_seekable_seekTableSize(fl) - fl->seekTablePos; } return 0; } -static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output) +size_t ZSTD_seekable_writeSeekTable(ZSTD_frameLog* fl, ZSTD_outBuffer* output) { /* seekTableIndex: the current index in the table and * seekTableSize: the amount of the table written so far @@ -261,50 +303,51 @@ static size_t ZSTD_seekable_writeSeekTable(ZSTD_seekable_CStream* zcs, ZSTD_outB * because of a small buffer, it can keep going where it left off. */ - size_t const sizePerFrame = 8 + (zcs->checksumFlag?4:0); - size_t const seekTableLen = ZSTD_seekable_seekTableSize(zcs); + size_t const sizePerFrame = 8 + (fl->checksumFlag?4:0); + size_t const seekTableLen = ZSTD_seekable_seekTableSize(fl); - CHECK_Z(ZSTD_stwrite32(zcs, output, ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0)); - CHECK_Z(ZSTD_stwrite32(zcs, output, seekTableLen - ZSTD_skippableHeaderSize, + CHECK_Z(ZSTD_stwrite32(fl, output, ZSTD_MAGIC_SKIPPABLE_START | 0xE, 0)); + CHECK_Z(ZSTD_stwrite32(fl, output, seekTableLen - ZSTD_skippableHeaderSize, 4)); - while (zcs->seekTableIndex < zcs->framelog.size) { - CHECK_Z(ZSTD_stwrite32( - zcs, output, zcs->framelog.entries[zcs->seekTableIndex].cSize, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex)); + while (fl->seekTableIndex < fl->size) { + CHECK_Z(ZSTD_stwrite32(fl, output, + fl->entries[fl->seekTableIndex].cSize, + ZSTD_skippableHeaderSize + + sizePerFrame * fl->seekTableIndex + 0)); - CHECK_Z(ZSTD_stwrite32( - zcs, output, zcs->framelog.entries[zcs->seekTableIndex].dSize, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex + 4)); + CHECK_Z(ZSTD_stwrite32(fl, output, + fl->entries[fl->seekTableIndex].dSize, + ZSTD_skippableHeaderSize + + sizePerFrame * fl->seekTableIndex + 4)); - if (zcs->checksumFlag) { + if (fl->checksumFlag) { CHECK_Z(ZSTD_stwrite32( - zcs, output, - zcs->framelog.entries[zcs->seekTableIndex].checksum, - ZSTD_skippableHeaderSize + sizePerFrame * zcs->seekTableIndex + - 8)); + fl, output, fl->entries[fl->seekTableIndex].checksum, + ZSTD_skippableHeaderSize + + sizePerFrame * fl->seekTableIndex + 8)); } - zcs->seekTableIndex++; + fl->seekTableIndex++; } - CHECK_Z(ZSTD_stwrite32(zcs, output, zcs->framelog.size, + CHECK_Z(ZSTD_stwrite32(fl, output, fl->size, seekTableLen - ZSTD_seekTableFooterSize)); - if (output->size - output->pos < 1) return seekTableLen - zcs->seekTablePos; - if (zcs->seekTablePos < seekTableLen - 4) { + if (output->size - output->pos < 1) return seekTableLen - fl->seekTablePos; + if (fl->seekTablePos < seekTableLen - 4) { BYTE sfd = 0; - sfd |= (zcs->checksumFlag) << 7; + sfd |= (fl->checksumFlag) << 7; ((BYTE*)output->dst)[output->pos] = sfd; output->pos++; - zcs->seekTablePos++; + fl->seekTablePos++; } - CHECK_Z(ZSTD_stwrite32(zcs, output, ZSTD_SEEKABLE_MAGICNUMBER, + CHECK_Z(ZSTD_stwrite32(fl, output, ZSTD_SEEKABLE_MAGICNUMBER, seekTableLen - 4)); - if (zcs->seekTablePos != seekTableLen) return ERROR(GENERIC); + if (fl->seekTablePos != seekTableLen) return ERROR(GENERIC); return 0; } @@ -314,10 +357,10 @@ size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* outpu const size_t endFrame = ZSTD_seekable_endFrame(zcs, output); if (ZSTD_isError(endFrame)) return endFrame; /* return an accurate size hint */ - if (endFrame) return endFrame + ZSTD_seekable_seekTableSize(zcs); + if (endFrame) return endFrame + ZSTD_seekable_seekTableSize(&zcs->framelog); } zcs->writingSeekTable = 1; - return ZSTD_seekable_writeSeekTable(zcs, output); + return ZSTD_seekable_writeSeekTable(&zcs->framelog, output); } From a00e9599f1db6123d773b222834826f98c1f4324 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 4 May 2017 17:24:29 -0700 Subject: [PATCH 016/400] removed -g from DEBUGFLAGS It inflates binary sizes, which is negative for the Windows build. It also makes it impossible to check if 2 different source codes get nonetheless compiled to the same binary, since checksum will be different, due to integrated source code. --- lib/Makefile | 2 +- programs/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index d8d8e179d..f5f610372 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -22,7 +22,7 @@ VERSION?= $(LIBVER) CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_ CFLAGS ?= -O3 -DEBUGFLAGS = -g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ +DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) diff --git a/programs/Makefile b/programs/Makefile index 0c920a87b..bb40253b9 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -41,7 +41,7 @@ CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ -I$(ZSTDDIR)/dictBuilder \ -DXXH_NAMESPACE=ZSTD_ # because xxhash.o already compiled with this macro from library CFLAGS ?= -O3 -DEBUGFLAGS = -g -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ +DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security CFLAGS += $(DEBUGFLAGS) $(MOREFLAGS) From c21a9c35960d7dd18c91b04b9af760f6c071773c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 4 May 2017 17:26:58 -0700 Subject: [PATCH 017/400] removed zstdmt generation from Appveyor artefact build --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 67c4f72d7..29eb1ac53 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -91,8 +91,6 @@ cp programs\zstd.exe zstd_%PLATFORM%.exe && appveyor PushArtifact zstd_%PLATFORM%.exe && cp programs\zstd.exe bin\zstd.exe && - make -C programs DEBUGFLAGS= clean zstdmt && - cp programs\zstd.exe bin\zstdmt.exe && cd bin\ && 7z a -tzip zstd-win-release-%PLATFORM%.zip * && appveyor PushArtifact zstd-win-release-%PLATFORM%.zip ) From 9203dab529cdd8c46bdb9b3dd5d6a6cfd3c27fab Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 4 May 2017 17:30:37 -0700 Subject: [PATCH 018/400] Appveyor build artefact creates zipped cli binary --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 29eb1ac53..df7567b8e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -88,8 +88,8 @@ ( if [%COMPILER%]==[gcc] if [%ARTIFACT%]==[true] lib\dll\example\build_package.bat && make -C programs DEBUGFLAGS= clean zstd && - cp programs\zstd.exe zstd_%PLATFORM%.exe && - appveyor PushArtifact zstd_%PLATFORM%.exe && + 7z a -tzip zstd-win-binary-%PLATFORM%.zip programs\zstd.exe && + appveyor PushArtifact zstd-win-binary-%PLATFORM%.zip && cp programs\zstd.exe bin\zstd.exe && cd bin\ && 7z a -tzip zstd-win-release-%PLATFORM%.zip * && appveyor PushArtifact zstd-win-release-%PLATFORM%.zip From 36153af5ec8f281ce507ee4ece4e78a4059d5452 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 4 May 2017 17:40:40 -0700 Subject: [PATCH 019/400] creates a binary archive without the `programs` directory also improves compression ratio to -mx9 --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index df7567b8e..1f8b8cf8a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -88,10 +88,10 @@ ( if [%COMPILER%]==[gcc] if [%ARTIFACT%]==[true] lib\dll\example\build_package.bat && make -C programs DEBUGFLAGS= clean zstd && - 7z a -tzip zstd-win-binary-%PLATFORM%.zip programs\zstd.exe && + cd programs\ && 7z a -tzip -mx9 zstd-win-binary-%PLATFORM%.zip zstd.exe && appveyor PushArtifact zstd-win-binary-%PLATFORM%.zip && - cp programs\zstd.exe bin\zstd.exe && - cd bin\ && 7z a -tzip zstd-win-release-%PLATFORM%.zip * && + cp zstd.exe ..\bin\zstd.exe && + cd ..\bin\ && 7z a -tzip -mx9 zstd-win-release-%PLATFORM%.zip * && appveyor PushArtifact zstd-win-release-%PLATFORM%.zip ) ) From 25b283339691af8cd9747f1b843618c4105e2450 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 5 May 2017 15:41:23 -0700 Subject: [PATCH 020/400] keep dev branch status only master branch status is removed, due to misattribution during cron jobs --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7caee5fd3..26305f51f 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,9 @@ and a command line utility producing and decoding `.zst` and `.gz` files. For other programming languages, you can consult a list of known ports on [Zstandard homepage](http://www.zstd.net/#other-languages). -|Branch |Status | -|------------|---------| -|master | [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=master)](https://travis-ci.org/facebook/zstd) | -|dev | [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=dev)](https://travis-ci.org/facebook/zstd) | +| dev branch status | +|----------------------| +| [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=dev)](https://travis-ci.org/facebook/zstd) As a reference, several fast compression algorithms were tested and compared on a server running Linux Debian (`Linux version 4.8.0-1-amd64`), From 3d55e1fbee1c5b2c188fd9980babc4dac2379d9e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 5 May 2017 15:48:42 -0700 Subject: [PATCH 021/400] added dev branch Appveyor badge --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 26305f51f..97b1a7d1d 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,14 @@ For other programming languages, you can consult a list of known ports on [Zstandard homepage](http://www.zstd.net/#other-languages). | dev branch status | -|----------------------| -| [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=dev)](https://travis-ci.org/facebook/zstd) +|-------------------| +| [![Build Status][travisDevBadge]][travisLink] [![Build status][AppveyorDevBadge]][AppveyorLink] | + +[travisDevBadge]: https://travis-ci.org/facebook/zstd.svg?branch=dev "Continuous Integration test suite" +[travisLink]: https://travis-ci.org/facebook/zstd +[AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/xt38wbdxjk5mrbem/branch/dev?svg=true "Windows test suite" +[AppveyorLink]: https://ci.appveyor.com/project/YannCollet/zstd-p0yf0 + As a reference, several fast compression algorithms were tested and compared on a server running Linux Debian (`Linux version 4.8.0-1-amd64`), From 11bff3fbd3a7d9ce64ccfec13ba3193d9fdda37f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 5 May 2017 15:55:03 -0700 Subject: [PATCH 022/400] added dev branch CircleCI badge --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97b1a7d1d..eee92f917 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,14 @@ you can consult a list of known ports on [Zstandard homepage](http://www.zstd.ne | dev branch status | |-------------------| -| [![Build Status][travisDevBadge]][travisLink] [![Build status][AppveyorDevBadge]][AppveyorLink] | +| [![Build Status][travisDevBadge]][travisLink] [![Build status][AppveyorDevBadge]][AppveyorLink] [![Build status][CircleDevBadge]][CircleLink] [travisDevBadge]: https://travis-ci.org/facebook/zstd.svg?branch=dev "Continuous Integration test suite" [travisLink]: https://travis-ci.org/facebook/zstd [AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/xt38wbdxjk5mrbem/branch/dev?svg=true "Windows test suite" [AppveyorLink]: https://ci.appveyor.com/project/YannCollet/zstd-p0yf0 +[CircleDevBadge]: https://circleci.com/gh/facebook/zstd/tree/dev.svg?style=shield "Short test suite" +[CircleLink]: https://circleci.com/gh/facebook/zstd As a reference, several fast compression algorithms were tested and compared From 01a1abfdb5a78cd4f63b0199be036b1546c4135c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 5 May 2017 19:15:24 -0700 Subject: [PATCH 023/400] cli : -d and -t do not stop after a failed decompression The problematic srcfile will be named on console/log, but decompression/test will continue onto next file in the list. --- programs/fileio.c | 67 ++++++++++++++++++++++++++++++++++------------ tests/playTests.sh | 31 +++++++++++---------- 2 files changed, 67 insertions(+), 31 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index e188936b2..ba15555dd 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -206,8 +206,8 @@ void FIO_setOverlapLog(unsigned overlapLog){ static int FIO_remove(const char* path) { #if defined(_WIN32) || defined(WIN32) - /* windows doesn't allow remove read-only files, so try to make it - * writable first */ + /* windows doesn't allow remove read-only files, + * so try to make it writable first */ chmod(path, _S_IWRITE); #endif return remove(path); @@ -983,16 +983,19 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ /** FIO_decompressFrame() : - @return : size of decoded frame + @return : size of decoded frame, or an error code */ +#define FIO_ERROR_ZSTD_DECODING ((unsigned long long)(-2)) unsigned long long FIO_decompressFrame(dRess_t* ress, FILE* finput, + const char* srcFileName, U64 alreadyDecoded) { U64 frameSize = 0; U32 storedSkips = 0; ZSTD_resetDStream(ress->dctx); + if (strlen(srcFileName)>20) srcFileName += strlen(srcFileName)-20; /* display last 20 characters */ /* Header loading (optional, saves one loop) */ { size_t const toRead = 9; @@ -1005,12 +1008,17 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, ZSTD_inBuffer inBuff = { ress->srcBuffer, ress->srcBufferLoaded, 0 }; ZSTD_outBuffer outBuff= { ress->dstBuffer, ress->dstBufferSize, 0 }; size_t const readSizeHint = ZSTD_decompressStream(ress->dctx, &outBuff, &inBuff); - if (ZSTD_isError(readSizeHint)) EXM_THROW(36, "Decoding error : %s", ZSTD_getErrorName(readSizeHint)); + if (ZSTD_isError(readSizeHint)) { + DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n", + srcFileName, ZSTD_getErrorName(readSizeHint)); + return FIO_ERROR_ZSTD_DECODING; + } /* Write block */ storedSkips = FIO_fwriteSparse(ress->dstFile, ress->dstBuffer, outBuff.pos, storedSkips); frameSize += outBuff.pos; - DISPLAYUPDATE(2, "\rDecoded : %u MB... ", (U32)((alreadyDecoded+frameSize)>>20) ); + DISPLAYUPDATE(2, "\r%-20.20s : %u MB... ", + srcFileName, (U32)((alreadyDecoded+frameSize)>>20) ); if (inBuff.pos > 0) { memmove(ress->srcBuffer, (char*)ress->srcBuffer + inBuff.pos, inBuff.size - inBuff.pos); @@ -1018,14 +1026,22 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, } if (readSizeHint == 0) break; /* end of frame */ - if (inBuff.size != inBuff.pos) EXM_THROW(37, "Decoding error : should consume entire input"); + if (inBuff.size != inBuff.pos) { + DISPLAYLEVEL(1, "%s : Decoding error (37) : should consume entire input \n", + srcFileName); + return FIO_ERROR_ZSTD_DECODING; + } /* Fill input buffer */ { size_t const toRead = MIN(readSizeHint, ress->srcBufferSize); /* support large skippable frames */ if (ress->srcBufferLoaded < toRead) - ress->srcBufferLoaded += fread(((char*)ress->srcBuffer) + ress->srcBufferLoaded, 1, toRead - ress->srcBufferLoaded, finput); - if (ress->srcBufferLoaded < toRead) EXM_THROW(39, "Read error : premature end"); - } } + ress->srcBufferLoaded += fread((char*)ress->srcBuffer + ress->srcBufferLoaded, + 1, toRead - ress->srcBufferLoaded, finput); + if (ress->srcBufferLoaded < toRead) { + DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n", + srcFileName); + return FIO_ERROR_ZSTD_DECODING; + } } } FIO_fwriteSparseEnd(ress->dstFile, storedSkips); @@ -1221,9 +1237,14 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch size_t const toRead = 4; const BYTE* buf = (const BYTE*)ress.srcBuffer; if (ress.srcBufferLoaded < toRead) - ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, (size_t)1, toRead - ress.srcBufferLoaded, srcFile); + ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, + (size_t)1, toRead - ress.srcBufferLoaded, srcFile); if (ress.srcBufferLoaded==0) { - if (readSomething==0) { DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); fclose(srcFile); return 1; } /* srcFileName is empty */ + if (readSomething==0) { + DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); + fclose(srcFile); + return 1; + } /* srcFileName is empty */ break; /* no more input */ } readSomething = 1; /* there is at least >= 4 bytes in srcFile */ @@ -1259,7 +1280,8 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch } else { if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); + unsigned const result = FIO_passThrough(ress.dstFile, srcFile, + ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ return result; } else { @@ -1267,9 +1289,15 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch fclose(srcFile); return 1; } } - filesize += FIO_decompressFrame(&ress, srcFile, filesize); + { unsigned long long const frameSize = FIO_decompressFrame(&ress, srcFile, srcFileName, filesize); + if (frameSize == FIO_ERROR_ZSTD_DECODING) { + fclose(srcFile); + return 1; + } + filesize += frameSize; + } } - } + } /* for each frame */ /* Final Status */ DISPLAYLEVEL(2, "\r%79s\r", ""); @@ -1364,15 +1392,20 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles dstFileName = (char*)malloc(dfnSize); if (dstFileName==NULL) EXM_THROW(74, "not enough memory for dstFileName"); } - if (sfnSize <= suffixSize || (strcmp(suffixPtr, GZ_EXTENSION) && strcmp(suffixPtr, XZ_EXTENSION) && strcmp(suffixPtr, ZSTD_EXTENSION) && strcmp(suffixPtr, LZMA_EXTENSION) && strcmp(suffixPtr, LZ4_EXTENSION))) { - DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%s/%s/%s/%s expected) -- ignored \n", srcFileName, GZ_EXTENSION, XZ_EXTENSION, ZSTD_EXTENSION, LZMA_EXTENSION); + if (sfnSize <= suffixSize + || (strcmp(suffixPtr, GZ_EXTENSION) + && strcmp(suffixPtr, XZ_EXTENSION) + && strcmp(suffixPtr, ZSTD_EXTENSION) + && strcmp(suffixPtr, LZMA_EXTENSION) + && strcmp(suffixPtr, LZ4_EXTENSION)) ) { + DISPLAYLEVEL(1, "zstd: %s: unknown suffix (%s/%s/%s/%s/%s expected) -- ignored \n", + srcFileName, GZ_EXTENSION, XZ_EXTENSION, ZSTD_EXTENSION, LZMA_EXTENSION, LZ4_EXTENSION); skippedFiles++; continue; } else { memcpy(dstFileName, srcFileName, sfnSize - suffixSize); dstFileName[sfnSize-suffixSize] = '\0'; } - missingFiles += FIO_decompressDstFile(ress, dstFileName, srcFileName); } free(dstFileName); diff --git a/tests/playTests.sh b/tests/playTests.sh index 021fd59fe..e69574588 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -92,7 +92,7 @@ $ZSTD tmp --stdout > tmpCompressed # long command format $ECHO "test : compress to named file" rm tmpCompressed $ZSTD tmp -o tmpCompressed -ls tmpCompressed # must work +test -f tmpCompressed # file must be created $ECHO "test : -o must be followed by filename (must fail)" $ZSTD tmp -of tmpCompressed && die "-o must be followed by filename " $ECHO "test : force write, correct order" @@ -142,21 +142,21 @@ $ZSTD -q -f tmpro rm -f tmpro tmpro.zst $ECHO "test : file removal" $ZSTD -f --rm tmp -ls tmp && die "tmp should no longer be present" +test ! -f tmp # tmp should no longer be present $ZSTD -f -d --rm tmp.zst -ls tmp.zst && die "tmp.zst should no longer be present" +test ! -f tmp.zst # tmp.zst should no longer be present $ECHO "test : --rm on stdin" $ECHO a | $ZSTD --rm > $INTOVOID # --rm should remain silent rm tmp $ZSTD -f tmp && die "tmp not present : should have failed" -ls tmp.zst && die "tmp.zst should not be created" +test ! -f tmp.zst # tmp.zst should not be created $ECHO "\n**** Advanced compression parameters **** " $ECHO "Hello world!" | $ZSTD --zstd=windowLog=21, - -o tmp.zst && die "wrong parameters not detected!" $ECHO "Hello world!" | $ZSTD --zstd=windowLo=21 - -o tmp.zst && die "wrong parameters not detected!" $ECHO "Hello world!" | $ZSTD --zstd=windowLog=21,slog - -o tmp.zst && die "wrong parameters not detected!" -ls tmp.zst && die "tmp.zst should not be created" +test ! -f tmp.zst # tmp.zst should not be created roundTripTest -g512K roundTripTest -g512K " --zstd=slen=3,tlen=48,strat=6" roundTripTest -g512K " --zstd=strat=6,wlog=23,clog=23,hlog=22,slog=6" @@ -201,16 +201,17 @@ $ECHO foo | $ZSTD > /dev/full && die "write error not detected!" $ECHO "$ECHO foo | $ZSTD | $ZSTD -d > /dev/full" $ECHO foo | $ZSTD | $ZSTD -d > /dev/full && die "write error not detected!" + $ECHO "\n**** symbolic link test **** " rm -f hello.tmp world.tmp hello.tmp.zst world.tmp.zst $ECHO "hello world" > hello.tmp ln -s hello.tmp world.tmp $ZSTD world.tmp hello.tmp -ls hello.tmp.zst || die "regular file should have been compressed!" -ls world.tmp.zst && die "symbolic link should not have been compressed!" +test -f hello.tmp.zst # regular file should have been compressed! +test ! -f world.tmp.zst # symbolic link should not have been compressed! $ZSTD world.tmp hello.tmp -f -ls world.tmp.zst || die "symbol link should have been compressed with --force" +test -f world.tmp.zst # symbolic link should have been compressed with --force rm -f hello.tmp world.tmp hello.tmp.zst world.tmp.zst fi @@ -225,10 +226,10 @@ $ZSTD tmpSparse -c | $ZSTD -dv --sparse -c > tmpOutSparse $DIFF -s tmpSparse tmpOutSparse $ZSTD tmpSparse -c | $ZSTD -dv --no-sparse -c > tmpOutNoSparse $DIFF -s tmpSparse tmpOutNoSparse -ls -ls tmpSparse* +ls -ls tmpSparse* # look at file size and block size on disk ./datagen -s1 -g1200007 -P100 | $ZSTD | $ZSTD -dv --sparse -c > tmpSparseOdd # Odd size file (to not finish on an exact nb of blocks) ./datagen -s1 -g1200007 -P100 | $DIFF -s - tmpSparseOdd -ls -ls tmpSparseOdd +ls -ls tmpSparseOdd # look at file size and block size on disk $ECHO "\n Sparse Compatibility with Console :" $ECHO "Hello World 1 !" | $ZSTD | $ZSTD -d -c $ECHO "Hello World 2 !" | $ZSTD | $ZSTD -d | cat @@ -238,7 +239,7 @@ cat tmpSparse1M tmpSparse1M > tmpSparse2M $ZSTD -v -f tmpSparse1M -o tmpSparseCompressed $ZSTD -d -v -f tmpSparseCompressed -o tmpSparseRegenerated $ZSTD -d -v -f tmpSparseCompressed -c >> tmpSparseRegenerated -ls -ls tmpSparse* +ls -ls tmpSparse* # look at file size and block size on disk $DIFF tmpSparse2M tmpSparseRegenerated rm tmpSparse* @@ -257,11 +258,11 @@ $ZSTD -df *.zst ls -ls tmp* $ECHO "compress tmp* into stdout > tmpall : " $ZSTD -c tmp1 tmp2 tmp3 > tmpall -ls -ls tmp* +ls -ls tmp* # check size of tmpall (should be tmp1.zst + tmp2.zst + tmp3.zst) $ECHO "decompress tmpall* into stdout > tmpdec : " cp tmpall tmpall2 $ZSTD -dc tmpall* > tmpdec -ls -ls tmp* +ls -ls tmp* # check size of tmpdec (should be 2*(tmp1 + tmp2 + tmp3)) $ECHO "compress multiple files including a missing one (notHere) : " $ZSTD -f tmp1 notHere tmp2 && die "missing file not detected!" @@ -379,7 +380,9 @@ $ZSTD -t tmp2.zst && die "bad file not detected !" $ZSTD -t tmp3 && die "bad file not detected !" # detects 0-sized files as bad $ECHO "test --rm and --test combined " $ZSTD -t --rm tmp1.zst -ls -ls tmp1.zst # check file is still present +test -f tmp1.zst # check file is still present +split -b16384 tmp1.zst tmpSplit. +$ZSTD -t tmpSplit.* && die "bad file not detected !" $ECHO "\n**** benchmark mode tests **** " From 0be6fd342984d375965255bff77f8936bcd85f8a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 8 May 2017 16:08:01 -0700 Subject: [PATCH 024/400] merged CCtx and CStream as a single same object To be changed : ZSTD_sizeof_CCtx(), ZSTD_estimateCCtxSize() --- doc/zstd_manual.html | 2 + lib/compress/zstd_compress.c | 124 +++++++++++++++++++---------------- lib/zstd.h | 3 +- tests/zstreamtest.c | 18 +++-- 4 files changed, 84 insertions(+), 63 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 2e77e7742..8cac4294f 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -244,6 +244,8 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);

    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 z 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 literal 0 HcmV?d00001 diff --git a/examples/seekable_compression.c b/contrib/seekable_format/examples/seekable_compression.c similarity index 99% rename from examples/seekable_compression.c rename to contrib/seekable_format/examples/seekable_compression.c index f4bceb10c..8d3fe8576 100644 --- a/examples/seekable_compression.c +++ b/contrib/seekable_format/examples/seekable_compression.c @@ -12,6 +12,8 @@ #define ZSTD_STATIC_LINKING_ONLY #include // presumes zstd library is installed +#include "zstd_seekable.h" + static void* malloc_orDie(size_t size) { void* const buff = malloc(size); diff --git a/examples/seekable_decompression.c b/contrib/seekable_format/examples/seekable_decompression.c similarity index 99% rename from examples/seekable_decompression.c rename to contrib/seekable_format/examples/seekable_decompression.c index 641e0429f..b134b87b6 100644 --- a/examples/seekable_decompression.c +++ b/contrib/seekable_format/examples/seekable_decompression.c @@ -15,6 +15,8 @@ #include // presumes zstd library is installed #include +#include "zstd_seekable.h" + static void* malloc_orDie(size_t size) { diff --git a/contrib/seekable_format/zstd_seekable.h b/contrib/seekable_format/zstd_seekable.h new file mode 100644 index 000000000..959b1bd0f --- /dev/null +++ b/contrib/seekable_format/zstd_seekable.h @@ -0,0 +1,140 @@ +#ifndef SEEKABLE_H +#define SEEKABLE_H + +#if defined (__cplusplus) +extern "C" { +#endif + +static const unsigned ZSTD_seekTableFooterSize = 9; + +#define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 + +#define ZSTD_SEEKABLE_MAXCHUNKS 0x8000000U + +/* 0xFE03F607 is the largest number x such that ZSTD_compressBound(x) fits in a 32-bit integer */ +#define ZSTD_SEEKABLE_MAX_CHUNK_DECOMPRESSED_SIZE 0xFE03F607 + +/*-**************************************************************************** +* Seekable Format +* +* The seekable format splits the compressed data into a series of "chunks", +* each compressed individually so that decompression of a section in the +* middle of an archive only requires zstd to decompress at most a chunk's +* worth of extra data, instead of the entire archive. +******************************************************************************/ + +typedef struct ZSTD_seekable_CStream_s ZSTD_seekable_CStream; +typedef struct ZSTD_seekable_DStream_s ZSTD_seekable_DStream; + +/*-**************************************************************************** +* Seekable compression - HowTo +* A ZSTD_seekable_CStream object is required to tracking streaming operation. +* Use ZSTD_seekable_createCStream() and ZSTD_seekable_freeCStream() to create/ +* release resources. +* +* Streaming objects are reusable to avoid allocation and deallocation, +* to start a new compression operation call ZSTD_seekable_initCStream() on the +* compressor. +* +* Data streamed to the seekable compressor will automatically be split into +* chunks of size `maxChunkSize` (provided in ZSTD_seekable_initCStream()), +* or if none is provided, will be cut off whenver ZSTD_endChunk() is called +* or when the default maximum chunk size is reached (approximately 4GB). +* +* Use ZSTD_seekable_initCStream() to initialize a ZSTD_seekable_CStream object +* for a new compression operation. +* `maxChunkSize` indicates the size at which to automatically start a new +* seekable frame. `maxChunkSize == 0` implies the default maximum size. +* `checksumFlag` indicates whether or not the seek table should include chunk +* checksums on the uncompressed data for verification. +* @return : a size hint for input to provide for compression, or an error code +* checkable with ZSTD_isError() +* +* Use ZSTD_seekable_compressStream() repetitively to consume input stream. +* The function will automatically update both `pos` fields. +* Note that it may not consume the entire input, in which case `pos < size`, +* and it's up to the caller to present again remaining data. +* @return : a size hint, preferred nb of bytes to use as input for next +* function call or an error code, which can be tested using +* ZSTD_isError(). +* Note 1 : it's just a hint, to help latency a little, any other +* value will work fine. +* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize() +* +* At any time, call ZSTD_seekable_endChunk() to end the current chunk and +* start a new one. +* +* ZSTD_endStream() will end the current chunk, and then write the seek table +* so that decompressors can efficiently find compressed chunks. +* ZSTD_endStream() may return a number > 0 if it was unable to flush all the +* necessary data to `output`. In this case, it should be called again until +* all remaining data is flushed out and 0 is returned. +******************************************************************************/ + +/*===== Seekable compressor management =====*/ +ZSTDLIB_API ZSTD_seekable_CStream* ZSTD_seekable_createCStream(void); +ZSTDLIB_API size_t ZSTD_seekable_freeCStream(ZSTD_seekable_CStream* zcs); + +/*===== Seekable compression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_initCStream(ZSTD_seekable_CStream* zcs, int compressionLevel, int checksumFlag, unsigned maxChunkSize); +ZSTDLIB_API size_t ZSTD_seekable_compressStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API size_t ZSTD_seekable_endChunk(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); +ZSTDLIB_API size_t ZSTD_seekable_endStream(ZSTD_seekable_CStream* zcs, ZSTD_outBuffer* output); + +/*-**************************************************************************** +* Seekable decompression - HowTo +* A ZSTD_seekable_DStream object is required to tracking streaming operation. +* Use ZSTD_seekable_createDStream() and ZSTD_seekable_freeDStream() to create/ +* release resources. +* +* Streaming objects are reusable to avoid allocation and deallocation, +* to start a new compression operation call ZSTD_seekable_initDStream() on the +* compressor. +* +* Use ZSTD_seekable_loadSeekTable() to load the seek table from a file. +* `src` should point to a block of data read from the end of the file, +* i.e. `src + srcSize` should always be the end of the file. +* @return : 0 if the table was loaded successfully, or if `srcSize` was too +* small, a size hint for how much data to provide. +* An error code may also be returned, checkable with ZSTD_isError() +* +* Use ZSTD_initDStream to prepare for a new decompression operation using the +* seektable loaded with ZSTD_seekable_loadSeekTable(). +* Data in the range [rangeStart, rangeEnd) will be decompressed. +* +* Call ZSTD_seekable_decompressStream() repetitively to consume input stream. +* @return : There are a number of possible return codes for this function +* - 0, the decompression operation has completed. +* - An error code checkable with ZSTD_isError +* + If this error code is ZSTD_error_needSeek, the user should seek +* to the file position provided by ZSTD_seekable_getSeekOffset() +* and indicate this to the stream with +* ZSTD_seekable_updateOffset(), before resuming decompression +* + Otherwise, this is a regular decompression error and the input +* file is likely corrupted or the API was incorrectly used. +* - A size hint, the preferred nb of bytes to provide as input to the +* next function call to improve latency. +* +* ZSTD_seekable_getSeekOffset() and ZSTD_seekable_updateOffset() are helper +* functions to indicate where the user should seek their file stream to, when +* a different position is required to continue decompression. +* Note that ZSTD_seekable_updateOffset will error if given an offset other +* than the one requested from ZSTD_seekable_getSeekOffset(). +******************************************************************************/ + +/*===== Seekable decompressor management =====*/ +ZSTDLIB_API ZSTD_seekable_DStream* ZSTD_seekable_createDStream(void); +ZSTDLIB_API size_t ZSTD_seekable_freeDStream(ZSTD_seekable_DStream* zds); + +/*===== Seekable decompression functions =====*/ +ZSTDLIB_API size_t ZSTD_seekable_loadSeekTable(ZSTD_seekable_DStream* zds, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_seekable_initDStream(ZSTD_seekable_DStream* zds, unsigned long long rangeStart, unsigned long long rangeEnd); +ZSTDLIB_API size_t ZSTD_seekable_decompressStream(ZSTD_seekable_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input); +ZSTDLIB_API unsigned long long ZSTD_seekable_getSeekOffset(ZSTD_seekable_DStream* zds); +ZSTDLIB_API size_t ZSTD_seekable_updateOffset(ZSTD_seekable_DStream* zds, unsigned long long offset); + +#if defined (__cplusplus) +} +#endif + +#endif diff --git a/doc/zstd_seekable_compression_format.md b/contrib/seekable_format/zstd_seekable_compression_format.md similarity index 100% rename from doc/zstd_seekable_compression_format.md rename to contrib/seekable_format/zstd_seekable_compression_format.md diff --git a/lib/compress/zstdseek_compress.c b/contrib/seekable_format/zstdseek_compress.c similarity index 99% rename from lib/compress/zstdseek_compress.c rename to contrib/seekable_format/zstdseek_compress.c index f9e108afc..2504287cd 100644 --- a/lib/compress/zstdseek_compress.c +++ b/contrib/seekable_format/zstdseek_compress.c @@ -10,10 +10,11 @@ #include /* malloc, free */ #define XXH_STATIC_LINKING_ONLY +#define XXH_NAMESPACE ZSTD_ #include "xxhash.h" #include "zstd_internal.h" /* includes zstd.h */ -#include "seekable.h" +#include "zstd_seekable.h" typedef struct { U32 cSize; diff --git a/lib/decompress/zstdseek_decompress.c b/contrib/seekable_format/zstdseek_decompress.c similarity index 99% rename from lib/decompress/zstdseek_decompress.c rename to contrib/seekable_format/zstdseek_decompress.c index 92901befa..3cb851ea5 100644 --- a/lib/decompress/zstdseek_decompress.c +++ b/contrib/seekable_format/zstdseek_decompress.c @@ -10,10 +10,11 @@ #include /* malloc, free */ #define XXH_STATIC_LINKING_ONLY +#define XXH_NAMESPACE ZSTD_ #include "xxhash.h" #include "zstd_internal.h" /* includes zstd.h */ -#include "seekable.h" +#include "zstd_seekable.h" typedef struct { U64 cOffset; diff --git a/doc/README.md b/doc/README.md index 0aee04280..6f761b33e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -17,6 +17,3 @@ __`zstd_manual.html`__ : Documentation on the functions found in `zstd.h`. See [http://zstd.net/zstd_manual.html](http://zstd.net/zstd_manual.html) for the manual released with the latest official `zstd` release. -__`zstd_seekable_compression_format.md`__ : This document defines the Zstandard -format for seekable compression. - diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index c7017d12c..a5b66f7d3 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -28,9 +28,6 @@

    +
    typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are effectively same object */
    +

    ZSTD_CStream management functions

    ZSTD_CStream* ZSTD_createCStream(void);
     size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
     

    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c08b315da..d7f90dff8 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -79,6 +79,8 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr) /*-************************************* * Context memory management ***************************************/ +typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage; + struct ZSTD_CCtx_s { const BYTE* nextSrc; /* next block here to continue on current prefix */ const BYTE* base; /* All regular indexes relative to this position */ @@ -115,6 +117,22 @@ struct ZSTD_CCtx_s { FSE_CTable* matchlengthCTable; FSE_CTable* litlengthCTable; unsigned* entropyScratchSpace; + + /* streaming */ + ZSTD_CDict* cdictLocal; + const ZSTD_CDict* cdict; + char* inBuff; + size_t inBuffSize; + size_t inToCompress; + size_t inBuffPos; + size_t inBuffTarget; + char* outBuff; + size_t outBuffSize; + size_t outBuffContentSize; + size_t outBuffFlushedSize; + ZSTD_cStreamStage streamStage; + U32 frameEnded; + U64 pledgedSrcSize; }; ZSTD_CCtx* ZSTD_createCCtx(void) @@ -253,8 +271,8 @@ static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2) { return (param1.cParams.hashLog == param2.cParams.hashLog) & (param1.cParams.chainLog == param2.cParams.chainLog) - & (param1.cParams.strategy == param2.cParams.strategy) - & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3)); + & (param1.cParams.strategy == param2.cParams.strategy) /* opt parser space */ + & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3)); /* hashlog3 space */ } /*! ZSTD_continueCCtx() : @@ -285,8 +303,11 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, ZSTD_parameters params, U64 frameContentSize, ZSTD_compResetPolicy_e const crp) { + DEBUGLOG(5, "ZSTD_resetCCtx_internal \n"); + if (crp == ZSTDcrp_continue) if (ZSTD_equivalentParams(params, zc->params)) { + DEBUGLOG(5, "ZSTD_equivalentParams()==1 \n"); zc->fseCTables_ready = 0; zc->hufCTable_repeatMode = HUF_repeat_none; return ZSTD_continueCCtx(zc, params, frameContentSize); @@ -312,6 +333,8 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, size_t const optSpace = ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optPotentialSpace : 0; size_t const neededSpace = entropySpace + optSpace + tableSpace + tokenSpace; if (zc->workSpaceSize < neededSpace) { + DEBUGLOG(5, "Need to update workSpaceSize from %uK to %uK \n", + (unsigned)zc->workSpaceSize>>10, (unsigned)neededSpace>>10); zc->workSpaceSize = 0; ZSTD_free(zc->workSpace, zc->customMem); zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem); @@ -335,6 +358,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, /* init params */ zc->params = params; zc->blockSize = blockSize; + DEBUGLOG(5, "blockSize = %uK \n", (U32)blockSize>>10); zc->frameContentSize = frameContentSize; zc->consumedSrcSize = 0; @@ -364,6 +388,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, /* opt parser space */ if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) { + DEBUGLOG(5, "reserving optimal parser space "); assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */ zc->seqStore.litFreq = (U32*)ptr; zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<stage!=ZSTDcs_init) return ERROR(stage_wrong); memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); @@ -2528,9 +2554,8 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity, size_t pos; if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall); - DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u \n", !params.fParams.noDictIDFlag); - DEBUGLOG(5, "ZSTD_writeFrameHeader : dictID : %u \n", dictID); - DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDSizeCode : %u \n", dictIDSizeCode); + DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u \n", + !params.fParams.noDictIDFlag, dictID, dictIDSizeCode); MEM_writeLE32(dst, ZSTD_MAGICNUMBER); op[4] = frameHeaderDecriptionByte; pos=5; @@ -2840,6 +2865,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity) BYTE* op = ostart; size_t fhSize = 0; + DEBUGLOG(5, "ZSTD_writeEpilogue \n"); if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /* init missing */ /* special case : empty frame */ @@ -2877,12 +2903,14 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, const void* src, size_t srcSize) { size_t endResult; - size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 1 /* last chunk */); + size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, + 1 /* frame mode */, 1 /* last chunk */); if (ZSTD_isError(cSize)) return cSize; endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); if (ZSTD_isError(endResult)) return endResult; if (cctx->params.fParams.contentSizeFlag) { /* control src size */ - if (cctx->frameContentSize != cctx->consumedSrcSize) return ERROR(srcSize_wrong); + if (cctx->frameContentSize != cctx->consumedSrcSize) + return ERROR(srcSize_wrong); } return cSize + endResult; } @@ -3084,30 +3112,6 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx, * Streaming ********************************************************************/ -typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage; - -struct ZSTD_CStream_s { - ZSTD_CCtx* cctx; - ZSTD_CDict* cdictLocal; - const ZSTD_CDict* cdict; - char* inBuff; - size_t inBuffSize; - size_t inToCompress; - size_t inBuffPos; - size_t inBuffTarget; - size_t blockSize; - char* outBuff; - size_t outBuffSize; - size_t outBuffContentSize; - size_t outBuffFlushedSize; - ZSTD_cStreamStage stage; - U32 checksum; - U32 frameEnded; - U64 pledgedSrcSize; - ZSTD_parameters params; - ZSTD_customMem customMem; -}; /* typedef'd to ZSTD_CStream within "zstd.h" */ - ZSTD_CStream* ZSTD_createCStream(void) { return ZSTD_createCStream_advanced(defaultCustomMem); @@ -3124,8 +3128,6 @@ ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem) if (zcs==NULL) return NULL; memset(zcs, 0, sizeof(ZSTD_CStream)); memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem)); - zcs->cctx = ZSTD_createCCtx_advanced(customMem); - if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; } return zcs; } @@ -3133,8 +3135,6 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs) { if (zcs==NULL) return 0; /* support free on NULL */ { ZSTD_customMem const cMem = zcs->customMem; - ZSTD_freeCCtx(zcs->cctx); - zcs->cctx = NULL; ZSTD_freeCDict(zcs->cdictLocal); zcs->cdictLocal = NULL; ZSTD_free(zcs->inBuff, cMem); @@ -3156,20 +3156,20 @@ size_t ZSTD_CStreamOutSize(void) return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; } -static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) +static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize) { if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */ DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag); - if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs->cctx, zcs->cdict, zcs->params.fParams, pledgedSrcSize)) - else CHECK_F(ZSTD_compressBegin_internal(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize)); + if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize)) + else CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, params, pledgedSrcSize)); zcs->inToCompress = 0; zcs->inBuffPos = 0; zcs->inBuffTarget = zcs->blockSize; zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; - zcs->stage = zcss_load; + zcs->streamStage = zcss_load; zcs->frameEnded = 0; zcs->pledgedSrcSize = pledgedSrcSize; return 0; /* ready to go */ @@ -3178,9 +3178,10 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long p size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) { - zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0); + ZSTD_parameters params = zcs->params; + params.fParams.contentSizeFlag = (pledgedSrcSize > 0); DEBUGLOG(5, "ZSTD_resetCStream : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag); - return ZSTD_resetCStream_internal(zcs, pledgedSrcSize); + return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } /* ZSTD_initCStream_internal() : @@ -3212,11 +3213,8 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs, zcs->outBuffSize = outBuffSize; } - zcs->checksum = params.fParams.checksumFlag > 0; - zcs->params = params; - DEBUGLOG(5, "ZSTD_initCStream_stage2 : dictIDFlag == %u \n", !params.fParams.noDictIDFlag); - return ZSTD_resetCStream_internal(zcs, pledgedSrcSize); + return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } /* ZSTD_initCStream_usingCDict_advanced() : @@ -3261,7 +3259,8 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize) { CHECK_F( ZSTD_checkCParams(params.cParams) ); - DEBUGLOG(5, "ZSTD_initCStream_advanced : dictIDFlag == %u \n", !params.fParams.noDictIDFlag); + DEBUGLOG(5, "ZSTD_initCStream_advanced : pledgedSrcSize == %u \n", (U32)pledgedSrcSize); + DEBUGLOG(5, "wlog %u \n", params.cParams.windowLog); return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize); } @@ -3287,7 +3286,7 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) { if (zcs==NULL) return 0; /* support sizeof on NULL */ - return sizeof(*zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize; + return sizeof(*zcs) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize; } /*====== Compression ======*/ @@ -3314,8 +3313,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, char* const oend = ostart + *dstCapacityPtr; char* op = ostart; + DEBUGLOG(5, "ZSTD_compressStream_generic \n"); while (someMoreWork) { - switch(zcs->stage) + switch(zcs->streamStage) { case zcss_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */ @@ -3323,12 +3323,14 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, /* complete inBuffer */ { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip); + DEBUGLOG(5, "loading %u/%u \n", (U32)loaded, (U32)toLoad); zcs->inBuffPos += loaded; ip += loaded; if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) { someMoreWork = 0; break; /* not enough input to get a full block : stop there, wait for more */ } } /* compress current block (note : this stage cannot be stopped in the middle) */ + DEBUGLOG(5, "stream compression stage (flush==%u)\n", flush); { void* cDst; size_t cSize; size_t const iSize = zcs->inBuffPos - zcs->inToCompress; @@ -3338,29 +3340,33 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, else cDst = zcs->outBuff, oSize = zcs->outBuffSize; cSize = (flush == zsf_end) ? - ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) : - ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize); + ZSTD_compressEnd(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) : + ZSTD_compressContinue(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize); if (ZSTD_isError(cSize)) return cSize; + DEBUGLOG(5, "cSize = %u \n", (U32)cSize); if (flush == zsf_end) zcs->frameEnded = 1; /* prepare next block */ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize; if (zcs->inBuffTarget > zcs->inBuffSize) - zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffSize >= blockSize */ + zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffTarget == blockSize <= inBuffSize */ + assert(zcs->inBuffTarget <= zcs->inBuffSize); zcs->inToCompress = zcs->inBuffPos; if (cDst == op) { op += cSize; break; } /* no need to flush */ zcs->outBuffContentSize = cSize; zcs->outBuffFlushedSize = 0; - zcs->stage = zcss_flush; /* pass-through to flush stage */ + zcs->streamStage = zcss_flush; /* pass-through to flush stage */ } case zcss_flush: + DEBUGLOG(5, "flush stage \n"); { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush); + DEBUGLOG(5, "toFlush: %u ; flushed: %u \n", (U32)toFlush, (U32)flushed); op += flushed; zcs->outBuffFlushedSize += flushed; if (toFlush!=flushed) { someMoreWork = 0; break; } /* dst too small to store flushed data : stop there */ zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; - zcs->stage = zcss_load; + zcs->streamStage = zcss_load; break; } @@ -3419,7 +3425,8 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) BYTE* const oend = (BYTE*)(output->dst) + output->size; BYTE* op = ostart; - if (zcs->stage != zcss_final) { + DEBUGLOG(5, "ZSTD_endStream (dstCapacity : %u) \n", (U32)(oend-op)); + if (zcs->streamStage != zcss_final) { /* flush whatever remains */ size_t srcSize = 0; size_t sizeWritten = output->size - output->pos; @@ -3429,13 +3436,14 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) op += sizeWritten; if (remainingToFlush) { output->pos += sizeWritten; - return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4); + return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + + ((zcs->params.fParams.checksumFlag > 0) * 4) /* optional 32-bits checksum */; } /* create epilogue */ - zcs->stage = zcss_final; + zcs->streamStage = zcss_final; zcs->outBuffContentSize = !notEnded ? 0 : /* write epilogue, including final empty block, into outBuff */ - ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0); + ZSTD_compressEnd(zcs, zcs->outBuff, zcs->outBuffSize, NULL, 0); if (ZSTD_isError(zcs->outBuffContentSize)) return zcs->outBuffContentSize; } @@ -3445,7 +3453,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) op += flushed; zcs->outBuffFlushedSize += flushed; output->pos += op-ostart; - if (toFlush==flushed) zcs->stage = zcss_init; /* end reached */ + if (toFlush==flushed) zcs->streamStage = zcss_init; /* end reached */ return toFlush - flushed; } } diff --git a/lib/zstd.h b/lib/zstd.h index f8050c136..3179c8c78 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -281,7 +281,8 @@ typedef struct ZSTD_outBuffer_s { * * *******************************************************************/ -typedef struct ZSTD_CStream_s ZSTD_CStream; +typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are effectively same object */ + /* Continue due distinghish them for compatibility with versions <= v1.2.0 */ /*===== ZSTD_CStream management functions =====*/ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 0e09e1856..6c210f2ff 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -53,13 +53,15 @@ static const U32 prime32 = 2654435761U; * Display Macros **************************************/ #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) -#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } +#define DISPLAYLEVEL(l, ...) if (g_displayLevel>=l) { \ + DISPLAY(__VA_ARGS__); \ + if (g_displayLevel>=4) fflush(stderr); } static U32 g_displayLevel = 2; #define DISPLAYUPDATE(l, ...) if (g_displayLevel>=l) { \ if ((FUZ_GetClockSpan(g_displayClock) > g_refreshRate) || (g_displayLevel>=4)) \ { g_displayClock = clock(); DISPLAY(__VA_ARGS__); \ - if (g_displayLevel>=4) fflush(stderr); } } + if (g_displayLevel>=4) fflush(stderr); } } static const clock_t g_refreshRate = CLOCKS_PER_SEC / 6; static clock_t g_displayClock = 0; @@ -155,7 +157,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo void* decodedBuffer = malloc(decodedBufferSize); size_t cSize; int testResult = 0; - U32 testNb=0; + U32 testNb = 1; ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem); ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem); ZSTD_inBuffer inBuff, inBuff2; @@ -344,6 +346,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo if (zc==NULL) goto _output_error; /* memory allocation issue */ /* use 1 */ { size_t const inSize = 513; + DISPLAYLEVEL(5, "use1 "); ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */ inBuff.src = CNBuffer; inBuff.size = inSize; @@ -351,14 +354,17 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo outBuff.dst = (char*)(compressedBuffer)+cSize; outBuff.size = ZSTD_compressBound(inSize); outBuff.pos = 0; + DISPLAYLEVEL(5, "compress1 "); { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); if (ZSTD_isError(r)) goto _output_error; } if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + DISPLAYLEVEL(5, "end1 "); { size_t const r = ZSTD_endStream(zc, &outBuff); if (r != 0) goto _output_error; } /* error, or some data not flushed */ } /* use 2 */ { size_t const inSize = 1025; /* will not continue, because tables auto-adjust and are therefore different size */ + DISPLAYLEVEL(5, "use2 "); ZSTD_initCStream_advanced(zc, NULL, 0, ZSTD_getParams(19, inSize, 0), inSize); /* needs btopt + search3 to trigger hashLog3 */ inBuff.src = CNBuffer; inBuff.size = inSize; @@ -366,9 +372,11 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo outBuff.dst = (char*)(compressedBuffer)+cSize; outBuff.size = ZSTD_compressBound(inSize); outBuff.pos = 0; + DISPLAYLEVEL(5, "compress2 "); { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); if (ZSTD_isError(r)) goto _output_error; } if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + DISPLAYLEVEL(5, "end2 "); { size_t const r = ZSTD_endStream(zc, &outBuff); if (r != 0) goto _output_error; } /* error, or some data not flushed */ } @@ -770,7 +778,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres outBuff.size = outBuff.pos + adjustedDstSize; remainingToFlush = ZSTD_endStream(zc, &outBuff); CHECK (ZSTD_isError(remainingToFlush), "flush error : %s", ZSTD_getErrorName(remainingToFlush)); - CHECK (enoughDstSize && remainingToFlush, "ZSTD_endStream() not fully flushed (%u remaining), but enough space available", (U32)remainingToFlush); + CHECK (enoughDstSize && remainingToFlush, + "ZSTD_endStream() not fully flushed (%u remaining), but enough space available (%u)", + (U32)remainingToFlush, (U32)adjustedDstSize); } } crcOrig = XXH64_digest(&xxhState); cSize = outBuff.pos; From 791d74427925351c776de1e94ea701a41e894e20 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 8 May 2017 16:17:30 -0700 Subject: [PATCH 025/400] Updated ZSTD_sizeof_CCtx() can now contain buffers if object used as CStream. ZSTD_sizeof_CStream() is now just a thin wrapper of ZSTD_sizeof_CCtx(). --- lib/compress/zstd_compress.c | 7 ++++--- lib/zstd.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d7f90dff8..d55ea5059 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -165,7 +165,9 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) { if (cctx==NULL) return 0; /* support sizeof on NULL */ - return sizeof(*cctx) + cctx->workSpaceSize; + return sizeof(*cctx) + cctx->workSpaceSize + + ZSTD_sizeof_CDict(cctx->cdictLocal) + + cctx->outBuffSize + cctx->inBuffSize; } size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value) @@ -3285,8 +3287,7 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs) { - if (zcs==NULL) return 0; /* support sizeof on NULL */ - return sizeof(*zcs) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize; + return ZSTD_sizeof_CCtx(zcs); /* same object */ } /*====== Compression ======*/ diff --git a/lib/zstd.h b/lib/zstd.h index 3179c8c78..bb447ee17 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -468,7 +468,7 @@ ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams); ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); /*! ZSTD_sizeofCCtx() : - * Gives the amount of memory used by a given ZSTD_CCtx */ + * amount of used memory is variable, depending primarily on compression level */ ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); typedef enum { @@ -597,7 +597,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize); /*===== Advanced Streaming compression functions =====*/ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem); -ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); /**< size of CStream is variable, depending primarily on compression level */ +ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); /**< same as ZSTD_sizeof_CCtx */ ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */ ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */ ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, From fc5145955a0c53a9157579ce9dc2abcadeff5e32 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 8 May 2017 17:07:59 -0700 Subject: [PATCH 026/400] updated ZSTD_estimateCCtxSize() added a parameter streaming, to estimate memory allocation size when the CCtx is used for streaming (CStream). Note : this function is not able to estimate memory cost of a potential internal CDict which can only happen when starting with ZSTD_initCStream_usingDict() --- doc/zstd_manual.html | 6 +++--- lib/compress/zstd_compress.c | 23 ++++++++++++++--------- lib/zstd.h | 8 +++++--- tests/paramgrill.c | 4 ++-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 8cac4294f..d70915458 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -372,7 +372,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Advanced compression functions

    
     
    -
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    +
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
     

    Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters. `frameContentSize` is an optional parameter, provide `0` if unknown


    @@ -382,7 +382,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v


    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    -

    Gives the amount of memory used by a given ZSTD_CCtx +

    amount of used memory is variable, depending primarily on compression level


    typedef enum {
    @@ -507,7 +507,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     

    Advanced streaming functions

    
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    -size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< size of CStream is variable, depending primarily on compression level */
    +size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index d55ea5059..1248032bd 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -244,7 +244,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
     }
     
     
    -size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
    +size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming)
     {
         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
    @@ -260,12 +260,17 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
                                   + entropyScratchSpace_size;
         size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
     
    -    size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
     
         /* allocate buffers */
    -    {   size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
    +    {   size_t const neededInBuffSize = ((size_t)1 << params.cParams.windowLog) + zcs->blockSize;
             if (zcs->inBuffSize < neededInBuffSize) {
                 zcs->inBuffSize = 0;
                 ZSTD_free(zcs->inBuff, zcs->customMem);
    -            zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
    +            zcs->inBuff = (char*)ZSTD_malloc(neededInBuffSize, zcs->customMem);
                 if (zcs->inBuff == NULL) return ERROR(memory_allocation);
                 zcs->inBuffSize = neededInBuffSize;
             }
    -        zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
         }
         if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
             size_t const outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
             zcs->outBuffSize = 0;
             ZSTD_free(zcs->outBuff, zcs->customMem);
    -        zcs->outBuff = (char*) ZSTD_malloc(outBuffSize, zcs->customMem);
    +        zcs->outBuff = (char*)ZSTD_malloc(outBuffSize, zcs->customMem);
             if (zcs->outBuff == NULL) return ERROR(memory_allocation);
             zcs->outBuffSize = outBuffSize;
         }
    diff --git a/lib/zstd.h b/lib/zstd.h
    index bb447ee17..e8614334b 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -460,8 +460,10 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
     ***************************************/
     /*! ZSTD_estimateCCtxSize() :
      *  Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
    - *  `frameContentSize` is an optional parameter, provide `0` if unknown */
    -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    + *  Set streaming to 1 if the CCtx will be used for streaming (CStream)
    + *  Note : this function is currently unable to estimate additional memory allocation needed to create an internal CDict
    + *         which can only happen when starting with ZSTD_initCStream_usingDict() */
    +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
     
     /*! ZSTD_createCCtx_advanced() :
      *  Create a ZSTD compression context using external alloc and free functions */
    @@ -599,7 +601,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
     ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
    -ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
    +ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
     ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    diff --git a/tests/paramgrill.c b/tests/paramgrill.c
    index 1913b54d0..3cc916e01 100644
    --- a/tests/paramgrill.c
    +++ b/tests/paramgrill.c
    @@ -388,8 +388,8 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_compressionParameters para
                 double W_DMemUsed_note = W_ratioNote * ( 40 + 9*cLevel) - log((double)W_DMemUsed);
                 double O_DMemUsed_note = O_ratioNote * ( 40 + 9*cLevel) - log((double)O_DMemUsed);
     
    -            size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize(params);
    -            size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize(winners[cLevel].params);
    +            size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize(params, 0/*streaming*/);
    +            size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize(winners[cLevel].params, 0);
                 double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed);
                 double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed);
     
    
    From 7855366598f3287974fba8a0ff4d32de56d9efcd Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 8 May 2017 17:15:00 -0700
    Subject: [PATCH 027/400] Updated ZSTD_freeCCtx()
    
    which can also contain streaming buffers now.
    Redirected ZSTD_freeCStream() towards it.
    ---
     lib/compress/zstd_compress.c | 19 ++++++++-----------
     1 file changed, 8 insertions(+), 11 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 1248032bd..748aff930 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -158,6 +158,13 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
     {
         if (cctx==NULL) return 0;   /* support free on NULL */
         ZSTD_free(cctx->workSpace, cctx->customMem);
    +    cctx->workSpace = NULL;
    +    ZSTD_freeCDict(cctx->cdictLocal);
    +    cctx->cdictLocal = NULL;
    +    ZSTD_free(cctx->inBuff, cctx->customMem);
    +    cctx->inBuff = NULL;
    +    ZSTD_free(cctx->outBuff, cctx->customMem);
    +    cctx->outBuff = NULL;
         ZSTD_free(cctx, cctx->customMem);
         return 0;   /* reserved as a potential error code in the future */
     }
    @@ -3140,17 +3147,7 @@ ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
     
     size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
     {
    -    if (zcs==NULL) return 0;   /* support free on NULL */
    -    {   ZSTD_customMem const cMem = zcs->customMem;
    -        ZSTD_freeCDict(zcs->cdictLocal);
    -        zcs->cdictLocal = NULL;
    -        ZSTD_free(zcs->inBuff, cMem);
    -        zcs->inBuff = NULL;
    -        ZSTD_free(zcs->outBuff, cMem);
    -        zcs->outBuff = NULL;
    -        ZSTD_free(zcs, cMem);
    -        return 0;
    -    }
    +    return ZSTD_freeCCtx(zcs);   /* same object */
     }
     
     
    
    From a1d6704d7f63fb9ad177a8364a40385206d21b53 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 8 May 2017 17:51:49 -0700
    Subject: [PATCH 028/400] added ZSTD_estimateCDictSize() and
     ZSTD_estimateDDictSize()
    
    it complements ZSTD_estimateCCtxSize()
    for the special case of ZSTD_initCStream_usingDict()
    ---
     doc/zstd_manual.html             | 24 ++++++++++++++++++------
     lib/compress/zstd_compress.c     |  8 ++++++++
     lib/decompress/zstd_decompress.c |  8 ++++++++
     lib/zstd.h                       | 24 +++++++++++++++++-------
     tests/fuzzer.c                   |  6 ++++++
     5 files changed, 57 insertions(+), 13 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index d70915458..9cfb67100 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -372,15 +372,17 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     
     

    Advanced compression functions

    
     
    -
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    -

    Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters. - `frameContentSize` is an optional parameter, provide `0` if unknown -


    -
    ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     

    Create a ZSTD compression context using external alloc and free functions


    +
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    +

    Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters. + Set streaming to 1 if the CCtx will be used for streaming (CStream). + Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict. + Use ZSTD_estimateCDictSize() and add this value to estimate total CCtx size +


    +
    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
     

    amount of used memory is variable, depending primarily on compression level


    @@ -406,6 +408,11 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Create a ZSTD_CDict using external alloc and free, and customized compression parameters


    +
    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    +

    Estimate amount of memory that will be needed to create a dictionary with following arguments + Note : if dictionary is created "byReference", reduce this amount by dictSize +


    +
    size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
     

    Gives the amount of memory used by a given ZSTD_sizeof_CDict


    @@ -476,6 +483,11 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Create a ZSTD_DDict using external alloc and free, optionally by reference


    +
    size_t ZSTD_estimateDDictSize(size_t dictSize);
    +

    Estimate amount of memory that will be needed to create a dictionary for decompression. + Note : if dictionary is created "byReference", reduce this amount by dictSize +


    +
    size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
     

    Gives the amount of memory used by a given ZSTD_DDict


    @@ -509,7 +521,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
     size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
    -size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
    +size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 748aff930..c5687b21c 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -2984,6 +2984,14 @@ struct ZSTD_CDict_s {
         ZSTD_CCtx* refContext;
     };  /* typedef'd tp ZSTD_CDict within "zstd.h" */
     
    +/*! ZSTD_estimateCDictSize() :
    + *  Estimate amount of memory that will be needed to create a dictionary with following arguments */
    +size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize)
    +{
    +    cParams = ZSTD_adjustCParams(cParams, 0, dictSize);
    +    return sizeof(ZSTD_CDict) + dictSize + ZSTD_estimateCCtxSize(cParams, 0);
    +}
    +
     size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
     {
         if (cdict==NULL) return 0;   /* support sizeof on NULL */
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 910f9ab78..88488b4b0 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -1969,6 +1969,14 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
         }
     }
     
    +/*! ZSTD_estimateDDictSize() :
    + *  Estimate amount of memory that will be needed to create a dictionary for decompression.
    + *  Note : if dictionary is created "byReference", reduce this amount by dictSize */
    +size_t ZSTD_estimateDDictSize(size_t dictSize)
    +{
    +    return dictSize + sizeof(ZSTD_DDict);
    +}
    +
     size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
     {
         if (ddict==NULL) return 0;   /* support sizeof on NULL */
    diff --git a/lib/zstd.h b/lib/zstd.h
    index e8614334b..270943b30 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -458,17 +458,17 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
     /***************************************
     *  Advanced compression functions
     ***************************************/
    -/*! ZSTD_estimateCCtxSize() :
    - *  Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
    - *  Set streaming to 1 if the CCtx will be used for streaming (CStream)
    - *  Note : this function is currently unable to estimate additional memory allocation needed to create an internal CDict
    - *         which can only happen when starting with ZSTD_initCStream_usingDict() */
    -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    -
     /*! ZSTD_createCCtx_advanced() :
      *  Create a ZSTD compression context using external alloc and free functions */
     ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     
    +/*! ZSTD_estimateCCtxSize() :
    + *  Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters.
    + *  Set streaming to 1 if the CCtx will be used for streaming (CStream).
    + *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    + *         Use ZSTD_estimateCDictSize() and add this value to estimate total CCtx size */
    +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    +
     /*! ZSTD_sizeofCCtx() :
      *  amount of used memory is variable, depending primarily on compression level */
     ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    @@ -493,6 +493,11 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, siz
     ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
                                                       ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
     
    +/*! ZSTD_estimateCDictSize() :
    + *  Estimate amount of memory that will be needed to create a dictionary with following arguments
    + *  Note : if dictionary is created "byReference", reduce this amount by dictSize */
    +ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    +
     /*! ZSTD_sizeof_CDict() :
      *  Gives the amount of memory used by a given ZSTD_sizeof_CDict */
     ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
    @@ -564,6 +569,11 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, siz
     ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
                                                       unsigned byReference, ZSTD_customMem customMem);
     
    +/*! ZSTD_estimateDDictSize() :
    + *  Estimate amount of memory that will be needed to create a dictionary for decompression.
    + *  Note : if dictionary is created "byReference", reduce this amount by dictSize */
    +ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize);
    +
     /*! ZSTD_sizeof_DDict() :
      *  Gives the amount of memory used by a given ZSTD_DDict */
     ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index a9dcf12e0..7ffcff26e 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -404,6 +404,12 @@ static int basicUnitTests(U32 seed, double compressibility)
                       if (r != CNBuffSize) goto _output_error);
             DISPLAYLEVEL(4, "OK \n");
     
    +        DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++);
    +        {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    +            size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize);
    +            DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize);
    +        }
    +
             DISPLAYLEVEL(4, "test%3i : compress with preprocessed dictionary : ", testNb++);
             {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
                 ZSTD_customMem customMem = { NULL, NULL, NULL };
    
    From 51652522a21b5897964019fc158dd86db1fafbd5 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 8 May 2017 17:52:46 -0700
    Subject: [PATCH 029/400] bumped version number
    
    ---
     lib/zstd.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 270943b30..c3a8a52a3 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -55,7 +55,7 @@ extern "C" {
     
     /*------   Version   ------*/
     #define ZSTD_VERSION_MAJOR    1
    -#define ZSTD_VERSION_MINOR    2
    +#define ZSTD_VERSION_MINOR    3
     #define ZSTD_VERSION_RELEASE  0
     
     #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
    
    From fa8dadb294cbda271c3c0b645a5adabd208d998b Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 8 May 2017 18:24:16 -0700
    Subject: [PATCH 030/400] separated ZSTD_estimateCStreamSize() from
     ZSTD_estimateCCtxSize()
    
    for clarity
    ---
     doc/zstd_manual.html         | 16 +++++++++-------
     lib/compress/zstd_compress.c | 22 ++++++++++++++--------
     lib/zstd.h                   | 12 +++++++-----
     tests/paramgrill.c           |  4 ++--
     4 files changed, 32 insertions(+), 22 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 9cfb67100..a5612c92c 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -1,10 +1,10 @@
     
     
     
    -zstd 1.2.0 Manual
    +zstd 1.3.0 Manual
     
     
    -

    zstd 1.2.0 Manual

    +

    zstd 1.3.0 Manual


    Contents

      @@ -376,11 +376,8 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

      Create a ZSTD compression context using external alloc and free functions


    -
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    -

    Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters. - Set streaming to 1 if the CCtx will be used for streaming (CStream). - Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict. - Use ZSTD_estimateCDictSize() and add this value to estimate total CCtx size +

    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    +

    Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters.


    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    @@ -519,6 +516,11 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     

    Advanced streaming functions

    
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    +/*! ZSTD_estimateCStreamSize() :
    + *  Provides amount of memory needed to allocate ZSTD_CStream with a set of compression parameters.
    + *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    + *         Use ZSTD_estimateCDictSize() to estimate its size, and add for total CStream size */
    +size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
     size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index c5687b21c..37590fca7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -251,7 +251,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
     }
     
     
    -size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming)
    +size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
     {
         size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
    @@ -272,12 +272,7 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned stream
         size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optBudget : 0;
         size_t const neededSpace = entropySpace + tableSpace + tokenSpace + optSpace;
     
    -    size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
    -    size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
    -    size_t const streamingBudget = inBuffSize + outBuffSize;
    -    size_t const streamingSize = streaming ? streamingBudget : 0;
    -
    -    return sizeof(ZSTD_CCtx) + neededSpace + streamingSize;
    +    return sizeof(ZSTD_CCtx) + neededSpace;
     }
     
     
    @@ -2989,7 +2984,7 @@ struct ZSTD_CDict_s {
     size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize)
     {
         cParams = ZSTD_adjustCParams(cParams, 0, dictSize);
    -    return sizeof(ZSTD_CDict) + dictSize + ZSTD_estimateCCtxSize(cParams, 0);
    +    return sizeof(ZSTD_CDict) + dictSize + ZSTD_estimateCCtxSize(cParams);
     }
     
     size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
    @@ -3158,6 +3153,17 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
         return ZSTD_freeCCtx(zcs);   /* same object */
     }
     
    +size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
    +{
    +    size_t const CCtxSize = ZSTD_estimateCCtxSize(cParams);
    +    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
    +    size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
    +    size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
    +    size_t const streamingSize = inBuffSize + outBuffSize;
    +
    +    return sizeof(ZSTD_CCtx) + CCtxSize + streamingSize;
    +}
    +
     
     /*======   Initialization   ======*/
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index c3a8a52a3..86f1c4405 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -463,11 +463,8 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
     ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     
     /*! ZSTD_estimateCCtxSize() :
    - *  Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters.
    - *  Set streaming to 1 if the CCtx will be used for streaming (CStream).
    - *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    - *         Use ZSTD_estimateCDictSize() and add this value to estimate total CCtx size */
    -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned streaming);
    + *  Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters. */
    +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
     
     /*! ZSTD_sizeofCCtx() :
      *  amount of used memory is variable, depending primarily on compression level */
    @@ -609,6 +606,11 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     
     /*=====   Advanced Streaming compression functions  =====*/
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    +/*! ZSTD_estimateCStreamSize() :
    + *  Provides amount of memory needed to allocate ZSTD_CStream with a set of compression parameters.
    + *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    + *         Use ZSTD_estimateCDictSize() to estimate its size, and add for total CStream size */
    +ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
     ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
    diff --git a/tests/paramgrill.c b/tests/paramgrill.c
    index 3cc916e01..1913b54d0 100644
    --- a/tests/paramgrill.c
    +++ b/tests/paramgrill.c
    @@ -388,8 +388,8 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_compressionParameters para
                 double W_DMemUsed_note = W_ratioNote * ( 40 + 9*cLevel) - log((double)W_DMemUsed);
                 double O_DMemUsed_note = O_ratioNote * ( 40 + 9*cLevel) - log((double)O_DMemUsed);
     
    -            size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize(params, 0/*streaming*/);
    -            size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize(winners[cLevel].params, 0);
    +            size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize(params);
    +            size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize(winners[cLevel].params);
                 double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed);
                 double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed);
     
    
    From 5a36c069e73d7c2297e44201c5eb7d758435208e Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 9 May 2017 15:11:30 -0700
    Subject: [PATCH 031/400] regroup memory usage function declarations
    
    in a single paragraph in zstd.h, for clarity
    ---
     doc/zstd_manual.html | 143 ++++++++++++++++++++---------------------
     lib/zstd.h           | 148 ++++++++++++++++++++-----------------------
     2 files changed, 136 insertions(+), 155 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index a5612c92c..c934da041 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -19,8 +19,8 @@
     
  • Streaming decompression - HowTo
  • START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
  • Advanced types
  • -
  • Compressed size functions
  • -
  • Decompressed size functions
  • +
  • Frame size functions
  • +
  • Context memory usage
  • Advanced compression functions
  • Advanced decompression functions
  • Advanced streaming functions
  • @@ -325,49 +325,81 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB typedef void (*ZSTD_freeFunction) (void* opaque, void* address); typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;

    -

    Compressed size functions

    
    +

    Frame size functions

    
     
     
    size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
     

    `src` should point to the start of a ZSTD encoded frame or skippable frame `srcSize` must be at least as large as the frame - @return : the compressed size of the frame pointed to by `src`, suitable to pass to - `ZSTD_decompress` or similar, or an error code if given invalid input. + @return : the compressed size of the frame pointed to by `src`, + suitable to pass to `ZSTD_decompress` or similar, + or an error code if given invalid input.


    -

    Decompressed size functions

    
    -
    -
    unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
    -

    `src` should point to the start of a ZSTD encoded frame - `srcSize` must be at least as large as the frame header. A value greater than or equal - to `ZSTD_frameHeaderSize_max` is guaranteed to be large enough in all cases. - @return : decompressed size of the frame pointed to be `src` if known, otherwise - - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined - - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) +

    #define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
    +#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
    +unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
    +

    `src` should point to the start of a ZSTD encoded frame. + `srcSize` must be at least as large as the frame header. + A value >= `ZSTD_frameHeaderSize_max` is guaranteed to be large enough. + @return : - decompressed size of the frame pointed to be `src` if known + - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small)


    unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
    -

    `src` should point the start of a series of ZSTD encoded and/or skippable frames - `srcSize` must be the _exact_ size of this series +

    `src` should point the start of a series of ZSTD encoded and/or skippable frames + `srcSize` must be the _exact_ size of this series (i.e. there should be a frame boundary exactly `srcSize` bytes after `src`) - @return : the decompressed size of all data in the contained frames, as a 64-bit value _if known_ - - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN - - if an error occurred: ZSTD_CONTENTSIZE_ERROR + @return : - decompressed size of all data in all successive frames + - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN + - if an error occurred: ZSTD_CONTENTSIZE_ERROR - note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. - When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. - In which case, it's necessary to use streaming mode to decompress data. - Optionally, application can still use ZSTD_decompress() while relying on implied limits. - (For example, data may be necessarily cut into blocks <= 16 KB). - note 2 : decompressed size is always present when compression is done with ZSTD_compress() - note 3 : decompressed size can be very large (64-bits value), - potentially larger than what local system can handle as a single memory segment. - In which case, it's necessary to use streaming mode to decompress data. - note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. - Always ensure result fits within application's authorized limits. - Each application can set its own limits. - note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to - read each contained frame header. This is efficient as most of the data is skipped, - however it does mean that all frame data must be present and valid. + note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. + When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. + In which case, it's necessary to use streaming mode to decompress data. + Optionally, application can still use ZSTD_decompress() while relying on implied limits. + (For example, data may be necessarily cut into blocks <= 16 KB). + note 2 : decompressed size is always present when compression is done with ZSTD_compress() + note 3 : decompressed size can be very large (64-bits value), + potentially larger than what local system can handle as a single memory segment. + In which case, it's necessary to use streaming mode to decompress data. + note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. + Always ensure result fits within application's authorized limits. + Each application can set its own limits. + note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to + read each contained frame header. This is efficient as most of the data is skipped, + however it does mean that all frame data must be present and valid. +


    + +

    Context memory usage

    
    +
    +
    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    +size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
    +size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
    +size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
    +size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
    +size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
    +

    These functions give the current memory usage of selected object. + Object memory usage can evolve if it's re-used multiple times. +


    + +
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    +size_t ZSTD_estimateDCtxSize(void);
    +

    These functions make it possible to estimate memory usage + of a future target object, before its allocation, + given a set of parameters, which vary depending on target object. + The objective is to guide decision before allocation. +


    + +
    size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    +

    Note : if streaming is init with function ZSTD_init?Stream_usingDict(), + an internal ?Dict will be created, which size is not estimated. + In this case, get additional size by using ZSTD_estimate?DictSize +


    + +
    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    +size_t ZSTD_estimateDDictSize(size_t dictSize);
    +

    Note : if dictionary is created "byReference", reduce estimation by dictSize


    Advanced compression functions

    
    @@ -376,14 +408,6 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     

    Create a ZSTD compression context using external alloc and free functions


    -
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    -

    Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters. -


    - -
    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    -

    amount of used memory is variable, depending primarily on compression level -


    -
    typedef enum {
         ZSTD_p_forceWindow,   /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
         ZSTD_p_forceRawDict   /* Force loading dictionary in "content-only" mode (no header analysis) */
    @@ -405,15 +429,6 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v
     

    Create a ZSTD_CDict using external alloc and free, and customized compression parameters


    -
    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    -

    Estimate amount of memory that will be needed to create a dictionary with following arguments - Note : if dictionary is created "byReference", reduce this amount by dictSize -


    - -
    size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
    -

    Gives the amount of memory used by a given ZSTD_sizeof_CDict -


    -
    ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
     

    @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. `estimatedSrcSize` value is optional, select 0 if not known @@ -457,18 +472,10 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v Note 3 : Skippable Frame Identifiers are considered valid.


    -
    size_t ZSTD_estimateDCtxSize(void);
    -

    Gives the potential amount of memory allocated to create a ZSTD_DCtx -


    -
    ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
     

    Create a ZSTD decompression context using external alloc and free functions


    -
    size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
    -

    Gives the amount of memory used by a given ZSTD_DCtx -


    -
    ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
     

    Create a digested dictionary, ready to start decompression operation without startup delay. Dictionary content is simply referenced, and therefore stays in dictBuffer. @@ -480,15 +487,6 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Create a ZSTD_DDict using external alloc and free, optionally by reference


    -
    size_t ZSTD_estimateDDictSize(size_t dictSize);
    -

    Estimate amount of memory that will be needed to create a dictionary for decompression. - Note : if dictionary is created "byReference", reduce this amount by dictSize -


    - -
    size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
    -

    Gives the amount of memory used by a given ZSTD_DDict -


    -
    unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
     

    Provides the dictID stored within dictionary. if @return == 0, the dictionary is not conformant with Zstandard specification. @@ -516,12 +514,6 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v

    Advanced streaming functions

    
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    -/*! ZSTD_estimateCStreamSize() :
    - *  Provides amount of memory needed to allocate ZSTD_CStream with a set of compression parameters.
    - *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    - *         Use ZSTD_estimateCDictSize() to estimate its size, and add for total CStream size */
    -size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    -size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
    @@ -540,11 +532,10 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict*
     
     

    Advanced Streaming decompression functions

    typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
    -size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
    +size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
     size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
    -size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
     

    Buffer-less and synchronous inner streaming functions

       This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 86f1c4405..690c851f1 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -350,9 +350,6 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output
     #define ZSTD_MAGICNUMBER            0xFD2FB528   /* >= v0.8.0 */
     #define ZSTD_MAGIC_SKIPPABLE_START  0x184D2A50U
     
    -#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
    -#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
    -
     #define ZSTD_WINDOWLOG_MAX_32  27
     #define ZSTD_WINDOWLOG_MAX_64  27
     #define ZSTD_WINDOWLOG_MAX    ((unsigned)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
    @@ -407,54 +404,88 @@ typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
     typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
     
     /***************************************
    -*  Compressed size functions
    +*  Frame size functions
     ***************************************/
     
     /*! ZSTD_findFrameCompressedSize() :
      *  `src` should point to the start of a ZSTD encoded frame or skippable frame
      *  `srcSize` must be at least as large as the frame
    - *  @return : the compressed size of the frame pointed to by `src`, suitable to pass to
    - *      `ZSTD_decompress` or similar, or an error code if given invalid input. */
    + *  @return : the compressed size of the frame pointed to by `src`,
    + *            suitable to pass to `ZSTD_decompress` or similar,
    + *            or an error code if given invalid input. */
     ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
     
    -/***************************************
    -*  Decompressed size functions
    -***************************************/
     /*! ZSTD_getFrameContentSize() :
    -*   `src` should point to the start of a ZSTD encoded frame
    -*   `srcSize` must be at least as large as the frame header.  A value greater than or equal
    -*       to `ZSTD_frameHeaderSize_max` is guaranteed to be large enough in all cases.
    -*   @return : decompressed size of the frame pointed to be `src` if known, otherwise
    -*             - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
    -*             - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
    + *  `src` should point to the start of a ZSTD encoded frame.
    + *  `srcSize` must be at least as large as the frame header.
    + *       A value >= `ZSTD_frameHeaderSize_max` is guaranteed to be large enough.
    + *  @return : - decompressed size of the frame pointed to be `src` if known
    + *            - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
    + *            - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
    +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
    +#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
     ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
     
     /*! ZSTD_findDecompressedSize() :
    -*   `src` should point the start of a series of ZSTD encoded and/or skippable frames
    -*   `srcSize` must be the _exact_ size of this series
    -*       (i.e. there should be a frame boundary exactly `srcSize` bytes after `src`)
    -*   @return : the decompressed size of all data in the contained frames, as a 64-bit value _if known_
    -*             - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN
    -*             - if an error occurred: ZSTD_CONTENTSIZE_ERROR
    -*
    -*    note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
    -*             When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
    -*             In which case, it's necessary to use streaming mode to decompress data.
    -*             Optionally, application can still use ZSTD_decompress() while relying on implied limits.
    -*             (For example, data may be necessarily cut into blocks <= 16 KB).
    -*    note 2 : decompressed size is always present when compression is done with ZSTD_compress()
    -*    note 3 : decompressed size can be very large (64-bits value),
    -*             potentially larger than what local system can handle as a single memory segment.
    -*             In which case, it's necessary to use streaming mode to decompress data.
    -*    note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
    -*             Always ensure result fits within application's authorized limits.
    -*             Each application can set its own limits.
    -*    note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to
    -*             read each contained frame header.  This is efficient as most of the data is skipped,
    -*             however it does mean that all frame data must be present and valid. */
    + *  `src` should point the start of a series of ZSTD encoded and/or skippable frames
    + *  `srcSize` must be the _exact_ size of this series
    + *       (i.e. there should be a frame boundary exactly `srcSize` bytes after `src`)
    + *  @return : - decompressed size of all data in all successive frames
    + *            - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN
    + *            - if an error occurred: ZSTD_CONTENTSIZE_ERROR
    + *
    + *   note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
    + *            When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
    + *            In which case, it's necessary to use streaming mode to decompress data.
    + *            Optionally, application can still use ZSTD_decompress() while relying on implied limits.
    + *            (For example, data may be necessarily cut into blocks <= 16 KB).
    + *   note 2 : decompressed size is always present when compression is done with ZSTD_compress()
    + *   note 3 : decompressed size can be very large (64-bits value),
    + *            potentially larger than what local system can handle as a single memory segment.
    + *            In which case, it's necessary to use streaming mode to decompress data.
    + *   note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
    + *            Always ensure result fits within application's authorized limits.
    + *            Each application can set its own limits.
    + *   note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to
    + *            read each contained frame header.  This is efficient as most of the data is skipped,
    + *            however it does mean that all frame data must be present and valid. */
     ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
     
     
    +/***************************************
    +*  Context memory usage
    +***************************************/
    +
    +/*! ZSTD_sizeof_*() :
    + *  These functions give the current memory usage of selected object.
    + *  Object memory usage can evolve if it's re-used multiple times. */
    +ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    +ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
    +ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
    +ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
    +ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
    +ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
    +
    +/*! ZSTD_estimate*() :
    + *  These functions make it possible to estimate memory usage
    + *  of a future target object, before its allocation,
    + *  given a set of parameters, which vary depending on target object.
    + *  The objective is to guide decision before allocation. */
    +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    +ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
    +
    +/*! ZSTD_estimate?StreamSize() :
    + *  Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
    + *         an internal ?Dict will be created, which size is not estimated.
    + *         In this case, get additional size by using ZSTD_estimate?DictSize */
    +ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    +
    +/*! ZSTD_estimate?DictSize() :
    + *  Note : if dictionary is created "byReference", reduce estimation by dictSize */
    +ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    +ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize);
    +
    +
     /***************************************
     *  Advanced compression functions
     ***************************************/
    @@ -462,14 +493,6 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t
      *  Create a ZSTD compression context using external alloc and free functions */
     ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     
    -/*! ZSTD_estimateCCtxSize() :
    - *  Provides amount of memory needed to allocate ZSTD_CCtx with a set of compression parameters. */
    -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    -
    -/*! ZSTD_sizeofCCtx() :
    - *  amount of used memory is variable, depending primarily on compression level */
    -ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    -
     typedef enum {
         ZSTD_p_forceWindow,   /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
         ZSTD_p_forceRawDict   /* Force loading dictionary in "content-only" mode (no header analysis) */
    @@ -490,15 +513,6 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, siz
     ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
                                                       ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
     
    -/*! ZSTD_estimateCDictSize() :
    - *  Estimate amount of memory that will be needed to create a dictionary with following arguments
    - *  Note : if dictionary is created "byReference", reduce this amount by dictSize */
    -ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    -
    -/*! ZSTD_sizeof_CDict() :
    - *  Gives the amount of memory used by a given ZSTD_sizeof_CDict */
    -ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
    -
     /*! ZSTD_getCParams() :
     *   @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
     *   `estimatedSrcSize` value is optional, select 0 if not known */
    @@ -543,18 +557,10 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
      *  Note 3 : Skippable Frame Identifiers are considered valid. */
     ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
     
    -/*! ZSTD_estimateDCtxSize() :
    - *  Gives the potential amount of memory allocated to create a ZSTD_DCtx */
    -ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
    -
     /*! ZSTD_createDCtx_advanced() :
      *  Create a ZSTD decompression context using external alloc and free functions */
     ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
     
    -/*! ZSTD_sizeof_DCtx() :
    - *  Gives the amount of memory used by a given ZSTD_DCtx */
    -ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
    -
     /*! ZSTD_createDDict_byReference() :
      *  Create a digested dictionary, ready to start decompression operation without startup delay.
      *  Dictionary content is simply referenced, and therefore stays in dictBuffer.
    @@ -566,15 +572,6 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, siz
     ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
                                                       unsigned byReference, ZSTD_customMem customMem);
     
    -/*! ZSTD_estimateDDictSize() :
    - *  Estimate amount of memory that will be needed to create a dictionary for decompression.
    - *  Note : if dictionary is created "byReference", reduce this amount by dictSize */
    -ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize);
    -
    -/*! ZSTD_sizeof_DDict() :
    - *  Gives the amount of memory used by a given ZSTD_DDict */
    -ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
    -
     /*! ZSTD_getDictID_fromDict() :
      *  Provides the dictID stored within dictionary.
      *  if @return == 0, the dictionary is not conformant with Zstandard specification.
    @@ -606,12 +603,6 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     
     /*=====   Advanced Streaming compression functions  =====*/
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    -/*! ZSTD_estimateCStreamSize() :
    - *  Provides amount of memory needed to allocate ZSTD_CStream with a set of compression parameters.
    - *  Special case : when using ZSTD_initCStream_usingDict(), init will transparently create an internal CDict.
    - *         Use ZSTD_estimateCDictSize() to estimate its size, and add for total CStream size */
    -ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    -ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);   /**< same as ZSTD_sizeof_CCtx */
     ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
     ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
    @@ -632,11 +623,10 @@ ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledg
     /*=====   Advanced Streaming decompression functions  =====*/
     typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
    -ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
    +ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
     ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
    -ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
     
     
     /*********************************************************************
    
    From 542c9dfcf8002fc6b5fe338abbb3316770833e40 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 9 May 2017 15:46:07 -0700
    Subject: [PATCH 032/400] changed name frameParams into frameHeader
    
    ZSTD_frameParams => ZSTD_frameHeader
    ZSTD_getFrameParams() -> ZSTD_getFrameHeader()
    
    The new naming is more distinctive from ZSTD_frameParameters,
    which is used during compression.
    
    ZSTD_frameHeader is clearer in its intention to described frame header content.
    It also implies we are decoding a ZSTD frame, hence we are at decoding stage.
    ---
     doc/zstd_manual.html             |  4 ++--
     lib/decompress/zstd_decompress.c | 27 +++++++++++++--------------
     lib/zstd.h                       |  4 ++--
     tests/fullbench.c                |  8 ++++----
     tests/fuzzer.c                   |  8 ++++----
     5 files changed, 25 insertions(+), 26 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index c934da041..d24a6b892 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -643,9 +643,9 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
         unsigned windowSize;
         unsigned dictID;
         unsigned checksumFlag;
    -} ZSTD_frameParams;
    +} ZSTD_frameHeader;
     

    -

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 88488b4b0..3c231a941 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -105,7 +105,7 @@ struct ZSTD_DCtx_s
         const void* vBase;            /* virtual start of previous segment if it was just before current one */
         const void* dictEnd;          /* end of previous segment */
         size_t expected;
    -    ZSTD_frameParams fParams;
    +    ZSTD_frameHeader fParams;
         blockType_e bType;   /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
         ZSTD_dStage stage;
         U32 litEntropy;
    @@ -219,12 +219,12 @@ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
     }
     
     
    -/** ZSTD_getFrameParams() :
    +/** ZSTD_getFrameHeader() :
     *   decode Frame Header, or require larger `srcSize`.
     *   @return : 0, `fparamsPtr` is correctly filled,
     *            >0, `srcSize` is too small, result is expected `srcSize`,
     *             or an error code, which can be tested using ZSTD_isError() */
    -size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
    +size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize)
     {
         const BYTE* ip = (const BYTE*)src;
     
    @@ -302,9 +302,8 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
             return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
         }
     #endif
    -    {
    -        ZSTD_frameParams fParams;
    -        if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0) return ZSTD_CONTENTSIZE_ERROR;
    +    {   ZSTD_frameHeader fParams;
    +        if (ZSTD_getFrameHeader(&fParams, src, srcSize) != 0) return ZSTD_CONTENTSIZE_ERROR;
             if (fParams.windowSize == 0) {
                 /* Either skippable or empty frame, size == 0 either way */
                 return 0;
    @@ -389,7 +388,7 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
     *   @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
     static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
     {
    -    size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
    +    size_t const result = ZSTD_getFrameHeader(&(dctx->fParams), src, headerSize);
         if (ZSTD_isError(result)) return result;  /* invalid header */
         if (result>0) return ERROR(srcSize_wrong);   /* headerSize too small */
         if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
    @@ -1364,13 +1363,13 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
             const BYTE* ip = (const BYTE*)src;
             const BYTE* const ipstart = ip;
             size_t remainingSize = srcSize;
    -        ZSTD_frameParams fParams;
    +        ZSTD_frameHeader fParams;
     
             size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize);
             if (ZSTD_isError(headerSize)) return headerSize;
     
             /* Frame Header */
    -        {   size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    +        {   size_t const ret = ZSTD_getFrameHeader(&fParams, ip, remainingSize);
                 if (ZSTD_isError(ret)) return ret;
                 if (ret > 0) return ERROR(srcSize_wrong);
             }
    @@ -2016,11 +2015,11 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
      *    Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
      *  - This is not a Zstandard frame.
      *  When identifying the exact failure cause, it's possible to use
    - *  ZSTD_getFrameParams(), which will provide a more precise error code. */
    + *  ZSTD_getFrameHeader(), which will provide a more precise error code. */
     unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
     {
    -    ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
    -    size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
    +    ZSTD_frameHeader zfp = { 0 , 0 , 0 , 0 };
    +    size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
         if (ZSTD_isError(hError)) return 0;
         return zfp.dictID;
     }
    @@ -2053,7 +2052,7 @@ struct ZSTD_DStream_s {
         ZSTD_DCtx* dctx;
         ZSTD_DDict* ddictLocal;
         const ZSTD_DDict* ddict;
    -    ZSTD_frameParams fParams;
    +    ZSTD_frameHeader fParams;
         ZSTD_dStreamStage stage;
         char*  inBuff;
         size_t inBuffSize;
    @@ -2217,7 +2216,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 /* fall-through */
     
             case zdss_loadHeader :
    -            {   size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    +            {   size_t const hSize = ZSTD_getFrameHeader(&zds->fParams, zds->headerBuffer, zds->lhSize);
                     if (ZSTD_isError(hSize))
     #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
                     {   U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 690c851f1..ddcaaf8bd 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -746,10 +746,10 @@ typedef struct {
         unsigned windowSize;
         unsigned dictID;
         unsigned checksumFlag;
    -} ZSTD_frameParams;
    +} ZSTD_frameHeader;
     
     /*=====   Buffer-less streaming decompression functions  =====*/
    -ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     ZSTDLIB_API void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    diff --git a/tests/fullbench.c b/tests/fullbench.c
    index 38cf22fa7..13323aec1 100644
    --- a/tests/fullbench.c
    +++ b/tests/fullbench.c
    @@ -297,10 +297,10 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
         case 31:  /* ZSTD_decodeLiteralsBlock */
             if (g_zdc==NULL) g_zdc = ZSTD_createDCtx();
             {   blockProperties_t bp;
    -            ZSTD_frameParams zfp;
    +            ZSTD_frameHeader zfp;
                 size_t frameHeaderSize, skippedSize;
                 g_cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1);
    -            frameHeaderSize = ZSTD_getFrameParams(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
    +            frameHeaderSize = ZSTD_getFrameHeader(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
                 if (frameHeaderSize==0) frameHeaderSize = ZSTD_frameHeaderSize_min;
                 ZSTD_getcBlockSize(dstBuff+frameHeaderSize, dstBuffSize, &bp);  /* Get 1st block type */
                 if (bp.blockType != bt_compressed) {
    @@ -315,13 +315,13 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb)
         case 32:   /* ZSTD_decodeSeqHeaders */
             if (g_zdc==NULL) g_zdc = ZSTD_createDCtx();
             {   blockProperties_t bp;
    -            ZSTD_frameParams zfp;
    +            ZSTD_frameHeader zfp;
                 const BYTE* ip = dstBuff;
                 const BYTE* iend;
                 size_t frameHeaderSize, cBlockSize;
                 ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1);   /* it would be better to use direct block compression here */
                 g_cSize = ZSTD_compress(dstBuff, dstBuffSize, src, srcSize, 1);
    -            frameHeaderSize = ZSTD_getFrameParams(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
    +            frameHeaderSize = ZSTD_getFrameHeader(&zfp, dstBuff, ZSTD_frameHeaderSize_min);
                 if (frameHeaderSize==0) frameHeaderSize = ZSTD_frameHeaderSize_min;
                 ip += frameHeaderSize;   /* Skip frame Header */
                 cBlockSize = ZSTD_getcBlockSize(ip, dstBuffSize, &bp);   /* Get 1st block type */
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 7ffcff26e..4b9cd97a5 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -339,8 +339,8 @@ static int basicUnitTests(U32 seed, double compressibility)
                 CHECKPLUS(r, ZSTD_compressEnd(ctxDuplicated, compressedBuffer, ZSTD_compressBound(testSize),
                                               (const char*)CNBuffer + dictSize, testSize),
                           cSize = r);
    -            {   ZSTD_frameParams fp;
    -                if (ZSTD_getFrameParams(&fp, compressedBuffer, cSize)) goto _output_error;
    +            {   ZSTD_frameHeader fp;
    +                if (ZSTD_getFrameHeader(&fp, compressedBuffer, cSize)) goto _output_error;
                     if ((fp.frameContentSize != testSize) && (fp.frameContentSize != 0)) goto _output_error;
             }   }
             DISPLAYLEVEL(4, "OK \n");
    @@ -862,8 +862,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
             }
     
             /* frame header decompression test */
    -        {   ZSTD_frameParams dParams;
    -            size_t const check = ZSTD_getFrameParams(&dParams, cBuffer, cSize);
    +        {   ZSTD_frameHeader dParams;
    +            size_t const check = ZSTD_getFrameHeader(&dParams, cBuffer, cSize);
                 CHECK(ZSTD_isError(check), "Frame Parameters extraction failed");
                 CHECK(dParams.frameContentSize != sampleSize, "Frame content size incorrect");
             }
    
    From f16f4497ca121f8a0ec82e2af35a4a00d82acf13 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 9 May 2017 16:18:17 -0700
    Subject: [PATCH 033/400] added ZSTD_estimateDStreamSize()
    
    ---
     doc/zstd_manual.html             | 15 ++++++++-------
     lib/decompress/zstd_decompress.c | 30 ++++++++++++++++++++----------
     lib/zstd.h                       | 15 ++++++++-------
     tests/zstreamtest.c              | 15 ++++++++++++++-
     4 files changed, 50 insertions(+), 25 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index d24a6b892..9cfb1b68b 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -321,6 +321,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
         ZSTD_frameParameters fParams;
     } ZSTD_parameters;
     

    +
    typedef struct {
    +    unsigned long long frameContentSize;
    +    unsigned windowSize;
    +    unsigned dictID;
    +    unsigned checksumFlag;
    +} ZSTD_frameHeader;
    +

    Custom memory allocation functions

    typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
     typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
     typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
    @@ -392,6 +399,7 @@ size_t ZSTD_estimateDCtxSize(void);
     


    size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    +size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
     

    Note : if streaming is init with function ZSTD_init?Stream_usingDict(), an internal ?Dict will be created, which size is not estimated. In this case, get additional size by using ZSTD_estimate?DictSize @@ -638,13 +646,6 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo It also returns Frame Size as fparamsPtr->frameContentSize.

    -
    typedef struct {
    -    unsigned long long frameContentSize;
    -    unsigned windowSize;
    -    unsigned dictID;
    -    unsigned checksumFlag;
    -} ZSTD_frameHeader;
    -

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 3c231a941..267aa94d0 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -221,20 +221,21 @@ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
     
     /** ZSTD_getFrameHeader() :
     *   decode Frame Header, or require larger `srcSize`.
    -*   @return : 0, `fparamsPtr` is correctly filled,
    +*   @return : 0, `fhiPtr` is correctly filled,
     *            >0, `srcSize` is too small, result is expected `srcSize`,
     *             or an error code, which can be tested using ZSTD_isError() */
    -size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize)
    +size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fhiPtr, const void* src, size_t srcSize)
     {
         const BYTE* ip = (const BYTE*)src;
    -
         if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
    +
         if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
             if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    +            /* skippable frame */
                 if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
    -            memset(fparamsPtr, 0, sizeof(*fparamsPtr));
    -            fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    -            fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
    +            memset(fhiPtr, 0, sizeof(*fhiPtr));
    +            fhiPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    +            fhiPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
                 return 0;
             }
             return ERROR(prefix_unknown);
    @@ -281,10 +282,10 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t
             }
             if (!windowSize) windowSize = (U32)frameContentSize;
             if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
    -        fparamsPtr->frameContentSize = frameContentSize;
    -        fparamsPtr->windowSize = windowSize;
    -        fparamsPtr->dictID = dictID;
    -        fparamsPtr->checksumFlag = checksumFlag;
    +        fhiPtr->frameContentSize = frameContentSize;
    +        fhiPtr->windowSize = windowSize;
    +        fhiPtr->dictID = dictID;
    +        fhiPtr->checksumFlag = checksumFlag;
         }
         return 0;
     }
    @@ -2182,6 +2183,15 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
                + zds->inBuffSize + zds->outBuffSize;
     }
     
    +size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader)
    +{
    +    size_t const windowSize = fHeader.windowSize;
    +    size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +    size_t const inBuffSize = blockSize;  /* no block can be larger */
    +    size_t const outBuffSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
    +    return sizeof(ZSTD_DStream) + ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
    +}
    +
     
     /* *****   Decompression   ***** */
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index ddcaaf8bd..08754cb2a 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -398,6 +398,13 @@ typedef struct {
         ZSTD_frameParameters fParams;
     } ZSTD_parameters;
     
    +typedef struct {
    +    unsigned long long frameContentSize;
    +    unsigned windowSize;
    +    unsigned dictID;
    +    unsigned checksumFlag;
    +} ZSTD_frameHeader;
    +
     /*= Custom memory allocation functions */
     typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
     typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
    @@ -479,6 +486,7 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
      *         an internal ?Dict will be created, which size is not estimated.
      *         In this case, get additional size by using ZSTD_estimate?DictSize */
     ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    +ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
     
     /*! ZSTD_estimate?DictSize() :
      *  Note : if dictionary is created "byReference", reduce estimation by dictSize */
    @@ -741,13 +749,6 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
       It also returns Frame Size as fparamsPtr->frameContentSize.
     */
     
    -typedef struct {
    -    unsigned long long frameContentSize;
    -    unsigned windowSize;
    -    unsigned dictID;
    -    unsigned checksumFlag;
    -} ZSTD_frameHeader;
    -
     /*=====   Buffer-less streaming decompression functions  =====*/
     ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 6c210f2ff..6ce309c55 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -262,7 +262,20 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         }   }
         DISPLAYLEVEL(3, "OK \n");
     
    -    DISPLAYLEVEL(3, "test%3i : check DStream size : ", testNb++);
    +    /* context size functions */
    +    DISPLAYLEVEL(3, "test%3i : estimate DStream size : ", testNb++);
    +    {   ZSTD_frameHeader fhi;
    +        const void* cStart = (char*)compressedBuffer + (skippableFrameSize + 8);
    +        size_t const gfhError = ZSTD_getFrameHeader(&fhi, cStart, cSize);
    +        if (gfhError!=0) goto _output_error;
    +        DISPLAYLEVEL(5, " (windowSize : %u) ", fhi.windowSize);
    +        {   size_t const s = ZSTD_estimateDStreamSize(fhi)
    +                           + ZSTD_estimateDDictSize(128 KB);  /* uses ZSTD_initDStream_usingDict() */
    +            if (ZSTD_isError(s)) goto _output_error;
    +            DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
    +    }   }
    +
    +    DISPLAYLEVEL(3, "test%3i : check actual DStream size : ", testNb++);
         { size_t const s = ZSTD_sizeof_DStream(zd);
           if (ZSTD_isError(s)) goto _output_error;
           DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
    
    From 461a9cc7c62f9d6fc5bcb2725601e2e073a0f392 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 9 May 2017 16:53:09 -0700
    Subject: [PATCH 034/400] fixed symbols test
    
    ---
     tests/symbols.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/symbols.c b/tests/symbols.c
    index 7dacfc058..ade3aa02c 100644
    --- a/tests/symbols.c
    +++ b/tests/symbols.c
    @@ -88,7 +88,7 @@ static const void *symbols[] = {
       &ZSTD_copyCCtx,
       &ZSTD_compressContinue,
       &ZSTD_compressEnd,
    -  &ZSTD_getFrameParams,
    +  &ZSTD_getFrameHeader,
       &ZSTD_decompressBegin,
       &ZSTD_decompressBegin_usingDict,
       &ZSTD_copyDCtx,
    
    From 6fb2f241322ec6f66ce53132f4226bed20f5f1bc Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 10 May 2017 11:06:06 -0700
    Subject: [PATCH 035/400] shortened ZSTD_createCStream_Advanced()
    
    https://github.com/facebook/zstd/pull/689#discussion_r115637613
    ---
     lib/compress/zstd_compress.c | 12 ++----------
     1 file changed, 2 insertions(+), 10 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 37590fca7..b1d799cdc 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3136,16 +3136,8 @@ ZSTD_CStream* ZSTD_createCStream(void)
     
     ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
     {
    -    ZSTD_CStream* zcs;
    -
    -    if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree) return NULL;
    -
    -    zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
    -    if (zcs==NULL) return NULL;
    -    memset(zcs, 0, sizeof(ZSTD_CStream));
    -    memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
    -    return zcs;
    +    /* CStream and CCtx are now same object */
    +    return ZSTD_createCCtx_advanced(customMem);
     }
     
     size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
    
    From 669346fe8b015c26586c8e3ca75751fffd161bb0 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 10 May 2017 11:08:00 -0700
    Subject: [PATCH 036/400] fixed ZSTD_estimateCStreamSize()
    
    https://github.com/facebook/zstd/pull/689#discussion_r115637721
    ---
     lib/compress/zstd_compress.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index b1d799cdc..848472ec4 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3153,7 +3153,7 @@ size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
         size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
         size_t const streamingSize = inBuffSize + outBuffSize;
     
    -    return sizeof(ZSTD_CCtx) + CCtxSize + streamingSize;
    +    return CCtxSize + streamingSize;
     }
     
     
    
    From cef02d9317743fba04673fa2da038670cd07f8b6 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 10 May 2017 11:14:08 -0700
    Subject: [PATCH 037/400] changed variable name, for clarity
    
    fhiPtr -> zfhPtr
    https://github.com/facebook/zstd/pull/689#discussion_r115638676
    ---
     doc/zstd_manual.html             |  2 +-
     lib/decompress/zstd_decompress.c | 18 +++++++++---------
     lib/zstd.h                       |  2 +-
     3 files changed, 11 insertions(+), 11 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 9cfb1b68b..cb376741f 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -646,7 +646,7 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
       It also returns Frame Size as fparamsPtr->frameContentSize.
     
    -

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 267aa94d0..379842b57 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -221,10 +221,10 @@ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
     
     /** ZSTD_getFrameHeader() :
     *   decode Frame Header, or require larger `srcSize`.
    -*   @return : 0, `fhiPtr` is correctly filled,
    +*   @return : 0, `zfhPtr` is correctly filled,
     *            >0, `srcSize` is too small, result is expected `srcSize`,
     *             or an error code, which can be tested using ZSTD_isError() */
    -size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fhiPtr, const void* src, size_t srcSize)
    +size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
     {
         const BYTE* ip = (const BYTE*)src;
         if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
    @@ -233,9 +233,9 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fhiPtr, const void* src, size_t src
             if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
                 /* skippable frame */
                 if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
    -            memset(fhiPtr, 0, sizeof(*fhiPtr));
    -            fhiPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    -            fhiPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
    +            memset(zfhPtr, 0, sizeof(*zfhPtr));
    +            zfhPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    +            zfhPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
                 return 0;
             }
             return ERROR(prefix_unknown);
    @@ -282,10 +282,10 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fhiPtr, const void* src, size_t src
             }
             if (!windowSize) windowSize = (U32)frameContentSize;
             if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
    -        fhiPtr->frameContentSize = frameContentSize;
    -        fhiPtr->windowSize = windowSize;
    -        fhiPtr->dictID = dictID;
    -        fhiPtr->checksumFlag = checksumFlag;
    +        zfhPtr->frameContentSize = frameContentSize;
    +        zfhPtr->windowSize = windowSize;
    +        zfhPtr->dictID = dictID;
    +        zfhPtr->checksumFlag = checksumFlag;
         }
         return 0;
     }
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 08754cb2a..c956860ab 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -750,7 +750,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
     */
     
     /*=====   Buffer-less streaming decompression functions  =====*/
    -ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* fparamsPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     ZSTDLIB_API void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    
    From 30ab64e21d09f8b493c2ae7968c7139b5d197e23 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 10 May 2017 11:30:19 -0700
    Subject: [PATCH 038/400] added test for ZSTD_estimateCStreamSize()
    
    ---
     tests/zstreamtest.c | 26 ++++++++++++++++++--------
     1 file changed, 18 insertions(+), 8 deletions(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 6ce309c55..5c166bfb8 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -163,6 +163,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         ZSTD_inBuffer  inBuff, inBuff2;
         ZSTD_outBuffer outBuff;
         buffer_t dictionary = g_nullBuffer;
    +    size_t const dictSize = 128 KB;
         unsigned dictID = 0;
     
         /* Create compressible test buffer */
    @@ -188,7 +189,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* Basic compression test */
         DISPLAYLEVEL(3, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    -    ZSTD_initCStream_usingDict(zc, CNBuffer, 128 KB, 1);
    +    ZSTD_initCStream_usingDict(zc, CNBuffer, dictSize, 1);
         outBuff.dst = (char*)(compressedBuffer)+cSize;
         outBuff.size = compressedBufferSize;
         outBuff.pos = 0;
    @@ -203,7 +204,16 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         cSize += outBuff.pos;
         DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/COMPRESSIBLE_NOISE_LENGTH*100);
     
    -    DISPLAYLEVEL(3, "test%3i : check CStream size : ", testNb++);
    +    /* context size functions */
    +    DISPLAYLEVEL(3, "test%3i : estimate CStream size : ", testNb++);
    +    {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize);
    +        size_t const s = ZSTD_estimateCStreamSize(cParams)
    +                       + ZSTD_estimateCDictSize(cParams, dictSize);  /* uses ZSTD_initCStream_usingDict() */
    +            if (ZSTD_isError(s)) goto _output_error;
    +            DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
    +    }
    +
    +    DISPLAYLEVEL(3, "test%3i : check actual CStream size : ", testNb++);
         { size_t const s = ZSTD_sizeof_CStream(zc);
           if (ZSTD_isError(s)) goto _output_error;
           DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
    @@ -221,7 +231,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* skippable frame test */
         DISPLAYLEVEL(3, "test%3i : decompress skippable frame : ", testNb++);
    -    ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
    +    ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
         inBuff.src = compressedBuffer;
         inBuff.size = cSize;
         inBuff.pos = 0;
    @@ -236,7 +246,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         /* Basic decompression test */
         inBuff2 = inBuff;
         DISPLAYLEVEL(3, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    -    ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
    +    ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
         { size_t const r = ZSTD_setDStreamParameter(zd, DStream_p_maxWindowSize, 1000000000);  /* large limit */
           if (ZSTD_isError(r)) goto _output_error; }
         { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff);
    @@ -270,7 +280,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
             if (gfhError!=0) goto _output_error;
             DISPLAYLEVEL(5, " (windowSize : %u) ", fhi.windowSize);
             {   size_t const s = ZSTD_estimateDStreamSize(fhi)
    -                           + ZSTD_estimateDDictSize(128 KB);  /* uses ZSTD_initDStream_usingDict() */
    +                           + ZSTD_estimateDDictSize(dictSize);  /* uses ZSTD_initDStream_usingDict() */
                 if (ZSTD_isError(s)) goto _output_error;
                 DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
         }   }
    @@ -285,7 +295,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         DISPLAYLEVEL(3, "test%3i : decompress byte-by-byte : ", testNb++);
         {   /* skippable frame */
             size_t r = 1;
    -        ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
    +        ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
             inBuff.src = compressedBuffer;
             outBuff.dst = decodedBuffer;
             inBuff.pos = 0;
    @@ -297,7 +307,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
                 if (ZSTD_isError(r)) goto _output_error;
             }
             /* normal frame */
    -        ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
    +        ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
             r=1;
             while (r) {
                 inBuff.size = inBuff.pos + 1;
    @@ -456,7 +466,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* Memory restriction */
         DISPLAYLEVEL(3, "test%3i : maxWindowSize < frame requirement : ", testNb++);
    -    ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB);
    +    ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
         { size_t const r = ZSTD_setDStreamParameter(zd, DStream_p_maxWindowSize, 1000);  /* too small limit */
           if (ZSTD_isError(r)) goto _output_error; }
         inBuff.src = compressedBuffer;
    
    From a99ece9e798fbdba086701bc0037494ad26d4578 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 10 May 2017 16:51:18 -0700
    Subject: [PATCH 039/400] Update zstd.1.md to use btultra
    
    ---
     programs/zstd.1    | 4 ++--
     programs/zstd.1.md | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/programs/zstd.1 b/programs/zstd.1
    index 0150b05df..427146795 100644
    --- a/programs/zstd.1
    +++ b/programs/zstd.1
    @@ -252,7 +252,7 @@ set process priority to real\-time
     Specify a strategy used by a match finder\.
     .
     .IP
    -There are 8 strategies numbered from 0 to 7, from faster to stronger: 0=ZSTD_fast, 1=ZSTD_dfast, 2=ZSTD_greedy, 3=ZSTD_lazy, 4=ZSTD_lazy2, 5=ZSTD_btlazy2, 6=ZSTD_btopt, 7=ZSTD_btopt2\.
    +There are 8 strategies numbered from 0 to 7, from faster to stronger: 0=ZSTD_fast, 1=ZSTD_dfast, 2=ZSTD_greedy, 3=ZSTD_lazy, 4=ZSTD_lazy2, 5=ZSTD_btlazy2, 6=ZSTD_btopt, 7=ZSTD_btultra\.
     .
     .TP
     \fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR
    @@ -306,7 +306,7 @@ The minimum \fIslen\fR is 3 and the maximum is 7\.
     Specify the minimum match length that causes a match finder to stop searching for better matches\.
     .
     .IP
    -A larger minimum match length usually improves compression ratio but decreases compression speed\. This option is only used with strategies ZSTD_btopt and ZSTD_btopt2\.
    +A larger minimum match length usually improves compression ratio but decreases compression speed\. This option is only used with strategies ZSTD_btopt and ZSTD_btultra\.
     .
     .IP
     The minimum \fItlen\fR is 4 and the maximum is 999\.
    diff --git a/programs/zstd.1.md b/programs/zstd.1.md
    index 118c9f2f8..2f5a6747e 100644
    --- a/programs/zstd.1.md
    +++ b/programs/zstd.1.md
    @@ -252,7 +252,7 @@ The list of available _options_:
     
         There are 8 strategies numbered from 0 to 7, from faster to stronger:
         0=ZSTD\_fast, 1=ZSTD\_dfast, 2=ZSTD\_greedy, 3=ZSTD\_lazy,
    -    4=ZSTD\_lazy2, 5=ZSTD\_btlazy2, 6=ZSTD\_btopt, 7=ZSTD\_btopt2.
    +    4=ZSTD\_lazy2, 5=ZSTD\_btlazy2, 6=ZSTD\_btopt, 7=ZSTD\_btultra.
     
     - `windowLog`=_wlog_, `wlog`=_wlog_:
         Specify the maximum number of bits for a match distance.
    @@ -304,7 +304,7 @@ The list of available _options_:
     
         A larger minimum match length usually improves compression ratio but
         decreases compression speed.
    -    This option is only used with strategies ZSTD_btopt and ZSTD_btopt2.
    +    This option is only used with strategies ZSTD_btopt and ZSTD_btultra.
     
         The minimum _tlen_ is 4 and the maximum is 999.
     
    
    From 374f868354b7a16db6da2a05abb34ea33bc8eda6 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 10 May 2017 17:48:42 -0700
    Subject: [PATCH 040/400] Update whitespace
    
    ---
     lib/compress/zstd_compress.c | 24 ++++++++++++------------
     1 file changed, 12 insertions(+), 12 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 9499a76e2..cb15a5a2e 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3498,9 +3498,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
         { 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
         { 23, 22, 22,  5,  4, 32, ZSTD_btopt   },  /* level 18 */
         { 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
    -    { 25, 25, 23,  7,  3, 64, ZSTD_btultra  },  /* level 20 */
    -    { 26, 26, 23,  7,  3,256, ZSTD_btultra  },  /* level 21 */
    -    { 27, 27, 25,  9,  3,512, ZSTD_btultra  },  /* level 22 */
    +    { 25, 25, 23,  7,  3, 64, ZSTD_btultra },  /* level 20 */
    +    { 26, 26, 23,  7,  3,256, ZSTD_btultra },  /* level 21 */
    +    { 27, 27, 25,  9,  3,512, ZSTD_btultra },  /* level 22 */
     },
     {   /* for srcSize <= 256 KB */
         /* W,  C,  H,  S,  L,  T, strat */
    @@ -3524,9 +3524,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
         { 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
         { 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
         { 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
    -    { 18, 19, 18, 11,  3,512, ZSTD_btultra  },  /* level 20.*/
    -    { 18, 19, 18, 12,  3,512, ZSTD_btultra  },  /* level 21.*/
    -    { 18, 19, 18, 13,  3,512, ZSTD_btultra  },  /* level 22.*/
    +    { 18, 19, 18, 11,  3,512, ZSTD_btultra },  /* level 20.*/
    +    { 18, 19, 18, 12,  3,512, ZSTD_btultra },  /* level 21.*/
    +    { 18, 19, 18, 13,  3,512, ZSTD_btultra },  /* level 22.*/
     },
     {   /* for srcSize <= 128 KB */
         /* W,  C,  H,  S,  L,  T, strat */
    @@ -3550,9 +3550,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
         { 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
         { 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
         { 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
    -    { 17, 18, 17,  9,  3,256, ZSTD_btultra  },  /* level 20.*/
    -    { 17, 18, 17, 10,  3,256, ZSTD_btultra  },  /* level 21.*/
    -    { 17, 18, 17, 11,  3,512, ZSTD_btultra  },  /* level 22.*/
    +    { 17, 18, 17,  9,  3,256, ZSTD_btultra },  /* level 20.*/
    +    { 17, 18, 17, 10,  3,256, ZSTD_btultra },  /* level 21.*/
    +    { 17, 18, 17, 11,  3,512, ZSTD_btultra },  /* level 22.*/
     },
     {   /* for srcSize <= 16 KB */
         /* W,  C,  H,  S,  L,  T, strat */
    @@ -3576,9 +3576,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
         { 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
         { 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
         { 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
    -    { 14, 15, 15,  8,  3,256, ZSTD_btultra  },  /* level 20.*/
    -    { 14, 15, 15,  9,  3,256, ZSTD_btultra  },  /* level 21.*/
    -    { 14, 15, 15, 10,  3,256, ZSTD_btultra  },  /* level 22.*/
    +    { 14, 15, 15,  8,  3,256, ZSTD_btultra },  /* level 20.*/
    +    { 14, 15, 15,  9,  3,256, ZSTD_btultra },  /* level 21.*/
    +    { 14, 15, 15, 10,  3,256, ZSTD_btultra },  /* level 22.*/
     },
     };
     
    
    From 05286fdd5af5dc26f54c4cc778b6eff21bd094a7 Mon Sep 17 00:00:00 2001
    From: Jos Collin 
    Date: Tue, 9 May 2017 08:36:05 +0530
    Subject: [PATCH 041/400] lib/common: warning: this statement may fall through
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    The following warning appears during the build. Fixed the review comments too.
    
    zstd/lib/common/bitstream.h: In function ‘BIT_initDStream’:
    zstd/lib/common/bitstream.h:277:33: warning: this statement may fall through [-Wimplicit-fallthrough=]
          case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) <<
          (sizeof(bitD->bitContainer)*8 - 16);
    
    Signed-off-by: Jos Collin 
    ---
     lib/common/bitstream.h | 27 +++++++++++++++++++--------
     1 file changed, 19 insertions(+), 8 deletions(-)
    
    diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h
    index ca42850df..74eb4b635 100644
    --- a/lib/common/bitstream.h
    +++ b/lib/common/bitstream.h
    @@ -39,7 +39,6 @@
     extern "C" {
     #endif
     
    -
     /*
     *  This API consists of small unitary functions, which must be inlined for best performance.
     *  Since link-time-optimization is not available for all compilers,
    @@ -303,13 +302,25 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
             bitD->bitContainer = *(const BYTE*)(bitD->start);
             switch(srcSize)
             {
    -            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    -            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    -            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    -            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    -            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    -            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    -            default:;
    +	    case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    +	            /* fall-through */
    +
    +	    case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    +	            /* fall-through */
    +	
    +	    case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    +	            /* fall-through */
    +	
    +	    case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    +	            /* fall-through */
    +	
    +	    case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    +	            /* fall-through */
    +	
    +	    case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    +	            /* fall-through */
    +	
    +            default: break;
             }
             { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
               bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
    
    From 7cd7a7564baaebdb8f4079e63ec62cd3841dc1d2 Mon Sep 17 00:00:00 2001
    From: Jos Collin 
    Date: Thu, 11 May 2017 13:17:20 +0530
    Subject: [PATCH 042/400] lib/compress: warning: this statement may fall
     through
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    The following warning appears during build.
    
    ../lib/compress/huf_compress.c: In function ‘HUF_compress1X_usingCTable’:
    ../lib/compress/huf_compress.c:444:8: warning: this statement may fall through [-Wimplicit-fallthrough=]
         if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
            ^
    ../lib/compress/huf_compress.c:465:18: note: in expansion of macro ‘HUF_FLUSHBITS_2’
                      HUF_FLUSHBITS_2(&bitC);
                      ^~~~~~~~~~~~~~~
    ../lib/compress/huf_compress.c:466:9: note: here
             case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
    
    ../lib/compress/zstd_compress.c: In function ‘ZSTD_compressStream_generic’:
    ../lib/compress/zstd_compress.c:3366:34: warning: this statement may fall through [-Wimplicit-fallthrough=]
                     zcs->streamStage = zcss_flush;   /* pass-through to flush stage */
                     ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
    ../lib/compress/zstd_compress.c:3369:9: note: here
             case zcss_flush:
    
    Signed-off-by: Jos Collin 
    ---
     lib/compress/huf_compress.c  | 7 +++++--
     lib/compress/zstd_compress.c | 2 +-
     2 files changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c
    index fe11aafb8..7248c2513 100644
    --- a/lib/compress/huf_compress.c
    +++ b/lib/compress/huf_compress.c
    @@ -463,12 +463,15 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si
         {
             case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
                      HUF_FLUSHBITS_2(&bitC);
    +		 /* fall-through */
             case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
                      HUF_FLUSHBITS_1(&bitC);
    +		 /* fall-through */
             case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
                      HUF_FLUSHBITS(&bitC);
    -        case 0 :
    -        default: ;
    +		 /* fall-through */
    +        case 0 : /* fall-through */
    +        default: break;
         }
     
         for (; n>0; n-=4) {  /* note : n&3==0 at this stage */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index cb15a5a2e..edf4609f7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3365,7 +3365,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                     zcs->outBuffFlushedSize = 0;
                     zcs->streamStage = zcss_flush;   /* pass-through to flush stage */
                 }
    -
    +	    /* fall-through */
             case zcss_flush:
                 DEBUGLOG(5, "flush stage \n");
                 {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    
    From 280510f2d5740c854f0da6ab267d6bbe56aba866 Mon Sep 17 00:00:00 2001
    From: Jos Collin 
    Date: Thu, 11 May 2017 14:27:34 +0530
    Subject: [PATCH 043/400] lib/legacy: warning: this statement may fall through
    
    The following warning appears during build at sevaral places.
    
    ../lib/legacy/zstd_v04.c:819:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
    
    ../lib/legacy/zstd_v05.c:821:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
    
    ../lib/legacy/zstd_v06.c:913:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    
    ../lib/legacy/zstd_v07.c:583:40: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) <<
                 (sizeof(bitD->bitContainer)*8 - 16);
    
    Signed-off-by: Jos Collin 
    ---
     lib/legacy/zstd_v04.c | 21 +++++++++++----------
     lib/legacy/zstd_v05.c | 26 ++++++++++++++------------
     lib/legacy/zstd_v06.c | 25 +++++++++++++------------
     lib/legacy/zstd_v07.c | 25 +++++++++++++------------
     4 files changed, 51 insertions(+), 46 deletions(-)
    
    diff --git a/lib/legacy/zstd_v04.c b/lib/legacy/zstd_v04.c
    index 1a29da92d..8b8e23cb0 100644
    --- a/lib/legacy/zstd_v04.c
    +++ b/lib/legacy/zstd_v04.c
    @@ -816,13 +816,13 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
             bitD->bitContainer = *(const BYTE*)(bitD->start);
             switch(srcSize)
             {
    -            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
    -            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);
    -            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);
    -            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24;
    -            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16;
    -            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) <<  8;
    -            default:;
    +            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);/* fall-through */
    +            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);/* fall-through */
    +            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);/* fall-through */
    +            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; /* fall-through */
    +            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; /* fall-through */
    +            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) <<  8; /* fall-through */
    +            default: break;
             }
             contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
             if (contain32 == 0) return ERROR(GENERIC);   /* endMark not present */
    @@ -3665,7 +3665,7 @@ static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDs
                         break;
                     }
                     zbc->stage = ZBUFFds_read;
    -
    +		/* fall-through */
             case ZBUFFds_read:
                 {
                     size_t neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
    @@ -3691,7 +3691,7 @@ static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDs
                     if (ip==iend) { notDone = 0; break; }   /* no more input */
                     zbc->stage = ZBUFFds_load;
                 }
    -
    +	    /* fall-through */
             case ZBUFFds_load:
                 {
                     size_t neededInSize = ZSTD_nextSrcSizeToDecompress(zbc->zc);
    @@ -3711,9 +3711,10 @@ static size_t ZBUFF_decompressContinue(ZBUFF_DCtx* zbc, void* dst, size_t* maxDs
                         if (!decodedSize) { zbc->stage = ZBUFFds_read; break; }   /* this was just a header */
                         zbc->outEnd = zbc->outStart +  decodedSize;
                         zbc->stage = ZBUFFds_flush;
    -                    // break; /* ZBUFFds_flush follows */
    +                    /* ZBUFFds_flush follows */
                     }
                 }
    +	    /* fall-through */
             case ZBUFFds_flush:
                 {
                     size_t toFlushSize = zbc->outEnd - zbc->outStart;
    diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c
    index 674f5b0e4..7101503cd 100644
    --- a/lib/legacy/zstd_v05.c
    +++ b/lib/legacy/zstd_v05.c
    @@ -818,13 +818,13 @@ MEM_STATIC size_t BITv05_initDStream(BITv05_DStream_t* bitD, const void* srcBuff
             bitD->bitContainer = *(const BYTE*)(bitD->start);
             switch(srcSize)
             {
    -            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);
    -            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);
    -            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);
    -            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24;
    -            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16;
    -            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) <<  8;
    -            default:;
    +            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);/* fall-through */
    +            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);/* fall-through */
    +            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);/* fall-through */
    +            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; /* fall-through */
    +            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; /* fall-through */
    +            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) <<  8; /* fall-through */
    +            default: break;
             }
             contain32 = ((const BYTE*)srcBuffer)[srcSize-1];
             if (contain32 == 0) return ERROR(GENERIC);   /* endMark not present */
    @@ -3955,7 +3955,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
                     zbc->stage = ZBUFFv05ds_decodeHeader;
                     break;
                 }
    -
    +	    /* fall-through */
             case ZBUFFv05ds_loadHeader:
                 /* complete header from src */
                 {
    @@ -3973,7 +3973,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
                     }
                     // zbc->stage = ZBUFFv05ds_decodeHeader; break;   /* useless : stage follows */
                 }
    -
    +	    /* fall-through */
             case ZBUFFv05ds_decodeHeader:
                     /* apply header to create / resize buffers */
                     {
    @@ -4000,7 +4000,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
                         break;
                     }
                     zbc->stage = ZBUFFv05ds_read;
    -
    +		/* fall-through */
             case ZBUFFv05ds_read:
                 {
                     size_t neededInSize = ZSTDv05_nextSrcSizeToDecompress(zbc->zc);
    @@ -4024,7 +4024,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
                     if (ip==iend) { notDone = 0; break; }   /* no more input */
                     zbc->stage = ZBUFFv05ds_load;
                 }
    -
    +	    /* fall-through */
             case ZBUFFv05ds_load:
                 {
                     size_t neededInSize = ZSTDv05_nextSrcSizeToDecompress(zbc->zc);
    @@ -4045,7 +4045,9 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
                         zbc->outEnd = zbc->outStart +  decodedSize;
                         zbc->stage = ZBUFFv05ds_flush;
                         // break; /* ZBUFFv05ds_flush follows */
    -            }   }
    +                }
    +	    }
    +	    /* fall-through */
             case ZBUFFv05ds_flush:
                 {
                     size_t toFlushSize = zbc->outEnd - zbc->outStart;
    diff --git a/lib/legacy/zstd_v06.c b/lib/legacy/zstd_v06.c
    index ad8c4cd31..26f0929da 100644
    --- a/lib/legacy/zstd_v06.c
    +++ b/lib/legacy/zstd_v06.c
    @@ -910,13 +910,13 @@ MEM_STATIC size_t BITv06_initDStream(BITv06_DStream_t* bitD, const void* srcBuff
             bitD->bitContainer = *(const BYTE*)(bitD->start);
             switch(srcSize)
             {
    -            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    -            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    -            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    -            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    -            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    -            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    -            default:;
    +            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);/* fall-through */
    +            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);/* fall-through */
    +            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);/* fall-through */
    +            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; /* fall-through */
    +            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; /* fall-through */
    +            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8; /* fall-through */
    +            default: break;
             }
             { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
               if (lastByte == 0) return ERROR(GENERIC);   /* endMark not present */
    @@ -3789,7 +3789,7 @@ size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapac
                 return 0;
             }
             dctx->expected = 0;   /* not necessary to copy more */
    -
    +	/* fall-through */
         case ZSTDds_decodeFrameHeader:
             {   size_t result;
                 memcpy(dctx->headerBuffer + ZSTDv06_frameHeaderSize_min, src, dctx->expected);
    @@ -4116,7 +4116,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
                             if (zbd->outBuff == NULL) return ERROR(memory_allocation);
                 }   }   }
                 zbd->stage = ZBUFFds_read;
    -
    +	    /* fall-through */
             case ZBUFFds_read:
                 {   size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
                     if (neededInSize==0) {  /* end of frame */
    @@ -4138,7 +4138,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
                     if (ip==iend) { notDone = 0; break; }   /* no more input */
                     zbd->stage = ZBUFFds_load;
                 }
    -
    +	    /* fall-through */
             case ZBUFFds_load:
                 {   size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
                     size_t const toLoad = neededInSize - zbd->inPos;   /* should always be <= remaining space within inBuff */
    @@ -4159,8 +4159,9 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
                         zbd->outEnd = zbd->outStart +  decodedSize;
                         zbd->stage = ZBUFFds_flush;
                         // break; /* ZBUFFds_flush follows */
    -            }   }
    -
    +                }
    +	    }
    +	    /* fall-through */
             case ZBUFFds_flush:
                 {   size_t const toFlushSize = zbd->outEnd - zbd->outStart;
                     size_t const flushedSize = ZBUFFv06_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
    diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c
    index a54ad0ffd..09a3f5b7c 100644
    --- a/lib/legacy/zstd_v07.c
    +++ b/lib/legacy/zstd_v07.c
    @@ -580,13 +580,13 @@ MEM_STATIC size_t BITv07_initDStream(BITv07_DStream_t* bitD, const void* srcBuff
             bitD->bitContainer = *(const BYTE*)(bitD->start);
             switch(srcSize)
             {
    -            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    -            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    -            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    -            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    -            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    -            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    -            default:;
    +            case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);/* fall-through */
    +            case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);/* fall-through */
    +            case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);/* fall-through */
    +            case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; /* fall-through */
    +            case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; /* fall-through */
    +            case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8; /* fall-through */
    +            default: break;
             }
             { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
               bitD->bitsConsumed = lastByte ? 8 - BITv07_highbit32(lastByte) : 0;
    @@ -4047,7 +4047,7 @@ size_t ZSTDv07_decompressContinue(ZSTDv07_DCtx* dctx, void* dst, size_t dstCapac
                 return 0;
             }
             dctx->expected = 0;   /* not necessary to copy more */
    -
    +	/* fall-through */
         case ZSTDds_decodeFrameHeader:
             {   size_t result;
                 memcpy(dctx->headerBuffer + ZSTDv07_frameHeaderSize_min, src, dctx->expected);
    @@ -4494,7 +4494,7 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
                 }   }   }
                 zbd->stage = ZBUFFds_read;
                 /* pass-through */
    -
    +	    /* fall-through */
             case ZBUFFds_read:
                 {   size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
                     if (neededInSize==0) {  /* end of frame */
    @@ -4517,7 +4517,7 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
                     if (ip==iend) { notDone = 0; break; }   /* no more input */
                     zbd->stage = ZBUFFds_load;
                 }
    -
    +	    /* fall-through */
             case ZBUFFds_load:
                 {   size_t const neededInSize = ZSTDv07_nextSrcSizeToDecompress(zbd->zd);
                     size_t const toLoad = neededInSize - zbd->inPos;   /* should always be <= remaining space within inBuff */
    @@ -4540,8 +4540,9 @@ size_t ZBUFFv07_decompressContinue(ZBUFFv07_DCtx* zbd,
                         zbd->stage = ZBUFFds_flush;
                         /* break; */
                         /* pass-through */
    -            }   }
    -
    +                }
    +	    }
    +	    /* fall-through */
             case ZBUFFds_flush:
                 {   size_t const toFlushSize = zbd->outEnd - zbd->outStart;
                     size_t const flushedSize = ZBUFFv07_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);
    
    From 33eb7ac6b6e152ce9263fdb1f84eb9bf50abe1eb Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 12 May 2017 12:36:11 -0700
    Subject: [PATCH 044/400] updated Advanced API proposal
    
    only declarations in zstd.h
    ---
     doc/zstd_manual.html | 159 ++++++++++++++++++++++++++++++++++
     lib/zstd.h           | 198 +++++++++++++++++++++++++++++++++++++++++++
     2 files changed, 357 insertions(+)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 59d146874..9b0973164 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -471,6 +471,165 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);
     

    Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters


    +

    New experimental advanced parameters API


    +
    typedef enum {
    +    /* compression parameters */
    +    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table (default:3) */
    +    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    +                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    +                              * default value : set through compressionLevel */
    +    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    +                              * Resulting table size is (1 << (hashLog+2)).
    +                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    +                              * Larger tables improve compression ratio of strategies <= dFast,
    +                              * and improve speed of strategies > dFast */
    +    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    +                              * Resulting table size is (1 << (chainLog+2)).
    +                              * Larger tables result in better and slower compression.
    +                              * This parameter is useless when using "fast" strategy */
    +    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    +                              * More attempts result in better and slower compression.
    +                              * This parameter is useless when using "fast" and "dFast" strategies */
    +    ZSTD_p_minMatchLength,   /* Minimum match size (except for repeat-matches, which limit is hard-coded).
    +                              * Larger values make compression and decompression faster, but decrease compression ratio
    +                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    +                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    +                              * Note that currently, for all strategies > fast, effective maximum is 6. */
    +    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    +                              * Length of Match considered "good enough" to stop search.
    +                              * Larger values make compression stronger and slower. */
    +    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    +                              * Cast selected strategy into unsigned for ZSTD_CCtx_setParameter() compatibility.
    +                              * The higher the value of selected strategy, the more complex it is,
    +                              * resulting in stronger and slower compression */
    +#if 0
    +    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    +                              * Can be set to a more precise value than windowLog.
    +                              * Will be transparently reduced to closest possible inferior value
    +                              * (see Zstandard compression format) */
    +                             /* Not ready yet ! */
    +#endif
    +
    +    /* frame parameters */
    +    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    +    ZSTD_p_contentChecksumFlag, /* A 32-bits content checksum is calculated and written at end of frame (default:0) */
    +    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    +
    +    /* dictionary parameters */
    +    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    +                              * This avoids duplicating dictionary content.
    +                              * But it also requires that dictionary buffer outlives its user (CCtx or CDict) */
    +                             /* Not ready yet ! */
    +    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    +                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    +
    +#if 0
    +    /* multi-threading parameters (not ready yet !) */
    +    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    +                              * More threads improve speed, but increases also memory usage */
    +    ZSTDMT_p_jobSize,        /* Size of a compression job. Each job is compressed in parallel.
    +                              * 0 means default, which is dynamically determined based on compression parameters.
    +                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    +                              * The minimum size is automatically and transparently enforced */
    +    ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job.
    +                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    +#endif
    +
    +    /* advanced parameters - may not remain available after API update */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    +                              * even when referencing into Dictionary content
    +                              * default : 0 when using a CDict, 1 when using a Prefix */
    +} ZSTD_cParameter;
    +

    +
    size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    +

    Set one compression parameter, selected by enum ZSTD_cParameter. + @result : 0, or an error code (which can be tested with ZSTD_isError()) +


    + +
    size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    +

    Total input data size to be compressed into a single frame. + This value will be controlled at the end, and result in error if not respected. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : 0 means zero, empty. + In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for all new compression jobs. + Note 2 : If all data is provided and consumed in a single round, + this value is overriden by srcSize instead. +


    + +
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +

    Reference a prefix (content-only dictionary) to bootstrap next compression job. + Decompression will have to use same prefix. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode". + Note 1 : Prefix content is referenced. It must outlive compression job. + Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters. + For this reason, compression parameters cannot be changed anymore after loading a prefix. + It's also a CPU-heavy operation, with non-negligible impact on latency. + Note 3 : Prefix is only used once. Tables are discarded at end of compression job. + If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict +


    + +
    ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    +size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    +size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    +

    Create a CDict object which is still mutable after creation. + It allows usage of ZSTD_CDict_setParameter(). + Once all compression parameters are selected, + it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). + Dictionary content will be copied internally, except if ZSTD_p_refDictContent is used. + After loading the dictionary, no more change is possible. + The only remaining operation is to free CDict object. + Note : An unfinished CDict behaves the same as a NULL CDict when referenced into a CCtx. + +


    + +
    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);  /* Not ready yet ! */
    +

    Add a prepared dictionary to cctx, it will used for next compression jobs. + Note that compression parameters will be enforced from within CDict. + Currently, they supercede any compression parameter previously set within CCtx. + The dictionary will remain valid for all future compression jobs performed using the same cctx. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : adding a NULL CDict means "return to no-dictionary mode". + Note 1 : Currently, only one dictionary can be managed. + Adding a new dictionary effectively "discards" any previous one. + Note 2 : CDict is just referenced, its lifetime must outlive CCtx. + +


    + +
    typedef enum {
    +    ZSTD_e_continue,  /* continue sending data, encoder transparently decides when to output result, depending on optimal conditions */
    +    ZSTD_e_flush,     /* flush any data provided and buffered so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_end        /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +} ZSTD_EndDirective;
    +

    +
    size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                              void* dst, size_t dstCapacity, size_t* dstPos,
    +                        const void* src, size_t srcSize, size_t* srcPos,
    +                              ZSTD_EndDirective endOp);
    +

    Behave about the same as ZSTD_compressStream. To note : + - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter() + - Compression parameters cannot be changed once compression is started. + - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize + - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. + - @return provides the amount of data ready to flush and still within internal buffers + or an error code, which can be tested using ZSTD_isError(). + if @return != 0, flush is not fully completed, so it must be called again to empty internal buffers. + - after a ZSTD_e_end directive, if internal buffer is not fully flushed, + only ZSTD_e_end and ZSTD_e_flush operations are allowed. + It is necessary to fully flush internal buffers + before changing compression parameters or start a new compression job. + +


    + +
    size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
    +

    Return a CCtx to clean state. + Useful after an error, or to interrupt an ongoing compression job and start a new one. + It's allowed to change compression parameters after a reset. + Any internal data not yet flushed is cancelled. + +


    +

    Advanced decompression functions

    
     
     
    unsigned ZSTD_isFrame(const void* buffer, size_t size);
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 256117662..be2168bf9 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -501,6 +501,8 @@ ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize);
      *  Create a ZSTD compression context using external alloc and free functions */
     ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     
    +
    +/* !!! Soon to be deprecated !!! */
     typedef enum {
         ZSTD_p_forceWindow,   /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
         ZSTD_p_forceRawDict   /* Force loading dictionary in "content-only" mode (no header analysis) */
    @@ -556,6 +558,202 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
                                 const ZSTD_CDict* cdict, ZSTD_frameParameters fParams);
     
     
    +/*===   New experimental advanced parameters API   ===*/
    +
    +/* notes on API design :
    + *   In below proposal, parameters are pushed one by one into an existing CCtx,
    + *   and then applied on all following compression jobs.
    + *   When no parameter is ever provided, CCtx is created with compression level 3.
    + *
    + *   Another approach could be to load parameters into an intermediate _opaque_ object.
    + *   The object would then be loaded into CCtx (like ZSTD_compress_advanced())
    + *   This approach would be compatible with ZSTD_createCDict_advanced().
    + *   But it's a bit more cumbersome for CCtx, because it requires to manage an additional object.
    + *
    + *   Below proposal push parameters directly into CCtx.
    + *   It's a bit more complex for CDict, as advanced version now requires 3 steps.
    + *   (basic CDict API remains the same).
    + *   See API details below
    + */
    +
    +/* notes on naming convention :
    + *   Initially, the API favored naming like ZSTD_setCCtxParameter() .
    + *   In this proposal, this is changed into ZSTD_CCtx_setParameter() .
    + *   The main idea is that it identifies more clearly the target object type.
    + *   It feels clearer when considering other potential variants :
    + *   ZSTD_CDict_setParameter() (rather than ZSTD_setCDictParameter())
    + *   ZSTD_DCtx_setParameter()  (rather than ZSTD_setDCtxParameter() )
    + *   The first verion looks clearer.
    + */
    +
    +typedef enum {
    +    /* compression parameters */
    +    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table (default:3) */
    +    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    +                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    +                              * default value : set through compressionLevel */
    +    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    +                              * Resulting table size is (1 << (hashLog+2)).
    +                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    +                              * Larger tables improve compression ratio of strategies <= dFast,
    +                              * and improve speed of strategies > dFast */
    +    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    +                              * Resulting table size is (1 << (chainLog+2)).
    +                              * Larger tables result in better and slower compression.
    +                              * This parameter is useless when using "fast" strategy */
    +    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    +                              * More attempts result in better and slower compression.
    +                              * This parameter is useless when using "fast" and "dFast" strategies */
    +    ZSTD_p_minMatchLength,   /* Minimum match size (except for repeat-matches, which limit is hard-coded).
    +                              * Larger values make compression and decompression faster, but decrease compression ratio
    +                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    +                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    +                              * Note that currently, for all strategies > fast, effective maximum is 6. */
    +    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    +                              * Length of Match considered "good enough" to stop search.
    +                              * Larger values make compression stronger and slower. */
    +    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    +                              * Cast selected strategy into unsigned for ZSTD_CCtx_setParameter() compatibility.
    +                              * The higher the value of selected strategy, the more complex it is,
    +                              * resulting in stronger and slower compression */
    +#if 0
    +    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    +                              * Can be set to a more precise value than windowLog.
    +                              * Will be transparently reduced to closest possible inferior value
    +                              * (see Zstandard compression format) */
    +                             /* Not ready yet ! */
    +#endif
    +
    +    /* frame parameters */
    +    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    +    ZSTD_p_contentChecksumFlag, /* A 32-bits content checksum is calculated and written at end of frame (default:0) */
    +    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    +
    +    /* dictionary parameters */
    +    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    +                              * This avoids duplicating dictionary content.
    +                              * But it also requires that dictionary buffer outlives its user (CCtx or CDict) */
    +                             /* Not ready yet ! */
    +    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    +                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    +
    +#if 0
    +    /* multi-threading parameters (not ready yet !) */
    +    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    +                              * More threads improve speed, but increases also memory usage */
    +    ZSTDMT_p_jobSize,        /* Size of a compression job. Each job is compressed in parallel.
    +                              * 0 means default, which is dynamically determined based on compression parameters.
    +                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    +                              * The minimum size is automatically and transparently enforced */
    +    ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job.
    +                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    +#endif
    +
    +    /* advanced parameters - may not remain available after API update */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    +                              * even when referencing into Dictionary content
    +                              * default : 0 when using a CDict, 1 when using a Prefix */
    +} ZSTD_cParameter;
    +
    +
    +/*! ZSTD_CCtx_setParameter() :
    + *  Set one compression parameter, selected by enum ZSTD_cParameter.
    + *  @result : 0, or an error code (which can be tested with ZSTD_isError()) */
    +ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    +
    +/*! ZSTD_CCtx_setPledgedSrcSize() :
    + *  Total input data size to be compressed into a single frame.
    + *  This value will be controlled at the end, and result in error if not respected.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Note 1 : 0 means zero, empty.
    + *           In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN.
    + *           Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for all new compression jobs.
    + *  Note 2 : If all data is provided and consumed in a single round,
    + *           this value is overriden by srcSize instead. */
    +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    +
    +/*! ZSTD_CCtx_refPrefix() :
    + *  Reference a prefix (content-only dictionary) to bootstrap next compression job.
    + *  Decompression will have to use same prefix.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode".
    + *  Note 1 : Prefix content is referenced. It must outlive compression job.
    + *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
    + *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    + *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    + *  Note 3 : Prefix is only used once. Tables are discarded at end of compression job.
    + *           If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict */
    +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +
    +
    +/*! ZSTD_CDict_createEmpty() :
    + *  Create a CDict object which is still mutable after creation.
    + *  It allows usage of ZSTD_CDict_setParameter().
    + *  Once all compression parameters are selected,
    + *  it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary().
    + *  Dictionary content will be copied internally, except if ZSTD_p_refDictContent is used.
    + *  After loading the dictionary, no more change is possible.
    + *  The only remaining operation is to free CDict object.
    + *  Note : An unfinished CDict behaves the same as a NULL CDict when referenced into a CCtx.
    + */
    +ZSTDLIB_API ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    +
    +/*! ZSTD_CCtx_refCDict() :
    + *  Add a prepared dictionary to cctx, it will used for next compression jobs.
    + *  Note that compression parameters will be enforced from within CDict.
    + *  Currently, they supercede any compression parameter previously set within CCtx.
    + *  The dictionary will remain valid for all future compression jobs performed using the same cctx.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : adding a NULL CDict means "return to no-dictionary mode".
    + *  Note 1 : Currently, only one dictionary can be managed.
    + *           Adding a new dictionary effectively "discards" any previous one.
    + *  Note 2 : CDict is just referenced, its lifetime must outlive CCtx.
    + */
    +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);  /* Not ready yet ! */
    +
    +
    +#if 0
    +// Target advanced compression API
    +// Not ready yet !!!
    +
    +typedef enum {
    +    ZSTD_e_continue,  /* continue sending data, encoder transparently decides when to output result, depending on optimal conditions */
    +    ZSTD_e_flush,     /* flush any data provided and buffered so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_end        /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +} ZSTD_EndDirective;
    +
    +/*! ZSTD_compressStream_generic() :
    + *  Behave about the same as ZSTD_compressStream. To note :
    + *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter()
    + *  - Compression parameters cannot be changed once compression is started.
    + *  - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize
    + *  - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit.
    + *  - @return provides the amount of data ready to flush and still within internal buffers
    + *            or an error code, which can be tested using ZSTD_isError().
    + *            if @return != 0, flush is not fully completed, so it must be called again to empty internal buffers.
    + *  - after a ZSTD_e_end directive, if internal buffer is not fully flushed,
    + *            only ZSTD_e_end and ZSTD_e_flush operations are allowed.
    + *            It is necessary to fully flush internal buffers
    + *            before changing compression parameters or start a new compression job.
    + */
    +ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                                          void* dst, size_t dstCapacity, size_t* dstPos,
    +                                    const void* src, size_t srcSize, size_t* srcPos,
    +                                          ZSTD_EndDirective endOp);
    +
    +/*! ZSTD_CCtx_reset() :
    + *  Return a CCtx to clean state.
    + *  Useful after an error, or to interrupt an ongoing compression job and start a new one.
    + *  It's allowed to change compression parameters after a reset.
    + *  Any internal data not yet flushed is cancelled.
    + */
    +ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
    +
    +#endif
    +
    +
     /*--- Advanced decompression functions ---*/
     
     /*! ZSTD_isFrame() :
    
    From db8e21d5a05b6370b01dc76b2fef4377825189b5 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 12 May 2017 13:46:49 -0700
    Subject: [PATCH 045/400] made ZSTD_compress_generic() definition accessible
    
    note that the implementation is not done yet.
    ---
     doc/zstd_manual.html         | 6 +++---
     lib/compress/zstd_compress.c | 6 +++---
     lib/zstd.h                   | 9 ++++-----
     3 files changed, 10 insertions(+), 11 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 9b0973164..a06d4b037 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -574,13 +574,13 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);
     size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
     size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
     

    Create a CDict object which is still mutable after creation. - It allows usage of ZSTD_CDict_setParameter(). + It's the only one case allowing usage of ZSTD_CDict_setParameter(). Once all compression parameters are selected, it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). - Dictionary content will be copied internally, except if ZSTD_p_refDictContent is used. + Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). After loading the dictionary, no more change is possible. The only remaining operation is to free CDict object. - Note : An unfinished CDict behaves the same as a NULL CDict when referenced into a CCtx. + Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx.


    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index edf4609f7..0db9d1cd0 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2468,14 +2468,14 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa } -/*! ZSTD_compress_generic() : +/*! ZSTD_compress_frameChunk() : * Compress a chunk of data into one or multiple blocks. * All blocks will be terminated, all input will be consumed. * Function will issue an error if there is not enough `dstCapacity` to hold the compressed content. * Frame is supposed already started (header already produced) * @return : compressed size, or an error code */ -static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, +static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastFrameChunk) @@ -2630,7 +2630,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, if (srcSize) { size_t const cSize = frame ? - ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : + ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) : ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize); if (ZSTD_isError(cSize)) return cSize; cctx->consumedSrcSize += srcSize; diff --git a/lib/zstd.h b/lib/zstd.h index be2168bf9..fcefc7af6 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -688,13 +688,13 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size /*! ZSTD_CDict_createEmpty() : * Create a CDict object which is still mutable after creation. - * It allows usage of ZSTD_CDict_setParameter(). + * It's the only one case allowing usage of ZSTD_CDict_setParameter(). * Once all compression parameters are selected, * it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). - * Dictionary content will be copied internally, except if ZSTD_p_refDictContent is used. + * Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). * After loading the dictionary, no more change is possible. * The only remaining operation is to free CDict object. - * Note : An unfinished CDict behaves the same as a NULL CDict when referenced into a CCtx. + * Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx. */ ZSTDLIB_API ZSTD_CDict* ZSTD_CDict_createEmpty(void); /* Not ready yet ! */ ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value); /* Not ready yet ! */ @@ -714,7 +714,6 @@ ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /* Not ready yet ! */ -#if 0 // Target advanced compression API // Not ready yet !!! @@ -749,9 +748,9 @@ ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, * It's allowed to change compression parameters after a reset. * Any internal data not yet flushed is cancelled. */ +// Not ready yet !!! ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx); -#endif /*--- Advanced decompression functions ---*/ From ef738c1b238b81c705b4bf511cad7821d771a189 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 12 May 2017 13:53:46 -0700 Subject: [PATCH 046/400] better error code when compressing using NULL CDict which is not allowed (but detected, and generates an error). --- lib/compress/zstd_compress.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 0db9d1cd0..57d788e59 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -177,6 +177,7 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) + cctx->outBuffSize + cctx->inBuffSize; } +/* older variant; will be deprecated */ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value) { switch(param) @@ -3078,7 +3079,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced( ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) { - if (cdict==NULL) return ERROR(GENERIC); /* does not support NULL cdict */ + if (cdict==NULL) return ERROR(dictionary_wrong); /* does not support NULL cdict */ DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u \n", !fParams.noDictIDFlag); if (cdict->dictContentSize) CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) ) @@ -3231,7 +3232,7 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs, * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams) { - if (!cdict) return ERROR(GENERIC); /* cannot handle NULL cdict (does not know what to do) */ + if (!cdict) return ERROR(dictionary_wrong); /* cannot handle NULL cdict (does not know what to do) */ { ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict); params.fParams = fParams; zcs->cdict = cdict; @@ -3242,7 +3243,7 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* /* note : cdict must outlive compression session */ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict) { - ZSTD_frameParameters const fParams = { 0 /* content */, 0 /* checksum */, 0 /* noDictID */ }; + ZSTD_frameParameters const fParams = { 0 /* contentSize */, 0 /* checksum */, 0 /* hideDictID */ }; return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, 0, fParams); } From b0edb7fb0eb90dfe51682d806f8282b6f1ff6b3a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 12 May 2017 15:31:53 -0700 Subject: [PATCH 047/400] added ZSTD_CCtx_setParameter() --- doc/zstd_manual.html | 11 +-- lib/compress/zstd_compress.c | 132 +++++++++++++++++++++++++++++++++-- lib/zstd.h | 8 ++- 3 files changed, 138 insertions(+), 13 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index a06d4b037..68efb6cc8 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -474,7 +474,9 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);

    New experimental advanced parameters API


    typedef enum {
         /* compression parameters */
    -    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table (default:3) */
    +    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    +                              * Default level is 3.
    +                              * Special: value 0 means "do not change cLevel". */
         ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
                                   * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
                                   * default value : set through compressionLevel */
    @@ -491,7 +493,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);
                                   * More attempts result in better and slower compression.
                                   * This parameter is useless when using "fast" and "dFast" strategies */
         ZSTD_p_minMatchLength,   /* Minimum match size (except for repeat-matches, which limit is hard-coded).
    -                              * Larger values make compression and decompression faster, but decrease compression ratio
    +                              * Larger values make faster compression and decompression, but decrease ratio.
                                   * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
                                   * Note that currently, for all strategies < btopt, effective minimum is 4.
                                   * Note that currently, for all strategies > fast, effective maximum is 6. */
    @@ -499,7 +501,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);
                                   * Length of Match considered "good enough" to stop search.
                                   * Larger values make compression stronger and slower. */
         ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    -                              * Cast selected strategy into unsigned for ZSTD_CCtx_setParameter() compatibility.
    +                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
                                   * The higher the value of selected strategy, the more complex it is,
                                   * resulting in stronger and slower compression */
     #if 0
    @@ -622,7 +624,8 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
      
     


    -
    size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
    +
    // Not ready yet !!!
    +size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
     

    Return a CCtx to clean state. Useful after an error, or to interrupt an ongoing compression job and start a new one. It's allowed to change compression parameters after a reset. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 57d788e59..e17521565 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -8,6 +8,13 @@ */ +/*-************************************* +* Tuning parameters +***************************************/ +#ifndef ZSTD_DEFAULT_CLEVEL +# define ZSTD_DEFAULT_CLEVEL 3 +#endif + /*-************************************* * Dependencies ***************************************/ @@ -97,6 +104,7 @@ struct ZSTD_CCtx_s { U32 rep[ZSTD_REP_NUM]; U32 repToConfirm[ZSTD_REP_NUM]; U32 dictID; + int compressionLevel; ZSTD_parameters params; void* workSpace; size_t workSpaceSize; @@ -151,6 +159,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) if (!cctx) return NULL; memset(cctx, 0, sizeof(ZSTD_CCtx)); cctx->customMem = customMem; + cctx->compressionLevel = ZSTD_DEFAULT_CLEVEL; return cctx; } @@ -177,6 +186,11 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx) + cctx->outBuffSize + cctx->inBuffSize; } +/* private API call, for dictBuilder only */ +const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); } + +static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) { return cctx->params; } + /* older variant; will be deprecated */ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value) { @@ -188,14 +202,121 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned } } -const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface */ +size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value) { - return &(ctx->seqStore); +# define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); } +# define LOADCPARAMS(cParams) \ + if (cctx->compressionLevel!=0) { \ + cParams = ZSTD_getCParams( \ + cctx->compressionLevel, \ + cctx->frameContentSize, 0); /* dictSize unknown at this stage */ \ + cctx->compressionLevel = 0; \ + } + + + switch(param) + { + case ZSTD_p_compressionLevel : + if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel(); /* cap max compression level */ + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + cctx->compressionLevel = value; + return 0; + + case ZSTD_p_windowLog : + CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.windowLog = value; + return 0; + + case ZSTD_p_hashLog : + CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.hashLog = value; + return 0; + + case ZSTD_p_chainLog : + CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.chainLog = value; + return 0; + + case ZSTD_p_searchLog : + CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.searchLog = value; + return 0; + + case ZSTD_p_minMatchLength : + CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.searchLength = value; + return 0; + + case ZSTD_p_targetLength : + CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.targetLength = value; + return 0; + + case ZSTD_p_compressionStrategy : + if (value > (unsigned)ZSTD_btultra) return ERROR(compressionParameter_unsupported); + LOADCPARAMS(cctx->params.cParams); + cctx->params.cParams.strategy = (ZSTD_strategy)value; + return 0; + +#if 0 + case ZSTD_p_windowSize : /* to be done later */ + return ERROR(compressionParameter_unsupported); +#endif + + case ZSTD_p_contentSizeFlag : /* Content size will be written in frame header _when known_ (default:1) */ + cctx->params.fParams.contentSizeFlag = value>0; + return 0; + + case ZSTD_p_contentChecksumFlag : /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */ + cctx->params.fParams.checksumFlag = value>0; + return 0; + + case ZSTD_p_dictIDFlag : /* When applicable, the dictID of used dictionary will be provided in frame header (default:1) */ + cctx->params.fParams.noDictIDFlag = value==0; + return 0; + + case ZSTD_p_refDictContent : /* to be done later */ + return ERROR(compressionParameter_unsupported); + + case ZSTD_p_forceMaxWindow : /* Force back-references to remain < windowSize, + * even when referencing into Dictionary content + * default : 0 when using a CDict, 1 when using a Prefix */ + cctx->forceWindow = value>0; + cctx->loadedDictEnd = 0; + return 0; + + case ZSTD_p_rawContentDict : /* load dictionary in "content-only" mode (no header analysis) (default:0) */ + cctx->forceRawDict = value>0; + return 0; + + default: return ERROR(parameter_unknown); + } } -static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) { - return cctx->params; + cctx->frameContentSize = pledgedSrcSize; + return 0; +} + +/* Not ready yet ! */ +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) +{ + (void)cctx; (void)prefix; (void)prefixSize; /* to be done later */ + return ERROR(compressionParameter_unsupported); +} + +/* Not ready yet ! */ +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +{ + (void)cctx; (void)cdict; /* to be done later */ + return ERROR(compressionParameter_unsupported); } @@ -3472,7 +3593,6 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) /*-===== Pre-defined compression levels =====-*/ -#define ZSTD_DEFAULT_CLEVEL 1 #define ZSTD_MAX_CLEVEL 22 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } @@ -3592,7 +3712,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l size_t const addedSize = srcSize ? 0 : 500; U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1; U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ - if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */ + if (compressionLevel <= 0) compressionLevel = 1; /* 0 == default; no negative compressionLevel yet */ if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; cp = ZSTD_defaultCParameters[tableID][compressionLevel]; if (MEM_32bits()) { /* auto-correction, for 32-bits mode */ diff --git a/lib/zstd.h b/lib/zstd.h index fcefc7af6..587f9f521 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -588,7 +588,9 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx, typedef enum { /* compression parameters */ - ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table (default:3) */ + ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table + * Default level is 3. + * Special: value 0 means "do not change cLevel". */ ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. * default value : set through compressionLevel */ @@ -605,7 +607,7 @@ typedef enum { * More attempts result in better and slower compression. * This parameter is useless when using "fast" and "dFast" strategies */ ZSTD_p_minMatchLength, /* Minimum match size (except for repeat-matches, which limit is hard-coded). - * Larger values make compression and decompression faster, but decrease compression ratio + * Larger values make faster compression and decompression, but decrease ratio. * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX. * Note that currently, for all strategies < btopt, effective minimum is 4. * Note that currently, for all strategies > fast, effective maximum is 6. */ @@ -613,7 +615,7 @@ typedef enum { * Length of Match considered "good enough" to stop search. * Larger values make compression stronger and slower. */ ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition. - * Cast selected strategy into unsigned for ZSTD_CCtx_setParameter() compatibility. + * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. * The higher the value of selected strategy, the more complex it is, * resulting in stronger and slower compression */ #if 0 From add66f816d5c4f3f73fe3803578b9ee3820371a0 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 12 May 2017 15:59:48 -0700 Subject: [PATCH 048/400] changed macro LOADCPARAMS by static function ZSTD_cLevelToCParams() for improved compiler checks. Also : ensure most parameters can receive value "0" to mean "do not change". --- doc/zstd_manual.html | 20 ++++++++++++------ lib/compress/zstd_compress.c | 41 ++++++++++++++++++++++++------------ lib/zstd.h | 20 ++++++++++++------ 3 files changed, 53 insertions(+), 28 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 68efb6cc8..8c74bcff0 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -479,31 +479,37 @@ size_t ZSTD_estimateDDictSize(size_t dictSize); * Special: value 0 means "do not change cLevel". */ ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. - * default value : set through compressionLevel */ + * default value : set through compressionLevel. + * Special: value 0 means "do not change windowLog". */ ZSTD_p_hashLog, /* Size of the probe table, as a power of 2. * Resulting table size is (1 << (hashLog+2)). * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. * Larger tables improve compression ratio of strategies <= dFast, - * and improve speed of strategies > dFast */ + * and improve speed of strategies > dFast. + * Special: value 0 means "do not change hashLog". */ ZSTD_p_chainLog, /* Size of the full-search table, as a power of 2. * Resulting table size is (1 << (chainLog+2)). * Larger tables result in better and slower compression. - * This parameter is useless when using "fast" strategy */ + * This parameter is useless when using "fast" strategy. + * Special: value 0 means "do not change chainLog". */ ZSTD_p_searchLog, /* Number of search attempts, as a power of 2. * More attempts result in better and slower compression. - * This parameter is useless when using "fast" and "dFast" strategies */ + * This parameter is useless when using "fast" and "dFast" strategies. + * Special: value 0 means "do not change searchLog". */ ZSTD_p_minMatchLength, /* Minimum match size (except for repeat-matches, which limit is hard-coded). * Larger values make faster compression and decompression, but decrease ratio. * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX. * Note that currently, for all strategies < btopt, effective minimum is 4. - * Note that currently, for all strategies > fast, effective maximum is 6. */ + * Note that currently, for all strategies > fast, effective maximum is 6. + * Special: value 0 means "do not change minMatchLength". */ ZSTD_p_targetLength, /* Only useful for strategies >= btopt. * Length of Match considered "good enough" to stop search. - * Larger values make compression stronger and slower. */ + * Larger values make compression stronger and slower. + * Special: value 0 means "do not change targetLength". */ ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition. * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. * The higher the value of selected strategy, the more complex it is, - * resulting in stronger and slower compression */ + * resulting in stronger and slower compression. */ #if 0 ZSTD_p_windowSize, /* Maximum allowed back-reference distance. * Can be set to a more precise value than windowLog. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e17521565..754bb8b08 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -202,15 +202,23 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned } } + +static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx) +{ + if (cctx->compressionLevel==0) return; + cctx->params.cParams = ZSTD_getCParams(cctx->compressionLevel, + cctx->frameContentSize, 0); + cctx->compressionLevel = 0; +} + size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value) { # define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); } -# define LOADCPARAMS(cParams) \ - if (cctx->compressionLevel!=0) { \ - cParams = ZSTD_getCParams( \ - cctx->compressionLevel, \ - cctx->frameContentSize, 0); /* dictSize unknown at this stage */ \ - cctx->compressionLevel = 0; \ +# define LOADCPARAMS(cctx) \ + if (cctx->compressionLevel!=0) { \ + cctx->params.cParams = ZSTD_getCParams( cctx->compressionLevel, \ + cctx->frameContentSize, 0); \ + cctx->compressionLevel = 0; \ } @@ -223,44 +231,50 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v return 0; case ZSTD_p_windowLog : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.windowLog = value; return 0; case ZSTD_p_hashLog : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.hashLog = value; return 0; case ZSTD_p_chainLog : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.chainLog = value; return 0; case ZSTD_p_searchLog : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.searchLog = value; return 0; case ZSTD_p_minMatchLength : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.searchLength = value; return 0; case ZSTD_p_targetLength : + if (value == 0) return 0; /* special value : 0 means "don't change anything" */ CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.targetLength = value; return 0; case ZSTD_p_compressionStrategy : if (value > (unsigned)ZSTD_btultra) return ERROR(compressionParameter_unsupported); - LOADCPARAMS(cctx->params.cParams); + ZSTD_cLevelToCParams(cctx); cctx->params.cParams.strategy = (ZSTD_strategy)value; return 0; @@ -325,7 +339,6 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) @return : 0, or an error code if one value is beyond authorized range */ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) { -# define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); } CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); diff --git a/lib/zstd.h b/lib/zstd.h index 587f9f521..c1ae9da54 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -593,31 +593,37 @@ typedef enum { * Special: value 0 means "do not change cLevel". */ ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. - * default value : set through compressionLevel */ + * default value : set through compressionLevel. + * Special: value 0 means "do not change windowLog". */ ZSTD_p_hashLog, /* Size of the probe table, as a power of 2. * Resulting table size is (1 << (hashLog+2)). * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX. * Larger tables improve compression ratio of strategies <= dFast, - * and improve speed of strategies > dFast */ + * and improve speed of strategies > dFast. + * Special: value 0 means "do not change hashLog". */ ZSTD_p_chainLog, /* Size of the full-search table, as a power of 2. * Resulting table size is (1 << (chainLog+2)). * Larger tables result in better and slower compression. - * This parameter is useless when using "fast" strategy */ + * This parameter is useless when using "fast" strategy. + * Special: value 0 means "do not change chainLog". */ ZSTD_p_searchLog, /* Number of search attempts, as a power of 2. * More attempts result in better and slower compression. - * This parameter is useless when using "fast" and "dFast" strategies */ + * This parameter is useless when using "fast" and "dFast" strategies. + * Special: value 0 means "do not change searchLog". */ ZSTD_p_minMatchLength, /* Minimum match size (except for repeat-matches, which limit is hard-coded). * Larger values make faster compression and decompression, but decrease ratio. * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX. * Note that currently, for all strategies < btopt, effective minimum is 4. - * Note that currently, for all strategies > fast, effective maximum is 6. */ + * Note that currently, for all strategies > fast, effective maximum is 6. + * Special: value 0 means "do not change minMatchLength". */ ZSTD_p_targetLength, /* Only useful for strategies >= btopt. * Length of Match considered "good enough" to stop search. - * Larger values make compression stronger and slower. */ + * Larger values make compression stronger and slower. + * Special: value 0 means "do not change targetLength". */ ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition. * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. * The higher the value of selected strategy, the more complex it is, - * resulting in stronger and slower compression */ + * resulting in stronger and slower compression. */ #if 0 ZSTD_p_windowSize, /* Maximum allowed back-reference distance. * Can be set to a more precise value than windowLog. From a5ffe3d37031e5bac9a3a8fd1ea073ced06a9756 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 12 May 2017 16:29:19 -0700 Subject: [PATCH 049/400] pushed enum values for strategy by one (ZSTD_fast==1) this makes it possible to use `0` to mean: "do not change strategy" --- doc/zstd_manual.html | 48 ++++++++++++++++++++---------------- lib/compress/zstd_compress.c | 12 ++++++--- lib/zstd.h | 48 ++++++++++++++++++++---------------- programs/fileio.c | 2 +- tests/fuzzer.c | 8 +++--- tests/zstreamtest.c | 8 +++--- 6 files changed, 71 insertions(+), 55 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 8c74bcff0..13eb5523e 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -31,9 +31,10 @@


    Introduction

    -  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
    -  at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
    -  decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
    +  zstd, short for Zstandard, is a fast lossless compression algorithm,
    +  targeting real-time compression scenarios at zlib-level and better compression ratios.
    +  The zstd compression library provides in-memory compression and decompression functions.
    +  The library supports compression levels from 1 up to ZSTD_maxCLevel() which is currently 22.
       Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory.
       Compression can be done in:
         - a single step (described as Simple API)
    @@ -73,21 +74,17 @@
     


    unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
    -

    NOTE: This function is planned to be obsolete, in favour of ZSTD_getFrameContentSize. - ZSTD_getFrameContentSize functions the same way, returning the decompressed size of a single - frame, but distinguishes empty frames from frames with an unknown size, or errors. - - Additionally, ZSTD_findDecompressedSize can be used instead. It can handle multiple - concatenated frames in one buffer, and so is more general. - As a result however, it requires more computation and entire frames to be passed to it, - as opposed to ZSTD_getFrameContentSize which requires only a single frame's header. +

    NOTE: This function is planned to be obsolete, in favor of ZSTD_getFrameContentSize(). + ZSTD_getFrameContentSize() works the same way, + returning the decompressed size of a single frame, + but distinguishes empty frames from frames with an unknown size, or errors. 'src' is the start of a zstd compressed frame. @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise. - note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. + note 1 : decompressed size is an optional field, it may not be present, typically in streaming mode. When `return==0`, data to decompress could be any size. In which case, it's necessary to use streaming mode to decompress data. - Optionally, application can still use ZSTD_decompress() while relying on implied limits. + Optionally, application can use ZSTD_decompress() while relying on implied limits. (For example, data may be necessarily cut into blocks <= 16 KB). note 2 : decompressed size is always present when compression is done with ZSTD_compress() note 3 : decompressed size can be very large (64-bits value), @@ -114,20 +111,26 @@ const char* ZSTD_getErrorName(size_t code); /*!< provides readable strin ZSTD_CCtx* ZSTD_createCCtx(void); size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);


    -
    size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
    +
    size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx,
    +                         void* dst, size_t dstCapacity,
    +                   const void* src, size_t srcSize,
    +                         int compressionLevel);
     

    Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()).


    Decompression context

      When decompressing many times,
    -  it is recommended to allocate a context just once, and re-use it for each successive compression operation.
    +  it is recommended to allocate a context only once,
    +  and re-use it for each successive compression operation.
       This will make workload friendlier for system's memory.
    -  Use one context per thread for parallel execution in multi-threaded environments. 
    +  Use one context per thread for parallel execution. 
     
    typedef struct ZSTD_DCtx_s ZSTD_DCtx;
     ZSTD_DCtx* ZSTD_createDCtx(void);
     size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
     

    -
    size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
    -

    Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). +

    size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx,
    +                           void* dst, size_t dstCapacity,
    +                     const void* src, size_t srcSize);
    +

    Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx())


    Simple dictionary API

    
    @@ -154,7 +157,8 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
     
     

    Fast dictionary API

    
     
    -
    ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, int compressionLevel);
    +
    ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
    +                             int compressionLevel);
     

    When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. @@ -298,7 +302,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB

    Advanced types

    
     
    -
    typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
    +
    typedef enum { ZSTD_fast=1, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2,
    +               ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
     

    typedef struct {
         unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
    @@ -509,7 +514,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);
         ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
                                   * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
                                   * The higher the value of selected strategy, the more complex it is,
    -                              * resulting in stronger and slower compression. */
    +                              * resulting in stronger and slower compression.
    +                              * Special: value 0 means "do not change strategy". */
     #if 0
         ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
                                   * Can be set to a more precise value than windowLog.
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 754bb8b08..565cf04a1 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -273,7 +273,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 return 0;
     
         case ZSTD_p_compressionStrategy :
    -            if (value > (unsigned)ZSTD_btultra) return ERROR(compressionParameter_unsupported);
    +            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +            CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
                 ZSTD_cLevelToCParams(cctx);
                 cctx->params.cParams.strategy = (ZSTD_strategy)value;
                 return 0;
    @@ -2575,14 +2576,17 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr
     
     static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
     {
    -    static const ZSTD_blockCompressor blockCompressor[2][8] = {
    -        { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
    +    static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = {
    +        { NULL,
    +          ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
               ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2,
               ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra },
    -        { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict,
    +        { NULL,
    +          ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict,
               ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict,
               ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict }
         };
    +    ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
     
         return blockCompressor[extDict][(U32)strat];
     }
    diff --git a/lib/zstd.h b/lib/zstd.h
    index c1ae9da54..b6e4b263c 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -36,9 +36,10 @@ extern "C" {
     /*******************************************************************************************************
       Introduction
     
    -  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
    -  at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
    -  decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
    +  zstd, short for Zstandard, is a fast lossless compression algorithm,
    +  targeting real-time compression scenarios at zlib-level and better compression ratios.
    +  The zstd compression library provides in-memory compression and decompression functions.
    +  The library supports compression levels from 1 up to ZSTD_maxCLevel() which is currently 22.
       Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory.
       Compression can be done in:
         - a single step (described as Simple API)
    @@ -89,21 +90,17 @@ ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
                                   const void* src, size_t compressedSize);
     
     /*! ZSTD_getDecompressedSize() :
    - *  NOTE: This function is planned to be obsolete, in favour of ZSTD_getFrameContentSize.
    - *  ZSTD_getFrameContentSize functions the same way, returning the decompressed size of a single
    - *  frame, but distinguishes empty frames from frames with an unknown size, or errors.
    - *
    - *  Additionally, ZSTD_findDecompressedSize can be used instead.  It can handle multiple
    - *  concatenated frames in one buffer, and so is more general.
    - *  As a result however, it requires more computation and entire frames to be passed to it,
    - *  as opposed to ZSTD_getFrameContentSize which requires only a single frame's header.
    + *  NOTE: This function is planned to be obsolete, in favor of ZSTD_getFrameContentSize().
    + *  ZSTD_getFrameContentSize() works the same way,
    + *  returning the decompressed size of a single frame,
    + *  but distinguishes empty frames from frames with an unknown size, or errors.
      *
      *  'src' is the start of a zstd compressed frame.
      *  @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise.
    - *   note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
    + *   note 1 : decompressed size is an optional field, it may not be present, typically in streaming mode.
      *            When `return==0`, data to decompress could be any size.
      *            In which case, it's necessary to use streaming mode to decompress data.
    - *            Optionally, application can still use ZSTD_decompress() while relying on implied limits.
    + *            Optionally, application can use ZSTD_decompress() while relying on implied limits.
      *            (For example, data may be necessarily cut into blocks <= 16 KB).
      *   note 2 : decompressed size is always present when compression is done with ZSTD_compress()
      *   note 3 : decompressed size can be very large (64-bits value),
    @@ -137,20 +134,26 @@ ZSTDLIB_API size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);
     
     /*! ZSTD_compressCCtx() :
      *  Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */
    -ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
    +ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx,
    +                                     void* dst, size_t dstCapacity,
    +                               const void* src, size_t srcSize,
    +                                     int compressionLevel);
     
     /*= Decompression context
      *  When decompressing many times,
    - *  it is recommended to allocate a context just once, and re-use it for each successive compression operation.
    + *  it is recommended to allocate a context only once,
    + *  and re-use it for each successive compression operation.
      *  This will make workload friendlier for system's memory.
    - *  Use one context per thread for parallel execution in multi-threaded environments. */
    + *  Use one context per thread for parallel execution. */
     typedef struct ZSTD_DCtx_s ZSTD_DCtx;
     ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
     ZSTDLIB_API size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
     
     /*! ZSTD_decompressDCtx() :
    - *  Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). */
    -ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
    + *  Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()) */
    +ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx,
    +                                       void* dst, size_t dstCapacity,
    +                                 const void* src, size_t srcSize);
     
     
     /**************************
    @@ -187,7 +190,8 @@ typedef struct ZSTD_CDict_s ZSTD_CDict;
     *   ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
     *   ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only.
     *   `dictBuffer` can be released after ZSTD_CDict creation, as its content is copied within CDict */
    -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, int compressionLevel);
    +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
    +                                         int compressionLevel);
     
     /*! ZSTD_freeCDict() :
     *   Function frees memory allocated by ZSTD_createCDict(). */
    @@ -375,7 +379,8 @@ static const size_t ZSTD_skippableHeaderSize = 8;  /* magic number + skippable f
     
     
     /*--- Advanced types ---*/
    -typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
    +typedef enum { ZSTD_fast=1, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2,
    +               ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy;   /* from faster to stronger */
     
     typedef struct {
         unsigned windowLog;      /**< largest match distance : larger == more compression, more memory needed during decompression */
    @@ -623,7 +628,8 @@ typedef enum {
         ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
                                   * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
                                   * The higher the value of selected strategy, the more complex it is,
    -                              * resulting in stronger and slower compression. */
    +                              * resulting in stronger and slower compression.
    +                              * Special: value 0 means "do not change strategy". */
     #if 0
         ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
                                   * Can be set to a more precise value than windowLog.
    diff --git a/programs/fileio.c b/programs/fileio.c
    index ba15555dd..2c12b924c 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -369,7 +369,7 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
                 if (comprParams->searchLog) params.cParams.searchLog = comprParams->searchLog;
                 if (comprParams->searchLength) params.cParams.searchLength = comprParams->searchLength;
                 if (comprParams->targetLength) params.cParams.targetLength = comprParams->targetLength;
    -            if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy)(comprParams->strategy - 1);   /* 0 means : do not change */
    +            if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy) comprParams->strategy;
     #ifdef ZSTD_MULTITHREAD
                 {   size_t const errorCode = ZSTDMT_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize);
                     if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode));
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 4b9cd97a5..6814d5476 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -12,9 +12,9 @@
     *  Compiler specific
     **************************************/
     #ifdef _MSC_VER    /* Visual Studio */
    -#  define _CRT_SECURE_NO_WARNINGS     /* fgets */
    -#  pragma warning(disable : 4127)     /* disable: C4127: conditional expression is constant */
    -#  pragma warning(disable : 4204)     /* disable: C4204: non-constant aggregate initializer */
    +#  define _CRT_SECURE_NO_WARNINGS   /* fgets */
    +#  pragma warning(disable : 4127)   /* disable: C4127: conditional expression is constant */
    +#  pragma warning(disable : 4204)   /* disable: C4204: non-constant aggregate initializer */
     #endif
     
     
    @@ -25,7 +25,7 @@
     #include         /* fgets, sscanf */
     #include        /* strcmp */
     #include          /* clock_t */
    -#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_compressContinue, ZSTD_compressBlock */
    +#define ZSTD_STATIC_LINKING_ONLY  /* ZSTD_compressContinue, ZSTD_compressBlock */
     #include "zstd.h"         /* ZSTD_VERSION_STRING */
     #include "zstd_errors.h"  /* ZSTD_getErrorCode */
     #include "zstdmt_compress.h"
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 5c166bfb8..6c4900ebb 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -12,9 +12,9 @@
     *  Compiler specific
     **************************************/
     #ifdef _MSC_VER    /* Visual Studio */
    -#  define _CRT_SECURE_NO_WARNINGS     /* fgets */
    -#  pragma warning(disable : 4127)     /* disable: C4127: conditional expression is constant */
    -#  pragma warning(disable : 4146)     /* disable: C4146: minus unsigned expression */
    +#  define _CRT_SECURE_NO_WARNINGS   /* fgets */
    +#  pragma warning(disable : 4127)   /* disable: C4127: conditional expression is constant */
    +#  pragma warning(disable : 4146)   /* disable: C4146: minus unsigned expression */
     #endif
     
     
    @@ -26,7 +26,7 @@
     #include          /* clock_t, clock() */
     #include        /* strcmp */
     #include "mem.h"
    -#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_maxCLevel, ZSTD_customMem, ZSTD_getDictID_fromFrame */
    +#define ZSTD_STATIC_LINKING_ONLY  /* ZSTD_maxCLevel, ZSTD_customMem, ZSTD_getDictID_fromFrame */
     #include "zstd.h"         /* ZSTD_compressBound */
     #include "zstd_errors.h"  /* ZSTD_error_srcSize_wrong */
     #include "zstdmt_compress.h"
    
    From 83d0c764dcd940fc058e8649c6982c7512563344 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 15 May 2017 17:15:46 -0700
    Subject: [PATCH 050/400] added several compilation flags
    
    ---
     examples/Makefile  |  2 +-
     lib/Makefile       |  4 +++-
     programs/Makefile  |  6 ++++--
     tests/Makefile     |  4 +++-
     tests/datagencli.c | 19 ++++++++++---------
     tests/fullbench.c  | 12 ++++++------
     tests/paramgrill.c | 10 ++++++----
     7 files changed, 33 insertions(+), 24 deletions(-)
    
    diff --git a/examples/Makefile b/examples/Makefile
    index b84983f08..e279a537d 100644
    --- a/examples/Makefile
    +++ b/examples/Makefile
    @@ -46,7 +46,7 @@ clean:
             simple_compression simple_decompression \
             dictionary_compression dictionary_decompression \
             streaming_compression streaming_decompression \
    -		multiple_streaming_compression
    +        multiple_streaming_compression
     	@echo Cleaning completed
     
     test: all
    diff --git a/lib/Makefile b/lib/Makefile
    index f5f610372..cc109944d 100644
    --- a/lib/Makefile
    +++ b/lib/Makefile
    @@ -24,7 +24,9 @@ CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_
     CFLAGS  ?= -O3
     DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
                -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -           -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security
    +           -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    +           -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +           -Wbad-function-cast -Wredundant-decls
     CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS)
     
    diff --git a/programs/Makefile b/programs/Makefile
    index bb40253b9..9efa00074 100644
    --- a/programs/Makefile
    +++ b/programs/Makefile
    @@ -43,7 +43,9 @@ CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
     CFLAGS  ?= -O3
     DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
               -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -          -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security
    +          -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    +          -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +          -Wbad-function-cast -Wredundant-decls
     CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     
    @@ -56,7 +58,7 @@ ZDICT_FILES := $(ZSTDDIR)/dictBuilder/*.c
     ZSTDDECOMP_O = $(ZSTDDIR)/decompress/zstd_decompress.o
     
     ZSTD_LEGACY_SUPPORT ?= 4
    -ZSTDLEGACY_FILES:=
    +ZSTDLEGACY_FILES :=
     ifneq ($(ZSTD_LEGACY_SUPPORT), 0)
     ifeq ($(shell test $(ZSTD_LEGACY_SUPPORT) -lt 8; echo $$?), 0)
     	ZSTDLEGACY_FILES += $(shell ls $(ZSTDDIR)/legacy/*.c | grep 'v0[$(ZSTD_LEGACY_SUPPORT)-7]')
    diff --git a/tests/Makefile b/tests/Makefile
    index ea58c0fe5..560c36e1f 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -33,7 +33,9 @@ CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
     CFLAGS  ?= -O3
     CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
                -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -           -Wstrict-prototypes -Wundef -Wformat-security
    +           -Wstrict-prototypes -Wundef -Wformat-security \
    +           -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +           -Wbad-function-cast -Wredundant-decls
     CFLAGS  += $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     
    diff --git a/tests/datagencli.c b/tests/datagencli.c
    index 2f3ebc4d6..3bb634b75 100644
    --- a/tests/datagencli.c
    +++ b/tests/datagencli.c
    @@ -48,7 +48,8 @@ static int usage(const char* programName)
         DISPLAY( "Arguments :\n");
         DISPLAY( " -g#    : generate # data (default:%i)\n", SIZE_DEFAULT);
         DISPLAY( " -s#    : Select seed (default:%i)\n", SEED_DEFAULT);
    -    DISPLAY( " -P#    : Select compressibility in %% (default:%i%%)\n", COMPRESSIBILITY_DEFAULT);
    +    DISPLAY( " -P#    : Select compressibility in %% (default:%i%%)\n",
    +                        COMPRESSIBILITY_DEFAULT);
         DISPLAY( " -h     : display help and exit\n");
         return 0;
     }
    @@ -56,7 +57,7 @@ static int usage(const char* programName)
     
     int main(int argc, const char** argv)
     {
    -    double proba = (double)COMPRESSIBILITY_DEFAULT / 100;
    +    unsigned probaU32 = COMPRESSIBILITY_DEFAULT;
         double litProba = 0.0;
         U64 size = SIZE_DEFAULT;
         U32 seed = SEED_DEFAULT;
    @@ -94,11 +95,10 @@ int main(int argc, const char** argv)
                         break;
                     case 'P':
                         argument++;
    -                    proba=0.0;
    +                    probaU32=0.0;
                         while ((*argument>='0') && (*argument<='9'))
    -                        proba *= 10, proba += *argument++ - '0';
    -                    if (proba>100.) proba=100.;
    -                    proba /= 100.;
    +                        probaU32 *= 10, probaU32 += *argument++ - '0';
    +                    if (probaU32>100.) probaU32=100.;
                         break;
                     case 'L':   /* hidden argument : Literal distribution probability */
                         argument++;
    @@ -117,11 +117,12 @@ int main(int argc, const char** argv)
                     }
         }   }   }   /* for(argNb=1; argNb %s !! \n", benchName, ZSTD_getErrorName(benchResult)); exit(1); }
                 }
    -            averageTime = (((double)BMK_clockSpan(clockStart)) / CLOCKS_PER_SEC) / nbRounds;
    -            if (averageTime < bestTime) bestTime = averageTime;
    -            DISPLAY("%2i- %-30.30s : %7.1f MB/s  (%9u)\r", loopNb, benchName, (double)srcSize / (1 MB) / bestTime, (U32)benchResult);
    -    }   }
    +            {   clock_t const clockTotal = BMK_clockSpan(clockStart);
    +                double const averageTime = (double)clockTotal / CLOCKS_PER_SEC / nbRounds;
    +                if (averageTime < bestTime) bestTime = averageTime;
    +                DISPLAY("%2i- %-30.30s : %7.1f MB/s  (%9u)\r", loopNb, benchName, (double)srcSize / (1 MB) / bestTime, (U32)benchResult);
    +    }   }   }
         DISPLAY("%2u\n", benchNb);
     
     _cleanOut:
    diff --git a/tests/paramgrill.c b/tests/paramgrill.c
    index 9b032c0a6..1185c6649 100644
    --- a/tests/paramgrill.c
    +++ b/tests/paramgrill.c
    @@ -38,7 +38,7 @@
     #define GB *(1ULL<<30)
     
     #define NBLOOPS    2
    -#define TIMELOOP   (2 * CLOCKS_PER_SEC)
    +#define TIMELOOP  (2 * CLOCKS_PER_SEC)
     
     #define NB_LEVELS_TRACKED 30
     
    @@ -47,7 +47,7 @@ static const size_t maxMemory = (sizeof(size_t)==4)  ?  (2 GB - 64 MB) : (size_t
     #define COMPRESSIBILITY_DEFAULT 0.50
     static const size_t sampleSize = 10000000;
     
    -static const U32 g_grillDuration_s = 60000;   /* about 16 hours */
    +static const double g_grillDuration_s = 90000;   /* about 24 hours */
     static const clock_t g_maxParamTime = 15 * CLOCKS_PER_SEC;
     static const clock_t g_maxVariationTime = 60 * CLOCKS_PER_SEC;
     static const int g_maxNbVariations = 64;
    @@ -87,9 +87,11 @@ void BMK_SetNbIterations(int nbLoops)
     *  Private functions
     *********************************************************/
     
    -static clock_t BMK_clockSpan(clock_t cStart) { return clock() - cStart; }  /* works even if overflow ; max span ~ 30 mn */
    +/* works even if overflow ; max span ~ 30 mn */
    +static clock_t BMK_clockSpan(clock_t cStart) { return clock() - cStart; }
     
    -static U32 BMK_timeSpan(time_t tStart) { return (U32)difftime(time(NULL), tStart); }  /* accuracy in seconds only, span can be multiple years */
    +/* accuracy in seconds only, span can be multiple years */
    +static double BMK_timeSpan(time_t tStart) { return difftime(time(NULL), tStart); }
     
     
     static size_t BMK_findMaxMem(U64 requiredMem)
    
    From 133f0aee54e4617310d0d81c7e4e85aa6581c84c Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 15 May 2017 17:44:04 -0700
    Subject: [PATCH 051/400] fixed redundant declarations in legacy v0.5 and v0.7
     decoders
    
    triggered by new flag -Wredundant-decls
    ---
     lib/legacy/zstd_v05.c | 7 -------
     lib/legacy/zstd_v07.c | 2 --
     2 files changed, 9 deletions(-)
    
    diff --git a/lib/legacy/zstd_v05.c b/lib/legacy/zstd_v05.c
    index 7101503cd..e929618a3 100644
    --- a/lib/legacy/zstd_v05.c
    +++ b/lib/legacy/zstd_v05.c
    @@ -326,13 +326,6 @@ size_t ZSTDv05_decompress_usingPreparedDCtx(
     *  Streaming functions (direct mode)
     ****************************************/
     size_t ZSTDv05_decompressBegin(ZSTDv05_DCtx* dctx);
    -size_t ZSTDv05_decompressBegin_usingDict(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize);
    -void   ZSTDv05_copyDCtx(ZSTDv05_DCtx* dctx, const ZSTDv05_DCtx* preparedDCtx);
    -
    -size_t ZSTDv05_getFrameParams(ZSTDv05_parameters* params, const void* src, size_t srcSize);
    -
    -size_t ZSTDv05_nextSrcSizeToDecompress(ZSTDv05_DCtx* dctx);
    -size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     
     /*
       Streaming decompression, direct mode (bufferless)
    diff --git a/lib/legacy/zstd_v07.c b/lib/legacy/zstd_v07.c
    index 09a3f5b7c..6669b71ce 100644
    --- a/lib/legacy/zstd_v07.c
    +++ b/lib/legacy/zstd_v07.c
    @@ -2920,8 +2920,6 @@ typedef struct {
     void ZSTDv07_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq);
     
     /* custom memory allocation functions */
    -void* ZSTDv07_defaultAllocFunction(void* opaque, size_t size);
    -void ZSTDv07_defaultFreeFunction(void* opaque, void* address);
     static const ZSTDv07_customMem defaultCustomMem = { ZSTDv07_defaultAllocFunction, ZSTDv07_defaultFreeFunction, NULL };
     
     #endif   /* ZSTDv07_CCOMMON_H_MODULE */
    
    From 46ac9ade9bf566323adff6140460e715db5a6968 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 15 May 2017 18:15:08 -0700
    Subject: [PATCH 052/400] fixed vla warning on linux
    
    ---
     programs/util.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/programs/util.h b/programs/util.h
    index 5f437b2b2..54ae16227 100644
    --- a/programs/util.h
    +++ b/programs/util.h
    @@ -609,7 +609,7 @@ UTIL_STATIC int UTIL_countPhysicalCores(void)
     
         /* try to determine if there's hyperthreading */
         {   FILE* const cpuinfo = fopen("/proc/cpuinfo", "r");
    -        size_t const BUF_SIZE = 80;
    +#define BUF_SIZE 80
             char buff[BUF_SIZE];
     
             int siblings = 0;
    
    From 2d4d31c18a739ba46f2c392e7649a315bdb1df74 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 11:34:38 -0700
    Subject: [PATCH 053/400] removed gcc compilation flag -Wbad-function-cast
    
    It makes it more difficult to directly cast the result of a function,
    requiring to store the result in an intermediate variable.
    It does not necessarily help readability,
    and this restriction can be difficult to overcome in some constructions,
    like some macros.
    
    also : fixed minor Visual conversion warnings in datagencli.c
    ---
     lib/Makefile       | 8 ++++----
     programs/Makefile  | 8 ++++----
     tests/Makefile     | 8 ++++----
     tests/datagencli.c | 4 ++--
     4 files changed, 14 insertions(+), 14 deletions(-)
    
    diff --git a/lib/Makefile b/lib/Makefile
    index cc109944d..f492c6bd1 100644
    --- a/lib/Makefile
    +++ b/lib/Makefile
    @@ -23,10 +23,10 @@ VERSION?= $(LIBVER)
     CPPFLAGS+= -I. -I./common -DXXH_NAMESPACE=ZSTD_
     CFLAGS  ?= -O3
     DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
    -           -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -           -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    -           -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    -           -Wbad-function-cast -Wredundant-decls
    +            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    +            -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    +            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +            -Wredundant-decls
     CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS)
     
    diff --git a/programs/Makefile b/programs/Makefile
    index 9efa00074..ab2db7284 100644
    --- a/programs/Makefile
    +++ b/programs/Makefile
    @@ -42,10 +42,10 @@ CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
                -DXXH_NAMESPACE=ZSTD_   # because xxhash.o already compiled with this macro from library
     CFLAGS  ?= -O3
     DEBUGFLAGS = -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
    -          -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -          -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    -          -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    -          -Wbad-function-cast -Wredundant-decls
    +            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    +            -Wstrict-prototypes -Wundef -Wpointer-arith -Wformat-security \
    +            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +            -Wredundant-decls
     CFLAGS  += $(DEBUGFLAGS) $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     
    diff --git a/tests/Makefile b/tests/Makefile
    index 560c36e1f..c275c081f 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -32,10 +32,10 @@ CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
                $(DEBUGFLAG)
     CFLAGS  ?= -O3
     CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
    -           -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    -           -Wstrict-prototypes -Wundef -Wformat-security \
    -           -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    -           -Wbad-function-cast -Wredundant-decls
    +            -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
    +            -Wstrict-prototypes -Wundef -Wformat-security \
    +            -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    +            -Wredundant-decls
     CFLAGS  += $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     
    diff --git a/tests/datagencli.c b/tests/datagencli.c
    index 3bb634b75..8a81939d1 100644
    --- a/tests/datagencli.c
    +++ b/tests/datagencli.c
    @@ -95,10 +95,10 @@ int main(int argc, const char** argv)
                         break;
                     case 'P':
                         argument++;
    -                    probaU32=0.0;
    +                    probaU32 = 0;
                         while ((*argument>='0') && (*argument<='9'))
                             probaU32 *= 10, probaU32 += *argument++ - '0';
    -                    if (probaU32>100.) probaU32=100.;
    +                    if (probaU32>100) probaU32 = 100;
                         break;
                     case 'L':   /* hidden argument : Literal distribution probability */
                         argument++;
    
    From b3ebe9b77c2a6065a9f6fc63227ea594bb3d8903 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 12:56:38 -0700
    Subject: [PATCH 054/400] [linux-kernel] Separate xxhash into its own module
    
    ---
     contrib/linux-kernel/include/linux/xxhash.h   | 230 ++++++
     contrib/linux-kernel/lib/Kconfig.diff         |  17 -
     contrib/linux-kernel/lib/Makefile.diff        |  13 -
     contrib/linux-kernel/lib/xxhash.c             | 494 ++++++++++++
     contrib/linux-kernel/lib/zstd/Makefile        |   4 +-
     contrib/linux-kernel/lib/zstd/compress.c      |  10 +-
     contrib/linux-kernel/lib/zstd/decompress.c    |  12 +-
     contrib/linux-kernel/lib/zstd/xxhash.c        | 700 ----------------
     contrib/linux-kernel/lib/zstd/xxhash.h        | 235 ------
     contrib/linux-kernel/lib/zstd/zstd_internal.h |   2 +-
     contrib/linux-kernel/test/Makefile            |  11 +-
     .../linux-kernel/test/XXHashUserlandTest.cpp  | 178 ++++
     .../linux-kernel/test/include/linux/errno.h   |   6 +
     contrib/linux-kernel/xxhash.diff              | 762 ++++++++++++++++++
     14 files changed, 1694 insertions(+), 980 deletions(-)
     create mode 100644 contrib/linux-kernel/include/linux/xxhash.h
     delete mode 100644 contrib/linux-kernel/lib/Kconfig.diff
     delete mode 100644 contrib/linux-kernel/lib/Makefile.diff
     create mode 100644 contrib/linux-kernel/lib/xxhash.c
     delete mode 100644 contrib/linux-kernel/lib/zstd/xxhash.c
     delete mode 100644 contrib/linux-kernel/lib/zstd/xxhash.h
     create mode 100644 contrib/linux-kernel/test/XXHashUserlandTest.cpp
     create mode 100644 contrib/linux-kernel/test/include/linux/errno.h
     create mode 100644 contrib/linux-kernel/xxhash.diff
    
    diff --git a/contrib/linux-kernel/include/linux/xxhash.h b/contrib/linux-kernel/include/linux/xxhash.h
    new file mode 100644
    index 000000000..464433704
    --- /dev/null
    +++ b/contrib/linux-kernel/include/linux/xxhash.h
    @@ -0,0 +1,230 @@
    +/*
    + * xxHash - Extremely Fast Hash algorithm
    + * Copyright (C) 2012-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + *     notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + *     copyright notice, this list of conditions and the following disclaimer
    + *     in the documentation and/or other materials provided with the
    + *     distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * You can contact the author at:
    + * - xxHash homepage: http://cyan4973.github.io/xxHash/
    + * - xxHash source repository: https://github.com/Cyan4973/xxHash
    + */
    +
    +/*
    + * Notice extracted from xxHash homepage:
    + *
    + * xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
    + * It also successfully passes all tests from the SMHasher suite.
    + *
    + * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2
    + * Duo @3GHz)
    + *
    + * Name            Speed       Q.Score   Author
    + * xxHash          5.4 GB/s     10
    + * CrapWow         3.2 GB/s      2       Andrew
    + * MumurHash 3a    2.7 GB/s     10       Austin Appleby
    + * SpookyHash      2.0 GB/s     10       Bob Jenkins
    + * SBox            1.4 GB/s      9       Bret Mulvey
    + * Lookup3         1.2 GB/s      9       Bob Jenkins
    + * SuperFastHash   1.2 GB/s      1       Paul Hsieh
    + * CityHash64      1.05 GB/s    10       Pike & Alakuijala
    + * FNV             0.55 GB/s     5       Fowler, Noll, Vo
    + * CRC32           0.43 GB/s     9
    + * MD5-32          0.33 GB/s    10       Ronald L. Rivest
    + * SHA1-32         0.28 GB/s    10
    + *
    + * Q.Score is a measure of quality of the hash function.
    + * It depends on successfully passing SMHasher test set.
    + * 10 is a perfect score.
    + *
    + * A 64-bits version, named xxh64 offers much better speed,
    + * but for 64-bits applications only.
    + * Name     Speed on 64 bits    Speed on 32 bits
    + * xxh64       13.8 GB/s            1.9 GB/s
    + * xxh32        6.8 GB/s            6.0 GB/s
    + */
    +
    +#ifndef XXHASH_H
    +#define XXHASH_H
    +
    +#include 
    +
    +/*-****************************
    + * Simple Hash Functions
    + *****************************/
    +
    +/**
    + * xxh32() - calculate the 32-bit hash of the input with a given seed.
    + *
    + * @input:  The data to hash. Must not be NULL.
    + * @length: The length of the data to hash.
    + * @seed:   The seed can be used to alter the result predictably.
    + *
    + * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
    + *
    + * Return:  The 32-bit hash of the data.
    + */
    +uint32_t xxh32(const void *input, size_t length, uint32_t seed);
    +
    +/**
    + * xxh32() - calculate the 64-bit hash of the input with a given seed.
    + *
    + * @input:  The data to hash. Must not be NULL.
    + * @length: The length of the data to hash.
    + * @seed:   The seed can be used to alter the result predictably.
    + *
    + * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems.
    + *
    + * Return:  The 64-bit hash of the data.
    + */
    +uint64_t xxh64(const void *input, size_t length, uint64_t seed);
    +
    +/*-****************************
    + * Streaming Hash Functions
    + *****************************/
    +
    +/*
    + * These definitions are only meant to allow allocation of XXH state
    + * statically, on stack, or in a struct for example.
    + * Do not use members directly.
    + */
    +
    +/**
    + * struct xxh32_state - private xxh32 state, do not use members directly
    + */
    +struct xxh32_state {
    +	uint32_t total_len_32;
    +	uint32_t large_len;
    +	uint32_t v1;
    +	uint32_t v2;
    +	uint32_t v3;
    +	uint32_t v4;
    +	uint32_t mem32[4];
    +	uint32_t memsize;
    +};
    +
    +/**
    + * struct xxh32_state - private xxh64 state, do not use members directly
    + */
    +struct xxh64_state {
    +	uint64_t total_len;
    +	uint64_t v1;
    +	uint64_t v2;
    +	uint64_t v3;
    +	uint64_t v4;
    +	uint64_t mem64[4];
    +	uint32_t memsize;
    +};
    +
    +/**
    + * xxh32_reset() - reset the xxh32 state to start a new hashing operation
    + *
    + * @state: The xxh32 state to reset.
    + * @seed:  Initialize the hash state with this seed.
    + *
    + * Call this function on any xxh32_state to prepare for a new hashing operation.
    + */
    +void xxh32_reset(struct xxh32_state *state, uint32_t seed);
    +
    +/**
    + * xxh32_update() - hash the data given and update the xxh32 state
    + *
    + * @state:  The xxh32 state to update.
    + * @input:  The data to hash. Must not be NULL.
    + * @length: The length of the data to hash.
    + *
    + * After calling xxh32_reset() call xxh32_update() as many times as necessary.
    + *
    + * Return:  Zero on success, otherwise an error code.
    + */
    +int xxh32_update(struct xxh32_state *state, const void *input, size_t length);
    +
    +/**
    + * xxh32_digest() - produce the current xxh32 hash
    + *
    + * @state: Produce the current xxh32 hash of this state.
    + *
    + * A hash value can be produced at any time. It is still possible to continue
    + * inserting input into the hash state after a call to xxh32_digest(), and
    + * generate new hashes later on, by calling xxh32_digest() again.
    + *
    + * Return: The xxh32 hash stored in the state.
    + */
    +uint32_t xxh32_digest(const struct xxh32_state *state);
    +
    +/**
    + * xxh64_reset() - reset the xxh64 state to start a new hashing operation
    + *
    + * @state: The xxh32 state to reset.
    + * @seed:  Initialize the hash state with this seed.
    + */
    +void xxh64_reset(struct xxh64_state *state, uint64_t seed);
    +
    +/**
    + * xxh64_update() - hash the data given and update the xxh64 state
    + * @state:  The xxh64 state to update.
    + * @input:  The data to hash. Must not be NULL.
    + * @length: The length of the data to hash.
    + *
    + * After calling xxh64_reset() call xxh64_update() as many times as necessary.
    + *
    + * Return:  Zero on success, otherwise an error code.
    + */
    +int xxh64_update(struct xxh64_state *state, const void *input, size_t length);
    +
    +/**
    + * xxh64_digest() - produce the current xxh64 hash
    + *
    + * @state: Produce the current xxh64 hash of this state.
    + *
    + * A hash value can be produced at any time. It is still possible to continue
    + * inserting input into the hash state after a call to xxh64_digest(), and
    + * generate new hashes later on, by calling xxh64_digest() again.
    + *
    + * Return: The xxh64 hash stored in the state.
    + */
    +uint64_t xxh64_digest(const struct xxh64_state *state);
    +
    +/*-**************************
    + * Utils
    + ***************************/
    +
    +/**
    + * xxh32_copy_state() - copy the source state into the destination state
    + *
    + * @src: The source xxh32 state.
    + * @dst: The destination xxh32 state.
    + */
    +void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src);
    +
    +/**
    + * xxh64_copy_state() - copy the source state into the destination state
    + *
    + * @src: The source xxh64 state.
    + * @dst: The destination xxh64 state.
    + */
    +void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src);
    +
    +#endif /* XXHASH_H */
    diff --git a/contrib/linux-kernel/lib/Kconfig.diff b/contrib/linux-kernel/lib/Kconfig.diff
    deleted file mode 100644
    index 07ae5398f..000000000
    --- a/contrib/linux-kernel/lib/Kconfig.diff
    +++ /dev/null
    @@ -1,17 +0,0 @@
    -diff --git a/lib/Kconfig b/lib/Kconfig
    -index 260a80e..39d9347 100644
    ---- a/lib/Kconfig
    -+++ b/lib/Kconfig
    -@@ -239,6 +239,12 @@ config LZ4HC_COMPRESS
    - config LZ4_DECOMPRESS
    - 	tristate
    - 
    -+config ZSTD_COMPRESS
    -+	tristate
    -+
    -+config ZSTD_DECOMPRESS
    -+	tristate
    -+
    - source "lib/xz/Kconfig"
    - 
    - #
    diff --git a/contrib/linux-kernel/lib/Makefile.diff b/contrib/linux-kernel/lib/Makefile.diff
    deleted file mode 100644
    index be6182b39..000000000
    --- a/contrib/linux-kernel/lib/Makefile.diff
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -diff --git a/lib/Makefile b/lib/Makefile
    -index 50144a3..b30a998 100644
    ---- a/lib/Makefile
    -+++ b/lib/Makefile
    -@@ -106,6 +106,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
    - obj-$(CONFIG_LZ4_COMPRESS) += lz4/
    - obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/
    - obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
    -+obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
    -+obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
    - obj-$(CONFIG_XZ_DEC) += xz/
    - obj-$(CONFIG_RAID6_PQ) += raid6/
    - 
    diff --git a/contrib/linux-kernel/lib/xxhash.c b/contrib/linux-kernel/lib/xxhash.c
    new file mode 100644
    index 000000000..f367222c0
    --- /dev/null
    +++ b/contrib/linux-kernel/lib/xxhash.c
    @@ -0,0 +1,494 @@
    +/*
    + * xxHash - Extremely Fast Hash algorithm
    + * Copyright (C) 2012-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + *     notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + *     copyright notice, this list of conditions and the following disclaimer
    + *     in the documentation and/or other materials provided with the
    + *     distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * You can contact the author at:
    + * - xxHash homepage: http://cyan4973.github.io/xxHash/
    + * - xxHash source repository: https://github.com/Cyan4973/xxHash
    + */
    +
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +
    +/*-*************************************
    + * Macros
    + **************************************/
    +#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r)))
    +#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r)))
    +
    +#ifdef __LITTLE_ENDIAN
    +# define XXH_CPU_LITTLE_ENDIAN 1
    +#else
    +# define XXH_CPU_LITTLE_ENDIAN 0
    +#endif
    +
    +/*-*************************************
    + * Constants
    + **************************************/
    +static const uint32_t PRIME32_1 = 2654435761U;
    +static const uint32_t PRIME32_2 = 2246822519U;
    +static const uint32_t PRIME32_3 = 3266489917U;
    +static const uint32_t PRIME32_4 =  668265263U;
    +static const uint32_t PRIME32_5 =  374761393U;
    +
    +static const uint64_t PRIME64_1 = 11400714785074694791ULL;
    +static const uint64_t PRIME64_2 = 14029467366897019727ULL;
    +static const uint64_t PRIME64_3 =  1609587929392839161ULL;
    +static const uint64_t PRIME64_4 =  9650029242287828579ULL;
    +static const uint64_t PRIME64_5 =  2870177450012600261ULL;
    +
    +/*-**************************
    + *  Utils
    + ***************************/
    +void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
    +{
    +	memcpy(dst, src, sizeof(*dst));
    +}
    +EXPORT_SYMBOL(xxh32_copy_state);
    +
    +void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
    +{
    +	memcpy(dst, src, sizeof(*dst));
    +}
    +EXPORT_SYMBOL(xxh64_copy_state);
    +
    +/*-***************************
    + * Simple Hash Functions
    + ****************************/
    +static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
    +{
    +	seed += input * PRIME32_2;
    +	seed = xxh_rotl32(seed, 13);
    +	seed *= PRIME32_1;
    +	return seed;
    +}
    +
    +uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
    +{
    +	const uint8_t *p = (const uint8_t *)input;
    +	const uint8_t *b_end = p + len;
    +	uint32_t h32;
    +
    +	if (len >= 16) {
    +		const uint8_t *const limit = b_end - 16;
    +		uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
    +		uint32_t v2 = seed + PRIME32_2;
    +		uint32_t v3 = seed + 0;
    +		uint32_t v4 = seed - PRIME32_1;
    +
    +		do {
    +			v1 = xxh32_round(v1, get_unaligned_le32(p));
    +			p += 4;
    +			v2 = xxh32_round(v2, get_unaligned_le32(p));
    +			p += 4;
    +			v3 = xxh32_round(v3, get_unaligned_le32(p));
    +			p += 4;
    +			v4 = xxh32_round(v4, get_unaligned_le32(p));
    +			p += 4;
    +		} while (p <= limit);
    +
    +		h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) +
    +			xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18);
    +	} else {
    +		h32 = seed + PRIME32_5;
    +	}
    +
    +	h32 += (uint32_t)len;
    +
    +	while (p + 4 <= b_end) {
    +		h32 += get_unaligned_le32(p) * PRIME32_3;
    +		h32 = xxh_rotl32(h32, 17) * PRIME32_4;
    +		p += 4;
    +	}
    +
    +	while (p < b_end) {
    +		h32 += (*p) * PRIME32_5;
    +		h32 = xxh_rotl32(h32, 11) * PRIME32_1;
    +		p++;
    +	}
    +
    +	h32 ^= h32 >> 15;
    +	h32 *= PRIME32_2;
    +	h32 ^= h32 >> 13;
    +	h32 *= PRIME32_3;
    +	h32 ^= h32 >> 16;
    +
    +	return h32;
    +}
    +EXPORT_SYMBOL(xxh32);
    +
    +static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
    +{
    +	acc += input * PRIME64_2;
    +	acc = xxh_rotl64(acc, 31);
    +	acc *= PRIME64_1;
    +	return acc;
    +}
    +
    +static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
    +{
    +	val = xxh64_round(0, val);
    +	acc ^= val;
    +	acc = acc * PRIME64_1 + PRIME64_4;
    +	return acc;
    +}
    +
    +uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
    +{
    +	const uint8_t *p = (const uint8_t *)input;
    +	const uint8_t *const b_end = p + len;
    +	uint64_t h64;
    +
    +	if (len >= 32) {
    +		const uint8_t *const limit = b_end - 32;
    +		uint64_t v1 = seed + PRIME64_1 + PRIME64_2;
    +		uint64_t v2 = seed + PRIME64_2;
    +		uint64_t v3 = seed + 0;
    +		uint64_t v4 = seed - PRIME64_1;
    +
    +		do {
    +			v1 = xxh64_round(v1, get_unaligned_le64(p));
    +			p += 8;
    +			v2 = xxh64_round(v2, get_unaligned_le64(p));
    +			p += 8;
    +			v3 = xxh64_round(v3, get_unaligned_le64(p));
    +			p += 8;
    +			v4 = xxh64_round(v4, get_unaligned_le64(p));
    +			p += 8;
    +		} while (p <= limit);
    +
    +		h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
    +			xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
    +		h64 = xxh64_merge_round(h64, v1);
    +		h64 = xxh64_merge_round(h64, v2);
    +		h64 = xxh64_merge_round(h64, v3);
    +		h64 = xxh64_merge_round(h64, v4);
    +
    +	} else {
    +		h64  = seed + PRIME64_5;
    +	}
    +
    +	h64 += (uint64_t)len;
    +
    +	while (p + 8 <= b_end) {
    +		const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
    +
    +		h64 ^= k1;
    +		h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
    +		p += 8;
    +	}
    +
    +	if (p + 4 <= b_end) {
    +		h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
    +		h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    +		p += 4;
    +	}
    +
    +	while (p < b_end) {
    +		h64 ^= (*p) * PRIME64_5;
    +		h64 = xxh_rotl64(h64, 11) * PRIME64_1;
    +		p++;
    +	}
    +
    +	h64 ^= h64 >> 33;
    +	h64 *= PRIME64_2;
    +	h64 ^= h64 >> 29;
    +	h64 *= PRIME64_3;
    +	h64 ^= h64 >> 32;
    +
    +	return h64;
    +}
    +EXPORT_SYMBOL(xxh64);
    +
    +/*-**************************************************
    + * Advanced Hash Functions
    + ***************************************************/
    +void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
    +{
    +	/* use a local state for memcpy() to avoid strict-aliasing warnings */
    +	struct xxh32_state state;
    +
    +	memset(&state, 0, sizeof(state));
    +	state.v1 = seed + PRIME32_1 + PRIME32_2;
    +	state.v2 = seed + PRIME32_2;
    +	state.v3 = seed + 0;
    +	state.v4 = seed - PRIME32_1;
    +	memcpy(statePtr, &state, sizeof(state));
    +}
    +EXPORT_SYMBOL(xxh32_reset);
    +
    +void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
    +{
    +	/* use a local state for memcpy() to avoid strict-aliasing warnings */
    +	struct xxh64_state state;
    +
    +	memset(&state, 0, sizeof(state));
    +	state.v1 = seed + PRIME64_1 + PRIME64_2;
    +	state.v2 = seed + PRIME64_2;
    +	state.v3 = seed + 0;
    +	state.v4 = seed - PRIME64_1;
    +	memcpy(statePtr, &state, sizeof(state));
    +}
    +EXPORT_SYMBOL(xxh64_reset);
    +
    +int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
    +{
    +	const uint8_t *p = (const uint8_t *)input;
    +	const uint8_t *const b_end = p + len;
    +
    +	if (input == NULL)
    +		return -EINVAL;
    +
    +	state->total_len_32 += (uint32_t)len;
    +	state->large_len |= (len >= 16) | (state->total_len_32 >= 16);
    +
    +	if (state->memsize + len < 16) { /* fill in tmp buffer */
    +		memcpy((uint8_t *)(state->mem32) + state->memsize, input, len);
    +		state->memsize += (uint32_t)len;
    +		return 0;
    +	}
    +
    +	if (state->memsize) { /* some data left from previous update */
    +		const uint32_t *p32 = state->mem32;
    +
    +		memcpy((uint8_t *)(state->mem32) + state->memsize, input,
    +			16 - state->memsize);
    +
    +		state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32));
    +		p32++;
    +		state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32));
    +		p32++;
    +		state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32));
    +		p32++;
    +		state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32));
    +		p32++;
    +
    +		p += 16-state->memsize;
    +		state->memsize = 0;
    +	}
    +
    +	if (p <= b_end - 16) {
    +		const uint8_t *const limit = b_end - 16;
    +		uint32_t v1 = state->v1;
    +		uint32_t v2 = state->v2;
    +		uint32_t v3 = state->v3;
    +		uint32_t v4 = state->v4;
    +
    +		do {
    +			v1 = xxh32_round(v1, get_unaligned_le32(p));
    +			p += 4;
    +			v2 = xxh32_round(v2, get_unaligned_le32(p));
    +			p += 4;
    +			v3 = xxh32_round(v3, get_unaligned_le32(p));
    +			p += 4;
    +			v4 = xxh32_round(v4, get_unaligned_le32(p));
    +			p += 4;
    +		} while (p <= limit);
    +
    +		state->v1 = v1;
    +		state->v2 = v2;
    +		state->v3 = v3;
    +		state->v4 = v4;
    +	}
    +
    +	if (p < b_end) {
    +		memcpy(state->mem32, p, (size_t)(b_end-p));
    +		state->memsize = (uint32_t)(b_end-p);
    +	}
    +
    +	return 0;
    +}
    +EXPORT_SYMBOL(xxh32_update);
    +
    +uint32_t xxh32_digest(const struct xxh32_state *state)
    +{
    +	const uint8_t *p = (const uint8_t *)state->mem32;
    +	const uint8_t *const b_end = (const uint8_t *)(state->mem32) +
    +		state->memsize;
    +	uint32_t h32;
    +
    +	if (state->large_len) {
    +		h32 = xxh_rotl32(state->v1, 1) + xxh_rotl32(state->v2, 7) +
    +			xxh_rotl32(state->v3, 12) + xxh_rotl32(state->v4, 18);
    +	} else {
    +		h32 = state->v3 /* == seed */ + PRIME32_5;
    +	}
    +
    +	h32 += state->total_len_32;
    +
    +	while (p + 4 <= b_end) {
    +		h32 += get_unaligned_le32(p) * PRIME32_3;
    +		h32 = xxh_rotl32(h32, 17) * PRIME32_4;
    +		p += 4;
    +	}
    +
    +	while (p < b_end) {
    +		h32 += (*p) * PRIME32_5;
    +		h32 = xxh_rotl32(h32, 11) * PRIME32_1;
    +		p++;
    +	}
    +
    +	h32 ^= h32 >> 15;
    +	h32 *= PRIME32_2;
    +	h32 ^= h32 >> 13;
    +	h32 *= PRIME32_3;
    +	h32 ^= h32 >> 16;
    +
    +	return h32;
    +}
    +EXPORT_SYMBOL(xxh32_digest);
    +
    +int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
    +{
    +	const uint8_t *p = (const uint8_t *)input;
    +	const uint8_t *const b_end = p + len;
    +
    +	if (input == NULL)
    +		return -EINVAL;
    +
    +	state->total_len += len;
    +
    +	if (state->memsize + len < 32) { /* fill in tmp buffer */
    +		memcpy(((uint8_t *)state->mem64) + state->memsize, input, len);
    +		state->memsize += (uint32_t)len;
    +		return 0;
    +	}
    +
    +	if (state->memsize) { /* tmp buffer is full */
    +		const uint64_t *p64 = state->mem64;
    +
    +		memcpy(((uint8_t *)p64) + state->memsize, input,
    +			32 - state->memsize);
    +
    +		state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64));
    +		p64++;
    +		state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64));
    +		p64++;
    +		state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64));
    +		p64++;
    +		state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64));
    +
    +		p += 32 - state->memsize;
    +		state->memsize = 0;
    +	}
    +
    +	if (p + 32 <= b_end) {
    +		const uint8_t *const limit = b_end - 32;
    +		uint64_t v1 = state->v1;
    +		uint64_t v2 = state->v2;
    +		uint64_t v3 = state->v3;
    +		uint64_t v4 = state->v4;
    +
    +		do {
    +			v1 = xxh64_round(v1, get_unaligned_le64(p));
    +			p += 8;
    +			v2 = xxh64_round(v2, get_unaligned_le64(p));
    +			p += 8;
    +			v3 = xxh64_round(v3, get_unaligned_le64(p));
    +			p += 8;
    +			v4 = xxh64_round(v4, get_unaligned_le64(p));
    +			p += 8;
    +		} while (p <= limit);
    +
    +		state->v1 = v1;
    +		state->v2 = v2;
    +		state->v3 = v3;
    +		state->v4 = v4;
    +	}
    +
    +	if (p < b_end) {
    +		memcpy(state->mem64, p, (size_t)(b_end-p));
    +		state->memsize = (uint32_t)(b_end - p);
    +	}
    +
    +	return 0;
    +}
    +EXPORT_SYMBOL(xxh64_update);
    +
    +uint64_t xxh64_digest(const struct xxh64_state *state)
    +{
    +	const uint8_t *p = (const uint8_t *)state->mem64;
    +	const uint8_t *const b_end = (const uint8_t *)state->mem64 +
    +		state->memsize;
    +	uint64_t h64;
    +
    +	if (state->total_len >= 32) {
    +		const uint64_t v1 = state->v1;
    +		const uint64_t v2 = state->v2;
    +		const uint64_t v3 = state->v3;
    +		const uint64_t v4 = state->v4;
    +
    +		h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
    +			xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
    +		h64 = xxh64_merge_round(h64, v1);
    +		h64 = xxh64_merge_round(h64, v2);
    +		h64 = xxh64_merge_round(h64, v3);
    +		h64 = xxh64_merge_round(h64, v4);
    +	} else {
    +		h64  = state->v3 + PRIME64_5;
    +	}
    +
    +	h64 += (uint64_t)state->total_len;
    +
    +	while (p + 8 <= b_end) {
    +		const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
    +
    +		h64 ^= k1;
    +		h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
    +		p += 8;
    +	}
    +
    +	if (p + 4 <= b_end) {
    +		h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
    +		h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    +		p += 4;
    +	}
    +
    +	while (p < b_end) {
    +		h64 ^= (*p) * PRIME64_5;
    +		h64 = xxh_rotl64(h64, 11) * PRIME64_1;
    +		p++;
    +	}
    +
    +	h64 ^= h64 >> 33;
    +	h64 *= PRIME64_2;
    +	h64 ^= h64 >> 29;
    +	h64 *= PRIME64_3;
    +	h64 ^= h64 >> 32;
    +
    +	return h64;
    +}
    +EXPORT_SYMBOL(xxh64_digest);
    +
    +MODULE_LICENSE("Dual BSD/GPL");
    +MODULE_DESCRIPTION("xxHash");
    diff --git a/contrib/linux-kernel/lib/zstd/Makefile b/contrib/linux-kernel/lib/zstd/Makefile
    index 067f68d19..aa5eb4d68 100644
    --- a/contrib/linux-kernel/lib/zstd/Makefile
    +++ b/contrib/linux-kernel/lib/zstd/Makefile
    @@ -3,7 +3,7 @@ obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
     
     ccflags-y += -O3
     
    -zstd_compress-y := entropy_common.o fse_decompress.o xxhash.o zstd_common.o \
    +zstd_compress-y := entropy_common.o fse_decompress.o zstd_common.o \
     				fse_compress.o huf_compress.o compress.o
    -zstd_decompress-y := entropy_common.o fse_decompress.o xxhash.o zstd_common.o \
    +zstd_decompress-y := entropy_common.o fse_decompress.o zstd_common.o \
     				huf_decompress.o decompress.o
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index 5f6d955a4..79c3207fe 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -73,7 +73,7 @@ struct ZSTD_CCtx_s {
     	size_t workSpaceSize;
     	size_t blockSize;
     	U64 frameContentSize;
    -	XXH64_state_t xxhState;
    +	struct xxh64_state xxhState;
     	ZSTD_customMem customMem;
     
     	seqStore_t seqStore;    /* sequences storage ptrs */
    @@ -221,7 +221,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra
     	cctx->loadedDictEnd = 0;
     	{ int i; for (i=0; irep[i] = repStartValue[i]; }
     	cctx->seqStore.litLengthSum = 0;  /* force reset of btopt stats */
    -	XXH64_reset(&cctx->xxhState, 0);
    +	xxh64_reset(&cctx->xxhState, 0);
     	return 0;
     }
     
    @@ -264,7 +264,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
     		}   }
     
     		if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace);   /* reset tables only */
    -		XXH64_reset(&zc->xxhState, 0);
    +		xxh64_reset(&zc->xxhState, 0);
     		zc->hashLog3 = hashLog3;
     		zc->hashTable = (U32*)(zc->workSpace);
     		zc->chainTable = zc->hashTable + hSize;
    @@ -2322,7 +2322,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     	U32 const maxDist = 1 << cctx->params.cParams.windowLog;
     
     	if (cctx->params.fParams.checksumFlag && srcSize)
    -		XXH64_update(&cctx->xxhState, src, srcSize);
    +		xxh64_update(&cctx->xxhState, src, srcSize);
     
     	while (remaining) {
     		U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
    @@ -2720,7 +2720,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
     	}
     
     	if (cctx->params.fParams.checksumFlag) {
    -		U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
    +		U32 const checksum = (U32) xxh64_digest(&cctx->xxhState);
     		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
     		MEM_writeLE32(op, checksum);
     		op += 4;
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 94f5fd560..98508b10d 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -81,7 +81,7 @@ struct ZSTD_DCtx_s
     	ZSTD_dStage stage;
     	U32 litEntropy;
     	U32 fseEntropy;
    -	XXH64_state_t xxhState;
    +	struct xxh64_state xxhState;
     	size_t headerSize;
     	U32 dictID;
     	const BYTE* litPtr;
    @@ -366,7 +366,7 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he
     	if (ZSTD_isError(result)) return result;  /* invalid header */
     	if (result>0) return ERROR(srcSize_wrong);   /* headerSize too small */
     	if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
    -	if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
    +	if (dctx->fParams.checksumFlag) xxh64_reset(&dctx->xxhState, 0);
     	return 0;
     }
     
    @@ -1517,7 +1517,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     		}
     
     		if (ZSTD_isError(decodedSize)) return decodedSize;
    -		if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
    +		if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, op, decodedSize);
     		op += decodedSize;
     		ip += cBlockSize;
     		remainingSize -= cBlockSize;
    @@ -1525,7 +1525,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     	}
     
     	if (dctx->fParams.checksumFlag) {   /* Frame content checksum verification */
    -		U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
    +		U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState);
     		U32 checkRead;
     		if (remainingSize<4) return ERROR(checksum_wrong);
     		checkRead = MEM_readLE32(ip);
    @@ -1731,7 +1731,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     				return ERROR(corruption_detected);
     			}
     			if (ZSTD_isError(rSize)) return rSize;
    -			if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
    +			if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, dst, rSize);
     
     			if (dctx->stage == ZSTDds_decompressLastBlock) {   /* end of frame */
     				if (dctx->fParams.checksumFlag) {  /* another round for frame checksum */
    @@ -1749,7 +1749,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     			return rSize;
     		}
     	case ZSTDds_checkChecksum:
    -		{   U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
    +		{   U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
     			U32 const check32 = MEM_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
     			if (check32 != h32) return ERROR(checksum_wrong);
     			dctx->expected = 0;
    diff --git a/contrib/linux-kernel/lib/zstd/xxhash.c b/contrib/linux-kernel/lib/zstd/xxhash.c
    deleted file mode 100644
    index 0d301ad86..000000000
    --- a/contrib/linux-kernel/lib/zstd/xxhash.c
    +++ /dev/null
    @@ -1,700 +0,0 @@
    -/*
    -*  xxHash - Fast Hash algorithm
    -*  Copyright (C) 2012-2016, Yann Collet
    -*
    -*  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -*
    -*  Redistribution and use in source and binary forms, with or without
    -*  modification, are permitted provided that the following conditions are
    -*  met:
    -*
    -*  * Redistributions of source code must retain the above copyright
    -*  notice, this list of conditions and the following disclaimer.
    -*  * Redistributions in binary form must reproduce the above
    -*  copyright notice, this list of conditions and the following disclaimer
    -*  in the documentation and/or other materials provided with the
    -*  distribution.
    -*
    -*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -*
    -*  You can contact the author at :
    -*  - xxHash homepage: http://www.xxhash.com
    -*  - xxHash source repository : https://github.com/Cyan4973/xxHash
    -*/
    -
    -
    -/* *************************************
    -*  Tuning parameters
    -***************************************/
    -/*!XXH_ACCEPT_NULL_INPUT_POINTER :
    - * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
    - * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
    - * By default, this option is disabled. To enable it, uncomment below define :
    - */
    -/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
    -
    -/*!XXH_FORCE_NATIVE_FORMAT :
    - * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
    - * Results are therefore identical for little-endian and big-endian CPU.
    - * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
    - * Should endian-independance be of no importance for your application, you may set the #define below to 1,
    - * to improve speed for Big-endian CPU.
    - * This option has no impact on Little_Endian CPU.
    - */
    -#define XXH_FORCE_NATIVE_FORMAT 0
    -
    -/*!XXH_FORCE_ALIGN_CHECK :
    - * This is a minor performance trick, only useful with lots of very small keys.
    - * It means : check for aligned/unaligned input.
    - * The check costs one initial branch per hash; set to 0 when the input data
    - * is guaranteed to be aligned.
    - */
    -#define XXH_FORCE_ALIGN_CHECK 0
    -
    -
    -/* *************************************
    -*  Includes & Memory related functions
    -***************************************/
    -/* Modify the local functions below should you wish to use some other memory routines */
    -/* for memcpy() */
    -#include 
    -static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
    -
    -#include "xxhash.h"
    -#include "mem.h"
    -
    -
    -/* *************************************
    -*  Compiler Specific Options
    -***************************************/
    -#include 
    -#define FORCE_INLINE static __always_inline
    -
    -
    -/* ****************************************
    -*  Compiler-specific Functions and Macros
    -******************************************/
    -#define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
    -#define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
    -
    -/* *************************************
    -*  Architecture Macros
    -***************************************/
    -typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
    -
    -/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
    -#ifndef XXH_CPU_LITTLE_ENDIAN
    -#   define XXH_CPU_LITTLE_ENDIAN   MEM_LITTLE_ENDIAN
    -#endif
    -
    -
    -/* ***************************
    -*  Memory reads
    -*****************************/
    -typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
    -
    -FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
    -{
    -	(void)endian;
    -	(void)align;
    -	return MEM_readLE32(ptr);
    -}
    -
    -FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
    -{
    -	return XXH_readLE32_align(ptr, endian, XXH_unaligned);
    -}
    -
    -static U32 XXH_readBE32(const void* ptr)
    -{
    -	return MEM_readBE32(ptr);
    -}
    -
    -FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
    -{
    -	(void)endian;
    -	(void)align;
    -	return MEM_readLE64(ptr);
    -}
    -
    -FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
    -{
    -	return XXH_readLE64_align(ptr, endian, XXH_unaligned);
    -}
    -
    -static U64 XXH_readBE64(const void* ptr)
    -{
    -	return MEM_readBE64(ptr);
    -}
    -
    -
    -/* *************************************
    -*  Macros
    -***************************************/
    -#define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(int)(!!(c)) }; }    /* use only *after* variable declarations */
    -
    -
    -/* *************************************
    -*  Constants
    -***************************************/
    -static const U32 PRIME32_1 = 2654435761U;
    -static const U32 PRIME32_2 = 2246822519U;
    -static const U32 PRIME32_3 = 3266489917U;
    -static const U32 PRIME32_4 =  668265263U;
    -static const U32 PRIME32_5 =  374761393U;
    -
    -static const U64 PRIME64_1 = 11400714785074694791ULL;
    -static const U64 PRIME64_2 = 14029467366897019727ULL;
    -static const U64 PRIME64_3 =  1609587929392839161ULL;
    -static const U64 PRIME64_4 =  9650029242287828579ULL;
    -static const U64 PRIME64_5 =  2870177450012600261ULL;
    -
    -XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
    -
    -
    -/* **************************
    -*  Utils
    -****************************/
    -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
    -{
    -	memcpy(dstState, srcState, sizeof(*dstState));
    -}
    -
    -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
    -{
    -	memcpy(dstState, srcState, sizeof(*dstState));
    -}
    -
    -
    -/* ***************************
    -*  Simple Hash Functions
    -*****************************/
    -
    -static U32 XXH32_round(U32 seed, U32 input)
    -{
    -	seed += input * PRIME32_2;
    -	seed  = XXH_rotl32(seed, 13);
    -	seed *= PRIME32_1;
    -	return seed;
    -}
    -
    -FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
    -{
    -	const BYTE* p = (const BYTE*)input;
    -	const BYTE* bEnd = p + len;
    -	U32 h32;
    -#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
    -
    -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
    -	if (p==NULL) {
    -		len=0;
    -		bEnd=p=(const BYTE*)(size_t)16;
    -	}
    -#endif
    -
    -	if (len>=16) {
    -		const BYTE* const limit = bEnd - 16;
    -		U32 v1 = seed + PRIME32_1 + PRIME32_2;
    -		U32 v2 = seed + PRIME32_2;
    -		U32 v3 = seed + 0;
    -		U32 v4 = seed - PRIME32_1;
    -
    -		do {
    -			v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
    -			v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
    -			v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
    -			v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
    -		} while (p<=limit);
    -
    -		h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
    -	} else {
    -		h32  = seed + PRIME32_5;
    -	}
    -
    -	h32 += (U32) len;
    -
    -	while (p+4<=bEnd) {
    -		h32 += XXH_get32bits(p) * PRIME32_3;
    -		h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;
    -		p+=4;
    -	}
    -
    -	while (p> 15;
    -	h32 *= PRIME32_2;
    -	h32 ^= h32 >> 13;
    -	h32 *= PRIME32_3;
    -	h32 ^= h32 >> 16;
    -
    -	return h32;
    -}
    -
    -
    -XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
    -{
    -#if 0
    -	/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
    -	XXH32_CREATESTATE_STATIC(state);
    -	XXH32_reset(state, seed);
    -	XXH32_update(state, input, len);
    -	return XXH32_digest(state);
    -#else
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if (XXH_FORCE_ALIGN_CHECK) {
    -		if ((((size_t)input) & 3) == 0) {   /* Input is 4-bytes aligned, leverage the speed benefit */
    -			if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -				return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
    -			else
    -				return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
    -	}   }
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
    -	else
    -		return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
    -#endif
    -}
    -
    -
    -static U64 XXH64_round(U64 acc, U64 input)
    -{
    -	acc += input * PRIME64_2;
    -	acc  = XXH_rotl64(acc, 31);
    -	acc *= PRIME64_1;
    -	return acc;
    -}
    -
    -static U64 XXH64_mergeRound(U64 acc, U64 val)
    -{
    -	val  = XXH64_round(0, val);
    -	acc ^= val;
    -	acc  = acc * PRIME64_1 + PRIME64_4;
    -	return acc;
    -}
    -
    -FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
    -{
    -	const BYTE* p = (const BYTE*)input;
    -	const BYTE* const bEnd = p + len;
    -	U64 h64;
    -#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
    -
    -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
    -	if (p==NULL) {
    -		len=0;
    -		bEnd=p=(const BYTE*)(size_t)32;
    -	}
    -#endif
    -
    -	if (len>=32) {
    -		const BYTE* const limit = bEnd - 32;
    -		U64 v1 = seed + PRIME64_1 + PRIME64_2;
    -		U64 v2 = seed + PRIME64_2;
    -		U64 v3 = seed + 0;
    -		U64 v4 = seed - PRIME64_1;
    -
    -		do {
    -			v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
    -			v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
    -			v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
    -			v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
    -		} while (p<=limit);
    -
    -		h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
    -		h64 = XXH64_mergeRound(h64, v1);
    -		h64 = XXH64_mergeRound(h64, v2);
    -		h64 = XXH64_mergeRound(h64, v3);
    -		h64 = XXH64_mergeRound(h64, v4);
    -
    -	} else {
    -		h64  = seed + PRIME64_5;
    -	}
    -
    -	h64 += (U64) len;
    -
    -	while (p+8<=bEnd) {
    -		U64 const k1 = XXH64_round(0, XXH_get64bits(p));
    -		h64 ^= k1;
    -		h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
    -		p+=8;
    -	}
    -
    -	if (p+4<=bEnd) {
    -		h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
    -		h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    -		p+=4;
    -	}
    -
    -	while (p> 33;
    -	h64 *= PRIME64_2;
    -	h64 ^= h64 >> 29;
    -	h64 *= PRIME64_3;
    -	h64 ^= h64 >> 32;
    -
    -	return h64;
    -}
    -
    -
    -XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
    -{
    -#if 0
    -	/* Simple version, good for code maintenance, but unfortunately slow for small inputs */
    -	XXH64_CREATESTATE_STATIC(state);
    -	XXH64_reset(state, seed);
    -	XXH64_update(state, input, len);
    -	return XXH64_digest(state);
    -#else
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if (XXH_FORCE_ALIGN_CHECK) {
    -		if ((((size_t)input) & 7)==0) {  /* Input is aligned, let's leverage the speed advantage */
    -			if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -				return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
    -			else
    -				return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
    -	}   }
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
    -	else
    -		return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
    -#endif
    -}
    -
    -
    -/* **************************************************
    -*  Advanced Hash Functions
    -****************************************************/
    -
    -
    -/*** Hash feed ***/
    -
    -XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
    -{
    -	XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
    -	memset(&state, 0, sizeof(state)-4);   /* do not write into reserved, for future removal */
    -	state.v1 = seed + PRIME32_1 + PRIME32_2;
    -	state.v2 = seed + PRIME32_2;
    -	state.v3 = seed + 0;
    -	state.v4 = seed - PRIME32_1;
    -	memcpy(statePtr, &state, sizeof(state));
    -	return XXH_OK;
    -}
    -
    -
    -XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
    -{
    -	XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
    -	memset(&state, 0, sizeof(state)-8);   /* do not write into reserved, for future removal */
    -	state.v1 = seed + PRIME64_1 + PRIME64_2;
    -	state.v2 = seed + PRIME64_2;
    -	state.v3 = seed + 0;
    -	state.v4 = seed - PRIME64_1;
    -	memcpy(statePtr, &state, sizeof(state));
    -	return XXH_OK;
    -}
    -
    -
    -FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
    -{
    -	const BYTE* p = (const BYTE*)input;
    -	const BYTE* const bEnd = p + len;
    -
    -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
    -	if (input==NULL) return XXH_ERROR;
    -#endif
    -
    -	state->total_len_32 += (unsigned)len;
    -	state->large_len |= (len>=16) | (state->total_len_32>=16);
    -
    -	if (state->memsize + len < 16)  {   /* fill in tmp buffer */
    -		XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
    -		state->memsize += (unsigned)len;
    -		return XXH_OK;
    -	}
    -
    -	if (state->memsize) {   /* some data left from previous update */
    -		XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
    -		{   const U32* p32 = state->mem32;
    -			state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
    -			state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
    -			state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
    -			state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
    -		}
    -		p += 16-state->memsize;
    -		state->memsize = 0;
    -	}
    -
    -	if (p <= bEnd-16) {
    -		const BYTE* const limit = bEnd - 16;
    -		U32 v1 = state->v1;
    -		U32 v2 = state->v2;
    -		U32 v3 = state->v3;
    -		U32 v4 = state->v4;
    -
    -		do {
    -			v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
    -			v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
    -			v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
    -			v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
    -		} while (p<=limit);
    -
    -		state->v1 = v1;
    -		state->v2 = v2;
    -		state->v3 = v3;
    -		state->v4 = v4;
    -	}
    -
    -	if (p < bEnd) {
    -		XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
    -		state->memsize = (unsigned)(bEnd-p);
    -	}
    -
    -	return XXH_OK;
    -}
    -
    -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
    -{
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
    -	else
    -		return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
    -}
    -
    -
    -
    -FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
    -{
    -	const BYTE * p = (const BYTE*)state->mem32;
    -	const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
    -	U32 h32;
    -
    -	if (state->large_len) {
    -		h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
    -	} else {
    -		h32 = state->v3 /* == seed */ + PRIME32_5;
    -	}
    -
    -	h32 += state->total_len_32;
    -
    -	while (p+4<=bEnd) {
    -		h32 += XXH_readLE32(p, endian) * PRIME32_3;
    -		h32  = XXH_rotl32(h32, 17) * PRIME32_4;
    -		p+=4;
    -	}
    -
    -	while (p> 15;
    -	h32 *= PRIME32_2;
    -	h32 ^= h32 >> 13;
    -	h32 *= PRIME32_3;
    -	h32 ^= h32 >> 16;
    -
    -	return h32;
    -}
    -
    -
    -XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
    -{
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH32_digest_endian(state_in, XXH_littleEndian);
    -	else
    -		return XXH32_digest_endian(state_in, XXH_bigEndian);
    -}
    -
    -
    -
    -/* **** XXH64 **** */
    -
    -FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
    -{
    -	const BYTE* p = (const BYTE*)input;
    -	const BYTE* const bEnd = p + len;
    -
    -#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
    -	if (input==NULL) return XXH_ERROR;
    -#endif
    -
    -	state->total_len += len;
    -
    -	if (state->memsize + len < 32) {  /* fill in tmp buffer */
    -		XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
    -		state->memsize += (U32)len;
    -		return XXH_OK;
    -	}
    -
    -	if (state->memsize) {   /* tmp buffer is full */
    -		XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
    -		state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
    -		state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
    -		state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
    -		state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
    -		p += 32-state->memsize;
    -		state->memsize = 0;
    -	}
    -
    -	if (p+32 <= bEnd) {
    -		const BYTE* const limit = bEnd - 32;
    -		U64 v1 = state->v1;
    -		U64 v2 = state->v2;
    -		U64 v3 = state->v3;
    -		U64 v4 = state->v4;
    -
    -		do {
    -			v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
    -			v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
    -			v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
    -			v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
    -		} while (p<=limit);
    -
    -		state->v1 = v1;
    -		state->v2 = v2;
    -		state->v3 = v3;
    -		state->v4 = v4;
    -	}
    -
    -	if (p < bEnd) {
    -		XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
    -		state->memsize = (unsigned)(bEnd-p);
    -	}
    -
    -	return XXH_OK;
    -}
    -
    -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
    -{
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
    -	else
    -		return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
    -}
    -
    -
    -
    -FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
    -{
    -	const BYTE * p = (const BYTE*)state->mem64;
    -	const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
    -	U64 h64;
    -
    -	if (state->total_len >= 32) {
    -		U64 const v1 = state->v1;
    -		U64 const v2 = state->v2;
    -		U64 const v3 = state->v3;
    -		U64 const v4 = state->v4;
    -
    -		h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
    -		h64 = XXH64_mergeRound(h64, v1);
    -		h64 = XXH64_mergeRound(h64, v2);
    -		h64 = XXH64_mergeRound(h64, v3);
    -		h64 = XXH64_mergeRound(h64, v4);
    -	} else {
    -		h64  = state->v3 + PRIME64_5;
    -	}
    -
    -	h64 += (U64) state->total_len;
    -
    -	while (p+8<=bEnd) {
    -		U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
    -		h64 ^= k1;
    -		h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
    -		p+=8;
    -	}
    -
    -	if (p+4<=bEnd) {
    -		h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
    -		h64  = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    -		p+=4;
    -	}
    -
    -	while (p> 33;
    -	h64 *= PRIME64_2;
    -	h64 ^= h64 >> 29;
    -	h64 *= PRIME64_3;
    -	h64 ^= h64 >> 32;
    -
    -	return h64;
    -}
    -
    -
    -XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
    -{
    -	XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
    -
    -	if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
    -		return XXH64_digest_endian(state_in, XXH_littleEndian);
    -	else
    -		return XXH64_digest_endian(state_in, XXH_bigEndian);
    -}
    -
    -
    -/* **************************
    -*  Canonical representation
    -****************************/
    -
    -/*! Default XXH result types are basic unsigned 32 and 64 bits.
    -*   The canonical representation follows human-readable write convention, aka big-endian (large digits first).
    -*   These functions allow transformation of hash result into and from its canonical format.
    -*   This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
    -*/
    -
    -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
    -{
    -	XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
    -	MEM_writeBE32(dst, hash);
    -}
    -
    -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
    -{
    -	XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
    -	MEM_writeBE64(dst, hash);
    -}
    -
    -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
    -{
    -	return XXH_readBE32(src);
    -}
    -
    -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
    -{
    -	return XXH_readBE64(src);
    -}
    diff --git a/contrib/linux-kernel/lib/zstd/xxhash.h b/contrib/linux-kernel/lib/zstd/xxhash.h
    deleted file mode 100644
    index 974a81c48..000000000
    --- a/contrib/linux-kernel/lib/zstd/xxhash.h
    +++ /dev/null
    @@ -1,235 +0,0 @@
    -/*
    -   xxHash - Extremely Fast Hash algorithm
    -   Header File
    -   Copyright (C) 2012-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -   You can contact the author at :
    -   - xxHash source repository : https://github.com/Cyan4973/xxHash
    -*/
    -
    -/* Notice extracted from xxHash homepage :
    -
    -xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
    -It also successfully passes all tests from the SMHasher suite.
    -
    -Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
    -
    -Name            Speed       Q.Score   Author
    -xxHash          5.4 GB/s     10
    -CrapWow         3.2 GB/s      2       Andrew
    -MumurHash 3a    2.7 GB/s     10       Austin Appleby
    -SpookyHash      2.0 GB/s     10       Bob Jenkins
    -SBox            1.4 GB/s      9       Bret Mulvey
    -Lookup3         1.2 GB/s      9       Bob Jenkins
    -SuperFastHash   1.2 GB/s      1       Paul Hsieh
    -CityHash64      1.05 GB/s    10       Pike & Alakuijala
    -FNV             0.55 GB/s     5       Fowler, Noll, Vo
    -CRC32           0.43 GB/s     9
    -MD5-32          0.33 GB/s    10       Ronald L. Rivest
    -SHA1-32         0.28 GB/s    10
    -
    -Q.Score is a measure of quality of the hash function.
    -It depends on successfully passing SMHasher test set.
    -10 is a perfect score.
    -
    -A 64-bits version, named XXH64, is available since r35.
    -It offers much better speed, but for 64-bits applications only.
    -Name     Speed on 64 bits    Speed on 32 bits
    -XXH64       13.8 GB/s            1.9 GB/s
    -XXH32        6.8 GB/s            6.0 GB/s
    -*/
    -
    -#ifndef XXHASH_H_5627135585666179
    -#define XXHASH_H_5627135585666179 1
    -
    -
    -/* ****************************
    -*  Definitions
    -******************************/
    -#include    /* size_t */
    -typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
    -
    -
    -/* ****************************
    -*  API modifier
    -******************************/
    -/** XXH_PRIVATE_API
    -*   This is useful if you want to include xxhash functions in `static` mode
    -*   in order to inline them, and remove their symbol from the public list.
    -*   Methodology :
    -*     #define XXH_PRIVATE_API
    -*     #include "xxhash.h"
    -*   `xxhash.c` is automatically included.
    -*   It's not useful to compile and link it as a separate module anymore.
    -*/
    -#define XXH_PUBLIC_API   /* do nothing */
    -
    -/*!XXH_NAMESPACE, aka Namespace Emulation :
    -
    -If you want to include _and expose_ xxHash functions from within your own library,
    -but also want to avoid symbol collisions with another library which also includes xxHash,
    -
    -you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
    -with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values).
    -
    -Note that no change is required within the calling program as long as it includes `xxhash.h` :
    -regular symbol name will be automatically translated by this header.
    -*/
    -
    -
    -/* *************************************
    -*  Version
    -***************************************/
    -#define XXH_VERSION_MAJOR    0
    -#define XXH_VERSION_MINOR    6
    -#define XXH_VERSION_RELEASE  2
    -#define XXH_VERSION_NUMBER  (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
    -XXH_PUBLIC_API unsigned XXH_versionNumber (void);
    -
    -
    -/* ****************************
    -*  Simple Hash Functions
    -******************************/
    -typedef unsigned int       XXH32_hash_t;
    -typedef unsigned long long XXH64_hash_t;
    -
    -XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
    -XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
    -
    -/*!
    -XXH32() :
    -	Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
    -	The memory between input & input+length must be valid (allocated and read-accessible).
    -	"seed" can be used to alter the result predictably.
    -	Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
    -XXH64() :
    -	Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
    -	"seed" can be used to alter the result predictably.
    -	This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
    -*/
    -
    -
    -/* ****************************
    -*  Streaming Hash Functions
    -******************************/
    -typedef struct XXH32_state_s XXH32_state_t;   /* incomplete type */
    -typedef struct XXH64_state_s XXH64_state_t;   /* incomplete type */
    -
    -
    -/* hash streaming */
    -
    -XXH_PUBLIC_API XXH_errorcode XXH32_reset  (XXH32_state_t* statePtr, unsigned int seed);
    -XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
    -XXH_PUBLIC_API XXH32_hash_t  XXH32_digest (const XXH32_state_t* statePtr);
    -
    -XXH_PUBLIC_API XXH_errorcode XXH64_reset  (XXH64_state_t* statePtr, unsigned long long seed);
    -XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
    -XXH_PUBLIC_API XXH64_hash_t  XXH64_digest (const XXH64_state_t* statePtr);
    -
    -/*
    -These functions generate the xxHash of an input provided in multiple segments.
    -Note that, for small input, they are slower than single-call functions, due to state management.
    -For small input, prefer `XXH32()` and `XXH64()` .
    -
    -XXH state must first be allocated, using XXH*_createState() .
    -
    -Start a new hash by initializing state with a seed, using XXH*_reset().
    -
    -Then, feed the hash state by calling XXH*_update() as many times as necessary.
    -Obviously, input must be allocated and read accessible.
    -The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
    -
    -Finally, a hash value can be produced anytime, by using XXH*_digest().
    -This function returns the nn-bits hash as an int or long long.
    -
    -It's still possible to continue inserting input into the hash state after a digest,
    -and generate some new hashes later on, by calling again XXH*_digest().
    -
    -When done, free XXH state space if it was allocated dynamically.
    -*/
    -
    -
    -/* **************************
    -*  Utils
    -****************************/
    -XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
    -XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
    -
    -
    -/* **************************
    -*  Canonical representation
    -****************************/
    -/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
    -*  The canonical representation uses human-readable write convention, aka big-endian (large digits first).
    -*  These functions allow transformation of hash result into and from its canonical format.
    -*  This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
    -*/
    -typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
    -typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
    -
    -XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
    -XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
    -
    -XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
    -XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
    -
    -
    -/* ================================================================================================
    -   This section contains definitions which are not guaranteed to remain stable.
    -   They may change in future versions, becoming incompatible with a different version of the library.
    -   They shall only be used with static linking.
    -   Never use these definitions in association with dynamic linking !
    -=================================================================================================== */
    -/* These definitions are only meant to allow allocation of XXH state
    -   statically, on stack, or in a struct for example.
    -   Do not use members directly. */
    -
    -struct XXH32_state_s {
    -	unsigned total_len_32;
    -	unsigned large_len;
    -	unsigned v1;
    -	unsigned v2;
    -	unsigned v3;
    -	unsigned v4;
    -	unsigned mem32[4];   /* buffer defined as U32 for alignment */
    -	unsigned memsize;
    -	unsigned reserved;   /* never read nor write, will be removed in a future version */
    -};   /* typedef'd to XXH32_state_t */
    -
    -struct XXH64_state_s {
    -	unsigned long long total_len;
    -	unsigned long long v1;
    -	unsigned long long v2;
    -	unsigned long long v3;
    -	unsigned long long v4;
    -	unsigned long long mem64[4];   /* buffer defined as U64 for alignment */
    -	unsigned memsize;
    -	unsigned reserved[2];          /* never read nor write, will be removed in a future version */
    -};   /* typedef'd to XXH64_state_t */
    -
    -#endif /* XXHASH_H_5627135585666179 */
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_internal.h b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    index 479d6827d..a61bd2713 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_internal.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    @@ -22,10 +22,10 @@
     ***************************************/
     #include 
     #include 
    +#include 
     #include 
     #include "mem.h"
     #include "error_private.h"
    -#include "xxhash.h"               /* XXH_reset, update, digest */
     
     
     /*-*************************************
    diff --git a/contrib/linux-kernel/test/Makefile b/contrib/linux-kernel/test/Makefile
    index 01e877b7e..0aa6d8173 100644
    --- a/contrib/linux-kernel/test/Makefile
    +++ b/contrib/linux-kernel/test/Makefile
    @@ -1,5 +1,5 @@
     
    -IFLAGS := -isystem include/ -I ../include/ -I ../lib/zstd/ -isystem googletest/googletest/include
    +IFLAGS := -isystem include/ -I ../include/ -I ../lib/zstd/ -isystem googletest/googletest/include -isystem ../../../lib/common/
     
     SOURCES := $(wildcard ../lib/zstd/*.c)
     OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
    @@ -15,6 +15,15 @@ CPPFLAGS += $(IFLAGS)
     UserlandTest: UserlandTest.cpp ../lib/zstd/libzstd.a
     	$(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@
     
    +../lib/zstd/xxhash.o: ../lib/zstd/xxhash.c
    +	$(CC) $(CFLAGS) -c $^ -o $@
    +
    +../../../lib/common/xxhash.o: ../../../lib/common/xxhash.c
    +	$(CC) $(CFLAGS) -c $^ -o $@
    +
    +XXHashUserlandTest: XXHashUserlandTest.cpp ../lib/xxhash.o ../../../lib/common/xxhash.o
    +	$(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@
    +
     # Install googletest
     .PHONY: googletest
     googletest:
    diff --git a/contrib/linux-kernel/test/XXHashUserlandTest.cpp b/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    new file mode 100644
    index 000000000..4ded2ae5e
    --- /dev/null
    +++ b/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    @@ -0,0 +1,178 @@
    +extern "C" {
    +#include 
    +#include 
    +}
    +#include 
    +#include 
    +#include 
    +#include 
    +#include 
    +#define XXH_STATIC_LINKING_ONLY
    +#include 
    +
    +using namespace std;
    +
    +namespace {
    +const std::array kTestInputs = {
    +  "",
    +  "0",
    +  "01234",
    +  "0123456789abcde",
    +  "0123456789abcdef",
    +  "0123456789abcdef0",
    +  "0123456789abcdef0123",
    +  "0123456789abcdef0123456789abcde",
    +  "0123456789abcdef0123456789abcdef",
    +  "0123456789abcdef0123456789abcdef0",
    +  "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
    +};
    +char const kEmpty[] = "";
    +char const kOne[] = "0";
    +char const kFive[] = "01234";
    +char const kFifteen[] = "0123456789abcde";
    +char const kSixteen[] = "0123456789abcdef";
    +char const kSeventeen[] = "0123456789abcdef0";
    +char const kTwenty[] = "0123456789abcdef0123";
    +char const kThirtyOne[] = "0123456789abcdef0123456789abcde";
    +char const kThirtyTwo[] = "0123456789abcdef0123456789abcdef";
    +char const kThirtyThree[] = "0123456789abcdef0123456789abcdef0";
    +char const kSixtyFour[] = "0123456789abcdef0123456789abcdef"
    +                          "0123456789abcdef0123456789abcdef";
    +
    +bool testXXH32(const void *input, const size_t length, uint32_t seed) {
    +  return XXH32(input, length, seed) == xxh32(input, length, seed);
    +}
    +
    +bool testXXH64(const void *input, const size_t length, uint32_t seed) {
    +  return XXH64(input, length, seed) == xxh64(input, length, seed);
    +}
    +
    +class XXH32State {
    +  struct xxh32_state kernelState;
    +  XXH32_state_t state;
    +
    +public:
    +  explicit XXH32State(const uint32_t seed) { reset(seed); }
    +  XXH32State(XXH32State const& other) noexcept {
    +    xxh32_copy_state(&kernelState, &other.kernelState);
    +    XXH32_copyState(&state, &other.state);
    +  }
    +  XXH32State& operator=(XXH32State const& other) noexcept {
    +    xxh32_copy_state(&kernelState, &other.kernelState);
    +    XXH32_copyState(&state, &other.state);
    +    return *this;
    +  }
    +
    +  void reset(const uint32_t seed) {
    +    xxh32_reset(&kernelState, seed);
    +    EXPECT_EQ(0, XXH32_reset(&state, seed));
    +  }
    +
    +  void update(const void *input, const size_t length) {
    +    EXPECT_EQ(0, xxh32_update(&kernelState, input, length));
    +    EXPECT_EQ(0, (int)XXH32_update(&state, input, length));
    +  }
    +
    +  bool testDigest() const {
    +    return xxh32_digest(&kernelState) == XXH32_digest(&state);
    +  }
    +};
    +
    +class XXH64State {
    +  struct xxh64_state kernelState;
    +  XXH64_state_t state;
    +
    +public:
    +  explicit XXH64State(const uint64_t seed) { reset(seed); }
    +  XXH64State(XXH64State const& other) noexcept {
    +    xxh64_copy_state(&kernelState, &other.kernelState);
    +    XXH64_copyState(&state, &other.state);
    +  }
    +  XXH64State& operator=(XXH64State const& other) noexcept {
    +    xxh64_copy_state(&kernelState, &other.kernelState);
    +    XXH64_copyState(&state, &other.state);
    +    return *this;
    +  }
    +
    +  void reset(const uint64_t seed) {
    +    xxh64_reset(&kernelState, seed);
    +    EXPECT_EQ(0, XXH64_reset(&state, seed));
    +  }
    +
    +  void update(const void *input, const size_t length) {
    +    EXPECT_EQ(0, xxh64_update(&kernelState, input, length));
    +    EXPECT_EQ(0, (int)XXH64_update(&state, input, length));
    +  }
    +
    +  bool testDigest() const {
    +    return xxh64_digest(&kernelState) == XXH64_digest(&state);
    +  }
    +};
    +}
    +
    +TEST(Simple, Null) {
    +  EXPECT_TRUE(testXXH32(NULL, 0, 0));
    +  EXPECT_TRUE(testXXH64(NULL, 0, 0));
    +}
    +
    +TEST(Stream, Null) {
    +  struct xxh32_state state32;
    +  xxh32_reset(&state32, 0);
    +  EXPECT_EQ(-EINVAL, xxh32_update(&state32, NULL, 0));
    +
    +  struct xxh64_state state64;
    +  xxh64_reset(&state64, 0);
    +  EXPECT_EQ(-EINVAL, xxh64_update(&state64, NULL, 0));
    +}
    +
    +TEST(Simple, TestInputs) {
    +  for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
    +    for (auto const input : kTestInputs) {
    +      EXPECT_TRUE(testXXH32(input.data(), input.size(), seed));
    +      EXPECT_TRUE(testXXH64(input.data(), input.size(), (uint64_t)seed));
    +    }
    +  }
    +}
    +
    +TEST(Stream, TestInputs) {
    +  for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
    +    for (auto const input : kTestInputs) {
    +      XXH32State s32(seed);
    +      XXH64State s64(seed);
    +      s32.update(input.data(), input.size());
    +      s64.update(input.data(), input.size());
    +      EXPECT_TRUE(s32.testDigest());
    +      EXPECT_TRUE(s64.testDigest());
    +    }
    +  }
    +}
    +
    +TEST(Stream, MultipleTestInputs) {
    +  for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
    +    XXH32State s32(seed);
    +    XXH64State s64(seed);
    +    for (auto const input : kTestInputs) {
    +      s32.update(input.data(), input.size());
    +      s64.update(input.data(), input.size());
    +    }
    +    EXPECT_TRUE(s32.testDigest());
    +    EXPECT_TRUE(s64.testDigest());
    +  }
    +}
    +
    +TEST(Stream, CopyState) {
    +  for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
    +    XXH32State s32(seed);
    +    XXH64State s64(seed);
    +    for (auto const input : kTestInputs) {
    +      auto t32(s32);
    +      t32.update(input.data(), input.size());
    +      s32 = t32;
    +      auto t64(s64);
    +      t64.update(input.data(), input.size());
    +      s64 = t64;
    +    }
    +    EXPECT_TRUE(s32.testDigest());
    +    EXPECT_TRUE(s64.testDigest());
    +  }
    +}
    diff --git a/contrib/linux-kernel/test/include/linux/errno.h b/contrib/linux-kernel/test/include/linux/errno.h
    new file mode 100644
    index 000000000..b9db08524
    --- /dev/null
    +++ b/contrib/linux-kernel/test/include/linux/errno.h
    @@ -0,0 +1,6 @@
    +#ifndef LINUX_ERRNO_H_
    +#define LINUX_ERRNO_H_
    +
    +#define EINVAL 22
    +
    +#endif // LINUX_ERRNO_H_
    diff --git a/contrib/linux-kernel/xxhash.diff b/contrib/linux-kernel/xxhash.diff
    new file mode 100644
    index 000000000..bbd5771b6
    --- /dev/null
    +++ b/contrib/linux-kernel/xxhash.diff
    @@ -0,0 +1,762 @@
    +diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h
    +new file mode 100644
    +index 0000000..4644337
    +--- /dev/null
    ++++ b/include/linux/xxhash.h
    +@@ -0,0 +1,230 @@
    ++/*
    ++ * xxHash - Extremely Fast Hash algorithm
    ++ * Copyright (C) 2012-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ *     notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ *     copyright notice, this list of conditions and the following disclaimer
    ++ *     in the documentation and/or other materials provided with the
    ++ *     distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * You can contact the author at:
    ++ * - xxHash homepage: http://cyan4973.github.io/xxHash/
    ++ * - xxHash source repository: https://github.com/Cyan4973/xxHash
    ++ */
    ++
    ++/*
    ++ * Notice extracted from xxHash homepage:
    ++ *
    ++ * xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
    ++ * It also successfully passes all tests from the SMHasher suite.
    ++ *
    ++ * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2
    ++ * Duo @3GHz)
    ++ *
    ++ * Name            Speed       Q.Score   Author
    ++ * xxHash          5.4 GB/s     10
    ++ * CrapWow         3.2 GB/s      2       Andrew
    ++ * MumurHash 3a    2.7 GB/s     10       Austin Appleby
    ++ * SpookyHash      2.0 GB/s     10       Bob Jenkins
    ++ * SBox            1.4 GB/s      9       Bret Mulvey
    ++ * Lookup3         1.2 GB/s      9       Bob Jenkins
    ++ * SuperFastHash   1.2 GB/s      1       Paul Hsieh
    ++ * CityHash64      1.05 GB/s    10       Pike & Alakuijala
    ++ * FNV             0.55 GB/s     5       Fowler, Noll, Vo
    ++ * CRC32           0.43 GB/s     9
    ++ * MD5-32          0.33 GB/s    10       Ronald L. Rivest
    ++ * SHA1-32         0.28 GB/s    10
    ++ *
    ++ * Q.Score is a measure of quality of the hash function.
    ++ * It depends on successfully passing SMHasher test set.
    ++ * 10 is a perfect score.
    ++ *
    ++ * A 64-bits version, named xxh64 offers much better speed,
    ++ * but for 64-bits applications only.
    ++ * Name     Speed on 64 bits    Speed on 32 bits
    ++ * xxh64       13.8 GB/s            1.9 GB/s
    ++ * xxh32        6.8 GB/s            6.0 GB/s
    ++ */
    ++
    ++#ifndef XXHASH_H
    ++#define XXHASH_H
    ++
    ++#include 
    ++
    ++/*-****************************
    ++ * Simple Hash Functions
    ++ *****************************/
    ++
    ++/**
    ++ * xxh32() - calculate the 32-bit hash of the input with a given seed.
    ++ *
    ++ * @input:  The data to hash. Must not be NULL.
    ++ * @length: The length of the data to hash.
    ++ * @seed:   The seed can be used to alter the result predictably.
    ++ *
    ++ * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
    ++ *
    ++ * Return:  The 32-bit hash of the data.
    ++ */
    ++uint32_t xxh32(const void *input, size_t length, uint32_t seed);
    ++
    ++/**
    ++ * xxh32() - calculate the 64-bit hash of the input with a given seed.
    ++ *
    ++ * @input:  The data to hash. Must not be NULL.
    ++ * @length: The length of the data to hash.
    ++ * @seed:   The seed can be used to alter the result predictably.
    ++ *
    ++ * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems.
    ++ *
    ++ * Return:  The 64-bit hash of the data.
    ++ */
    ++uint64_t xxh64(const void *input, size_t length, uint64_t seed);
    ++
    ++/*-****************************
    ++ * Streaming Hash Functions
    ++ *****************************/
    ++
    ++/*
    ++ * These definitions are only meant to allow allocation of XXH state
    ++ * statically, on stack, or in a struct for example.
    ++ * Do not use members directly.
    ++ */
    ++
    ++/**
    ++ * struct xxh32_state - private xxh32 state, do not use members directly
    ++ */
    ++struct xxh32_state {
    ++	uint32_t total_len_32;
    ++	uint32_t large_len;
    ++	uint32_t v1;
    ++	uint32_t v2;
    ++	uint32_t v3;
    ++	uint32_t v4;
    ++	uint32_t mem32[4];
    ++	uint32_t memsize;
    ++};
    ++
    ++/**
    ++ * struct xxh32_state - private xxh64 state, do not use members directly
    ++ */
    ++struct xxh64_state {
    ++	uint64_t total_len;
    ++	uint64_t v1;
    ++	uint64_t v2;
    ++	uint64_t v3;
    ++	uint64_t v4;
    ++	uint64_t mem64[4];
    ++	uint32_t memsize;
    ++};
    ++
    ++/**
    ++ * xxh32_reset() - reset the xxh32 state to start a new hashing operation
    ++ *
    ++ * @state: The xxh32 state to reset.
    ++ * @seed:  Initialize the hash state with this seed.
    ++ *
    ++ * Call this function on any xxh32_state to prepare for a new hashing operation.
    ++ */
    ++void xxh32_reset(struct xxh32_state *state, uint32_t seed);
    ++
    ++/**
    ++ * xxh32_update() - hash the data given and update the xxh32 state
    ++ *
    ++ * @state:  The xxh32 state to update.
    ++ * @input:  The data to hash. Must not be NULL.
    ++ * @length: The length of the data to hash.
    ++ *
    ++ * After calling xxh32_reset() call xxh32_update() as many times as necessary.
    ++ *
    ++ * Return:  Zero on success, otherwise an error code.
    ++ */
    ++int xxh32_update(struct xxh32_state *state, const void *input, size_t length);
    ++
    ++/**
    ++ * xxh32_digest() - produce the current xxh32 hash
    ++ *
    ++ * @state: Produce the current xxh32 hash of this state.
    ++ *
    ++ * A hash value can be produced at any time. It is still possible to continue
    ++ * inserting input into the hash state after a call to xxh32_digest(), and
    ++ * generate new hashes later on, by calling xxh32_digest() again.
    ++ *
    ++ * Return: The xxh32 hash stored in the state.
    ++ */
    ++uint32_t xxh32_digest(const struct xxh32_state *state);
    ++
    ++/**
    ++ * xxh64_reset() - reset the xxh64 state to start a new hashing operation
    ++ *
    ++ * @state: The xxh32 state to reset.
    ++ * @seed:  Initialize the hash state with this seed.
    ++ */
    ++void xxh64_reset(struct xxh64_state *state, uint64_t seed);
    ++
    ++/**
    ++ * xxh64_update() - hash the data given and update the xxh64 state
    ++ * @state:  The xxh64 state to update.
    ++ * @input:  The data to hash. Must not be NULL.
    ++ * @length: The length of the data to hash.
    ++ *
    ++ * After calling xxh64_reset() call xxh64_update() as many times as necessary.
    ++ *
    ++ * Return:  Zero on success, otherwise an error code.
    ++ */
    ++int xxh64_update(struct xxh64_state *state, const void *input, size_t length);
    ++
    ++/**
    ++ * xxh64_digest() - produce the current xxh64 hash
    ++ *
    ++ * @state: Produce the current xxh64 hash of this state.
    ++ *
    ++ * A hash value can be produced at any time. It is still possible to continue
    ++ * inserting input into the hash state after a call to xxh64_digest(), and
    ++ * generate new hashes later on, by calling xxh64_digest() again.
    ++ *
    ++ * Return: The xxh64 hash stored in the state.
    ++ */
    ++uint64_t xxh64_digest(const struct xxh64_state *state);
    ++
    ++/*-**************************
    ++ * Utils
    ++ ***************************/
    ++
    ++/**
    ++ * xxh32_copy_state() - copy the source state into the destination state
    ++ *
    ++ * @src: The source xxh32 state.
    ++ * @dst: The destination xxh32 state.
    ++ */
    ++void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src);
    ++
    ++/**
    ++ * xxh64_copy_state() - copy the source state into the destination state
    ++ *
    ++ * @src: The source xxh64 state.
    ++ * @dst: The destination xxh64 state.
    ++ */
    ++void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src);
    ++
    ++#endif /* XXHASH_H */
    +diff --git a/lib/Kconfig b/lib/Kconfig
    +index 0c8b78a..b6009d7 100644
    +--- a/lib/Kconfig
    ++++ b/lib/Kconfig
    +@@ -184,6 +184,9 @@ config CRC8
    + 	  when they need to do cyclic redundancy check according CRC8
    + 	  algorithm. Module will be called crc8.
    + 
    ++config XXHASH
    ++	tristate
    ++
    + config AUDIT_GENERIC
    + 	bool
    + 	depends on AUDIT && !AUDIT_ARCH
    +diff --git a/lib/Makefile b/lib/Makefile
    +index 320ac46..e16f94a 100644
    +--- a/lib/Makefile
    ++++ b/lib/Makefile
    +@@ -101,6 +101,7 @@ obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
    + obj-$(CONFIG_CRC7)	+= crc7.o
    + obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
    + obj-$(CONFIG_CRC8)	+= crc8.o
    ++obj-$(CONFIG_XXHASH)	+= xxhash.o
    + obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
    + 
    + obj-$(CONFIG_842_COMPRESS) += 842/
    +diff --git a/lib/xxhash.c b/lib/xxhash.c
    +new file mode 100644
    +index 0000000..f367222
    +--- /dev/null
    ++++ b/lib/xxhash.c
    +@@ -0,0 +1,494 @@
    ++/*
    ++ * xxHash - Extremely Fast Hash algorithm
    ++ * Copyright (C) 2012-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ *     notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ *     copyright notice, this list of conditions and the following disclaimer
    ++ *     in the documentation and/or other materials provided with the
    ++ *     distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * You can contact the author at:
    ++ * - xxHash homepage: http://cyan4973.github.io/xxHash/
    ++ * - xxHash source repository: https://github.com/Cyan4973/xxHash
    ++ */
    ++
    ++#include 
    ++#include 
    ++#include 
    ++#include 
    ++#include 
    ++#include 
    ++#include 
    ++
    ++/*-*************************************
    ++ * Macros
    ++ **************************************/
    ++#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r)))
    ++#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r)))
    ++
    ++#ifdef __LITTLE_ENDIAN
    ++# define XXH_CPU_LITTLE_ENDIAN 1
    ++#else
    ++# define XXH_CPU_LITTLE_ENDIAN 0
    ++#endif
    ++
    ++/*-*************************************
    ++ * Constants
    ++ **************************************/
    ++static const uint32_t PRIME32_1 = 2654435761U;
    ++static const uint32_t PRIME32_2 = 2246822519U;
    ++static const uint32_t PRIME32_3 = 3266489917U;
    ++static const uint32_t PRIME32_4 =  668265263U;
    ++static const uint32_t PRIME32_5 =  374761393U;
    ++
    ++static const uint64_t PRIME64_1 = 11400714785074694791ULL;
    ++static const uint64_t PRIME64_2 = 14029467366897019727ULL;
    ++static const uint64_t PRIME64_3 =  1609587929392839161ULL;
    ++static const uint64_t PRIME64_4 =  9650029242287828579ULL;
    ++static const uint64_t PRIME64_5 =  2870177450012600261ULL;
    ++
    ++/*-**************************
    ++ *  Utils
    ++ ***************************/
    ++void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
    ++{
    ++	memcpy(dst, src, sizeof(*dst));
    ++}
    ++EXPORT_SYMBOL(xxh32_copy_state);
    ++
    ++void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
    ++{
    ++	memcpy(dst, src, sizeof(*dst));
    ++}
    ++EXPORT_SYMBOL(xxh64_copy_state);
    ++
    ++/*-***************************
    ++ * Simple Hash Functions
    ++ ****************************/
    ++static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
    ++{
    ++	seed += input * PRIME32_2;
    ++	seed = xxh_rotl32(seed, 13);
    ++	seed *= PRIME32_1;
    ++	return seed;
    ++}
    ++
    ++uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
    ++{
    ++	const uint8_t *p = (const uint8_t *)input;
    ++	const uint8_t *b_end = p + len;
    ++	uint32_t h32;
    ++
    ++	if (len >= 16) {
    ++		const uint8_t *const limit = b_end - 16;
    ++		uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
    ++		uint32_t v2 = seed + PRIME32_2;
    ++		uint32_t v3 = seed + 0;
    ++		uint32_t v4 = seed - PRIME32_1;
    ++
    ++		do {
    ++			v1 = xxh32_round(v1, get_unaligned_le32(p));
    ++			p += 4;
    ++			v2 = xxh32_round(v2, get_unaligned_le32(p));
    ++			p += 4;
    ++			v3 = xxh32_round(v3, get_unaligned_le32(p));
    ++			p += 4;
    ++			v4 = xxh32_round(v4, get_unaligned_le32(p));
    ++			p += 4;
    ++		} while (p <= limit);
    ++
    ++		h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) +
    ++			xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18);
    ++	} else {
    ++		h32 = seed + PRIME32_5;
    ++	}
    ++
    ++	h32 += (uint32_t)len;
    ++
    ++	while (p + 4 <= b_end) {
    ++		h32 += get_unaligned_le32(p) * PRIME32_3;
    ++		h32 = xxh_rotl32(h32, 17) * PRIME32_4;
    ++		p += 4;
    ++	}
    ++
    ++	while (p < b_end) {
    ++		h32 += (*p) * PRIME32_5;
    ++		h32 = xxh_rotl32(h32, 11) * PRIME32_1;
    ++		p++;
    ++	}
    ++
    ++	h32 ^= h32 >> 15;
    ++	h32 *= PRIME32_2;
    ++	h32 ^= h32 >> 13;
    ++	h32 *= PRIME32_3;
    ++	h32 ^= h32 >> 16;
    ++
    ++	return h32;
    ++}
    ++EXPORT_SYMBOL(xxh32);
    ++
    ++static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
    ++{
    ++	acc += input * PRIME64_2;
    ++	acc = xxh_rotl64(acc, 31);
    ++	acc *= PRIME64_1;
    ++	return acc;
    ++}
    ++
    ++static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
    ++{
    ++	val = xxh64_round(0, val);
    ++	acc ^= val;
    ++	acc = acc * PRIME64_1 + PRIME64_4;
    ++	return acc;
    ++}
    ++
    ++uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
    ++{
    ++	const uint8_t *p = (const uint8_t *)input;
    ++	const uint8_t *const b_end = p + len;
    ++	uint64_t h64;
    ++
    ++	if (len >= 32) {
    ++		const uint8_t *const limit = b_end - 32;
    ++		uint64_t v1 = seed + PRIME64_1 + PRIME64_2;
    ++		uint64_t v2 = seed + PRIME64_2;
    ++		uint64_t v3 = seed + 0;
    ++		uint64_t v4 = seed - PRIME64_1;
    ++
    ++		do {
    ++			v1 = xxh64_round(v1, get_unaligned_le64(p));
    ++			p += 8;
    ++			v2 = xxh64_round(v2, get_unaligned_le64(p));
    ++			p += 8;
    ++			v3 = xxh64_round(v3, get_unaligned_le64(p));
    ++			p += 8;
    ++			v4 = xxh64_round(v4, get_unaligned_le64(p));
    ++			p += 8;
    ++		} while (p <= limit);
    ++
    ++		h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
    ++			xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
    ++		h64 = xxh64_merge_round(h64, v1);
    ++		h64 = xxh64_merge_round(h64, v2);
    ++		h64 = xxh64_merge_round(h64, v3);
    ++		h64 = xxh64_merge_round(h64, v4);
    ++
    ++	} else {
    ++		h64  = seed + PRIME64_5;
    ++	}
    ++
    ++	h64 += (uint64_t)len;
    ++
    ++	while (p + 8 <= b_end) {
    ++		const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
    ++
    ++		h64 ^= k1;
    ++		h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
    ++		p += 8;
    ++	}
    ++
    ++	if (p + 4 <= b_end) {
    ++		h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
    ++		h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    ++		p += 4;
    ++	}
    ++
    ++	while (p < b_end) {
    ++		h64 ^= (*p) * PRIME64_5;
    ++		h64 = xxh_rotl64(h64, 11) * PRIME64_1;
    ++		p++;
    ++	}
    ++
    ++	h64 ^= h64 >> 33;
    ++	h64 *= PRIME64_2;
    ++	h64 ^= h64 >> 29;
    ++	h64 *= PRIME64_3;
    ++	h64 ^= h64 >> 32;
    ++
    ++	return h64;
    ++}
    ++EXPORT_SYMBOL(xxh64);
    ++
    ++/*-**************************************************
    ++ * Advanced Hash Functions
    ++ ***************************************************/
    ++void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
    ++{
    ++	/* use a local state for memcpy() to avoid strict-aliasing warnings */
    ++	struct xxh32_state state;
    ++
    ++	memset(&state, 0, sizeof(state));
    ++	state.v1 = seed + PRIME32_1 + PRIME32_2;
    ++	state.v2 = seed + PRIME32_2;
    ++	state.v3 = seed + 0;
    ++	state.v4 = seed - PRIME32_1;
    ++	memcpy(statePtr, &state, sizeof(state));
    ++}
    ++EXPORT_SYMBOL(xxh32_reset);
    ++
    ++void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
    ++{
    ++	/* use a local state for memcpy() to avoid strict-aliasing warnings */
    ++	struct xxh64_state state;
    ++
    ++	memset(&state, 0, sizeof(state));
    ++	state.v1 = seed + PRIME64_1 + PRIME64_2;
    ++	state.v2 = seed + PRIME64_2;
    ++	state.v3 = seed + 0;
    ++	state.v4 = seed - PRIME64_1;
    ++	memcpy(statePtr, &state, sizeof(state));
    ++}
    ++EXPORT_SYMBOL(xxh64_reset);
    ++
    ++int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
    ++{
    ++	const uint8_t *p = (const uint8_t *)input;
    ++	const uint8_t *const b_end = p + len;
    ++
    ++	if (input == NULL)
    ++		return -EINVAL;
    ++
    ++	state->total_len_32 += (uint32_t)len;
    ++	state->large_len |= (len >= 16) | (state->total_len_32 >= 16);
    ++
    ++	if (state->memsize + len < 16) { /* fill in tmp buffer */
    ++		memcpy((uint8_t *)(state->mem32) + state->memsize, input, len);
    ++		state->memsize += (uint32_t)len;
    ++		return 0;
    ++	}
    ++
    ++	if (state->memsize) { /* some data left from previous update */
    ++		const uint32_t *p32 = state->mem32;
    ++
    ++		memcpy((uint8_t *)(state->mem32) + state->memsize, input,
    ++			16 - state->memsize);
    ++
    ++		state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32));
    ++		p32++;
    ++		state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32));
    ++		p32++;
    ++		state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32));
    ++		p32++;
    ++		state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32));
    ++		p32++;
    ++
    ++		p += 16-state->memsize;
    ++		state->memsize = 0;
    ++	}
    ++
    ++	if (p <= b_end - 16) {
    ++		const uint8_t *const limit = b_end - 16;
    ++		uint32_t v1 = state->v1;
    ++		uint32_t v2 = state->v2;
    ++		uint32_t v3 = state->v3;
    ++		uint32_t v4 = state->v4;
    ++
    ++		do {
    ++			v1 = xxh32_round(v1, get_unaligned_le32(p));
    ++			p += 4;
    ++			v2 = xxh32_round(v2, get_unaligned_le32(p));
    ++			p += 4;
    ++			v3 = xxh32_round(v3, get_unaligned_le32(p));
    ++			p += 4;
    ++			v4 = xxh32_round(v4, get_unaligned_le32(p));
    ++			p += 4;
    ++		} while (p <= limit);
    ++
    ++		state->v1 = v1;
    ++		state->v2 = v2;
    ++		state->v3 = v3;
    ++		state->v4 = v4;
    ++	}
    ++
    ++	if (p < b_end) {
    ++		memcpy(state->mem32, p, (size_t)(b_end-p));
    ++		state->memsize = (uint32_t)(b_end-p);
    ++	}
    ++
    ++	return 0;
    ++}
    ++EXPORT_SYMBOL(xxh32_update);
    ++
    ++uint32_t xxh32_digest(const struct xxh32_state *state)
    ++{
    ++	const uint8_t *p = (const uint8_t *)state->mem32;
    ++	const uint8_t *const b_end = (const uint8_t *)(state->mem32) +
    ++		state->memsize;
    ++	uint32_t h32;
    ++
    ++	if (state->large_len) {
    ++		h32 = xxh_rotl32(state->v1, 1) + xxh_rotl32(state->v2, 7) +
    ++			xxh_rotl32(state->v3, 12) + xxh_rotl32(state->v4, 18);
    ++	} else {
    ++		h32 = state->v3 /* == seed */ + PRIME32_5;
    ++	}
    ++
    ++	h32 += state->total_len_32;
    ++
    ++	while (p + 4 <= b_end) {
    ++		h32 += get_unaligned_le32(p) * PRIME32_3;
    ++		h32 = xxh_rotl32(h32, 17) * PRIME32_4;
    ++		p += 4;
    ++	}
    ++
    ++	while (p < b_end) {
    ++		h32 += (*p) * PRIME32_5;
    ++		h32 = xxh_rotl32(h32, 11) * PRIME32_1;
    ++		p++;
    ++	}
    ++
    ++	h32 ^= h32 >> 15;
    ++	h32 *= PRIME32_2;
    ++	h32 ^= h32 >> 13;
    ++	h32 *= PRIME32_3;
    ++	h32 ^= h32 >> 16;
    ++
    ++	return h32;
    ++}
    ++EXPORT_SYMBOL(xxh32_digest);
    ++
    ++int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
    ++{
    ++	const uint8_t *p = (const uint8_t *)input;
    ++	const uint8_t *const b_end = p + len;
    ++
    ++	if (input == NULL)
    ++		return -EINVAL;
    ++
    ++	state->total_len += len;
    ++
    ++	if (state->memsize + len < 32) { /* fill in tmp buffer */
    ++		memcpy(((uint8_t *)state->mem64) + state->memsize, input, len);
    ++		state->memsize += (uint32_t)len;
    ++		return 0;
    ++	}
    ++
    ++	if (state->memsize) { /* tmp buffer is full */
    ++		const uint64_t *p64 = state->mem64;
    ++
    ++		memcpy(((uint8_t *)p64) + state->memsize, input,
    ++			32 - state->memsize);
    ++
    ++		state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64));
    ++		p64++;
    ++		state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64));
    ++		p64++;
    ++		state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64));
    ++		p64++;
    ++		state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64));
    ++
    ++		p += 32 - state->memsize;
    ++		state->memsize = 0;
    ++	}
    ++
    ++	if (p + 32 <= b_end) {
    ++		const uint8_t *const limit = b_end - 32;
    ++		uint64_t v1 = state->v1;
    ++		uint64_t v2 = state->v2;
    ++		uint64_t v3 = state->v3;
    ++		uint64_t v4 = state->v4;
    ++
    ++		do {
    ++			v1 = xxh64_round(v1, get_unaligned_le64(p));
    ++			p += 8;
    ++			v2 = xxh64_round(v2, get_unaligned_le64(p));
    ++			p += 8;
    ++			v3 = xxh64_round(v3, get_unaligned_le64(p));
    ++			p += 8;
    ++			v4 = xxh64_round(v4, get_unaligned_le64(p));
    ++			p += 8;
    ++		} while (p <= limit);
    ++
    ++		state->v1 = v1;
    ++		state->v2 = v2;
    ++		state->v3 = v3;
    ++		state->v4 = v4;
    ++	}
    ++
    ++	if (p < b_end) {
    ++		memcpy(state->mem64, p, (size_t)(b_end-p));
    ++		state->memsize = (uint32_t)(b_end - p);
    ++	}
    ++
    ++	return 0;
    ++}
    ++EXPORT_SYMBOL(xxh64_update);
    ++
    ++uint64_t xxh64_digest(const struct xxh64_state *state)
    ++{
    ++	const uint8_t *p = (const uint8_t *)state->mem64;
    ++	const uint8_t *const b_end = (const uint8_t *)state->mem64 +
    ++		state->memsize;
    ++	uint64_t h64;
    ++
    ++	if (state->total_len >= 32) {
    ++		const uint64_t v1 = state->v1;
    ++		const uint64_t v2 = state->v2;
    ++		const uint64_t v3 = state->v3;
    ++		const uint64_t v4 = state->v4;
    ++
    ++		h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
    ++			xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
    ++		h64 = xxh64_merge_round(h64, v1);
    ++		h64 = xxh64_merge_round(h64, v2);
    ++		h64 = xxh64_merge_round(h64, v3);
    ++		h64 = xxh64_merge_round(h64, v4);
    ++	} else {
    ++		h64  = state->v3 + PRIME64_5;
    ++	}
    ++
    ++	h64 += (uint64_t)state->total_len;
    ++
    ++	while (p + 8 <= b_end) {
    ++		const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
    ++
    ++		h64 ^= k1;
    ++		h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
    ++		p += 8;
    ++	}
    ++
    ++	if (p + 4 <= b_end) {
    ++		h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
    ++		h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
    ++		p += 4;
    ++	}
    ++
    ++	while (p < b_end) {
    ++		h64 ^= (*p) * PRIME64_5;
    ++		h64 = xxh_rotl64(h64, 11) * PRIME64_1;
    ++		p++;
    ++	}
    ++
    ++	h64 ^= h64 >> 33;
    ++	h64 *= PRIME64_2;
    ++	h64 ^= h64 >> 29;
    ++	h64 *= PRIME64_3;
    ++	h64 ^= h64 >> 32;
    ++
    ++	return h64;
    ++}
    ++EXPORT_SYMBOL(xxh64_digest);
    ++
    ++MODULE_LICENSE("Dual BSD/GPL");
    ++MODULE_DESCRIPTION("xxHash");
    
    From 1d42ca8f6d6d52f6f8baf64713b755dbfccec248 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 15:54:02 -0700
    Subject: [PATCH 055/400] Add zstd.diff
    
    ---
     contrib/linux-kernel/README.md         |    22 +-
     contrib/linux-kernel/lib/Kconfig.diff  |    19 +
     contrib/linux-kernel/lib/Makefile.diff |    13 +
     contrib/linux-kernel/zstd.diff         | 12547 +++++++++++++++++++++++
     4 files changed, 12596 insertions(+), 5 deletions(-)
     create mode 100644 contrib/linux-kernel/lib/Kconfig.diff
     create mode 100644 contrib/linux-kernel/lib/Makefile.diff
     create mode 100644 contrib/linux-kernel/zstd.diff
    
    diff --git a/contrib/linux-kernel/README.md b/contrib/linux-kernel/README.md
    index 16bc2d48f..214c520bd 100644
    --- a/contrib/linux-kernel/README.md
    +++ b/contrib/linux-kernel/README.md
    @@ -1,21 +1,33 @@
     # Linux Kernel Patch
     
    -There are three pieces, the `zstd_compress` and `zstd_decompress` kernel modules, the BtrFS patch, and the SquashFS patch.
    +There are four pieces, the `xxhash` kernel module, the `zstd_compress` and `zstd_decompress` kernel modules, the BtrFS patch, and the SquashFS patch.
     The patches are based off of the linux kernel master branch (version 4.10).
     
    +## xxHash kernel module
    +
    +* The patch is locaed in `xxhash.diff`.
    +* The header is in `include/linux/xxhash.h`.
    +* The source is in `lib/xxhash.c`.
    +* `test/XXHashUserLandTest.cpp` contains tests for the patch in userland by mocking the kernel headers.
    +  I tested the tests by commenting a line of of each branch in `xxhash.c` one line at a time, and made sure the tests failed.
    +  It can be run with the following commands:
    +  ```
    +  cd test && make googletest && make XXHashUserLandTest && ./XXHashUserLandTest
    +  ```
    +* I also benchmarked the `xxhash` module against upstream xxHash, and made sure that they ran at the same speed.
    +
     ## Zstd Kernel modules
     
    +* The (large) patch is locaed in `zstd.diff`, which depends on `xxhash.diff`.
     * The header is in `include/linux/zstd.h`.
     * It is split up into `zstd_compress` and `zstd_decompress`, which can be loaded independently.
     * Source files are in `lib/zstd/`.
     * `lib/Kconfig` and `lib/Makefile` need to be modified by applying `lib/Kconfig.diff` and `lib/Makefile.diff` respectively.
    +  These changes are also included in the `zstd.diff`.
     * `test/UserlandTest.cpp` contains tests for the patch in userland by mocking the kernel headers.
       It can be run with the following commands:
       ```
    -  cd test
    -  make googletest
    -  make UserlandTest
    -  ./UserlandTest
    +  cd test && make googletest && make UserlandTest && ./UserlandTest
       ```
     
     ## BtrFS
    diff --git a/contrib/linux-kernel/lib/Kconfig.diff b/contrib/linux-kernel/lib/Kconfig.diff
    new file mode 100644
    index 000000000..227c6e2cc
    --- /dev/null
    +++ b/contrib/linux-kernel/lib/Kconfig.diff
    @@ -0,0 +1,19 @@
    +diff --git a/lib/Kconfig b/lib/Kconfig
    +index b6009d7..f00ddab 100644
    +--- a/lib/Kconfig
    ++++ b/lib/Kconfig
    +@@ -241,6 +241,14 @@ config LZ4HC_COMPRESS
    + config LZ4_DECOMPRESS
    + 	tristate
    + 
    ++config ZSTD_COMPRESS
    ++	select XXHASH
    ++	tristate
    ++
    ++config ZSTD_DECOMPRESS
    ++	select XXHASH
    ++	tristate
    ++
    + source "lib/xz/Kconfig"
    + 
    + #
    diff --git a/contrib/linux-kernel/lib/Makefile.diff b/contrib/linux-kernel/lib/Makefile.diff
    new file mode 100644
    index 000000000..f92efe8e9
    --- /dev/null
    +++ b/contrib/linux-kernel/lib/Makefile.diff
    @@ -0,0 +1,13 @@
    +diff --git a/lib/Makefile b/lib/Makefile
    +index e16f94a..0cfd529 100644
    +--- a/lib/Makefile
    ++++ b/lib/Makefile
    +@@ -115,6 +115,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
    + obj-$(CONFIG_LZ4_COMPRESS) += lz4/
    + obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/
    + obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
    ++obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
    ++obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
    + obj-$(CONFIG_XZ_DEC) += xz/
    + obj-$(CONFIG_RAID6_PQ) += raid6/
    + 
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff
    new file mode 100644
    index 000000000..c2775bbbf
    --- /dev/null
    +++ b/contrib/linux-kernel/zstd.diff
    @@ -0,0 +1,12547 @@
    +diff --git a/include/linux/zstd.h b/include/linux/zstd.h
    +new file mode 100644
    +index 0000000..ee7bd82
    +--- /dev/null
    ++++ b/include/linux/zstd.h
    +@@ -0,0 +1,1150 @@
    ++/*
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++#ifndef ZSTD_H
    ++#define ZSTD_H
    ++
    ++/* ======   Dependency   ======*/
    ++#include    /* size_t */
    ++
    ++
    ++/*-*****************************************************************************
    ++ * Introduction
    ++ *
    ++ * zstd, short for Zstandard, is a fast lossless compression algorithm,
    ++ * targeting real-time compression scenarios at zlib-level and better
    ++ * compression ratios. The zstd compression library provides in-memory
    ++ * compression and decompression functions. The library supports compression
    ++ * levels from 1 up to ZSTD_maxCLevel() which is 22. Levels >= 20, labeled
    ++ * ultra, should be used with caution, as they require more memory.
    ++ * Compression can be done in:
    ++ *  - a single step, reusing a context (described as Explicit memory management)
    ++ *  - unbounded multiple steps (described as Streaming compression)
    ++ * The compression ratio achievable on small data can be highly improved using
    ++ * compression with a dictionary in:
    ++ *  - a single step (described as Simple dictionary API)
    ++ *  - a single step, reusing a dictionary (described as Fast dictionary API)
    ++ ******************************************************************************/
    ++
    ++/*======  Helper functions  ======*/
    ++
    ++/**
    ++ * enum ZSTD_ErrorCode - zstd error codes
    ++ *
    ++ * Functions that return size_t can be checked for errors using ZSTD_isError()
    ++ * and the ZSTD_ErrorCode can be extracted using ZSTD_getErrorCode().
    ++ */
    ++typedef enum {
    ++	ZSTD_error_no_error,
    ++	ZSTD_error_GENERIC,
    ++	ZSTD_error_prefix_unknown,
    ++	ZSTD_error_version_unsupported,
    ++	ZSTD_error_parameter_unknown,
    ++	ZSTD_error_frameParameter_unsupported,
    ++	ZSTD_error_frameParameter_unsupportedBy32bits,
    ++	ZSTD_error_frameParameter_windowTooLarge,
    ++	ZSTD_error_compressionParameter_unsupported,
    ++	ZSTD_error_init_missing,
    ++	ZSTD_error_memory_allocation,
    ++	ZSTD_error_stage_wrong,
    ++	ZSTD_error_dstSize_tooSmall,
    ++	ZSTD_error_srcSize_wrong,
    ++	ZSTD_error_corruption_detected,
    ++	ZSTD_error_checksum_wrong,
    ++	ZSTD_error_tableLog_tooLarge,
    ++	ZSTD_error_maxSymbolValue_tooLarge,
    ++	ZSTD_error_maxSymbolValue_tooSmall,
    ++	ZSTD_error_dictionary_corrupted,
    ++	ZSTD_error_dictionary_wrong,
    ++	ZSTD_error_dictionaryCreation_failed,
    ++	ZSTD_error_maxCode
    ++} ZSTD_ErrorCode;
    ++
    ++/**
    ++ * ZSTD_maxCLevel() - maximum compression level available
    ++ *
    ++ * Return: Maximum compression level available.
    ++ */
    ++int ZSTD_maxCLevel(void);
    ++/**
    ++ * ZSTD_compressBound() - maximum compressed size in worst case scenario
    ++ * @srcSize: The size of the data to compress.
    ++ *
    ++ * Return:   The maximum compressed size in the worst case scenario.
    ++ */
    ++size_t ZSTD_compressBound(size_t srcSize);
    ++/**
    ++ * ZSTD_isError() - tells if a size_t function result is an error code
    ++ * @code:  The function result to check for error.
    ++ *
    ++ * Return: Non-zero iff the code is an error.
    ++ */
    ++static __attribute__((unused)) unsigned int ZSTD_isError(size_t code)
    ++{
    ++	return code > (size_t)-ZSTD_error_maxCode;
    ++}
    ++/**
    ++ * ZSTD_getErrorCode() - translates an error function result to a ZSTD_ErrorCode
    ++ * @functionResult: The result of a function for which ZSTD_isError() is true.
    ++ *
    ++ * Return:          The ZSTD_ErrorCode corresponding to the functionResult or 0
    ++ *                  if the functionResult isn't an error.
    ++ */
    ++static __attribute__((unused)) ZSTD_ErrorCode ZSTD_getErrorCode(
    ++	size_t functionResult)
    ++{
    ++	if (!ZSTD_isError(functionResult))
    ++		return (ZSTD_ErrorCode)0;
    ++	return (ZSTD_ErrorCode)(0 - functionResult);
    ++}
    ++
    ++/**
    ++ * enum ZSTD_strategy - zstd compression search strategy
    ++ *
    ++ * From faster to stronger.
    ++ */
    ++typedef enum {
    ++	ZSTD_fast,
    ++	ZSTD_dfast,
    ++	ZSTD_greedy,
    ++	ZSTD_lazy,
    ++	ZSTD_lazy2,
    ++	ZSTD_btlazy2,
    ++	ZSTD_btopt,
    ++	ZSTD_btopt2
    ++} ZSTD_strategy;
    ++
    ++/**
    ++ * struct ZSTD_compressionParameters - zstd compression parameters
    ++ * @windowLog:    Log of the largest match distance. Larger means more
    ++ *                compression, and more memory needed during decompression.
    ++ * @chainLog:     Fully searched segment. Larger means more compression, slower,
    ++ *                and more memory (useless for fast).
    ++ * @hashLog:      Dispatch table. Larger means more compression,
    ++ *                slower, and more memory.
    ++ * @searchLog:    Number of searches. Larger means more compression and slower.
    ++ * @searchLength: Match length searched. Larger means faster decompression,
    ++ *                sometimes less compression.
    ++ * @targetLength: Acceptable match size for optimal parser (only). Larger means
    ++ *                more compression, and slower.
    ++ * @strategy:     The zstd compression strategy.
    ++ */
    ++typedef struct {
    ++	unsigned int windowLog;
    ++	unsigned int chainLog;
    ++	unsigned int hashLog;
    ++	unsigned int searchLog;
    ++	unsigned int searchLength;
    ++	unsigned int targetLength;
    ++	ZSTD_strategy strategy;
    ++} ZSTD_compressionParameters;
    ++
    ++/**
    ++ * struct ZSTD_frameParameters - zstd frame parameters
    ++ * @contentSizeFlag: Controls whether content size will be present in the frame
    ++ *                   header (when known).
    ++ * @checksumFlag:    Controls whether a 32-bit checksum is generated at the end
    ++ *                   of the frame for error detection.
    ++ * @noDictIDFlag:    Controls whether dictID will be saved into the frame header
    ++ *                   when using dictionary compression.
    ++ *
    ++ * The default value is all fields set to 0.
    ++ */
    ++typedef struct {
    ++	unsigned int contentSizeFlag;
    ++	unsigned int checksumFlag;
    ++	unsigned int noDictIDFlag;
    ++} ZSTD_frameParameters;
    ++
    ++/**
    ++ * struct ZSTD_parameters - zstd parameters
    ++ * @cParams: The compression parameters.
    ++ * @fParams: The frame parameters.
    ++ */
    ++typedef struct {
    ++	ZSTD_compressionParameters cParams;
    ++	ZSTD_frameParameters fParams;
    ++} ZSTD_parameters;
    ++
    ++/**
    ++ * ZSTD_getCParams() - returns ZSTD_compressionParameters for selected level
    ++ * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel().
    ++ * @estimatedSrcSize: The estimated source size to compress or 0 if unknown.
    ++ * @dictSize:         The dictionary size or 0 if a dictionary isn't being used.
    ++ *
    ++ * Return:            The selected ZSTD_compressionParameters.
    ++ */
    ++ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel,
    ++	unsigned long long estimatedSrcSize, size_t dictSize);
    ++
    ++/**
    ++ * ZSTD_getParams() - returns ZSTD_parameters for selected level
    ++ * @compressionLevel: The compression level from 1 to ZSTD_maxCLevel().
    ++ * @estimatedSrcSize: The estimated source size to compress or 0 if unknown.
    ++ * @dictSize:         The dictionary size or 0 if a dictionary isn't being used.
    ++ *
    ++ * The same as ZSTD_getCParams() except also selects the default frame
    ++ * parameters (all zero).
    ++ *
    ++ * Return:            The selected ZSTD_parameters.
    ++ */
    ++ZSTD_parameters ZSTD_getParams(int compressionLevel,
    ++	unsigned long long estimatedSrcSize, size_t dictSize);
    ++
    ++/*-*************************************
    ++ * Explicit memory management
    ++ **************************************/
    ++
    ++/**
    ++ * ZSTD_CCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_CCtx
    ++ * @cParams: The compression parameters to be used for compression.
    ++ *
    ++ * If multiple compression parameters might be used, the caller must call
    ++ * ZSTD_CCtxWorkspaceBound() for each set of parameters and use the maximum
    ++ * size.
    ++ *
    ++ * Return:   A lower bound on the size of the workspace that is passed to
    ++ *           ZSTD_initCCtx().
    ++ */
    ++size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters cParams);
    ++
    ++/**
    ++ * struct ZSTD_CCtx - the zstd compression context
    ++ *
    ++ * When compressing many times it is recommended to allocate a context just once
    ++ * and reuse it for each successive compression operation.
    ++ */
    ++typedef struct ZSTD_CCtx_s ZSTD_CCtx;
    ++/**
    ++ * ZSTD_initCCtx() - initialize a zstd compression context
    ++ * @workspace:     The workspace to emplace the context into. It must outlive
    ++ *                 the returned context.
    ++ * @workspaceSize: The size of workspace. Use ZSTD_CCtxWorkspaceBound() to
    ++ *                 determine how large the workspace must be.
    ++ *
    ++ * Return:         A compression context emplaced into workspace.
    ++ */
    ++ZSTD_CCtx *ZSTD_initCCtx(void *workspace, size_t workspaceSize);
    ++
    ++/**
    ++ * ZSTD_compressCCtx() - compress src into dst
    ++ * @ctx:         The context. Must have been initialized with a workspace at
    ++ *               least as large as ZSTD_CCtxWorkspaceBound(params.cParams).
    ++ * @dst:         The buffer to compress src into.
    ++ * @dstCapacity: The size of the destination buffer. May be any size, but
    ++ *               ZSTD_compressBound(srcSize) is guaranteed to be large enough.
    ++ * @src:         The data to compress.
    ++ * @srcSize:     The size of the data to compress.
    ++ * @params:      The parameters to use for compression. See ZSTD_getParams().
    ++ *
    ++ * Return:       The compressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_compressCCtx(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize, ZSTD_parameters params);
    ++
    ++/**
    ++ * ZSTD_DCtxWorkspaceBound() - amount of memory needed to initialize a ZSTD_DCtx
    ++ *
    ++ * Return: A lower bound on the size of the workspace that is passed to
    ++ *         ZSTD_initDCtx().
    ++ */
    ++size_t ZSTD_DCtxWorkspaceBound(void);
    ++
    ++/**
    ++ * struct ZSTD_DCtx - the zstd decompression context
    ++ *
    ++ * When decompressing many times it is recommended to allocate a context just
    ++ * once and reuse it for each successive decompression operation.
    ++ */
    ++typedef struct ZSTD_DCtx_s ZSTD_DCtx;
    ++/**
    ++ * ZSTD_initDCtx() - initialize a zstd decompression context
    ++ * @workspace:     The workspace to emplace the context into. It must outlive
    ++ *                 the returned context.
    ++ * @workspaceSize: The size of workspace. Use ZSTD_DCtxWorkspaceBound() to
    ++ *                 determine how large the workspace must be.
    ++ *
    ++ * Return:         A decompression context emplaced into workspace.
    ++ */
    ++ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize);
    ++
    ++/**
    ++ * ZSTD_decompressDCtx() - decompress zstd compressed src into dst
    ++ * @ctx:         The decompression context.
    ++ * @dst:         The buffer to decompress src into.
    ++ * @dstCapacity: The size of the destination buffer. Must be at least as large
    ++ *               as the decompressed size. If the caller cannot upper bound the
    ++ *               decompressed size, then it's better to use the streaming API.
    ++ * @src:         The zstd compressed data to decompress. Multiple concatenated
    ++ *               frames and skippable frames are allowed.
    ++ * @srcSize:     The exact size of the data to decompress.
    ++ *
    ++ * Return:       The decompressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_decompressDCtx(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++
    ++/*-************************
    ++ * Simple dictionary API
    ++ **************************/
    ++
    ++/**
    ++ * ZSTD_compress_usingDict() - compress src into dst using a dictionary
    ++ * @ctx:         The context. Must have been initialized with a workspace at
    ++ *               least as large as ZSTD_CCtxWorkspaceBound(params.cParams).
    ++ * @dst:         The buffer to compress src into.
    ++ * @dstCapacity: The size of the destination buffer. May be any size, but
    ++ *               ZSTD_compressBound(srcSize) is guaranteed to be large enough.
    ++ * @src:         The data to compress.
    ++ * @srcSize:     The size of the data to compress.
    ++ * @dict:        The dictionary to use for compression.
    ++ * @dictSize:    The size of the dictionary.
    ++ * @params:      The parameters to use for compression. See ZSTD_getParams().
    ++ *
    ++ * Compression using a predefined dictionary. The same dictionary must be used
    ++ * during decompression.
    ++ *
    ++ * Return:       The compressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_compress_usingDict(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize, const void *dict, size_t dictSize,
    ++	ZSTD_parameters params);
    ++
    ++/**
    ++ * ZSTD_decompress_usingDict() - decompress src into dst using a dictionary
    ++ * @ctx:         The decompression context.
    ++ * @dst:         The buffer to decompress src into.
    ++ * @dstCapacity: The size of the destination buffer. Must be at least as large
    ++ *               as the decompressed size. If the caller cannot upper bound the
    ++ *               decompressed size, then it's better to use the streaming API.
    ++ * @src:         The zstd compressed data to decompress. Multiple concatenated
    ++ *               frames and skippable frames are allowed.
    ++ * @srcSize:     The exact size of the data to decompress.
    ++ * @dict:        The dictionary to use for decompression. The same dictionary
    ++ *               must've been used to compress the data.
    ++ * @dictSize:    The size of the dictionary.
    ++ *
    ++ * Return:       The decompressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_decompress_usingDict(ZSTD_DCtx *ctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize, const void *dict, size_t dictSize);
    ++
    ++/*-**************************
    ++ * Fast dictionary API
    ++ ***************************/
    ++
    ++/**
    ++ * ZSTD_CDictWorkspaceBound() - memory needed to initialize a ZSTD_CDict
    ++ * @cParams: The compression parameters to be used for compression.
    ++ *
    ++ * Return:   A lower bound on the size of the workspace that is passed to
    ++ *           ZSTD_initCDict().
    ++ */
    ++size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams);
    ++
    ++/**
    ++ * struct ZSTD_CDict - a digested dictionary to be used for compression
    ++ */
    ++typedef struct ZSTD_CDict_s ZSTD_CDict;
    ++
    ++/**
    ++ * ZSTD_initCDict() - initialize a digested dictionary for compression
    ++ * @dictBuffer:    The dictionary to digest. The buffer is referenced by the
    ++ *                 ZSTD_CDict so it must outlive the returned ZSTD_CDict.
    ++ * @dictSize:      The size of the dictionary.
    ++ * @params:        The parameters to use for compression. See ZSTD_getParams().
    ++ * @workspace:     The workspace. It must outlive the returned ZSTD_CDict.
    ++ * @workspaceSize: The workspace size. Must be at least
    ++ *                 ZSTD_CDictWorkspaceBound(params.cParams).
    ++ *
    ++ * When compressing multiple messages / blocks with the same dictionary it is
    ++ * recommended to load it just once. The ZSTD_CDict merely references the
    ++ * dictBuffer, so it must outlive the returned ZSTD_CDict.
    ++ *
    ++ * Return:         The digested dictionary emplaced into workspace.
    ++ */
    ++ZSTD_CDict *ZSTD_initCDict(const void *dictBuffer, size_t dictSize,
    ++	ZSTD_parameters params, void *workspace, size_t workspaceSize);
    ++
    ++/**
    ++ * ZSTD_compress_usingCDict() - compress src into dst using a ZSTD_CDict
    ++ * @ctx:         The context. Must have been initialized with a workspace at
    ++ *               least as large as ZSTD_CCtxWorkspaceBound(cParams) where
    ++ *               cParams are the compression parameters used to initialize the
    ++ *               cdict.
    ++ * @dst:         The buffer to compress src into.
    ++ * @dstCapacity: The size of the destination buffer. May be any size, but
    ++ *               ZSTD_compressBound(srcSize) is guaranteed to be large enough.
    ++ * @src:         The data to compress.
    ++ * @srcSize:     The size of the data to compress.
    ++ * @cdict:       The digested dictionary to use for compression.
    ++ * @params:      The parameters to use for compression. See ZSTD_getParams().
    ++ *
    ++ * Compression using a digested dictionary. The same dictionary must be used
    ++ * during decompression.
    ++ *
    ++ * Return:       The compressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize, const ZSTD_CDict *cdict);
    ++
    ++
    ++/**
    ++ * ZSTD_DDictWorkspaceBound() - memory needed to initialize a ZSTD_DDict
    ++ *
    ++ * Return:  A lower bound on the size of the workspace that is passed to
    ++ *          ZSTD_initDDict().
    ++ */
    ++size_t ZSTD_DDictWorkspaceBound(void);
    ++
    ++/**
    ++ * struct ZSTD_DDict - a digested dictionary to be used for decompression
    ++ */
    ++typedef struct ZSTD_DDict_s ZSTD_DDict;
    ++
    ++/**
    ++ * ZSTD_initDDict() - initialize a digested dictionary for decompression
    ++ * @dictBuffer:    The dictionary to digest. The buffer is referenced by the
    ++ *                 ZSTD_DDict so it must outlive the returned ZSTD_DDict.
    ++ * @dictSize:      The size of the dictionary.
    ++ * @workspace:     The workspace. It must outlive the returned ZSTD_DDict.
    ++ * @workspaceSize: The workspace size. Must be at least
    ++ *                 ZSTD_DDictWorkspaceBound().
    ++ *
    ++ * When decompressing multiple messages / blocks with the same dictionary it is
    ++ * recommended to load it just once. The ZSTD_DDict merely references the
    ++ * dictBuffer, so it must outlive the returned ZSTD_DDict.
    ++ *
    ++ * Return:         The digested dictionary emplaced into workspace.
    ++ */
    ++ZSTD_DDict *ZSTD_initDDict(const void *dictBuffer, size_t dictSize,
    ++	void *workspace, size_t workspaceSize);
    ++
    ++/**
    ++ * ZSTD_decompress_usingDDict() - decompress src into dst using a ZSTD_DDict
    ++ * @ctx:         The decompression context.
    ++ * @dst:         The buffer to decompress src into.
    ++ * @dstCapacity: The size of the destination buffer. Must be at least as large
    ++ *               as the decompressed size. If the caller cannot upper bound the
    ++ *               decompressed size, then it's better to use the streaming API.
    ++ * @src:         The zstd compressed data to decompress. Multiple concatenated
    ++ *               frames and skippable frames are allowed.
    ++ * @srcSize:     The exact size of the data to decompress.
    ++ * @ddict:       The digested dictionary to use for decompression. The same
    ++ *               dictionary must've been used to compress the data.
    ++ *
    ++ * Return:       The decompressed size or an error, which can be checked using
    ++ *               ZSTD_isError().
    ++ */
    ++size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst,
    ++	size_t dstCapacity, const void *src, size_t srcSize,
    ++	const ZSTD_DDict *ddict);
    ++
    ++
    ++/*-**************************
    ++ * Streaming
    ++ ***************************/
    ++
    ++/**
    ++ * struct ZSTD_inBuffer - input buffer for streaming
    ++ * @src:  Start of the input buffer.
    ++ * @size: Size of the input buffer.
    ++ * @pos:  Position where reading stopped. Will be updated.
    ++ *        Necessarily 0 <= pos <= size.
    ++ */
    ++typedef struct ZSTD_inBuffer_s {
    ++	const void *src;
    ++	size_t size;
    ++	size_t pos;
    ++} ZSTD_inBuffer;
    ++
    ++/**
    ++ * struct ZSTD_outBuffer - output buffer for streaming
    ++ * @dst:  Start of the output buffer.
    ++ * @size: Size of the output buffer.
    ++ * @pos:  Position where writing stopped. Will be updated.
    ++ *        Necessarily 0 <= pos <= size.
    ++ */
    ++typedef struct ZSTD_outBuffer_s {
    ++	void *dst;
    ++	size_t size;
    ++	size_t pos;
    ++} ZSTD_outBuffer;
    ++
    ++
    ++
    ++/*-*****************************************************************************
    ++ * Streaming compression - HowTo
    ++ *
    ++ * A ZSTD_CStream object is required to track streaming operation.
    ++ * Use ZSTD_initCStream() to initialize a ZSTD_CStream object.
    ++ * ZSTD_CStream objects can be reused multiple times on consecutive compression
    ++ * operations. It is recommended to re-use ZSTD_CStream in situations where many
    ++ * streaming operations will be achieved consecutively. Use one separate
    ++ * ZSTD_CStream per thread for parallel execution.
    ++ *
    ++ * Use ZSTD_compressStream() repetitively to consume input stream.
    ++ * The function will automatically update both `pos` fields.
    ++ * Note that it may not consume the entire input, in which case `pos < size`,
    ++ * and it's up to the caller to present again remaining data.
    ++ * It returns a hint for the preferred number of bytes to use as an input for
    ++ * the next function call.
    ++ *
    ++ * At any moment, it's possible to flush whatever data remains within internal
    ++ * buffer, using ZSTD_flushStream(). `output->pos` will be updated. There might
    ++ * still be some content left within the internal buffer if `output->size` is
    ++ * too small. It returns the number of bytes left in the internal buffer and
    ++ * must be called until it returns 0.
    ++ *
    ++ * ZSTD_endStream() instructs to finish a frame. It will perform a flush and
    ++ * write frame epilogue. The epilogue is required for decoders to consider a
    ++ * frame completed. Similar to ZSTD_flushStream(), it may not be able to flush
    ++ * the full content if `output->size` is too small. In which case, call again
    ++ * ZSTD_endStream() to complete the flush. It returns the number of bytes left
    ++ * in the internal buffer and must be called until it returns 0.
    ++ ******************************************************************************/
    ++
    ++/**
    ++ * ZSTD_CStreamWorkspaceBound() - memory needed to initialize a ZSTD_CStream
    ++ * @cParams: The compression parameters to be used for compression.
    ++ *
    ++ * Return:   A lower bound on the size of the workspace that is passed to
    ++ *           ZSTD_initCStream() and ZSTD_initCStream_usingCDict().
    ++ */
    ++size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams);
    ++
    ++/**
    ++ * struct ZSTD_CStream - the zstd streaming compression context
    ++ */
    ++typedef struct ZSTD_CStream_s ZSTD_CStream;
    ++
    ++/*===== ZSTD_CStream management functions =====*/
    ++/**
    ++ * ZSTD_initCStream() - initialize a zstd streaming compression context
    ++ * @params:         The zstd compression parameters.
    ++ * @pledgedSrcSize: If params.fParams.contentSizeFlag == 1 then the caller must
    ++ *                  pass the source size (zero means empty source). Otherwise,
    ++ *                  the caller may optionally pass the source size, or zero if
    ++ *                  unknown.
    ++ * @workspace:      The workspace to emplace the context into. It must outlive
    ++ *                  the returned context.
    ++ * @workspaceSize:  The size of workspace.
    ++ *                  Use ZSTD_CStreamWorkspaceBound(params.cParams) to determine
    ++ *                  how large the workspace must be.
    ++ *
    ++ * Return:          The zstd streaming compression context.
    ++ */
    ++ZSTD_CStream *ZSTD_initCStream(ZSTD_parameters params,
    ++	unsigned long long pledgedSrcSize, void *workspace,
    ++	size_t workspaceSize);
    ++
    ++/**
    ++ * ZSTD_initCStream_usingCDict() - initialize a streaming compression context
    ++ * @cdict:          The digested dictionary to use for compression.
    ++ * @pledgedSrcSize: Optionally the source size, or zero if unknown.
    ++ * @workspace:      The workspace to emplace the context into. It must outlive
    ++ *                  the returned context.
    ++ * @workspaceSize:  The size of workspace. Call ZSTD_CStreamWorkspaceBound()
    ++ *                  with the cParams used to initialize the cdict to determine
    ++ *                  how large the workspace must be.
    ++ *
    ++ * Return:          The zstd streaming compression context.
    ++ */
    ++ZSTD_CStream *ZSTD_initCStream_usingCDict(const ZSTD_CDict *cdict,
    ++	unsigned long long pledgedSrcSize, void *workspace,
    ++	size_t workspaceSize);
    ++
    ++/*===== Streaming compression functions =====*/
    ++/**
    ++ * ZSTD_resetCStream() - reset the context using parameters from creation
    ++ * @zcs:            The zstd streaming compression context to reset.
    ++ * @pledgedSrcSize: Optionally the source size, or zero if unknown.
    ++ *
    ++ * Resets the context using the parameters from creation. Skips dictionary
    ++ * loading, since it can be reused. If `pledgedSrcSize` is non-zero the frame
    ++ * content size is always written into the frame header.
    ++ *
    ++ * Return:          Zero or an error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize);
    ++/**
    ++ * ZSTD_compressStream() - streaming compress some of input into output
    ++ * @zcs:    The zstd streaming compression context.
    ++ * @output: Destination buffer. `output->pos` is updated to indicate how much
    ++ *          compressed data was written.
    ++ * @input:  Source buffer. `input->pos` is updated to indicate how much data was
    ++ *          read. Note that it may not consume the entire input, in which case
    ++ *          `input->pos < input->size`, and it's up to the caller to present
    ++ *          remaining data again.
    ++ *
    ++ * The `input` and `output` buffers may be any size. Guaranteed to make some
    ++ * forward progress if `input` and `output` are not empty.
    ++ *
    ++ * Return:  A hint for the number of bytes to use as the input for the next
    ++ *          function call or an error, which can be checked using
    ++ *          ZSTD_isError().
    ++ */
    ++size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output,
    ++	ZSTD_inBuffer *input);
    ++/**
    ++ * ZSTD_flushStream() - flush internal buffers into output
    ++ * @zcs:    The zstd streaming compression context.
    ++ * @output: Destination buffer. `output->pos` is updated to indicate how much
    ++ *          compressed data was written.
    ++ *
    ++ * ZSTD_flushStream() must be called until it returns 0, meaning all the data
    ++ * has been flushed. Since ZSTD_flushStream() causes a block to be ended,
    ++ * calling it too often will degrade the compression ratio.
    ++ *
    ++ * Return:  The number of bytes still present within internal buffers or an
    ++ *          error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output);
    ++/**
    ++ * ZSTD_endStream() - flush internal buffers into output and end the frame
    ++ * @zcs:    The zstd streaming compression context.
    ++ * @output: Destination buffer. `output->pos` is updated to indicate how much
    ++ *          compressed data was written.
    ++ *
    ++ * ZSTD_endStream() must be called until it returns 0, meaning all the data has
    ++ * been flushed and the frame epilogue has been written.
    ++ *
    ++ * Return:  The number of bytes still present within internal buffers or an
    ++ *          error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output);
    ++
    ++/**
    ++ * ZSTD_CStreamInSize() - recommended size for the input buffer
    ++ *
    ++ * Return: The recommended size for the input buffer.
    ++ */
    ++size_t ZSTD_CStreamInSize(void);
    ++/**
    ++ * ZSTD_CStreamOutSize() - recommended size for the output buffer
    ++ *
    ++ * When the output buffer is at least this large, it is guaranteed to be large
    ++ * enough to flush at least one complete compressed block.
    ++ *
    ++ * Return: The recommended size for the output buffer.
    ++ */
    ++size_t ZSTD_CStreamOutSize(void);
    ++
    ++
    ++
    ++/*-*****************************************************************************
    ++ * Streaming decompression - HowTo
    ++ *
    ++ * A ZSTD_DStream object is required to track streaming operations.
    ++ * Use ZSTD_initDStream() to initialize a ZSTD_DStream object.
    ++ * ZSTD_DStream objects can be re-used multiple times.
    ++ *
    ++ * Use ZSTD_decompressStream() repetitively to consume your input.
    ++ * The function will update both `pos` fields.
    ++ * If `input->pos < input->size`, some input has not been consumed.
    ++ * It's up to the caller to present again remaining data.
    ++ * If `output->pos < output->size`, decoder has flushed everything it could.
    ++ * Returns 0 iff a frame is completely decoded and fully flushed.
    ++ * Otherwise it returns a suggested next input size that will never load more
    ++ * than the current frame.
    ++ ******************************************************************************/
    ++
    ++/**
    ++ * ZSTD_DStreamWorkspaceBound() - memory needed to initialize a ZSTD_DStream
    ++ * @maxWindowSize: The maximum window size allowed for compressed frames.
    ++ *
    ++ * Return:         A lower bound on the size of the workspace that is passed to
    ++ *                 ZSTD_initDStream() and ZSTD_initDStream_usingDDict().
    ++ */
    ++size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize);
    ++
    ++/**
    ++ * struct ZSTD_DStream - the zstd streaming decompression context
    ++ */
    ++typedef struct ZSTD_DStream_s ZSTD_DStream;
    ++/*===== ZSTD_DStream management functions =====*/
    ++/**
    ++ * ZSTD_initDStream() - initialize a zstd streaming decompression context
    ++ * @maxWindowSize: The maximum window size allowed for compressed frames.
    ++ * @workspace:     The workspace to emplace the context into. It must outlive
    ++ *                 the returned context.
    ++ * @workspaceSize: The size of workspace.
    ++ *                 Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine
    ++ *                 how large the workspace must be.
    ++ *
    ++ * Return:         The zstd streaming decompression context.
    ++ */
    ++ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace,
    ++	size_t workspaceSize);
    ++/**
    ++ * ZSTD_initDStream_usingDDict() - initialize streaming decompression context
    ++ * @maxWindowSize: The maximum window size allowed for compressed frames.
    ++ * @ddict:         The digested dictionary to use for decompression.
    ++ * @workspace:     The workspace to emplace the context into. It must outlive
    ++ *                 the returned context.
    ++ * @workspaceSize: The size of workspace.
    ++ *                 Use ZSTD_DStreamWorkspaceBound(maxWindowSize) to determine
    ++ *                 how large the workspace must be.
    ++ *
    ++ * Return:         The zstd streaming decompression context.
    ++ */
    ++ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize,
    ++	const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize);
    ++
    ++/*===== Streaming decompression functions =====*/
    ++/**
    ++ * ZSTD_resetDStream() - reset the context using parameters from creation
    ++ * @zds:   The zstd streaming decompression context to reset.
    ++ *
    ++ * Resets the context using the parameters from creation. Skips dictionary
    ++ * loading, since it can be reused.
    ++ *
    ++ * Return: Zero or an error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_resetDStream(ZSTD_DStream *zds);
    ++/**
    ++ * ZSTD_decompressStream() - streaming decompress some of input into output
    ++ * @zds:    The zstd streaming decompression context.
    ++ * @output: Destination buffer. `output.pos` is updated to indicate how much
    ++ *          decompressed data was written.
    ++ * @input:  Source buffer. `input.pos` is updated to indicate how much data was
    ++ *          read. Note that it may not consume the entire input, in which case
    ++ *          `input.pos < input.size`, and it's up to the caller to present
    ++ *          remaining data again.
    ++ *
    ++ * The `input` and `output` buffers may be any size. Guaranteed to make some
    ++ * forward progress if `input` and `output` are not empty.
    ++ * ZSTD_decompressStream() will not consume the last byte of the frame until
    ++ * the entire frame is flushed.
    ++ *
    ++ * Return:  Returns 0 iff a frame is completely decoded and fully flushed.
    ++ *          Otherwise returns a hint for the number of bytes to use as the input
    ++ *          for the next function call or an error, which can be checked using
    ++ *          ZSTD_isError(). The size hint will never load more than the frame.
    ++ */
    ++size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output,
    ++	ZSTD_inBuffer *input);
    ++
    ++/**
    ++ * ZSTD_DStreamInSize() - recommended size for the input buffer
    ++ *
    ++ * Return: The recommended size for the input buffer.
    ++ */
    ++size_t ZSTD_DStreamInSize(void);
    ++/**
    ++ * ZSTD_DStreamOutSize() - recommended size for the output buffer
    ++ *
    ++ * When the output buffer is at least this large, it is guaranteed to be large
    ++ * enough to flush at least one complete decompressed block.
    ++ *
    ++ * Return: The recommended size for the output buffer.
    ++ */
    ++size_t ZSTD_DStreamOutSize(void);
    ++
    ++
    ++/* --- Constants ---*/
    ++#define ZSTD_MAGICNUMBER            0xFD2FB528   /* >= v0.8.0 */
    ++#define ZSTD_MAGIC_SKIPPABLE_START  0x184D2A50U
    ++
    ++#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
    ++#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)
    ++
    ++#define ZSTD_WINDOWLOG_MAX_32  27
    ++#define ZSTD_WINDOWLOG_MAX_64  27
    ++#define ZSTD_WINDOWLOG_MAX \
    ++	((unsigned int)(sizeof(size_t) == 4 \
    ++		? ZSTD_WINDOWLOG_MAX_32 \
    ++		: ZSTD_WINDOWLOG_MAX_64))
    ++#define ZSTD_WINDOWLOG_MIN 10
    ++#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
    ++#define ZSTD_HASHLOG_MIN        6
    ++#define ZSTD_CHAINLOG_MAX     (ZSTD_WINDOWLOG_MAX+1)
    ++#define ZSTD_CHAINLOG_MIN      ZSTD_HASHLOG_MIN
    ++#define ZSTD_HASHLOG3_MAX      17
    ++#define ZSTD_SEARCHLOG_MAX    (ZSTD_WINDOWLOG_MAX-1)
    ++#define ZSTD_SEARCHLOG_MIN      1
    ++/* only for ZSTD_fast, other strategies are limited to 6 */
    ++#define ZSTD_SEARCHLENGTH_MAX   7
    ++/* only for ZSTD_btopt, other strategies are limited to 4 */
    ++#define ZSTD_SEARCHLENGTH_MIN   3
    ++#define ZSTD_TARGETLENGTH_MIN   4
    ++#define ZSTD_TARGETLENGTH_MAX 999
    ++
    ++/* for static allocation */
    ++#define ZSTD_FRAMEHEADERSIZE_MAX 18
    ++#define ZSTD_FRAMEHEADERSIZE_MIN  6
    ++static const size_t ZSTD_frameHeaderSize_prefix = 5;
    ++static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN;
    ++static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
    ++/* magic number + skippable frame length */
    ++static const size_t ZSTD_skippableHeaderSize = 8;
    ++
    ++
    ++/*-*************************************
    ++ * Compressed size functions
    ++ **************************************/
    ++
    ++/**
    ++ * ZSTD_findFrameCompressedSize() - returns the size of a compressed frame
    ++ * @src:     Source buffer. It should point to the start of a zstd encoded frame
    ++ *           or a skippable frame.
    ++ * @srcSize: The size of the source buffer. It must be at least as large as the
    ++ *           size of the frame.
    ++ *
    ++ * Return:   The compressed size of the frame pointed to by `src` or an error,
    ++ *           which can be check with ZSTD_isError().
    ++ *           Suitable to pass to ZSTD_decompress() or similar functions.
    ++ */
    ++size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize);
    ++
    ++/*-*************************************
    ++ * Decompressed size functions
    ++ **************************************/
    ++/**
    ++ * ZSTD_getFrameContentSize() - returns the content size in a zstd frame header
    ++ * @src:     It should point to the start of a zstd encoded frame.
    ++ * @srcSize: The size of the source buffer. It must be at least as large as the
    ++ *           frame header. `ZSTD_frameHeaderSize_max` is always large enough.
    ++ *
    ++ * Return:   The frame content size stored in the frame header if known.
    ++ *           `ZSTD_CONTENTSIZE_UNKNOWN` if the content size isn't stored in the
    ++ *           frame header. `ZSTD_CONTENTSIZE_ERROR` on invalid input.
    ++ */
    ++unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
    ++
    ++/**
    ++ * ZSTD_findDecompressedSize() - returns decompressed size of a series of frames
    ++ * @src:     It should point to the start of a series of zstd encoded and/or
    ++ *           skippable frames.
    ++ * @srcSize: The exact size of the series of frames.
    ++ *
    ++ * If any zstd encoded frame in the series doesn't have the frame content size
    ++ * set, `ZSTD_CONTENTSIZE_UNKNOWN` is returned. But frame content size is always
    ++ * set when using ZSTD_compress(). The decompressed size can be very large.
    ++ * If the source is untrusted, the decompressed size could be wrong or
    ++ * intentionally modified. Always ensure the result fits within the
    ++ * application's authorized limits. ZSTD_findDecompressedSize() handles multiple
    ++ * frames, and so it must traverse the input to read each frame header. This is
    ++ * efficient as most of the data is skipped, however it does mean that all frame
    ++ * data must be present and valid.
    ++ *
    ++ * Return:   Decompressed size of all the data contained in the frames if known.
    ++ *           `ZSTD_CONTENTSIZE_UNKNOWN` if the decompressed size is unknown.
    ++ *           `ZSTD_CONTENTSIZE_ERROR` if an error occurred.
    ++ */
    ++unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize);
    ++
    ++/*-*************************************
    ++ * Advanced compression functions
    ++ **************************************/
    ++/**
    ++ * ZSTD_checkCParams() - ensure parameter values remain within authorized range
    ++ * @cParams: The zstd compression parameters.
    ++ *
    ++ * Return:   Zero or an error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams);
    ++
    ++/**
    ++ * ZSTD_adjustCParams() - optimize parameters for a given srcSize and dictSize
    ++ * @srcSize:  Optionally the estimated source size, or zero if unknown.
    ++ * @dictSize: Optionally the estimated dictionary size, or zero if unknown.
    ++ *
    ++ * Return:    The optimized parameters.
    ++ */
    ++ZSTD_compressionParameters ZSTD_adjustCParams(
    ++	ZSTD_compressionParameters cParams, unsigned long long srcSize,
    ++	size_t dictSize);
    ++
    ++/*--- Advanced decompression functions ---*/
    ++
    ++/**
    ++ * ZSTD_isFrame() - returns true iff the buffer starts with a valid frame
    ++ * @buffer: The source buffer to check.
    ++ * @size:   The size of the source buffer, must be at least 4 bytes.
    ++ *
    ++ * Return: True iff the buffer starts with a zstd or skippable frame identifier.
    ++ */
    ++unsigned int ZSTD_isFrame(const void *buffer, size_t size);
    ++
    ++/**
    ++ * ZSTD_getDictID_fromDict() - returns the dictionary id stored in a dictionary
    ++ * @dict:     The dictionary buffer.
    ++ * @dictSize: The size of the dictionary buffer.
    ++ *
    ++ * Return:    The dictionary id stored within the dictionary or 0 if the
    ++ *            dictionary is not a zstd dictionary. If it returns 0 the
    ++ *            dictionary can still be loaded as a content-only dictionary.
    ++ */
    ++unsigned int ZSTD_getDictID_fromDict(const void *dict, size_t dictSize);
    ++
    ++/**
    ++ * ZSTD_getDictID_fromDDict() - returns the dictionary id stored in a ZSTD_DDict
    ++ * @ddict: The ddict to find the id of.
    ++ *
    ++ * Return: The dictionary id stored within `ddict` or 0 if the dictionary is not
    ++ *         a zstd dictionary. If it returns 0 `ddict` will be loaded as a
    ++ *         content-only dictionary.
    ++ */
    ++unsigned int ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict);
    ++
    ++/**
    ++ * ZSTD_getDictID_fromFrame() - returns the dictionary id stored in a zstd frame
    ++ * @src:     Source buffer. It must be a zstd encoded frame.
    ++ * @srcSize: The size of the source buffer. It must be at least as large as the
    ++ *           frame header. `ZSTD_frameHeaderSize_max` is always large enough.
    ++ *
    ++ * Return:   The dictionary id required to decompress the frame stored within
    ++ *           `src` or 0 if the dictionary id could not be decoded. It can return
    ++ *           0 if the frame does not require a dictionary, the dictionary id
    ++ *           wasn't stored in the frame, `src` is not a zstd frame, or `srcSize`
    ++ *           is too small.
    ++ */
    ++unsigned int ZSTD_getDictID_fromFrame(const void *src, size_t srcSize);
    ++
    ++/**
    ++ * struct ZSTD_frameParams - zstd frame parameters stored in the frame header
    ++ * @frameContentSize: The frame content size, or 0 if not present.
    ++ * @windowSize:       The window size, or 0 if the frame is a skippable frame.
    ++ * @dictID:           The dictionary id, or 0 if not present.
    ++ * @checksumFlag:     Whether a checksum was used.
    ++ */
    ++typedef struct {
    ++	unsigned long long frameContentSize;
    ++	unsigned int windowSize;
    ++	unsigned int dictID;
    ++	unsigned int checksumFlag;
    ++} ZSTD_frameParams;
    ++
    ++/**
    ++ * ZSTD_getFrameParams() - extracts parameters from a zstd or skippable frame
    ++ * @fparamsPtr: On success the frame parameters are written here.
    ++ * @src:        The source buffer. It must point to a zstd or skippable frame.
    ++ * @srcSize:    The size of the source buffer. `ZSTD_frameHeaderSize_max` is
    ++ *              always large enough to succeed.
    ++ *
    ++ * Return:      0 on success. If more data is required it returns how many bytes
    ++ *              must be provided to make forward progress. Otherwise it returns
    ++ *              an error, which can be checked using ZSTD_isError().
    ++ */
    ++size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src,
    ++	size_t srcSize);
    ++
    ++/*-*****************************************************************************
    ++ * Buffer-less and synchronous inner streaming functions
    ++ *
    ++ * This is an advanced API, giving full control over buffer management, for
    ++ * users which need direct control over memory.
    ++ * But it's also a complex one, with many restrictions (documented below).
    ++ * Prefer using normal streaming API for an easier experience
    ++ ******************************************************************************/
    ++
    ++/*-*****************************************************************************
    ++ * Buffer-less streaming compression (synchronous mode)
    ++ *
    ++ * A ZSTD_CCtx object is required to track streaming operations.
    ++ * Use ZSTD_initCCtx() to initialize a context.
    ++ * ZSTD_CCtx object can be re-used multiple times within successive compression
    ++ * operations.
    ++ *
    ++ * Start by initializing a context.
    ++ * Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary
    ++ * compression,
    ++ * or ZSTD_compressBegin_advanced(), for finer parameter control.
    ++ * It's also possible to duplicate a reference context which has already been
    ++ * initialized, using ZSTD_copyCCtx()
    ++ *
    ++ * Then, consume your input using ZSTD_compressContinue().
    ++ * There are some important considerations to keep in mind when using this
    ++ * advanced function :
    ++ * - ZSTD_compressContinue() has no internal buffer. It uses externally provided
    ++ *   buffer only.
    ++ * - Interface is synchronous : input is consumed entirely and produce 1+
    ++ *   (or more) compressed blocks.
    ++ * - Caller must ensure there is enough space in `dst` to store compressed data
    ++ *   under worst case scenario. Worst case evaluation is provided by
    ++ *   ZSTD_compressBound().
    ++ *   ZSTD_compressContinue() doesn't guarantee recover after a failed
    ++ *   compression.
    ++ * - ZSTD_compressContinue() presumes prior input ***is still accessible and
    ++ *   unmodified*** (up to maximum distance size, see WindowLog).
    ++ *   It remembers all previous contiguous blocks, plus one separated memory
    ++ *   segment (which can itself consists of multiple contiguous blocks)
    ++ * - ZSTD_compressContinue() detects that prior input has been overwritten when
    ++ *   `src` buffer overlaps. In which case, it will "discard" the relevant memory
    ++ *   section from its history.
    ++ *
    ++ * Finish a frame with ZSTD_compressEnd(), which will write the last block(s)
    ++ * and optional checksum. It's possible to use srcSize==0, in which case, it
    ++ * will write a final empty block to end the frame. Without last block mark,
    ++ * frames will be considered unfinished (corrupted) by decoders.
    ++ *
    ++ * `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress some new
    ++ * frame.
    ++ ******************************************************************************/
    ++
    ++/*=====   Buffer-less streaming compression functions  =====*/
    ++size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel);
    ++size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict,
    ++	size_t dictSize, int compressionLevel);
    ++size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict,
    ++	size_t dictSize, ZSTD_parameters params,
    ++	unsigned long long pledgedSrcSize);
    ++size_t ZSTD_copyCCtx(ZSTD_CCtx *cctx, const ZSTD_CCtx *preparedCCtx,
    ++	unsigned long long pledgedSrcSize);
    ++size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict,
    ++	unsigned long long pledgedSrcSize);
    ++size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++
    ++
    ++
    ++/*-*****************************************************************************
    ++ * Buffer-less streaming decompression (synchronous mode)
    ++ *
    ++ * A ZSTD_DCtx object is required to track streaming operations.
    ++ * Use ZSTD_initDCtx() to initialize a context.
    ++ * A ZSTD_DCtx object can be re-used multiple times.
    ++ *
    ++ * First typical operation is to retrieve frame parameters, using
    ++ * ZSTD_getFrameParams(). It fills a ZSTD_frameParams structure which provide
    ++ * important information to correctly decode the frame, such as the minimum
    ++ * rolling buffer size to allocate to decompress data (`windowSize`), and the
    ++ * dictionary ID used.
    ++ * Note: content size is optional, it may not be present. 0 means unknown.
    ++ * Note that these values could be wrong, either because of data malformation,
    ++ * or because an attacker is spoofing deliberate false information. As a
    ++ * consequence, check that values remain within valid application range,
    ++ * especially `windowSize`, before allocation. Each application can set its own
    ++ * limit, depending on local restrictions. For extended interoperability, it is
    ++ * recommended to support at least 8 MB.
    ++ * Frame parameters are extracted from the beginning of the compressed frame.
    ++ * Data fragment must be large enough to ensure successful decoding, typically
    ++ * `ZSTD_frameHeaderSize_max` bytes.
    ++ * Result: 0: successful decoding, the `ZSTD_frameParams` structure is filled.
    ++ *        >0: `srcSize` is too small, provide at least this many bytes.
    ++ *        errorCode, which can be tested using ZSTD_isError().
    ++ *
    ++ * Start decompression, with ZSTD_decompressBegin() or
    ++ * ZSTD_decompressBegin_usingDict(). Alternatively, you can copy a prepared
    ++ * context, using ZSTD_copyDCtx().
    ++ *
    ++ * Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue()
    ++ * alternatively.
    ++ * ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize'
    ++ * to ZSTD_decompressContinue().
    ++ * ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will
    ++ * fail.
    ++ *
    ++ * The result of ZSTD_decompressContinue() is the number of bytes regenerated
    ++ * within 'dst' (necessarily <= dstCapacity). It can be zero, which is not an
    ++ * error; it just means ZSTD_decompressContinue() has decoded some metadata
    ++ * item. It can also be an error code, which can be tested with ZSTD_isError().
    ++ *
    ++ * ZSTD_decompressContinue() needs previous data blocks during decompression, up
    ++ * to `windowSize`. They should preferably be located contiguously, prior to
    ++ * current block. Alternatively, a round buffer of sufficient size is also
    ++ * possible. Sufficient size is determined by frame parameters.
    ++ * ZSTD_decompressContinue() is very sensitive to contiguity, if 2 blocks don't
    ++ * follow each other, make sure that either the compressor breaks contiguity at
    ++ * the same place, or that previous contiguous segment is large enough to
    ++ * properly handle maximum back-reference.
    ++ *
    ++ * A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
    ++ * Context can then be reset to start a new decompression.
    ++ *
    ++ * Note: it's possible to know if next input to present is a header or a block,
    ++ * using ZSTD_nextInputType(). This information is not required to properly
    ++ * decode a frame.
    ++ *
    ++ * == Special case: skippable frames ==
    ++ *
    ++ * Skippable frames allow integration of user-defined data into a flow of
    ++ * concatenated frames. Skippable frames will be ignored (skipped) by a
    ++ * decompressor. The format of skippable frames is as follows:
    ++ * a) Skippable frame ID - 4 Bytes, Little endian format, any value from
    ++ *    0x184D2A50 to 0x184D2A5F
    ++ * b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
    ++ * c) Frame Content - any content (User Data) of length equal to Frame Size
    ++ * For skippable frames ZSTD_decompressContinue() always returns 0.
    ++ * For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0
    ++ * what means that a frame is skippable.
    ++ * Note: If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might
    ++ *       actually be a zstd encoded frame with no content. For purposes of
    ++ *       decompression, it is valid in both cases to skip the frame using
    ++ *       ZSTD_findFrameCompressedSize() to find its size in bytes.
    ++ * It also returns frame size as fparamsPtr->frameContentSize.
    ++ ******************************************************************************/
    ++
    ++/*=====   Buffer-less streaming decompression functions  =====*/
    ++size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx);
    ++size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict,
    ++	size_t dictSize);
    ++void   ZSTD_copyDCtx(ZSTD_DCtx *dctx, const ZSTD_DCtx *preparedDCtx);
    ++size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx);
    ++size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++typedef enum {
    ++	ZSTDnit_frameHeader,
    ++	ZSTDnit_blockHeader,
    ++	ZSTDnit_block,
    ++	ZSTDnit_lastBlock,
    ++	ZSTDnit_checksum,
    ++	ZSTDnit_skippableFrame
    ++} ZSTD_nextInputType_e;
    ++ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx);
    ++
    ++/*-*****************************************************************************
    ++ * Block functions
    ++ *
    ++ * Block functions produce and decode raw zstd blocks, without frame metadata.
    ++ * Frame metadata cost is typically ~18 bytes, which can be non-negligible for
    ++ * very small blocks (< 100 bytes). User will have to take in charge required
    ++ * information to regenerate data, such as compressed and content sizes.
    ++ *
    ++ * A few rules to respect:
    ++ * - Compressing and decompressing require a context structure
    ++ *   + Use ZSTD_initCCtx() and ZSTD_initDCtx()
    ++ * - It is necessary to init context before starting
    ++ *   + compression : ZSTD_compressBegin()
    ++ *   + decompression : ZSTD_decompressBegin()
    ++ *   + variants _usingDict() are also allowed
    ++ *   + copyCCtx() and copyDCtx() work too
    ++ * - Block size is limited, it must be <= ZSTD_getBlockSizeMax()
    ++ *   + If you need to compress more, cut data into multiple blocks
    ++ *   + Consider using the regular ZSTD_compress() instead, as frame metadata
    ++ *     costs become negligible when source size is large.
    ++ * - When a block is considered not compressible enough, ZSTD_compressBlock()
    ++ *   result will be zero. In which case, nothing is produced into `dst`.
    ++ *   + User must test for such outcome and deal directly with uncompressed data
    ++ *   + ZSTD_decompressBlock() doesn't accept uncompressed data as input!!!
    ++ *   + In case of multiple successive blocks, decoder must be informed of
    ++ *     uncompressed block existence to follow proper history. Use
    ++ *     ZSTD_insertBlock() in such a case.
    ++ ******************************************************************************/
    ++
    ++/* Define for static allocation */
    ++#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024)
    ++/*=====   Raw zstd block functions  =====*/
    ++size_t ZSTD_getBlockSizeMax(ZSTD_CCtx *cctx);
    ++size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity,
    ++	const void *src, size_t srcSize);
    ++size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart,
    ++	size_t blockSize);
    ++
    ++#endif  /* ZSTD_H */
    +diff --git a/lib/Kconfig b/lib/Kconfig
    +index b6009d7..f00ddab 100644
    +--- a/lib/Kconfig
    ++++ b/lib/Kconfig
    +@@ -241,6 +241,14 @@ config LZ4HC_COMPRESS
    + config LZ4_DECOMPRESS
    + 	tristate
    + 
    ++config ZSTD_COMPRESS
    ++	select XXHASH
    ++	tristate
    ++
    ++config ZSTD_DECOMPRESS
    ++	select XXHASH
    ++	tristate
    ++
    + source "lib/xz/Kconfig"
    + 
    + #
    +diff --git a/lib/Makefile b/lib/Makefile
    +index e16f94a..0cfd529 100644
    +--- a/lib/Makefile
    ++++ b/lib/Makefile
    +@@ -115,6 +115,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
    + obj-$(CONFIG_LZ4_COMPRESS) += lz4/
    + obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/
    + obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
    ++obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
    ++obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
    + obj-$(CONFIG_XZ_DEC) += xz/
    + obj-$(CONFIG_RAID6_PQ) += raid6/
    + 
    +diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile
    +new file mode 100644
    +index 0000000..aa5eb4d
    +--- /dev/null
    ++++ b/lib/zstd/Makefile
    +@@ -0,0 +1,9 @@
    ++obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
    ++obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
    ++
    ++ccflags-y += -O3
    ++
    ++zstd_compress-y := entropy_common.o fse_decompress.o zstd_common.o \
    ++				fse_compress.o huf_compress.o compress.o
    ++zstd_decompress-y := entropy_common.o fse_decompress.o zstd_common.o \
    ++				huf_decompress.o decompress.o
    +diff --git a/lib/zstd/bitstream.h b/lib/zstd/bitstream.h
    +new file mode 100644
    +index 0000000..9d21540
    +--- /dev/null
    ++++ b/lib/zstd/bitstream.h
    +@@ -0,0 +1,391 @@
    ++/* ******************************************************************
    ++   bitstream
    ++   Part of FSE library
    ++   header file (to include)
    ++   Copyright (C) 2013-2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++   You can contact the author at :
    ++   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++****************************************************************** */
    ++#ifndef BITSTREAM_H_MODULE
    ++#define BITSTREAM_H_MODULE
    ++
    ++/*
    ++*  This API consists of small unitary functions, which must be inlined for best performance.
    ++*  Since link-time-optimization is not available for all compilers,
    ++*  these functions are defined into a .h to be included.
    ++*/
    ++
    ++/*-****************************************
    ++*  Dependencies
    ++******************************************/
    ++#include "mem.h"            /* unaligned access routines */
    ++#include "error_private.h"  /* error codes and messages */
    ++
    ++
    ++/*=========================================
    ++*  Target specific
    ++=========================================*/
    ++#define STREAM_ACCUMULATOR_MIN_32  25
    ++#define STREAM_ACCUMULATOR_MIN_64  57
    ++#define STREAM_ACCUMULATOR_MIN    ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
    ++
    ++/*-******************************************
    ++*  bitStream encoding API (write forward)
    ++********************************************/
    ++/* bitStream can mix input from multiple sources.
    ++*  A critical property of these streams is that they encode and decode in **reverse** direction.
    ++*  So the first bit sequence you add will be the last to be read, like a LIFO stack.
    ++*/
    ++typedef struct
    ++{
    ++	size_t bitContainer;
    ++	int    bitPos;
    ++	char*  startPtr;
    ++	char*  ptr;
    ++	char*  endPtr;
    ++} BIT_CStream_t;
    ++
    ++MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
    ++MEM_STATIC void   BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
    ++MEM_STATIC void   BIT_flushBits(BIT_CStream_t* bitC);
    ++MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
    ++
    ++/* Start with initCStream, providing the size of buffer to write into.
    ++*  bitStream will never write outside of this buffer.
    ++*  `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
    ++*
    ++*  bits are first added to a local register.
    ++*  Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
    ++*  Writing data into memory is an explicit operation, performed by the flushBits function.
    ++*  Hence keep track how many bits are potentially stored into local register to avoid register overflow.
    ++*  After a flushBits, a maximum of 7 bits might still be stored into local register.
    ++*
    ++*  Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
    ++*
    ++*  Last operation is to close the bitStream.
    ++*  The function returns the final size of CStream in bytes.
    ++*  If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
    ++*/
    ++
    ++
    ++/*-********************************************
    ++*  bitStream decoding API (read backward)
    ++**********************************************/
    ++typedef struct
    ++{
    ++	size_t   bitContainer;
    ++	unsigned bitsConsumed;
    ++	const char* ptr;
    ++	const char* start;
    ++} BIT_DStream_t;
    ++
    ++typedef enum { BIT_DStream_unfinished = 0,
    ++			   BIT_DStream_endOfBuffer = 1,
    ++			   BIT_DStream_completed = 2,
    ++			   BIT_DStream_overflow = 3 } BIT_DStream_status;  /* result of BIT_reloadDStream() */
    ++			   /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
    ++
    ++MEM_STATIC size_t   BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
    ++MEM_STATIC size_t   BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
    ++MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
    ++MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
    ++
    ++
    ++/* Start by invoking BIT_initDStream().
    ++*  A chunk of the bitStream is then stored into a local register.
    ++*  Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
    ++*  You can then retrieve bitFields stored into the local register, **in reverse order**.
    ++*  Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
    ++*  A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
    ++*  Otherwise, it can be less than that, so proceed accordingly.
    ++*  Checking if DStream has reached its end can be performed with BIT_endOfDStream().
    ++*/
    ++
    ++
    ++/*-****************************************
    ++*  unsafe API
    ++******************************************/
    ++MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
    ++/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
    ++
    ++MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
    ++/* unsafe version; does not check buffer overflow */
    ++
    ++MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
    ++/* faster, but works only if nbBits >= 1 */
    ++
    ++
    ++
    ++/*-**************************************************************
    ++*  Internal functions
    ++****************************************************************/
    ++MEM_STATIC unsigned BIT_highbit32 (register U32 val)
    ++{
    ++#   if defined(_MSC_VER)   /* Visual */
    ++	unsigned long r=0;
    ++	_BitScanReverse ( &r, val );
    ++	return (unsigned) r;
    ++#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* Use GCC Intrinsic */
    ++	return 31 - __builtin_clz (val);
    ++#   else   /* Software version */
    ++	static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    ++	U32 v = val;
    ++	v |= v >> 1;
    ++	v |= v >> 2;
    ++	v |= v >> 4;
    ++	v |= v >> 8;
    ++	v |= v >> 16;
    ++	return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
    ++#   endif
    ++}
    ++
    ++/*=====    Local Constants   =====*/
    ++static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,  0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF };   /* up to 26 bits */
    ++
    ++
    ++/*-**************************************************************
    ++*  bitStream encoding
    ++****************************************************************/
    ++/*! BIT_initCStream() :
    ++ *  `dstCapacity` must be > sizeof(void*)
    ++ *  @return : 0 if success,
    ++			  otherwise an error code (can be tested using ERR_isError() ) */
    ++MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
    ++{
    ++	bitC->bitContainer = 0;
    ++	bitC->bitPos = 0;
    ++	bitC->startPtr = (char*)startPtr;
    ++	bitC->ptr = bitC->startPtr;
    ++	bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr);
    ++	if (dstCapacity <= sizeof(bitC->ptr)) return ERROR(dstSize_tooSmall);
    ++	return 0;
    ++}
    ++
    ++/*! BIT_addBits() :
    ++	can add up to 26 bits into `bitC`.
    ++	Does not check for register overflow ! */
    ++MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    ++{
    ++	bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
    ++	bitC->bitPos += nbBits;
    ++}
    ++
    ++/*! BIT_addBitsFast() :
    ++ *  works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
    ++MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    ++{
    ++	bitC->bitContainer |= value << bitC->bitPos;
    ++	bitC->bitPos += nbBits;
    ++}
    ++
    ++/*! BIT_flushBitsFast() :
    ++ *  unsafe version; does not check buffer overflow */
    ++MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
    ++{
    ++	size_t const nbBytes = bitC->bitPos >> 3;
    ++	MEM_writeLEST(bitC->ptr, bitC->bitContainer);
    ++	bitC->ptr += nbBytes;
    ++	bitC->bitPos &= 7;
    ++	bitC->bitContainer >>= nbBytes*8;   /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
    ++}
    ++
    ++/*! BIT_flushBits() :
    ++ *  safe version; check for buffer overflow, and prevents it.
    ++ *  note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
    ++MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
    ++{
    ++	size_t const nbBytes = bitC->bitPos >> 3;
    ++	MEM_writeLEST(bitC->ptr, bitC->bitContainer);
    ++	bitC->ptr += nbBytes;
    ++	if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
    ++	bitC->bitPos &= 7;
    ++	bitC->bitContainer >>= nbBytes*8;   /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
    ++}
    ++
    ++/*! BIT_closeCStream() :
    ++ *  @return : size of CStream, in bytes,
    ++			  or 0 if it could not fit into dstBuffer */
    ++MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
    ++{
    ++	BIT_addBitsFast(bitC, 1, 1);   /* endMark */
    ++	BIT_flushBits(bitC);
    ++
    ++	if (bitC->ptr >= bitC->endPtr) return 0; /* doesn't fit within authorized budget : cancel */
    ++
    ++	return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
    ++}
    ++
    ++
    ++/*-********************************************************
    ++* bitStream decoding
    ++**********************************************************/
    ++/*! BIT_initDStream() :
    ++*   Initialize a BIT_DStream_t.
    ++*   `bitD` : a pointer to an already allocated BIT_DStream_t structure.
    ++*   `srcSize` must be the *exact* size of the bitStream, in bytes.
    ++*   @return : size of stream (== srcSize) or an errorCode if a problem is detected
    ++*/
    ++MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
    ++{
    ++	if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
    ++
    ++	if (srcSize >=  sizeof(bitD->bitContainer)) {  /* normal case */
    ++		bitD->start = (const char*)srcBuffer;
    ++		bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
    ++		bitD->bitContainer = MEM_readLEST(bitD->ptr);
    ++		{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
    ++		  bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */
    ++		  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
    ++	} else {
    ++		bitD->start = (const char*)srcBuffer;
    ++		bitD->ptr   = bitD->start;
    ++		bitD->bitContainer = *(const BYTE*)(bitD->start);
    ++		switch(srcSize)
    ++		{
    ++			case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    ++			case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    ++			case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    ++			case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    ++			case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    ++			case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    ++			default:;
    ++		}
    ++		{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
    ++		  bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
    ++		  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
    ++		bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
    ++	}
    ++
    ++	return srcSize;
    ++}
    ++
    ++MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
    ++{
    ++	return bitContainer >> start;
    ++}
    ++
    ++MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
    ++{
    ++	return (bitContainer >> start) & BIT_mask[nbBits];
    ++}
    ++
    ++MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
    ++{
    ++	return bitContainer & BIT_mask[nbBits];
    ++}
    ++
    ++/*! BIT_lookBits() :
    ++ *  Provides next n bits from local register.
    ++ *  local register is not modified.
    ++ *  On 32-bits, maxNbBits==24.
    ++ *  On 64-bits, maxNbBits==56.
    ++ *  @return : value extracted
    ++ */
    ++ MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
    ++{
    ++	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
    ++	return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
    ++}
    ++
    ++/*! BIT_lookBitsFast() :
    ++*   unsafe version; only works only if nbBits >= 1 */
    ++MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
    ++{
    ++	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
    ++	return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
    ++}
    ++
    ++MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
    ++{
    ++	bitD->bitsConsumed += nbBits;
    ++}
    ++
    ++/*! BIT_readBits() :
    ++ *  Read (consume) next n bits from local register and update.
    ++ *  Pay attention to not read more than nbBits contained into local register.
    ++ *  @return : extracted value.
    ++ */
    ++MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
    ++{
    ++	size_t const value = BIT_lookBits(bitD, nbBits);
    ++	BIT_skipBits(bitD, nbBits);
    ++	return value;
    ++}
    ++
    ++/*! BIT_readBitsFast() :
    ++*   unsafe version; only works only if nbBits >= 1 */
    ++MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
    ++{
    ++	size_t const value = BIT_lookBitsFast(bitD, nbBits);
    ++	BIT_skipBits(bitD, nbBits);
    ++	return value;
    ++}
    ++
    ++/*! BIT_reloadDStream() :
    ++*   Refill `bitD` from buffer previously set in BIT_initDStream() .
    ++*   This function is safe, it guarantees it will not read beyond src buffer.
    ++*   @return : status of `BIT_DStream_t` internal register.
    ++			  if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
    ++MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
    ++{
    ++	if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
    ++		return BIT_DStream_overflow;
    ++
    ++	if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
    ++		bitD->ptr -= bitD->bitsConsumed >> 3;
    ++		bitD->bitsConsumed &= 7;
    ++		bitD->bitContainer = MEM_readLEST(bitD->ptr);
    ++		return BIT_DStream_unfinished;
    ++	}
    ++	if (bitD->ptr == bitD->start) {
    ++		if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
    ++		return BIT_DStream_completed;
    ++	}
    ++	{   U32 nbBytes = bitD->bitsConsumed >> 3;
    ++		BIT_DStream_status result = BIT_DStream_unfinished;
    ++		if (bitD->ptr - nbBytes < bitD->start) {
    ++			nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */
    ++			result = BIT_DStream_endOfBuffer;
    ++		}
    ++		bitD->ptr -= nbBytes;
    ++		bitD->bitsConsumed -= nbBytes*8;
    ++		bitD->bitContainer = MEM_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD) */
    ++		return result;
    ++	}
    ++}
    ++
    ++/*! BIT_endOfDStream() :
    ++*   @return Tells if DStream has exactly reached its end (all bits consumed).
    ++*/
    ++MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
    ++{
    ++	return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
    ++}
    ++
    ++#endif /* BITSTREAM_H_MODULE */
    +diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
    +new file mode 100644
    +index 0000000..79c3207
    +--- /dev/null
    ++++ b/lib/zstd/compress.c
    +@@ -0,0 +1,3384 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++
    ++/*-*************************************
    ++*  Dependencies
    ++***************************************/
    ++#include 
    ++#include 
    ++#include          /* memset */
    ++#include "mem.h"
    ++#include "fse.h"
    ++#include "huf.h"
    ++#include "zstd_internal.h"  /* includes zstd.h */
    ++
    ++#ifdef current
    ++#  undef current
    ++#endif
    ++
    ++/*-*************************************
    ++*  Constants
    ++***************************************/
    ++static const U32 g_searchStrength = 8;   /* control skip over incompressible data */
    ++#define HASH_READ_SIZE 8
    ++typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
    ++
    ++
    ++/*-*************************************
    ++*  Helper functions
    ++***************************************/
    ++#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
    ++size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
    ++
    ++
    ++/*-*************************************
    ++*  Sequence storage
    ++***************************************/
    ++static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
    ++{
    ++	ssPtr->lit = ssPtr->litStart;
    ++	ssPtr->sequences = ssPtr->sequencesStart;
    ++	ssPtr->longLengthID = 0;
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Context memory management
    ++***************************************/
    ++struct ZSTD_CCtx_s {
    ++	const BYTE* nextSrc;    /* next block here to continue on current prefix */
    ++	const BYTE* base;       /* All regular indexes relative to this position */
    ++	const BYTE* dictBase;   /* extDict indexes relative to this position */
    ++	U32   dictLimit;        /* below that point, need extDict */
    ++	U32   lowLimit;         /* below that point, no more data */
    ++	U32   nextToUpdate;     /* index from which to continue dictionary update */
    ++	U32   nextToUpdate3;    /* index from which to continue dictionary update */
    ++	U32   hashLog3;         /* dispatch table : larger == faster, more memory */
    ++	U32   loadedDictEnd;    /* index of end of dictionary */
    ++	U32   forceWindow;      /* force back-references to respect limit of 1<3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
    ++	size_t const h3Size = ((size_t)1) << hashLog3;
    ++	size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    ++	size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<customMem = customMem;
    ++	return cctx;
    ++}
    ++
    ++ZSTD_CCtx* ZSTD_initCCtx(void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	ZSTD_CCtx* cctx = ZSTD_createCCtx_advanced(stackMem);
    ++	if (cctx) {
    ++		cctx->workSpace = ZSTD_stackAllocAll(cctx->customMem.opaque, &cctx->workSpaceSize);
    ++	}
    ++	return cctx;
    ++}
    ++
    ++size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
    ++{
    ++	if (cctx==NULL) return 0;   /* support free on NULL */
    ++	ZSTD_free(cctx->workSpace, cctx->customMem);
    ++	ZSTD_free(cctx, cctx->customMem);
    ++	return 0;   /* reserved as a potential error code in the future */
    ++}
    ++
    ++const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx)   /* hidden interface */
    ++{
    ++	return &(ctx->seqStore);
    ++}
    ++
    ++static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx)
    ++{
    ++	return cctx->params;
    ++}
    ++
    ++
    ++/** ZSTD_checkParams() :
    ++	ensure param values remain within authorized range.
    ++	@return : 0, or an error code if one value is beyond authorized range */
    ++size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
    ++{
    ++#   define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); }
    ++	CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
    ++	CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
    ++	CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
    ++	CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
    ++	CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
    ++	CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
    ++	if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
    ++	return 0;
    ++}
    ++
    ++
    ++/** ZSTD_cycleLog() :
    ++ *  condition for correct operation : hashLog > 1 */
    ++static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
    ++{
    ++	U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
    ++	return hashLog - btScale;
    ++}
    ++
    ++/** ZSTD_adjustCParams() :
    ++	optimize `cPar` for a given input (`srcSize` and `dictSize`).
    ++	mostly downsizing to reduce memory consumption and initialization.
    ++	Both `srcSize` and `dictSize` are optional (use 0 if unknown),
    ++	but if both are 0, no optimization can be done.
    ++	Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
    ++ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
    ++{
    ++	if (srcSize+dictSize == 0) return cPar;   /* no size information available : no adjustment */
    ++
    ++	/* resize params, to use less memory when necessary */
    ++	{   U32 const minSrcSize = (srcSize==0) ? 500 : 0;
    ++		U64 const rSize = srcSize + dictSize + minSrcSize;
    ++		if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog;
    ++	}   }
    ++	if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
    ++	{   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
    ++		if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
    ++	}
    ++
    ++	if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
    ++
    ++	return cPar;
    ++}
    ++
    ++
    ++static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
    ++{
    ++	return (param1.cParams.hashLog  == param2.cParams.hashLog)
    ++		 & (param1.cParams.chainLog == param2.cParams.chainLog)
    ++		 & (param1.cParams.strategy == param2.cParams.strategy)
    ++		 & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
    ++}
    ++
    ++/*! ZSTD_continueCCtx() :
    ++	reuse CCtx without reset (note : requires no dictionary) */
    ++static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
    ++{
    ++	U32 const end = (U32)(cctx->nextSrc - cctx->base);
    ++	cctx->params = params;
    ++	cctx->frameContentSize = frameContentSize;
    ++	cctx->lowLimit = end;
    ++	cctx->dictLimit = end;
    ++	cctx->nextToUpdate = end+1;
    ++	cctx->stage = ZSTDcs_init;
    ++	cctx->dictID = 0;
    ++	cctx->loadedDictEnd = 0;
    ++	{ int i; for (i=0; irep[i] = repStartValue[i]; }
    ++	cctx->seqStore.litLengthSum = 0;  /* force reset of btopt stats */
    ++	xxh64_reset(&cctx->xxhState, 0);
    ++	return 0;
    ++}
    ++
    ++typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
    ++
    ++/*! ZSTD_resetCCtx_advanced() :
    ++	note : `params` must be validated */
    ++static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
    ++									   ZSTD_parameters params, U64 frameContentSize,
    ++									   ZSTD_compResetPolicy_e const crp)
    ++{
    ++	if (crp == ZSTDcrp_continue)
    ++		if (ZSTD_equivalentParams(params, zc->params)) {
    ++			zc->flagStaticTables = 0;
    ++			zc->flagStaticHufTable = HUF_repeat_none;
    ++			return ZSTD_continueCCtx(zc, params, frameContentSize);
    ++		}
    ++
    ++	{   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    ++		U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
    ++		size_t const maxNbSeq = blockSize / divider;
    ++		size_t const tokenSpace = blockSize + 11*maxNbSeq;
    ++		size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
    ++		size_t const hSize = ((size_t)1) << params.cParams.hashLog;
    ++		U32    const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
    ++		size_t const h3Size = ((size_t)1) << hashLog3;
    ++		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    ++		void* ptr;
    ++
    ++		/* Check if workSpace is large enough, alloc a new one if needed */
    ++		{   size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<workSpaceSize < neededSpace) {
    ++				ZSTD_free(zc->workSpace, zc->customMem);
    ++				zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
    ++				if (zc->workSpace == NULL) return ERROR(memory_allocation);
    ++				zc->workSpaceSize = neededSpace;
    ++		}   }
    ++
    ++		if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace);   /* reset tables only */
    ++		xxh64_reset(&zc->xxhState, 0);
    ++		zc->hashLog3 = hashLog3;
    ++		zc->hashTable = (U32*)(zc->workSpace);
    ++		zc->chainTable = zc->hashTable + hSize;
    ++		zc->hashTable3 = zc->chainTable + chainSize;
    ++		ptr = zc->hashTable3 + h3Size;
    ++		zc->hufTable = (HUF_CElt*)ptr;
    ++		zc->flagStaticTables = 0;
    ++		zc->flagStaticHufTable = HUF_repeat_none;
    ++		ptr = ((U32*)ptr) + 256;  /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
    ++
    ++		zc->nextToUpdate = 1;
    ++		zc->nextSrc = NULL;
    ++		zc->base = NULL;
    ++		zc->dictBase = NULL;
    ++		zc->dictLimit = 0;
    ++		zc->lowLimit = 0;
    ++		zc->params = params;
    ++		zc->blockSize = blockSize;
    ++		zc->frameContentSize = frameContentSize;
    ++		{ int i; for (i=0; irep[i] = repStartValue[i]; }
    ++
    ++		if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
    ++			zc->seqStore.litFreq = (U32*)ptr;
    ++			zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
    ++			zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
    ++			ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
    ++			zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
    ++			ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
    ++			zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
    ++			ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
    ++			zc->seqStore.litLengthSum = 0;
    ++		}
    ++		zc->seqStore.sequencesStart = (seqDef*)ptr;
    ++		ptr = zc->seqStore.sequencesStart + maxNbSeq;
    ++		zc->seqStore.llCode = (BYTE*) ptr;
    ++		zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
    ++		zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
    ++		zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
    ++
    ++		zc->stage = ZSTDcs_init;
    ++		zc->dictID = 0;
    ++		zc->loadedDictEnd = 0;
    ++
    ++		return 0;
    ++	}
    ++}
    ++
    ++/* ZSTD_invalidateRepCodes() :
    ++ * ensures next compression will not use repcodes from previous block.
    ++ * Note : only works with regular variant;
    ++ *        do not use with extDict variant ! */
    ++void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
    ++	int i;
    ++	for (i=0; irep[i] = 0;
    ++}
    ++
    ++/*! ZSTD_copyCCtx() :
    ++*   Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
    ++*   Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
    ++*   @return : 0, or an error code */
    ++size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
    ++{
    ++	if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
    ++
    ++
    ++	memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    ++	{   ZSTD_parameters params = srcCCtx->params;
    ++		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    ++		ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
    ++	}
    ++
    ++	/* copy tables */
    ++	{   size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
    ++		size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
    ++		size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
    ++		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    ++		memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
    ++	}
    ++
    ++	/* copy dictionary offsets */
    ++	dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
    ++	dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
    ++	dstCCtx->nextSrc      = srcCCtx->nextSrc;
    ++	dstCCtx->base         = srcCCtx->base;
    ++	dstCCtx->dictBase     = srcCCtx->dictBase;
    ++	dstCCtx->dictLimit    = srcCCtx->dictLimit;
    ++	dstCCtx->lowLimit     = srcCCtx->lowLimit;
    ++	dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
    ++	dstCCtx->dictID       = srcCCtx->dictID;
    ++
    ++	/* copy entropy tables */
    ++	dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
    ++	dstCCtx->flagStaticHufTable = srcCCtx->flagStaticHufTable;
    ++	if (srcCCtx->flagStaticTables) {
    ++		memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
    ++		memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
    ++		memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
    ++	}
    ++	if (srcCCtx->flagStaticHufTable) {
    ++		memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
    ++	}
    ++
    ++	return 0;
    ++}
    ++
    ++
    ++/*! ZSTD_reduceTable() :
    ++*   reduce table indexes by `reducerValue` */
    ++static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
    ++{
    ++	U32 u;
    ++	for (u=0 ; u < size ; u++) {
    ++		if (table[u] < reducerValue) table[u] = 0;
    ++		else table[u] -= reducerValue;
    ++	}
    ++}
    ++
    ++/*! ZSTD_reduceIndex() :
    ++*   rescale all indexes to avoid future overflow (indexes are U32) */
    ++static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
    ++{
    ++	{ U32 const hSize = 1 << zc->params.cParams.hashLog;
    ++	  ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
    ++
    ++	{ U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
    ++	  ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
    ++
    ++	{ U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
    ++	  ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
    ++}
    ++
    ++
    ++/*-*******************************************************
    ++*  Block entropic compression
    ++*********************************************************/
    ++
    ++/* See doc/zstd_compression_format.md for detailed format description */
    ++
    ++size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
    ++	memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
    ++	MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
    ++	return ZSTD_blockHeaderSize+srcSize;
    ++}
    ++
    ++
    ++static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	BYTE* const ostart = (BYTE* const)dst;
    ++	U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
    ++
    ++	if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
    ++
    ++	switch(flSize)
    ++	{
    ++		case 1: /* 2 - 1 - 5 */
    ++			ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
    ++			break;
    ++		case 2: /* 2 - 2 - 12 */
    ++			MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
    ++			break;
    ++		default:   /*note : should not be necessary : flSize is within {1,2,3} */
    ++		case 3: /* 2 - 2 - 20 */
    ++			MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
    ++			break;
    ++	}
    ++
    ++	memcpy(ostart + flSize, src, srcSize);
    ++	return srcSize + flSize;
    ++}
    ++
    ++static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	BYTE* const ostart = (BYTE* const)dst;
    ++	U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
    ++
    ++	(void)dstCapacity;  /* dstCapacity already guaranteed to be >=4, hence large enough */
    ++
    ++	switch(flSize)
    ++	{
    ++		case 1: /* 2 - 1 - 5 */
    ++			ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
    ++			break;
    ++		case 2: /* 2 - 2 - 12 */
    ++			MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
    ++			break;
    ++		default:   /*note : should not be necessary : flSize is necessarily within {1,2,3} */
    ++		case 3: /* 2 - 2 - 20 */
    ++			MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
    ++			break;
    ++	}
    ++
    ++	ostart[flSize] = *(const BYTE*)src;
    ++	return flSize+1;
    ++}
    ++
    ++
    ++static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
    ++
    ++static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
    ++									 void* dst, size_t dstCapacity,
    ++							   const void* src, size_t srcSize)
    ++{
    ++	size_t const minGain = ZSTD_minGain(srcSize);
    ++	size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
    ++	BYTE*  const ostart = (BYTE*)dst;
    ++	U32 singleStream = srcSize < 256;
    ++	symbolEncodingType_e hType = set_compressed;
    ++	size_t cLitSize;
    ++
    ++
    ++	/* small ? don't even attempt compression (speed opt) */
    ++#   define LITERAL_NOENTROPY 63
    ++	{   size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
    ++		if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
    ++	}
    ++
    ++	if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
    ++	{   HUF_repeat repeat = zc->flagStaticHufTable;
    ++		int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
    ++		if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
    ++		cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
    ++								: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat);
    ++		if (repeat != HUF_repeat_none) { hType = set_repeat; }    /* reused the existing table */
    ++		else { zc->flagStaticHufTable = HUF_repeat_check; }       /* now have a table to reuse */
    ++	}
    ++
    ++	if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
    ++		zc->flagStaticHufTable = HUF_repeat_none;
    ++		return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
    ++	}
    ++	if (cLitSize==1) {
    ++		zc->flagStaticHufTable = HUF_repeat_none;
    ++		return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
    ++	}
    ++
    ++	/* Build header */
    ++	switch(lhSize)
    ++	{
    ++	case 3: /* 2 - 2 - 10 - 10 */
    ++		{   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
    ++			MEM_writeLE24(ostart, lhc);
    ++			break;
    ++		}
    ++	case 4: /* 2 - 2 - 14 - 14 */
    ++		{   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
    ++			MEM_writeLE32(ostart, lhc);
    ++			break;
    ++		}
    ++	default:   /* should not be necessary, lhSize is only {3,4,5} */
    ++	case 5: /* 2 - 2 - 18 - 18 */
    ++		{   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
    ++			MEM_writeLE32(ostart, lhc);
    ++			ostart[4] = (BYTE)(cLitSize >> 10);
    ++			break;
    ++		}
    ++	}
    ++	return lhSize+cLitSize;
    ++}
    ++
    ++static const BYTE LL_Code[64] = {  0,  1,  2,  3,  4,  5,  6,  7,
    ++								   8,  9, 10, 11, 12, 13, 14, 15,
    ++								  16, 16, 17, 17, 18, 18, 19, 19,
    ++								  20, 20, 20, 20, 21, 21, 21, 21,
    ++								  22, 22, 22, 22, 22, 22, 22, 22,
    ++								  23, 23, 23, 23, 23, 23, 23, 23,
    ++								  24, 24, 24, 24, 24, 24, 24, 24,
    ++								  24, 24, 24, 24, 24, 24, 24, 24 };
    ++
    ++static const BYTE ML_Code[128] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    ++								  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    ++								  32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
    ++								  38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
    ++								  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
    ++								  41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
    ++								  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
    ++								  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
    ++
    ++
    ++void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
    ++{
    ++	BYTE const LL_deltaCode = 19;
    ++	BYTE const ML_deltaCode = 36;
    ++	const seqDef* const sequences = seqStorePtr->sequencesStart;
    ++	BYTE* const llCodeTable = seqStorePtr->llCode;
    ++	BYTE* const ofCodeTable = seqStorePtr->ofCode;
    ++	BYTE* const mlCodeTable = seqStorePtr->mlCode;
    ++	U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
    ++	U32 u;
    ++	for (u=0; u 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
    ++		ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
    ++		mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
    ++	}
    ++	if (seqStorePtr->longLengthID==1)
    ++		llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
    ++	if (seqStorePtr->longLengthID==2)
    ++		mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
    ++}
    ++
    ++MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
    ++							  void* dst, size_t dstCapacity,
    ++							  size_t srcSize)
    ++{
    ++	const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
    ++	const seqStore_t* seqStorePtr = &(zc->seqStore);
    ++	U32 count[MaxSeq+1];
    ++	S16 norm[MaxSeq+1];
    ++	FSE_CTable* CTable_LitLength = zc->litlengthCTable;
    ++	FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
    ++	FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
    ++	U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
    ++	const seqDef* const sequences = seqStorePtr->sequencesStart;
    ++	const BYTE* const ofCodeTable = seqStorePtr->ofCode;
    ++	const BYTE* const llCodeTable = seqStorePtr->llCode;
    ++	const BYTE* const mlCodeTable = seqStorePtr->mlCode;
    ++	BYTE* const ostart = (BYTE*)dst;
    ++	BYTE* const oend = ostart + dstCapacity;
    ++	BYTE* op = ostart;
    ++	size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
    ++	BYTE* seqHead;
    ++	BYTE scratchBuffer[1<litStart;
    ++		size_t const litSize = seqStorePtr->lit - literals;
    ++		size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
    ++		if (ZSTD_isError(cSize)) return cSize;
    ++		op += cSize;
    ++	}
    ++
    ++	/* Sequences Header */
    ++	if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
    ++	if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
    ++	else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
    ++	else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
    ++	if (nbSeq==0) goto _check_compressibility;
    ++
    ++	/* seqHead : flags for FSE encoding type */
    ++	seqHead = op++;
    ++
    ++#define MIN_SEQ_FOR_DYNAMIC_FSE   64
    ++#define MAX_SEQ_FOR_STATIC_FSE  1000
    ++
    ++	/* convert length/distances into codes */
    ++	ZSTD_seqToCodes(seqStorePtr);
    ++
    ++	/* CTable for Literal Lengths */
    ++	{   U32 max = MaxLL;
    ++		size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
    ++		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
    ++			*op++ = llCodeTable[0];
    ++			FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
    ++			LLtype = set_rle;
    ++		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
    ++			LLtype = set_repeat;
    ++		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
    ++			FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
    ++			LLtype = set_basic;
    ++		} else {
    ++			size_t nbSeq_1 = nbSeq;
    ++			const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
    ++			if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
    ++			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    ++			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    ++			  if (FSE_isError(NCountSize)) return NCountSize;
    ++			  op += NCountSize; }
    ++			FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
    ++			LLtype = set_compressed;
    ++	}   }
    ++
    ++	/* CTable for Offsets */
    ++	{   U32 max = MaxOff;
    ++		size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
    ++		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
    ++			*op++ = ofCodeTable[0];
    ++			FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
    ++			Offtype = set_rle;
    ++		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
    ++			Offtype = set_repeat;
    ++		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
    ++			FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
    ++			Offtype = set_basic;
    ++		} else {
    ++			size_t nbSeq_1 = nbSeq;
    ++			const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
    ++			if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
    ++			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    ++			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    ++			  if (FSE_isError(NCountSize)) return NCountSize;
    ++			  op += NCountSize; }
    ++			FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
    ++			Offtype = set_compressed;
    ++	}   }
    ++
    ++	/* CTable for MatchLengths */
    ++	{   U32 max = MaxML;
    ++		size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
    ++		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
    ++			*op++ = *mlCodeTable;
    ++			FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
    ++			MLtype = set_rle;
    ++		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
    ++			MLtype = set_repeat;
    ++		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
    ++			FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
    ++			MLtype = set_basic;
    ++		} else {
    ++			size_t nbSeq_1 = nbSeq;
    ++			const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
    ++			if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
    ++			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    ++			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    ++			  if (FSE_isError(NCountSize)) return NCountSize;
    ++			  op += NCountSize; }
    ++			FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
    ++			MLtype = set_compressed;
    ++	}   }
    ++
    ++	*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
    ++	zc->flagStaticTables = 0;
    ++
    ++	/* Encoding Sequences */
    ++	{   BIT_CStream_t blockStream;
    ++		FSE_CState_t  stateMatchLength;
    ++		FSE_CState_t  stateOffsetBits;
    ++		FSE_CState_t  stateLitLength;
    ++
    ++		CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
    ++
    ++		/* first symbols */
    ++		FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
    ++		FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
    ++		FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
    ++		BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
    ++		if (MEM_32bits()) BIT_flushBits(&blockStream);
    ++		BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
    ++		if (MEM_32bits()) BIT_flushBits(&blockStream);
    ++		if (longOffsets) {
    ++			U32 const ofBits = ofCodeTable[nbSeq-1];
    ++			int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
    ++			if (extraBits) {
    ++				BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
    ++				BIT_flushBits(&blockStream);
    ++			}
    ++			BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
    ++						ofBits - extraBits);
    ++		} else {
    ++			BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
    ++		}
    ++		BIT_flushBits(&blockStream);
    ++
    ++		{   size_t n;
    ++			for (n=nbSeq-2 ; n= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
    ++					BIT_flushBits(&blockStream);                                /* (7)*/
    ++				BIT_addBits(&blockStream, sequences[n].litLength, llBits);
    ++				if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
    ++				BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
    ++				if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
    ++				if (longOffsets) {
    ++					int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
    ++					if (extraBits) {
    ++						BIT_addBits(&blockStream, sequences[n].offset, extraBits);
    ++						BIT_flushBits(&blockStream);                            /* (7)*/
    ++					}
    ++					BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
    ++								ofBits - extraBits);                            /* 31 */
    ++				} else {
    ++					BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */
    ++				}
    ++				BIT_flushBits(&blockStream);                                    /* (7)*/
    ++		}   }
    ++
    ++		FSE_flushCState(&blockStream, &stateMatchLength);
    ++		FSE_flushCState(&blockStream, &stateOffsetBits);
    ++		FSE_flushCState(&blockStream, &stateLitLength);
    ++
    ++		{   size_t const streamSize = BIT_closeCStream(&blockStream);
    ++			if (streamSize==0) return ERROR(dstSize_tooSmall);   /* not enough space */
    ++			op += streamSize;
    ++	}   }
    ++
    ++	/* check compressibility */
    ++_check_compressibility:
    ++	{   size_t const minGain = ZSTD_minGain(srcSize);
    ++		size_t const maxCSize = srcSize - minGain;
    ++		if ((size_t)(op-ostart) >= maxCSize) {
    ++			zc->flagStaticHufTable = HUF_repeat_none;
    ++			return 0;
    ++	}   }
    ++
    ++	/* confirm repcodes */
    ++	{ int i; for (i=0; irep[i] = zc->repToConfirm[i]; }
    ++
    ++	return op - ostart;
    ++}
    ++
    ++#if 0 /* for debug */
    ++#  define STORESEQ_DEBUG
    ++U32 g_startDebug = 0;
    ++const BYTE* g_start = NULL;
    ++#endif
    ++
    ++/*! ZSTD_storeSeq() :
    ++	Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
    ++	`offsetCode` : distance to match, or 0 == repCode.
    ++	`matchCode` : matchLength - MINMATCH
    ++*/
    ++MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
    ++{
    ++#ifdef STORESEQ_DEBUG
    ++	if (g_startDebug) {
    ++		const U32 pos = (U32)((const BYTE*)literals - g_start);
    ++		if (g_start==NULL) g_start = (const BYTE*)literals;
    ++		if ((pos > 1895000) && (pos < 1895300))
    ++			fprintf(stderr, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
    ++				   pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
    ++	}
    ++#endif
    ++	/* copy Literals */
    ++	ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
    ++	seqStorePtr->lit += litLength;
    ++
    ++	/* literal Length */
    ++	if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
    ++	seqStorePtr->sequences[0].litLength = (U16)litLength;
    ++
    ++	/* match offset */
    ++	seqStorePtr->sequences[0].offset = offsetCode + 1;
    ++
    ++	/* match Length */
    ++	if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
    ++	seqStorePtr->sequences[0].matchLength = (U16)matchCode;
    ++
    ++	seqStorePtr->sequences++;
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Match length counter
    ++***************************************/
    ++static unsigned ZSTD_NbCommonBytes (register size_t val)
    ++{
    ++	if (MEM_isLittleEndian()) {
    ++		if (MEM_64bits()) {
    ++#       if defined(_MSC_VER) && defined(_WIN64)
    ++			unsigned long r = 0;
    ++			_BitScanForward64( &r, (U64)val );
    ++			return (unsigned)(r>>3);
    ++#       elif defined(__GNUC__) && (__GNUC__ >= 3)
    ++			return (__builtin_ctzll((U64)val) >> 3);
    ++#       else
    ++			static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
    ++			return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
    ++#       endif
    ++		} else { /* 32 bits */
    ++#       if defined(_MSC_VER)
    ++			unsigned long r=0;
    ++			_BitScanForward( &r, (U32)val );
    ++			return (unsigned)(r>>3);
    ++#       elif defined(__GNUC__) && (__GNUC__ >= 3)
    ++			return (__builtin_ctz((U32)val) >> 3);
    ++#       else
    ++			static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
    ++			return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
    ++#       endif
    ++		}
    ++	} else {  /* Big Endian CPU */
    ++		if (MEM_64bits()) {
    ++#       if defined(_MSC_VER) && defined(_WIN64)
    ++			unsigned long r = 0;
    ++			_BitScanReverse64( &r, val );
    ++			return (unsigned)(r>>3);
    ++#       elif defined(__GNUC__) && (__GNUC__ >= 3)
    ++			return (__builtin_clzll(val) >> 3);
    ++#       else
    ++			unsigned r;
    ++			const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */
    ++			if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
    ++			if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
    ++			r += (!val);
    ++			return r;
    ++#       endif
    ++		} else { /* 32 bits */
    ++#       if defined(_MSC_VER)
    ++			unsigned long r = 0;
    ++			_BitScanReverse( &r, (unsigned long)val );
    ++			return (unsigned)(r>>3);
    ++#       elif defined(__GNUC__) && (__GNUC__ >= 3)
    ++			return (__builtin_clz((U32)val) >> 3);
    ++#       else
    ++			unsigned r;
    ++			if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
    ++			r += (!val);
    ++			return r;
    ++#       endif
    ++	}   }
    ++}
    ++
    ++
    ++static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
    ++{
    ++	const BYTE* const pStart = pIn;
    ++	const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
    ++
    ++	while (pIn < pInLoopLimit) {
    ++		size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
    ++		if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
    ++		pIn += ZSTD_NbCommonBytes(diff);
    ++		return (size_t)(pIn - pStart);
    ++	}
    ++	if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
    ++	if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
    ++	if ((pIn> (32-h) ; }
    ++MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); }   /* only in zstd_opt.h */
    ++
    ++static const U32 prime4bytes = 2654435761U;
    ++static U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
    ++static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
    ++
    ++static const U64 prime5bytes = 889523592379ULL;
    ++static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }
    ++static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
    ++
    ++static const U64 prime6bytes = 227718039650203ULL;
    ++static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }
    ++static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
    ++
    ++static const U64 prime7bytes = 58295818150454627ULL;
    ++static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }
    ++static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
    ++
    ++static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
    ++static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
    ++static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
    ++
    ++static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
    ++{
    ++	switch(mls)
    ++	{
    ++	//case 3: return ZSTD_hash3Ptr(p, hBits);
    ++	default:
    ++	case 4: return ZSTD_hash4Ptr(p, hBits);
    ++	case 5: return ZSTD_hash5Ptr(p, hBits);
    ++	case 6: return ZSTD_hash6Ptr(p, hBits);
    ++	case 7: return ZSTD_hash7Ptr(p, hBits);
    ++	case 8: return ZSTD_hash8Ptr(p, hBits);
    ++	}
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Fast Scan
    ++***************************************/
    ++static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
    ++{
    ++	U32* const hashTable = zc->hashTable;
    ++	U32  const hBits = zc->params.cParams.hashLog;
    ++	const BYTE* const base = zc->base;
    ++	const BYTE* ip = base + zc->nextToUpdate;
    ++	const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    ++	const size_t fastHashFillStep = 3;
    ++
    ++	while(ip <= iend) {
    ++		hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
    ++		ip += fastHashFillStep;
    ++	}
    ++}
    ++
    ++
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
    ++							   const void* src, size_t srcSize,
    ++							   const U32 mls)
    ++{
    ++	U32* const hashTable = cctx->hashTable;
    ++	U32  const hBits = cctx->params.cParams.hashLog;
    ++	seqStore_t* seqStorePtr = &(cctx->seqStore);
    ++	const BYTE* const base = cctx->base;
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const U32   lowestIndex = cctx->dictLimit;
    ++	const BYTE* const lowest = base + lowestIndex;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - HASH_READ_SIZE;
    ++	U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
    ++	U32 offsetSaved = 0;
    ++
    ++	/* init */
    ++	ip += (ip==lowest);
    ++	{   U32 const maxRep = (U32)(ip-lowest);
    ++		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
    ++		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
    ++	}
    ++
    ++	/* Main Search Loop */
    ++	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
    ++		size_t mLength;
    ++		size_t const h = ZSTD_hashPtr(ip, hBits, mls);
    ++		U32 const current = (U32)(ip-base);
    ++		U32 const matchIndex = hashTable[h];
    ++		const BYTE* match = base + matchIndex;
    ++		hashTable[h] = current;   /* update hash table */
    ++
    ++		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
    ++			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    ++			ip++;
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    ++		} else {
    ++			U32 offset;
    ++			if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
    ++				ip += ((ip-anchor) >> g_searchStrength) + 1;
    ++				continue;
    ++			}
    ++			mLength = ZSTD_count(ip+4, match+4, iend) + 4;
    ++			offset = (U32)(ip-match);
    ++			while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
    ++			offset_2 = offset_1;
    ++			offset_1 = offset;
    ++
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    ++		}
    ++
    ++		/* match found */
    ++		ip += mLength;
    ++		anchor = ip;
    ++
    ++		if (ip <= ilimit) {
    ++			/* Fill Table */
    ++			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    ++			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
    ++			/* check immediate repcode */
    ++			while ( (ip <= ilimit)
    ++				 && ( (offset_2>0)
    ++				 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    ++				/* store sequence */
    ++				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
    ++				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; }  /* swap offset_2 <=> offset_1 */
    ++				hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
    ++				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
    ++				ip += rLength;
    ++				anchor = ip;
    ++				continue;   /* faster when present ... (?) */
    ++	}   }   }
    ++
    ++	/* save reps for next block */
    ++	cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
    ++	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
    ++					   const void* src, size_t srcSize)
    ++{
    ++	const U32 mls = ctx->params.cParams.searchLength;
    ++	switch(mls)
    ++	{
    ++	default: /* includes case 3 */
    ++	case 4 :
    ++		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
    ++	case 5 :
    ++		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
    ++	case 6 :
    ++		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
    ++	case 7 :
    ++		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
    ++								 const void* src, size_t srcSize,
    ++								 const U32 mls)
    ++{
    ++	U32* hashTable = ctx->hashTable;
    ++	const U32 hBits = ctx->params.cParams.hashLog;
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const base = ctx->base;
    ++	const BYTE* const dictBase = ctx->dictBase;
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const U32   lowestIndex = ctx->lowLimit;
    ++	const BYTE* const dictStart = dictBase + lowestIndex;
    ++	const U32   dictLimit = ctx->dictLimit;
    ++	const BYTE* const lowPrefixPtr = base + dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
    ++
    ++	/* Search Loop */
    ++	while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
    ++		const size_t h = ZSTD_hashPtr(ip, hBits, mls);
    ++		const U32 matchIndex = hashTable[h];
    ++		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
    ++		const BYTE* match = matchBase + matchIndex;
    ++		const U32 current = (U32)(ip-base);
    ++		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    ++		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
    ++		const BYTE* repMatch = repBase + repIndex;
    ++		size_t mLength;
    ++		hashTable[h] = current;   /* update hash table */
    ++
    ++		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    ++		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    ++			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    ++			mLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
    ++			ip++;
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    ++		} else {
    ++			if ( (matchIndex < lowestIndex) ||
    ++				 (MEM_read32(match) != MEM_read32(ip)) ) {
    ++				ip += ((ip-anchor) >> g_searchStrength) + 1;
    ++				continue;
    ++			}
    ++			{   const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    ++				const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
    ++				U32 offset;
    ++				mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
    ++				while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    ++				offset = current - matchIndex;
    ++				offset_2 = offset_1;
    ++				offset_1 = offset;
    ++				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    ++		}   }
    ++
    ++		/* found a match : store it */
    ++		ip += mLength;
    ++		anchor = ip;
    ++
    ++		if (ip <= ilimit) {
    ++			/* Fill Table */
    ++			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
    ++			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
    ++			/* check immediate repcode */
    ++			while (ip <= ilimit) {
    ++				U32 const current2 = (U32)(ip-base);
    ++				U32 const repIndex2 = current2 - offset_2;
    ++				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    ++				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    ++				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    ++					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    ++					size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    ++					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    ++					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    ++					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
    ++					ip += repLength2;
    ++					anchor = ip;
    ++					continue;
    ++				}
    ++				break;
    ++	}   }   }
    ++
    ++	/* save reps for next block */
    ++	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
    ++						 const void* src, size_t srcSize)
    ++{
    ++	U32 const mls = ctx->params.cParams.searchLength;
    ++	switch(mls)
    ++	{
    ++	default: /* includes case 3 */
    ++	case 4 :
    ++		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
    ++	case 5 :
    ++		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
    ++	case 6 :
    ++		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
    ++	case 7 :
    ++		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
    ++	}
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Double Fast
    ++***************************************/
    ++static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
    ++{
    ++	U32* const hashLarge = cctx->hashTable;
    ++	U32  const hBitsL = cctx->params.cParams.hashLog;
    ++	U32* const hashSmall = cctx->chainTable;
    ++	U32  const hBitsS = cctx->params.cParams.chainLog;
    ++	const BYTE* const base = cctx->base;
    ++	const BYTE* ip = base + cctx->nextToUpdate;
    ++	const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    ++	const size_t fastHashFillStep = 3;
    ++
    ++	while(ip <= iend) {
    ++		hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
    ++		hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
    ++		ip += fastHashFillStep;
    ++	}
    ++}
    ++
    ++
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
    ++								 const void* src, size_t srcSize,
    ++								 const U32 mls)
    ++{
    ++	U32* const hashLong = cctx->hashTable;
    ++	const U32 hBitsL = cctx->params.cParams.hashLog;
    ++	U32* const hashSmall = cctx->chainTable;
    ++	const U32 hBitsS = cctx->params.cParams.chainLog;
    ++	seqStore_t* seqStorePtr = &(cctx->seqStore);
    ++	const BYTE* const base = cctx->base;
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const U32 lowestIndex = cctx->dictLimit;
    ++	const BYTE* const lowest = base + lowestIndex;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - HASH_READ_SIZE;
    ++	U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
    ++	U32 offsetSaved = 0;
    ++
    ++	/* init */
    ++	ip += (ip==lowest);
    ++	{   U32 const maxRep = (U32)(ip-lowest);
    ++		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
    ++		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
    ++	}
    ++
    ++	/* Main Search Loop */
    ++	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
    ++		size_t mLength;
    ++		size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
    ++		size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
    ++		U32 const current = (U32)(ip-base);
    ++		U32 const matchIndexL = hashLong[h2];
    ++		U32 const matchIndexS = hashSmall[h];
    ++		const BYTE* matchLong = base + matchIndexL;
    ++		const BYTE* match = base + matchIndexS;
    ++		hashLong[h2] = hashSmall[h] = current;   /* update hash tables */
    ++
    ++		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
    ++			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    ++			ip++;
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    ++		} else {
    ++			U32 offset;
    ++			if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
    ++				mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
    ++				offset = (U32)(ip-matchLong);
    ++				while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
    ++			} else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
    ++				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
    ++				U32 const matchIndex3 = hashLong[h3];
    ++				const BYTE* match3 = base + matchIndex3;
    ++				hashLong[h3] = current + 1;
    ++				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
    ++					mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
    ++					ip++;
    ++					offset = (U32)(ip-match3);
    ++					while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
    ++				} else {
    ++					mLength = ZSTD_count(ip+4, match+4, iend) + 4;
    ++					offset = (U32)(ip-match);
    ++					while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
    ++				}
    ++			} else {
    ++				ip += ((ip-anchor) >> g_searchStrength) + 1;
    ++				continue;
    ++			}
    ++
    ++			offset_2 = offset_1;
    ++			offset_1 = offset;
    ++
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    ++		}
    ++
    ++		/* match found */
    ++		ip += mLength;
    ++		anchor = ip;
    ++
    ++		if (ip <= ilimit) {
    ++			/* Fill Table */
    ++			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
    ++				hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    ++			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
    ++				hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
    ++
    ++			/* check immediate repcode */
    ++			while ( (ip <= ilimit)
    ++				 && ( (offset_2>0)
    ++				 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    ++				/* store sequence */
    ++				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
    ++				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
    ++				hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
    ++				hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
    ++				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
    ++				ip += rLength;
    ++				anchor = ip;
    ++				continue;   /* faster when present ... (?) */
    ++	}   }   }
    ++
    ++	/* save reps for next block */
    ++	cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
    ++	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	const U32 mls = ctx->params.cParams.searchLength;
    ++	switch(mls)
    ++	{
    ++	default: /* includes case 3 */
    ++	case 4 :
    ++		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
    ++	case 5 :
    ++		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
    ++	case 6 :
    ++		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
    ++	case 7 :
    ++		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
    ++								 const void* src, size_t srcSize,
    ++								 const U32 mls)
    ++{
    ++	U32* const hashLong = ctx->hashTable;
    ++	U32  const hBitsL = ctx->params.cParams.hashLog;
    ++	U32* const hashSmall = ctx->chainTable;
    ++	U32  const hBitsS = ctx->params.cParams.chainLog;
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const base = ctx->base;
    ++	const BYTE* const dictBase = ctx->dictBase;
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const U32   lowestIndex = ctx->lowLimit;
    ++	const BYTE* const dictStart = dictBase + lowestIndex;
    ++	const U32   dictLimit = ctx->dictLimit;
    ++	const BYTE* const lowPrefixPtr = base + dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
    ++
    ++	/* Search Loop */
    ++	while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
    ++		const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
    ++		const U32 matchIndex = hashSmall[hSmall];
    ++		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
    ++		const BYTE* match = matchBase + matchIndex;
    ++
    ++		const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
    ++		const U32 matchLongIndex = hashLong[hLong];
    ++		const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
    ++		const BYTE* matchLong = matchLongBase + matchLongIndex;
    ++
    ++		const U32 current = (U32)(ip-base);
    ++		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    ++		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
    ++		const BYTE* repMatch = repBase + repIndex;
    ++		size_t mLength;
    ++		hashSmall[hSmall] = hashLong[hLong] = current;   /* update hash table */
    ++
    ++		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    ++		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    ++			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    ++			mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
    ++			ip++;
    ++			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    ++		} else {
    ++			if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
    ++				const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
    ++				const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
    ++				U32 offset;
    ++				mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
    ++				offset = current - matchLongIndex;
    ++				while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
    ++				offset_2 = offset_1;
    ++				offset_1 = offset;
    ++				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    ++
    ++			} else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
    ++				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
    ++				U32 const matchIndex3 = hashLong[h3];
    ++				const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
    ++				const BYTE* match3 = match3Base + matchIndex3;
    ++				U32 offset;
    ++				hashLong[h3] = current + 1;
    ++				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
    ++					const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
    ++					const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
    ++					mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
    ++					ip++;
    ++					offset = current+1 - matchIndex3;
    ++					while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
    ++				} else {
    ++					const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    ++					const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
    ++					mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
    ++					offset = current - matchIndex;
    ++					while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    ++				}
    ++				offset_2 = offset_1;
    ++				offset_1 = offset;
    ++				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    ++
    ++			} else {
    ++				ip += ((ip-anchor) >> g_searchStrength) + 1;
    ++				continue;
    ++		}   }
    ++
    ++		/* found a match : store it */
    ++		ip += mLength;
    ++		anchor = ip;
    ++
    ++		if (ip <= ilimit) {
    ++			/* Fill Table */
    ++			hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
    ++			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
    ++			hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
    ++			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
    ++			/* check immediate repcode */
    ++			while (ip <= ilimit) {
    ++				U32 const current2 = (U32)(ip-base);
    ++				U32 const repIndex2 = current2 - offset_2;
    ++				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    ++				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    ++				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    ++					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    ++					size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    ++					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    ++					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    ++					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
    ++					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
    ++					ip += repLength2;
    ++					anchor = ip;
    ++					continue;
    ++				}
    ++				break;
    ++	}   }   }
    ++
    ++	/* save reps for next block */
    ++	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
    ++						 const void* src, size_t srcSize)
    ++{
    ++	U32 const mls = ctx->params.cParams.searchLength;
    ++	switch(mls)
    ++	{
    ++	default: /* includes case 3 */
    ++	case 4 :
    ++		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
    ++	case 5 :
    ++		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
    ++	case 6 :
    ++		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
    ++	case 7 :
    ++		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
    ++	}
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Binary Tree search
    ++***************************************/
    ++/** ZSTD_insertBt1() : add one or multiple positions to tree.
    ++*   ip : assumed <= iend-8 .
    ++*   @return : nb of positions added */
    ++static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
    ++						  U32 extDict)
    ++{
    ++	U32*   const hashTable = zc->hashTable;
    ++	U32    const hashLog = zc->params.cParams.hashLog;
    ++	size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
    ++	U32*   const bt = zc->chainTable;
    ++	U32    const btLog  = zc->params.cParams.chainLog - 1;
    ++	U32    const btMask = (1 << btLog) - 1;
    ++	U32 matchIndex = hashTable[h];
    ++	size_t commonLengthSmaller=0, commonLengthLarger=0;
    ++	const BYTE* const base = zc->base;
    ++	const BYTE* const dictBase = zc->dictBase;
    ++	const U32 dictLimit = zc->dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const BYTE* match;
    ++	const U32 current = (U32)(ip-base);
    ++	const U32 btLow = btMask >= current ? 0 : current - btMask;
    ++	U32* smallerPtr = bt + 2*(current&btMask);
    ++	U32* largerPtr  = smallerPtr + 1;
    ++	U32 dummy32;   /* to be nullified at the end */
    ++	U32 const windowLow = zc->lowLimit;
    ++	U32 matchEndIdx = current+8;
    ++	size_t bestLength = 8;
    ++#ifdef ZSTD_C_PREDICT
    ++	U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
    ++	U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
    ++	predictedSmall += (predictedSmall>0);
    ++	predictedLarge += (predictedLarge>0);
    ++#endif /* ZSTD_C_PREDICT */
    ++
    ++	hashTable[h] = current;   /* Update Hash Table */
    ++
    ++	while (nbCompares-- && (matchIndex > windowLow)) {
    ++		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    ++		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
    ++
    ++#ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
    ++		const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
    ++		if (matchIndex == predictedSmall) {
    ++			/* no need to check length, result known */
    ++			*smallerPtr = matchIndex;
    ++			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++			predictedSmall = predictPtr[1] + (predictPtr[1]>0);
    ++			continue;
    ++		}
    ++		if (matchIndex == predictedLarge) {
    ++			*largerPtr = matchIndex;
    ++			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			largerPtr = nextPtr;
    ++			matchIndex = nextPtr[0];
    ++			predictedLarge = predictPtr[0] + (predictPtr[0]>0);
    ++			continue;
    ++		}
    ++#endif
    ++		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
    ++			match = base + matchIndex;
    ++			if (match[matchLength] == ip[matchLength])
    ++				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
    ++		} else {
    ++			match = dictBase + matchIndex;
    ++			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
    ++			if (matchIndex+matchLength >= dictLimit)
    ++				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
    ++		}
    ++
    ++		if (matchLength > bestLength) {
    ++			bestLength = matchLength;
    ++			if (matchLength > matchEndIdx - matchIndex)
    ++				matchEndIdx = matchIndex + (U32)matchLength;
    ++		}
    ++
    ++		if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
    ++			break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
    ++
    ++		if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
    ++			/* match is smaller than current */
    ++			*smallerPtr = matchIndex;             /* update smaller idx */
    ++			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
    ++			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++		} else {
    ++			/* match is larger than current */
    ++			*largerPtr = matchIndex;
    ++			commonLengthLarger = matchLength;
    ++			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			largerPtr = nextPtr;
    ++			matchIndex = nextPtr[0];
    ++	}   }
    ++
    ++	*smallerPtr = *largerPtr = 0;
    ++	if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
    ++	if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
    ++	return 1;
    ++}
    ++
    ++
    ++static size_t ZSTD_insertBtAndFindBestMatch (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iend,
    ++						size_t* offsetPtr,
    ++						U32 nbCompares, const U32 mls,
    ++						U32 extDict)
    ++{
    ++	U32*   const hashTable = zc->hashTable;
    ++	U32    const hashLog = zc->params.cParams.hashLog;
    ++	size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
    ++	U32*   const bt = zc->chainTable;
    ++	U32    const btLog  = zc->params.cParams.chainLog - 1;
    ++	U32    const btMask = (1 << btLog) - 1;
    ++	U32 matchIndex  = hashTable[h];
    ++	size_t commonLengthSmaller=0, commonLengthLarger=0;
    ++	const BYTE* const base = zc->base;
    ++	const BYTE* const dictBase = zc->dictBase;
    ++	const U32 dictLimit = zc->dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const U32 current = (U32)(ip-base);
    ++	const U32 btLow = btMask >= current ? 0 : current - btMask;
    ++	const U32 windowLow = zc->lowLimit;
    ++	U32* smallerPtr = bt + 2*(current&btMask);
    ++	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    ++	U32 matchEndIdx = current+8;
    ++	U32 dummy32;   /* to be nullified at the end */
    ++	size_t bestLength = 0;
    ++
    ++	hashTable[h] = current;   /* Update Hash Table */
    ++
    ++	while (nbCompares-- && (matchIndex > windowLow)) {
    ++		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    ++		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
    ++		const BYTE* match;
    ++
    ++		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
    ++			match = base + matchIndex;
    ++			if (match[matchLength] == ip[matchLength])
    ++				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
    ++		} else {
    ++			match = dictBase + matchIndex;
    ++			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
    ++			if (matchIndex+matchLength >= dictLimit)
    ++				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
    ++		}
    ++
    ++		if (matchLength > bestLength) {
    ++			if (matchLength > matchEndIdx - matchIndex)
    ++				matchEndIdx = matchIndex + (U32)matchLength;
    ++			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    ++				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
    ++			if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
    ++				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
    ++		}
    ++
    ++		if (match[matchLength] < ip[matchLength]) {
    ++			/* match is smaller than current */
    ++			*smallerPtr = matchIndex;             /* update smaller idx */
    ++			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
    ++			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++		} else {
    ++			/* match is larger than current */
    ++			*largerPtr = matchIndex;
    ++			commonLengthLarger = matchLength;
    ++			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			largerPtr = nextPtr;
    ++			matchIndex = nextPtr[0];
    ++	}   }
    ++
    ++	*smallerPtr = *largerPtr = 0;
    ++
    ++	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    ++	return bestLength;
    ++}
    ++
    ++
    ++static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
    ++{
    ++	const BYTE* const base = zc->base;
    ++	const U32 target = (U32)(ip - base);
    ++	U32 idx = zc->nextToUpdate;
    ++
    ++	while(idx < target)
    ++		idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
    ++}
    ++
    ++/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
    ++static size_t ZSTD_BtFindBestMatch (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 mls)
    ++{
    ++	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    ++	ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
    ++	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
    ++}
    ++
    ++
    ++static size_t ZSTD_BtFindBestMatch_selectMLS (
    ++						ZSTD_CCtx* zc,   /* Index table will be updated */
    ++						const BYTE* ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	default : /* includes case 3 */
    ++	case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    ++	case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    ++	case 7 :
    ++	case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
    ++{
    ++	const BYTE* const base = zc->base;
    ++	const U32 target = (U32)(ip - base);
    ++	U32 idx = zc->nextToUpdate;
    ++
    ++	while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
    ++}
    ++
    ++
    ++/** Tree updater, providing best match */
    ++static size_t ZSTD_BtFindBestMatch_extDict (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 mls)
    ++{
    ++	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    ++	ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
    ++	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
    ++}
    ++
    ++
    ++static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
    ++						ZSTD_CCtx* zc,   /* Index table will be updated */
    ++						const BYTE* ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	default : /* includes case 3 */
    ++	case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    ++	case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    ++	case 7 :
    ++	case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
    ++	}
    ++}
    ++
    ++
    ++
    ++/* *********************************
    ++*  Hash Chain
    ++***********************************/
    ++#define NEXT_IN_CHAIN(d, mask)   chainTable[(d) & mask]
    ++
    ++/* Update chains up to ip (excluded)
    ++   Assumption : always within prefix (i.e. not within extDict) */
    ++FORCE_INLINE
    ++U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
    ++{
    ++	U32* const hashTable  = zc->hashTable;
    ++	const U32 hashLog = zc->params.cParams.hashLog;
    ++	U32* const chainTable = zc->chainTable;
    ++	const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
    ++	const BYTE* const base = zc->base;
    ++	const U32 target = (U32)(ip - base);
    ++	U32 idx = zc->nextToUpdate;
    ++
    ++	while(idx < target) { /* catch up */
    ++		size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
    ++		NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
    ++		hashTable[h] = idx;
    ++		idx++;
    ++	}
    ++
    ++	zc->nextToUpdate = target;
    ++	return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
    ++}
    ++
    ++
    ++
    ++FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
    ++size_t ZSTD_HcFindBestMatch_generic (
    ++						ZSTD_CCtx* zc,   /* Index table will be updated */
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 mls, const U32 extDict)
    ++{
    ++	U32* const chainTable = zc->chainTable;
    ++	const U32 chainSize = (1 << zc->params.cParams.chainLog);
    ++	const U32 chainMask = chainSize-1;
    ++	const BYTE* const base = zc->base;
    ++	const BYTE* const dictBase = zc->dictBase;
    ++	const U32 dictLimit = zc->dictLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const U32 lowLimit = zc->lowLimit;
    ++	const U32 current = (U32)(ip-base);
    ++	const U32 minChain = current > chainSize ? current - chainSize : 0;
    ++	int nbAttempts=maxNbAttempts;
    ++	size_t ml=EQUAL_READ32-1;
    ++
    ++	/* HC4 match finder */
    ++	U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
    ++
    ++	for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
    ++		const BYTE* match;
    ++		size_t currentMl=0;
    ++		if ((!extDict) || matchIndex >= dictLimit) {
    ++			match = base + matchIndex;
    ++			if (match[ml] == ip[ml])   /* potentially better */
    ++				currentMl = ZSTD_count(ip, match, iLimit);
    ++		} else {
    ++			match = dictBase + matchIndex;
    ++			if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    ++				currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
    ++		}
    ++
    ++		/* save best solution */
    ++		if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
    ++
    ++		if (matchIndex <= minChain) break;
    ++		matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
    ++	}
    ++
    ++	return ml;
    ++}
    ++
    ++
    ++FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	default : /* includes case 3 */
    ++	case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
    ++	case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
    ++	case 7 :
    ++	case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
    ++	}
    ++}
    ++
    ++
    ++FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* ip, const BYTE* const iLimit,
    ++						size_t* offsetPtr,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	default : /* includes case 3 */
    ++	case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
    ++	case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
    ++	case 7 :
    ++	case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
    ++	}
    ++}
    ++
    ++
    ++/* *******************************
    ++*  Common parser - lazy strategy
    ++*********************************/
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
    ++									 const void* src, size_t srcSize,
    ++									 const U32 searchMethod, const U32 depth)
    ++{
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	const BYTE* const base = ctx->base + ctx->dictLimit;
    ++
    ++	U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
    ++	U32 const mls = ctx->params.cParams.searchLength;
    ++
    ++	typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
    ++						size_t* offsetPtr,
    ++						U32 maxNbAttempts, U32 matchLengthSearch);
    ++	searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
    ++	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset=0;
    ++
    ++	/* init */
    ++	ip += (ip==base);
    ++	ctx->nextToUpdate3 = ctx->nextToUpdate;
    ++	{   U32 const maxRep = (U32)(ip-base);
    ++		if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
    ++		if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
    ++	}
    ++
    ++	/* Match Loop */
    ++	while (ip < ilimit) {
    ++		size_t matchLength=0;
    ++		size_t offset=0;
    ++		const BYTE* start=ip+1;
    ++
    ++		/* check repCode */
    ++		if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
    ++			/* repcode : we take it */
    ++			matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    ++			if (depth==0) goto _storeSequence;
    ++		}
    ++
    ++		/* first search (depth 0) */
    ++		{   size_t offsetFound = 99999999;
    ++			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
    ++			if (ml2 > matchLength)
    ++				matchLength = ml2, start = ip, offset=offsetFound;
    ++		}
    ++
    ++		if (matchLength < EQUAL_READ32) {
    ++			ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
    ++			continue;
    ++		}
    ++
    ++		/* let's try to find a better solution */
    ++		if (depth>=1)
    ++		while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
    ++				size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    ++				int const gain2 = (int)(mlRep * 3);
    ++				int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
    ++				if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
    ++					matchLength = mlRep, offset = 0, start = ip;
    ++			}
    ++			{   size_t offset2=99999999;
    ++				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    ++				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    ++				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    ++				if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    ++					matchLength = ml2, offset = offset2, start = ip;
    ++					continue;   /* search a better one */
    ++			}   }
    ++
    ++			/* let's find an even better one */
    ++			if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
    ++					size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    ++					int const gain2 = (int)(ml2 * 4);
    ++					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
    ++					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
    ++						matchLength = ml2, offset = 0, start = ip;
    ++				}
    ++				{   size_t offset2=99999999;
    ++					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    ++					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    ++					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    ++					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    ++						matchLength = ml2, offset = offset2, start = ip;
    ++						continue;
    ++			}   }   }
    ++			break;  /* nothing found : store previous solution */
    ++		}
    ++
    ++		/* catch up */
    ++		if (offset) {
    ++			while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE]))   /* only search for offset within prefix */
    ++				{ start--; matchLength++; }
    ++			offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
    ++		}
    ++
    ++		/* store sequence */
    ++_storeSequence:
    ++		{   size_t const litLength = start - anchor;
    ++			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
    ++			anchor = ip = start + matchLength;
    ++		}
    ++
    ++		/* check immediate repcode */
    ++		while ( (ip <= ilimit)
    ++			 && ((offset_2>0)
    ++			 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    ++			/* store sequence */
    ++			matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
    ++			offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
    ++			ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
    ++			ip += matchLength;
    ++			anchor = ip;
    ++			continue;   /* faster when present ... (?) */
    ++	}   }
    ++
    ++	/* Save reps for next block */
    ++	ctx->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
    ++	ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
    ++}
    ++
    ++static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
    ++}
    ++
    ++static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
    ++}
    ++
    ++static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
    ++}
    ++
    ++
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
    ++									 const void* src, size_t srcSize,
    ++									 const U32 searchMethod, const U32 depth)
    ++{
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	const BYTE* const base = ctx->base;
    ++	const U32 dictLimit = ctx->dictLimit;
    ++	const U32 lowestIndex = ctx->lowLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const BYTE* const dictBase = ctx->dictBase;
    ++	const BYTE* const dictEnd  = dictBase + dictLimit;
    ++	const BYTE* const dictStart  = dictBase + ctx->lowLimit;
    ++
    ++	const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
    ++	const U32 mls = ctx->params.cParams.searchLength;
    ++
    ++	typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
    ++						size_t* offsetPtr,
    ++						U32 maxNbAttempts, U32 matchLengthSearch);
    ++	searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
    ++
    ++	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
    ++
    ++	/* init */
    ++	ctx->nextToUpdate3 = ctx->nextToUpdate;
    ++	ip += (ip == prefixStart);
    ++
    ++	/* Match Loop */
    ++	while (ip < ilimit) {
    ++		size_t matchLength=0;
    ++		size_t offset=0;
    ++		const BYTE* start=ip+1;
    ++		U32 current = (U32)(ip-base);
    ++
    ++		/* check repCode */
    ++		{   const U32 repIndex = (U32)(current+1 - offset_1);
    ++			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
    ++			const BYTE* const repMatch = repBase + repIndex;
    ++			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    ++			if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
    ++				/* repcode detected we should take it */
    ++				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++				matchLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    ++				if (depth==0) goto _storeSequence;
    ++		}   }
    ++
    ++		/* first search (depth 0) */
    ++		{   size_t offsetFound = 99999999;
    ++			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
    ++			if (ml2 > matchLength)
    ++				matchLength = ml2, start = ip, offset=offsetFound;
    ++		}
    ++
    ++		 if (matchLength < EQUAL_READ32) {
    ++			ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
    ++			continue;
    ++		}
    ++
    ++		/* let's try to find a better solution */
    ++		if (depth>=1)
    ++		while (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    ++				if (MEM_read32(ip) == MEM_read32(repMatch)) {
    ++					/* repcode detected */
    ++					const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++					size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    ++					int const gain2 = (int)(repLength * 3);
    ++					int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
    ++					if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    ++						matchLength = repLength, offset = 0, start = ip;
    ++			}   }
    ++
    ++			/* search match, depth 1 */
    ++			{   size_t offset2=99999999;
    ++				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    ++				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    ++				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    ++				if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    ++					matchLength = ml2, offset = offset2, start = ip;
    ++					continue;   /* search a better one */
    ++			}   }
    ++
    ++			/* let's find an even better one */
    ++			if ((depth==2) && (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    ++					if (MEM_read32(ip) == MEM_read32(repMatch)) {
    ++						/* repcode detected */
    ++						const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++						size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    ++						int gain2 = (int)(repLength * 4);
    ++						int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
    ++						if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    ++							matchLength = repLength, offset = 0, start = ip;
    ++				}   }
    ++
    ++				/* search match, depth 2 */
    ++				{   size_t offset2=99999999;
    ++					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    ++					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    ++					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    ++					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    ++						matchLength = ml2, offset = offset2, start = ip;
    ++						continue;
    ++			}   }   }
    ++			break;  /* nothing found : store previous solution */
    ++		}
    ++
    ++		/* catch up */
    ++		if (offset) {
    ++			U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
    ++			const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
    ++			const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
    ++			while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; }  /* catch up */
    ++			offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
    ++		}
    ++
    ++		/* store sequence */
    ++_storeSequence:
    ++		{   size_t const litLength = start - anchor;
    ++			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
    ++			anchor = ip = start + matchLength;
    ++		}
    ++
    ++		/* check immediate repcode */
    ++		while (ip <= ilimit) {
    ++			const U32 repIndex = (U32)((ip-base) - offset_2);
    ++			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
    ++			const BYTE* const repMatch = repBase + repIndex;
    ++			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    ++			if (MEM_read32(ip) == MEM_read32(repMatch)) {
    ++				/* repcode detected we should take it */
    ++				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++				matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    ++				offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset;   /* swap offset history */
    ++				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
    ++				ip += matchLength;
    ++				anchor = ip;
    ++				continue;   /* faster when present ... (?) */
    ++			}
    ++			break;
    ++	}   }
    ++
    ++	/* Save reps for next block */
    ++	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
    ++}
    ++
    ++static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
    ++}
    ++
    ++static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
    ++}
    ++
    ++static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
    ++}
    ++
    ++
    ++/* The optimal parser */
    ++#include "zstd_opt.h"
    ++
    ++static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++#ifdef ZSTD_OPT_H_91842398743
    ++	ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
    ++#else
    ++	(void)ctx; (void)src; (void)srcSize;
    ++	return;
    ++#endif
    ++}
    ++
    ++static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++#ifdef ZSTD_OPT_H_91842398743
    ++	ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
    ++#else
    ++	(void)ctx; (void)src; (void)srcSize;
    ++	return;
    ++#endif
    ++}
    ++
    ++static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++#ifdef ZSTD_OPT_H_91842398743
    ++	ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
    ++#else
    ++	(void)ctx; (void)src; (void)srcSize;
    ++	return;
    ++#endif
    ++}
    ++
    ++static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    ++{
    ++#ifdef ZSTD_OPT_H_91842398743
    ++	ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
    ++#else
    ++	(void)ctx; (void)src; (void)srcSize;
    ++	return;
    ++#endif
    ++}
    ++
    ++
    ++typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
    ++
    ++static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
    ++{
    ++	static const ZSTD_blockCompressor blockCompressor[2][8] = {
    ++		{ ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
    ++		{ ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
    ++	};
    ++
    ++	return blockCompressor[extDict][(U32)strat];
    ++}
    ++
    ++
    ++static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
    ++	const BYTE* const base = zc->base;
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const U32 current = (U32)(istart-base);
    ++	if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0;   /* don't even attempt compression below a certain srcSize */
    ++	ZSTD_resetSeqStore(&(zc->seqStore));
    ++	if (current > zc->nextToUpdate + 384)
    ++		zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
    ++	blockCompressor(zc, src, srcSize);
    ++	return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
    ++}
    ++
    ++
    ++/*! ZSTD_compress_generic() :
    ++*   Compress a chunk of data into one or multiple blocks.
    ++*   All blocks will be terminated, all input will be consumed.
    ++*   Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
    ++*   Frame is supposed already started (header already produced)
    ++*   @return : compressed size, or an error code
    ++*/
    ++static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    ++									 void* dst, size_t dstCapacity,
    ++							   const void* src, size_t srcSize,
    ++									 U32 lastFrameChunk)
    ++{
    ++	size_t blockSize = cctx->blockSize;
    ++	size_t remaining = srcSize;
    ++	const BYTE* ip = (const BYTE*)src;
    ++	BYTE* const ostart = (BYTE*)dst;
    ++	BYTE* op = ostart;
    ++	U32 const maxDist = 1 << cctx->params.cParams.windowLog;
    ++
    ++	if (cctx->params.fParams.checksumFlag && srcSize)
    ++		xxh64_update(&cctx->xxhState, src, srcSize);
    ++
    ++	while (remaining) {
    ++		U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
    ++		size_t cSize;
    ++
    ++		if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall);   /* not enough space to store compressed block */
    ++		if (remaining < blockSize) blockSize = remaining;
    ++
    ++		/* preemptive overflow correction */
    ++		if (cctx->lowLimit > (3U<<29)) {
    ++			U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
    ++			U32 const current = (U32)(ip - cctx->base);
    ++			U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
    ++			U32 const correction = current - newCurrent;
    ++			ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
    ++			ZSTD_reduceIndex(cctx, correction);
    ++			cctx->base += correction;
    ++			cctx->dictBase += correction;
    ++			cctx->lowLimit -= correction;
    ++			cctx->dictLimit -= correction;
    ++			if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
    ++			else cctx->nextToUpdate -= correction;
    ++		}
    ++
    ++		if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
    ++			/* enforce maxDist */
    ++			U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
    ++			if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
    ++			if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
    ++		}
    ++
    ++		cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
    ++		if (ZSTD_isError(cSize)) return cSize;
    ++
    ++		if (cSize == 0) {  /* block is not compressible */
    ++			U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
    ++			if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
    ++			MEM_writeLE32(op, cBlockHeader24);   /* no pb, 4th byte will be overwritten */
    ++			memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
    ++			cSize = ZSTD_blockHeaderSize+blockSize;
    ++		} else {
    ++			U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
    ++			MEM_writeLE24(op, cBlockHeader24);
    ++			cSize += ZSTD_blockHeaderSize;
    ++		}
    ++
    ++		remaining -= blockSize;
    ++		dstCapacity -= cSize;
    ++		ip += blockSize;
    ++		op += cSize;
    ++	}
    ++
    ++	if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
    ++	return op-ostart;
    ++}
    ++
    ++
    ++static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
    ++									ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
    ++{   BYTE* const op = (BYTE*)dst;
    ++	U32   const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536);   /* 0-3 */
    ++	U32   const checksumFlag = params.fParams.checksumFlag>0;
    ++	U32   const windowSize = 1U << params.cParams.windowLog;
    ++	U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
    ++	BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
    ++	U32   const fcsCode = params.fParams.contentSizeFlag ?
    ++					 (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) :   /* 0-3 */
    ++					  0;
    ++	BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
    ++	size_t pos;
    ++
    ++	if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
    ++
    ++	MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
    ++	op[4] = frameHeaderDecriptionByte; pos=5;
    ++	if (!singleSegment) op[pos++] = windowLogByte;
    ++	switch(dictIDSizeCode)
    ++	{
    ++		default:   /* impossible */
    ++		case 0 : break;
    ++		case 1 : op[pos] = (BYTE)(dictID); pos++; break;
    ++		case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
    ++		case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
    ++	}
    ++	switch(fcsCode)
    ++	{
    ++		default:   /* impossible */
    ++		case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
    ++		case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
    ++		case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
    ++		case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
    ++	}
    ++	return pos;
    ++}
    ++
    ++
    ++static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
    ++							  void* dst, size_t dstCapacity,
    ++						const void* src, size_t srcSize,
    ++							   U32 frame, U32 lastFrameChunk)
    ++{
    ++	const BYTE* const ip = (const BYTE*) src;
    ++	size_t fhSize = 0;
    ++
    ++	if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
    ++
    ++	if (frame && (cctx->stage==ZSTDcs_init)) {
    ++		fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
    ++		if (ZSTD_isError(fhSize)) return fhSize;
    ++		dstCapacity -= fhSize;
    ++		dst = (char*)dst + fhSize;
    ++		cctx->stage = ZSTDcs_ongoing;
    ++	}
    ++
    ++	/* Check if blocks follow each other */
    ++	if (src != cctx->nextSrc) {
    ++		/* not contiguous */
    ++		ptrdiff_t const delta = cctx->nextSrc - ip;
    ++		cctx->lowLimit = cctx->dictLimit;
    ++		cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
    ++		cctx->dictBase = cctx->base;
    ++		cctx->base -= delta;
    ++		cctx->nextToUpdate = cctx->dictLimit;
    ++		if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit;   /* too small extDict */
    ++	}
    ++
    ++	/* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
    ++	if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
    ++		ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
    ++		U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
    ++		cctx->lowLimit = lowLimitMax;
    ++	}
    ++
    ++	cctx->nextSrc = ip + srcSize;
    ++
    ++	if (srcSize) {
    ++		size_t const cSize = frame ?
    ++							 ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
    ++							 ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
    ++		if (ZSTD_isError(cSize)) return cSize;
    ++		return cSize + fhSize;
    ++	} else
    ++		return fhSize;
    ++}
    ++
    ++
    ++size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
    ++							  void* dst, size_t dstCapacity,
    ++						const void* src, size_t srcSize)
    ++{
    ++	return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 0);
    ++}
    ++
    ++
    ++size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
    ++{
    ++	return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
    ++}
    ++
    ++size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
    ++	if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
    ++	return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
    ++}
    ++
    ++/*! ZSTD_loadDictionaryContent() :
    ++ *  @return : 0, or an error code
    ++ */
    ++static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
    ++{
    ++	const BYTE* const ip = (const BYTE*) src;
    ++	const BYTE* const iend = ip + srcSize;
    ++
    ++	/* input becomes current prefix */
    ++	zc->lowLimit = zc->dictLimit;
    ++	zc->dictLimit = (U32)(zc->nextSrc - zc->base);
    ++	zc->dictBase = zc->base;
    ++	zc->base += ip - zc->nextSrc;
    ++	zc->nextToUpdate = zc->dictLimit;
    ++	zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base);
    ++
    ++	zc->nextSrc = iend;
    ++	if (srcSize <= HASH_READ_SIZE) return 0;
    ++
    ++	switch(zc->params.cParams.strategy)
    ++	{
    ++	case ZSTD_fast:
    ++		ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
    ++		break;
    ++
    ++	case ZSTD_dfast:
    ++		ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
    ++		break;
    ++
    ++	case ZSTD_greedy:
    ++	case ZSTD_lazy:
    ++	case ZSTD_lazy2:
    ++		if (srcSize >= HASH_READ_SIZE)
    ++			ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
    ++		break;
    ++
    ++	case ZSTD_btlazy2:
    ++	case ZSTD_btopt:
    ++	case ZSTD_btopt2:
    ++		if (srcSize >= HASH_READ_SIZE)
    ++			ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
    ++		break;
    ++
    ++	default:
    ++		return ERROR(GENERIC);   /* strategy doesn't exist; impossible */
    ++	}
    ++
    ++	zc->nextToUpdate = (U32)(iend - zc->base);
    ++	return 0;
    ++}
    ++
    ++
    ++/* Dictionaries that assign zero probability to symbols that show up causes problems
    ++   when FSE encoding.  Refuse dictionaries that assign zero probability to symbols
    ++   that we may encounter during compression.
    ++   NOTE: This behavior is not standard and could be improved in the future. */
    ++static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
    ++	U32 s;
    ++	if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
    ++	for (s = 0; s <= maxSymbolValue; ++s) {
    ++		if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
    ++	}
    ++	return 0;
    ++}
    ++
    ++
    ++/* Dictionary format :
    ++ * See :
    ++ * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
    ++ */
    ++/*! ZSTD_loadZstdDictionary() :
    ++ * @return : 0, or an error code
    ++ *  assumptions : magic number supposed already checked
    ++ *                dictSize supposed > 8
    ++ */
    ++static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    ++{
    ++	const BYTE* dictPtr = (const BYTE*)dict;
    ++	const BYTE* const dictEnd = dictPtr + dictSize;
    ++	short offcodeNCount[MaxOff+1];
    ++	unsigned offcodeMaxValue = MaxOff;
    ++	BYTE scratchBuffer[1<dictID = cctx->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
    ++	dictPtr += 4;
    ++
    ++	{   size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
    ++		if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
    ++		dictPtr += hufHeaderSize;
    ++	}
    ++
    ++	{   unsigned offcodeLog;
    ++		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    ++		/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
    ++		CHECK_E (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    ++		dictPtr += offcodeHeaderSize;
    ++	}
    ++
    ++	{   short matchlengthNCount[MaxML+1];
    ++		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
    ++		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
    ++		/* Every match length code must have non-zero probability */
    ++		CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
    ++		CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    ++		dictPtr += matchlengthHeaderSize;
    ++	}
    ++
    ++	{   short litlengthNCount[MaxLL+1];
    ++		unsigned litlengthMaxValue = MaxLL, litlengthLog;
    ++		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
    ++		/* Every literal length code must have non-zero probability */
    ++		CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
    ++		CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    ++		dictPtr += litlengthHeaderSize;
    ++	}
    ++
    ++	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    ++	cctx->rep[0] = MEM_readLE32(dictPtr+0);
    ++	cctx->rep[1] = MEM_readLE32(dictPtr+4);
    ++	cctx->rep[2] = MEM_readLE32(dictPtr+8);
    ++	dictPtr += 12;
    ++
    ++	{   size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
    ++		U32 offcodeMax = MaxOff;
    ++		if (dictContentSize <= ((U32)-1) - 128 KB) {
    ++			U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
    ++			offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
    ++		}
    ++		/* All offset values <= dictContentSize + 128 KB must be representable */
    ++		CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
    ++		/* All repCodes must be <= dictContentSize and != 0*/
    ++		{   U32 u;
    ++			for (u=0; u<3; u++) {
    ++				if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
    ++				if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
    ++		}   }
    ++
    ++		cctx->flagStaticTables = 1;
    ++		cctx->flagStaticHufTable = HUF_repeat_valid;
    ++		return ZSTD_loadDictionaryContent(cctx, dictPtr, dictContentSize);
    ++	}
    ++}
    ++
    ++/** ZSTD_compress_insertDictionary() :
    ++*   @return : 0, or an error code */
    ++static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    ++{
    ++	if ((dict==NULL) || (dictSize<=8)) return 0;
    ++
    ++	/* dict as pure content */
    ++	if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
    ++		return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
    ++
    ++	/* dict as zstd dictionary */
    ++	return ZSTD_loadZstdDictionary(cctx, dict, dictSize);
    ++}
    ++
    ++/*! ZSTD_compressBegin_internal() :
    ++*   @return : 0, or an error code */
    ++static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
    ++							 const void* dict, size_t dictSize,
    ++								   ZSTD_parameters params, U64 pledgedSrcSize)
    ++{
    ++	ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
    ++	CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
    ++	return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
    ++}
    ++
    ++
    ++/*! ZSTD_compressBegin_advanced() :
    ++*   @return : 0, or an error code */
    ++size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
    ++							 const void* dict, size_t dictSize,
    ++								   ZSTD_parameters params, unsigned long long pledgedSrcSize)
    ++{
    ++	/* compression parameters verification and optimization */
    ++	CHECK_F(ZSTD_checkCParams(params.cParams));
    ++	return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
    ++}
    ++
    ++
    ++size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
    ++{
    ++	ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
    ++	return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
    ++}
    ++
    ++
    ++size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
    ++{
    ++	return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);
    ++}
    ++
    ++
    ++/*! ZSTD_writeEpilogue() :
    ++*   Ends a frame.
    ++*   @return : nb of bytes written into dst (or an error code) */
    ++static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
    ++{
    ++	BYTE* const ostart = (BYTE*)dst;
    ++	BYTE* op = ostart;
    ++	size_t fhSize = 0;
    ++
    ++	if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong);  /* init missing */
    ++
    ++	/* special case : empty frame */
    ++	if (cctx->stage == ZSTDcs_init) {
    ++		fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
    ++		if (ZSTD_isError(fhSize)) return fhSize;
    ++		dstCapacity -= fhSize;
    ++		op += fhSize;
    ++		cctx->stage = ZSTDcs_ongoing;
    ++	}
    ++
    ++	if (cctx->stage != ZSTDcs_ending) {
    ++		/* write one last empty block, make it the "last" block */
    ++		U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
    ++		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    ++		MEM_writeLE32(op, cBlockHeader24);
    ++		op += ZSTD_blockHeaderSize;
    ++		dstCapacity -= ZSTD_blockHeaderSize;
    ++	}
    ++
    ++	if (cctx->params.fParams.checksumFlag) {
    ++		U32 const checksum = (U32) xxh64_digest(&cctx->xxhState);
    ++		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    ++		MEM_writeLE32(op, checksum);
    ++		op += 4;
    ++	}
    ++
    ++	cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
    ++	return op-ostart;
    ++}
    ++
    ++
    ++size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
    ++						 void* dst, size_t dstCapacity,
    ++				   const void* src, size_t srcSize)
    ++{
    ++	size_t endResult;
    ++	size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 1);
    ++	if (ZSTD_isError(cSize)) return cSize;
    ++	endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
    ++	if (ZSTD_isError(endResult)) return endResult;
    ++	return cSize + endResult;
    ++}
    ++
    ++
    ++static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
    ++							   void* dst, size_t dstCapacity,
    ++						 const void* src, size_t srcSize,
    ++						 const void* dict,size_t dictSize,
    ++							   ZSTD_parameters params)
    ++{
    ++	CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
    ++	return ZSTD_compressEnd(cctx, dst,  dstCapacity, src, srcSize);
    ++}
    ++
    ++size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, ZSTD_parameters params)
    ++{
    ++	return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
    ++}
    ++
    ++
    ++size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, ZSTD_parameters params)
    ++{
    ++	return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, NULL, 0, params);
    ++}
    ++
    ++
    ++/* =====  Dictionary API  ===== */
    ++
    ++struct ZSTD_CDict_s {
    ++	void* dictBuffer;
    ++	const void* dictContent;
    ++	size_t dictContentSize;
    ++	ZSTD_CCtx* refContext;
    ++};  /* typedef'd tp ZSTD_CDict within "zstd.h" */
    ++
    ++size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams)
    ++{
    ++	return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CDict));
    ++}
    ++
    ++static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
    ++											 ZSTD_parameters params, ZSTD_customMem customMem)
    ++{
    ++	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    ++
    ++	{   ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    ++		ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
    ++
    ++		if (!cdict || !cctx) {
    ++			ZSTD_free(cdict, customMem);
    ++			ZSTD_freeCCtx(cctx);
    ++			return NULL;
    ++		}
    ++
    ++		if ((byReference) || (!dictBuffer) || (!dictSize)) {
    ++			cdict->dictBuffer = NULL;
    ++			cdict->dictContent = dictBuffer;
    ++		} else {
    ++			void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    ++			if (!internalBuffer) { ZSTD_free(cctx, customMem); ZSTD_free(cdict, customMem); return NULL; }
    ++			memcpy(internalBuffer, dictBuffer, dictSize);
    ++			cdict->dictBuffer = internalBuffer;
    ++			cdict->dictContent = internalBuffer;
    ++		}
    ++
    ++		{   size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
    ++			if (ZSTD_isError(errorCode)) {
    ++				ZSTD_free(cdict->dictBuffer, customMem);
    ++				ZSTD_free(cdict, customMem);
    ++				ZSTD_freeCCtx(cctx);
    ++				return NULL;
    ++		}   }
    ++
    ++		cdict->refContext = cctx;
    ++		cdict->dictContentSize = dictSize;
    ++		return cdict;
    ++	}
    ++}
    ++
    ++ZSTD_CDict* ZSTD_initCDict(const void* dict, size_t dictSize, ZSTD_parameters params, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	return ZSTD_createCDict_advanced(dict, dictSize, 1, params, stackMem);
    ++}
    ++
    ++size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
    ++{
    ++	if (cdict==NULL) return 0;   /* support free on NULL */
    ++	{   ZSTD_customMem const cMem = cdict->refContext->customMem;
    ++		ZSTD_freeCCtx(cdict->refContext);
    ++		ZSTD_free(cdict->dictBuffer, cMem);
    ++		ZSTD_free(cdict, cMem);
    ++		return 0;
    ++	}
    ++}
    ++
    ++static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
    ++	return ZSTD_getParamsFromCCtx(cdict->refContext);
    ++}
    ++
    ++size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize)
    ++{
    ++	if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
    ++	else {
    ++		ZSTD_parameters params = cdict->refContext->params;
    ++		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    ++		CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, params, pledgedSrcSize));
    ++	}
    ++	return 0;
    ++}
    ++
    ++/*! ZSTD_compress_usingCDict() :
    ++*   Compression using a digested Dictionary.
    ++*   Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
    ++*   Note that compression level is decided during dictionary creation */
    ++size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
    ++								void* dst, size_t dstCapacity,
    ++								const void* src, size_t srcSize,
    ++								const ZSTD_CDict* cdict)
    ++{
    ++	CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
    ++
    ++	if (cdict->refContext->params.fParams.contentSizeFlag==1) {
    ++		cctx->params.fParams.contentSizeFlag = 1;
    ++		cctx->frameContentSize = srcSize;
    ++	} else {
    ++		cctx->params.fParams.contentSizeFlag = 0;
    ++	}
    ++
    ++	return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
    ++}
    ++
    ++
    ++
    ++/* ******************************************************************
    ++*  Streaming
    ++********************************************************************/
    ++
    ++typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
    ++
    ++struct ZSTD_CStream_s {
    ++	ZSTD_CCtx* cctx;
    ++	ZSTD_CDict* cdictLocal;
    ++	const ZSTD_CDict* cdict;
    ++	char*  inBuff;
    ++	size_t inBuffSize;
    ++	size_t inToCompress;
    ++	size_t inBuffPos;
    ++	size_t inBuffTarget;
    ++	size_t blockSize;
    ++	char*  outBuff;
    ++	size_t outBuffSize;
    ++	size_t outBuffContentSize;
    ++	size_t outBuffFlushedSize;
    ++	ZSTD_cStreamStage stage;
    ++	U32    checksum;
    ++	U32    frameEnded;
    ++	U64    pledgedSrcSize;
    ++	U64    inputProcessed;
    ++	ZSTD_parameters params;
    ++	ZSTD_customMem customMem;
    ++};   /* typedef'd to ZSTD_CStream within "zstd.h" */
    ++
    ++size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams)
    ++{
    ++	size_t const inBuffSize = (size_t)1 << cParams.windowLog;
    ++	size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, inBuffSize);
    ++	size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
    ++
    ++	return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize);
    ++}
    ++
    ++ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
    ++{
    ++	ZSTD_CStream* zcs;
    ++
    ++	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    ++
    ++	zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
    ++	if (zcs==NULL) return NULL;
    ++	memset(zcs, 0, sizeof(ZSTD_CStream));
    ++	memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
    ++	zcs->cctx = ZSTD_createCCtx_advanced(customMem);
    ++	if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
    ++	return zcs;
    ++}
    ++
    ++size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
    ++{
    ++	if (zcs==NULL) return 0;   /* support free on NULL */
    ++	{   ZSTD_customMem const cMem = zcs->customMem;
    ++		ZSTD_freeCCtx(zcs->cctx);
    ++		zcs->cctx = NULL;
    ++		ZSTD_freeCDict(zcs->cdictLocal);
    ++		zcs->cdictLocal = NULL;
    ++		ZSTD_free(zcs->inBuff, cMem);
    ++		zcs->inBuff = NULL;
    ++		ZSTD_free(zcs->outBuff, cMem);
    ++		zcs->outBuff = NULL;
    ++		ZSTD_free(zcs, cMem);
    ++		return 0;
    ++	}
    ++}
    ++
    ++
    ++/*======   Initialization   ======*/
    ++
    ++size_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    ++size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
    ++
    ++static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    ++{
    ++	if (zcs->inBuffSize==0) return ERROR(stage_wrong);   /* zcs has not been init at least once => can't reset */
    ++
    ++	if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
    ++	else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
    ++
    ++	zcs->inToCompress = 0;
    ++	zcs->inBuffPos = 0;
    ++	zcs->inBuffTarget = zcs->blockSize;
    ++	zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
    ++	zcs->stage = zcss_load;
    ++	zcs->frameEnded = 0;
    ++	zcs->pledgedSrcSize = pledgedSrcSize;
    ++	zcs->inputProcessed = 0;
    ++	return 0;   /* ready to go */
    ++}
    ++
    ++size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    ++{
    ++
    ++	zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    ++
    ++	return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
    ++}
    ++
    ++static size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
    ++								 const void* dict, size_t dictSize,
    ++								 ZSTD_parameters params, unsigned long long pledgedSrcSize)
    ++{
    ++	/* allocate buffers */
    ++	{   size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
    ++		if (zcs->inBuffSize < neededInBuffSize) {
    ++			zcs->inBuffSize = neededInBuffSize;
    ++			ZSTD_free(zcs->inBuff, zcs->customMem);
    ++			zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
    ++			if (zcs->inBuff == NULL) return ERROR(memory_allocation);
    ++		}
    ++		zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
    ++	}
    ++	if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
    ++		zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
    ++		ZSTD_free(zcs->outBuff, zcs->customMem);
    ++		zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
    ++		if (zcs->outBuff == NULL) return ERROR(memory_allocation);
    ++	}
    ++
    ++	if (dict && dictSize >= 8) {
    ++		ZSTD_freeCDict(zcs->cdictLocal);
    ++		zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0, params, zcs->customMem);
    ++		if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    ++		zcs->cdict = zcs->cdictLocal;
    ++	} else zcs->cdict = NULL;
    ++
    ++	zcs->checksum = params.fParams.checksumFlag > 0;
    ++	zcs->params = params;
    ++
    ++	return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
    ++}
    ++
    ++ZSTD_CStream* ZSTD_initCStream(ZSTD_parameters params, unsigned long long pledgedSrcSize, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	ZSTD_CStream* const zcs = ZSTD_createCStream_advanced(stackMem);
    ++	if (zcs) {
    ++		size_t const code = ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
    ++		if (ZSTD_isError(code)) { return NULL; }
    ++	}
    ++	return zcs;
    ++}
    ++
    ++ZSTD_CStream* ZSTD_initCStream_usingCDict(const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
    ++	ZSTD_CStream* const zcs = ZSTD_initCStream(params, pledgedSrcSize, workspace, workspaceSize);
    ++	if (zcs) {
    ++		zcs->cdict = cdict;
    ++		if (ZSTD_isError(ZSTD_resetCStream_internal(zcs, pledgedSrcSize))) {
    ++			return NULL;
    ++		}
    ++	}
    ++	return zcs;
    ++}
    ++
    ++/*======   Compression   ======*/
    ++
    ++typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
    ++
    ++MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	size_t const length = MIN(dstCapacity, srcSize);
    ++	memcpy(dst, src, length);
    ++	return length;
    ++}
    ++
    ++static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
    ++							  void* dst, size_t* dstCapacityPtr,
    ++						const void* src, size_t* srcSizePtr,
    ++							  ZSTD_flush_e const flush)
    ++{
    ++	U32 someMoreWork = 1;
    ++	const char* const istart = (const char*)src;
    ++	const char* const iend = istart + *srcSizePtr;
    ++	const char* ip = istart;
    ++	char* const ostart = (char*)dst;
    ++	char* const oend = ostart + *dstCapacityPtr;
    ++	char* op = ostart;
    ++
    ++	while (someMoreWork) {
    ++		switch(zcs->stage)
    ++		{
    ++		case zcss_init: return ERROR(init_missing);   /* call ZBUFF_compressInit() first ! */
    ++
    ++		case zcss_load:
    ++			/* complete inBuffer */
    ++			{   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    ++				size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
    ++				zcs->inBuffPos += loaded;
    ++				ip += loaded;
    ++				if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
    ++					someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
    ++			}   }
    ++			/* compress current block (note : this stage cannot be stopped in the middle) */
    ++			{   void* cDst;
    ++				size_t cSize;
    ++				size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
    ++				size_t oSize = oend-op;
    ++				if (oSize >= ZSTD_compressBound(iSize))
    ++					cDst = op;   /* compress directly into output buffer (avoid flush stage) */
    ++				else
    ++					cDst = zcs->outBuff, oSize = zcs->outBuffSize;
    ++				cSize = (flush == zsf_end) ?
    ++						ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
    ++						ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
    ++				if (ZSTD_isError(cSize)) return cSize;
    ++				if (flush == zsf_end) zcs->frameEnded = 1;
    ++				/* prepare next block */
    ++				zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
    ++				if (zcs->inBuffTarget > zcs->inBuffSize)
    ++					zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;   /* note : inBuffSize >= blockSize */
    ++				zcs->inToCompress = zcs->inBuffPos;
    ++				if (cDst == op) { op += cSize; break; }   /* no need to flush */
    ++				zcs->outBuffContentSize = cSize;
    ++				zcs->outBuffFlushedSize = 0;
    ++				zcs->stage = zcss_flush;   /* pass-through to flush stage */
    ++			}
    ++
    ++		case zcss_flush:
    ++			{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    ++				size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    ++				op += flushed;
    ++				zcs->outBuffFlushedSize += flushed;
    ++				if (toFlush!=flushed) { someMoreWork = 0; break; }  /* dst too small to store flushed data : stop there */
    ++				zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
    ++				zcs->stage = zcss_load;
    ++				break;
    ++			}
    ++
    ++		case zcss_final:
    ++			someMoreWork = 0;   /* do nothing */
    ++			break;
    ++
    ++		default:
    ++			return ERROR(GENERIC);   /* impossible */
    ++		}
    ++	}
    ++
    ++	*srcSizePtr = ip - istart;
    ++	*dstCapacityPtr = op - ostart;
    ++	zcs->inputProcessed += *srcSizePtr;
    ++	if (zcs->frameEnded) return 0;
    ++	{   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
    ++		if (hintInSize==0) hintInSize = zcs->blockSize;
    ++		return hintInSize;
    ++	}
    ++}
    ++
    ++size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
    ++{
    ++	size_t sizeRead = input->size - input->pos;
    ++	size_t sizeWritten = output->size - output->pos;
    ++	size_t const result = ZSTD_compressStream_generic(zcs,
    ++													  (char*)(output->dst) + output->pos, &sizeWritten,
    ++													  (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
    ++	input->pos += sizeRead;
    ++	output->pos += sizeWritten;
    ++	return result;
    ++}
    ++
    ++
    ++/*======   Finalize   ======*/
    ++
    ++/*! ZSTD_flushStream() :
    ++*   @return : amount of data remaining to flush */
    ++size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
    ++{
    ++	size_t srcSize = 0;
    ++	size_t sizeWritten = output->size - output->pos;
    ++	size_t const result = ZSTD_compressStream_generic(zcs,
    ++													 (char*)(output->dst) + output->pos, &sizeWritten,
    ++													 &srcSize, &srcSize, /* use a valid src address instead of NULL */
    ++													  zsf_flush);
    ++	output->pos += sizeWritten;
    ++	if (ZSTD_isError(result)) return result;
    ++	return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
    ++}
    ++
    ++
    ++size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
    ++{
    ++	BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
    ++	BYTE* const oend = (BYTE*)(output->dst) + output->size;
    ++	BYTE* op = ostart;
    ++
    ++	if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize))
    ++		return ERROR(srcSize_wrong);   /* pledgedSrcSize not respected */
    ++
    ++	if (zcs->stage != zcss_final) {
    ++		/* flush whatever remains */
    ++		size_t srcSize = 0;
    ++		size_t sizeWritten = output->size - output->pos;
    ++		size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end);  /* use a valid src address instead of NULL */
    ++		size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    ++		op += sizeWritten;
    ++		if (remainingToFlush) {
    ++			output->pos += sizeWritten;
    ++			return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4);
    ++		}
    ++		/* create epilogue */
    ++		zcs->stage = zcss_final;
    ++		zcs->outBuffContentSize = !notEnded ? 0 :
    ++			ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0);  /* write epilogue, including final empty block, into outBuff */
    ++	}
    ++
    ++	/* flush epilogue */
    ++	{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    ++		size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    ++		op += flushed;
    ++		zcs->outBuffFlushedSize += flushed;
    ++		output->pos += op-ostart;
    ++		if (toFlush==flushed) zcs->stage = zcss_init;  /* end reached */
    ++		return toFlush - flushed;
    ++	}
    ++}
    ++
    ++
    ++
    ++/*-=====  Pre-defined compression levels  =====-*/
    ++
    ++#define ZSTD_DEFAULT_CLEVEL 1
    ++#define ZSTD_MAX_CLEVEL     22
    ++int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
    ++
    ++static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
    ++{   /* "default" */
    ++	/* W,  C,  H,  S,  L, TL, strat */
    ++	{ 18, 12, 12,  1,  7, 16, ZSTD_fast    },  /* level  0 - never used */
    ++	{ 19, 13, 14,  1,  7, 16, ZSTD_fast    },  /* level  1 */
    ++	{ 19, 15, 16,  1,  6, 16, ZSTD_fast    },  /* level  2 */
    ++	{ 20, 16, 17,  1,  5, 16, ZSTD_dfast   },  /* level  3.*/
    ++	{ 20, 18, 18,  1,  5, 16, ZSTD_dfast   },  /* level  4.*/
    ++	{ 20, 15, 18,  3,  5, 16, ZSTD_greedy  },  /* level  5 */
    ++	{ 21, 16, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
    ++	{ 21, 17, 20,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
    ++	{ 21, 18, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
    ++	{ 21, 20, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
    ++	{ 21, 19, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
    ++	{ 22, 20, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
    ++	{ 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
    ++	{ 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 13 */
    ++	{ 22, 21, 22,  6,  5, 16, ZSTD_lazy2   },  /* level 14 */
    ++	{ 22, 21, 21,  5,  5, 16, ZSTD_btlazy2 },  /* level 15 */
    ++	{ 23, 22, 22,  5,  5, 16, ZSTD_btlazy2 },  /* level 16 */
    ++	{ 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
    ++	{ 23, 23, 22,  6,  5, 32, ZSTD_btopt   },  /* level 18 */
    ++	{ 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
    ++	{ 25, 25, 23,  7,  3, 64, ZSTD_btopt2  },  /* level 20 */
    ++	{ 26, 26, 23,  7,  3,256, ZSTD_btopt2  },  /* level 21 */
    ++	{ 27, 27, 25,  9,  3,512, ZSTD_btopt2  },  /* level 22 */
    ++},
    ++{   /* for srcSize <= 256 KB */
    ++	/* W,  C,  H,  S,  L,  T, strat */
    ++	{  0,  0,  0,  0,  0,  0, ZSTD_fast    },  /* level  0 - not used */
    ++	{ 18, 13, 14,  1,  6,  8, ZSTD_fast    },  /* level  1 */
    ++	{ 18, 14, 13,  1,  5,  8, ZSTD_dfast   },  /* level  2 */
    ++	{ 18, 16, 15,  1,  5,  8, ZSTD_dfast   },  /* level  3 */
    ++	{ 18, 15, 17,  1,  5,  8, ZSTD_greedy  },  /* level  4.*/
    ++	{ 18, 16, 17,  4,  5,  8, ZSTD_greedy  },  /* level  5.*/
    ++	{ 18, 16, 17,  3,  5,  8, ZSTD_lazy    },  /* level  6.*/
    ++	{ 18, 17, 17,  4,  4,  8, ZSTD_lazy    },  /* level  7 */
    ++	{ 18, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
    ++	{ 18, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
    ++	{ 18, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
    ++	{ 18, 18, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 11.*/
    ++	{ 18, 18, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 12.*/
    ++	{ 18, 19, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13 */
    ++	{ 18, 18, 18,  4,  4, 16, ZSTD_btopt   },  /* level 14.*/
    ++	{ 18, 18, 18,  4,  3, 16, ZSTD_btopt   },  /* level 15.*/
    ++	{ 18, 19, 18,  6,  3, 32, ZSTD_btopt   },  /* level 16.*/
    ++	{ 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
    ++	{ 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
    ++	{ 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
    ++	{ 18, 19, 18, 11,  3,512, ZSTD_btopt2  },  /* level 20.*/
    ++	{ 18, 19, 18, 12,  3,512, ZSTD_btopt2  },  /* level 21.*/
    ++	{ 18, 19, 18, 13,  3,512, ZSTD_btopt2  },  /* level 22.*/
    ++},
    ++{   /* for srcSize <= 128 KB */
    ++	/* W,  C,  H,  S,  L,  T, strat */
    ++	{ 17, 12, 12,  1,  7,  8, ZSTD_fast    },  /* level  0 - not used */
    ++	{ 17, 12, 13,  1,  6,  8, ZSTD_fast    },  /* level  1 */
    ++	{ 17, 13, 16,  1,  5,  8, ZSTD_fast    },  /* level  2 */
    ++	{ 17, 16, 16,  2,  5,  8, ZSTD_dfast   },  /* level  3 */
    ++	{ 17, 13, 15,  3,  4,  8, ZSTD_greedy  },  /* level  4 */
    ++	{ 17, 15, 17,  4,  4,  8, ZSTD_greedy  },  /* level  5 */
    ++	{ 17, 16, 17,  3,  4,  8, ZSTD_lazy    },  /* level  6 */
    ++	{ 17, 15, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  7 */
    ++	{ 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
    ++	{ 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
    ++	{ 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
    ++	{ 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
    ++	{ 17, 17, 17,  8,  4,  8, ZSTD_lazy2   },  /* level 12 */
    ++	{ 17, 18, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13.*/
    ++	{ 17, 17, 17,  7,  3,  8, ZSTD_btopt   },  /* level 14.*/
    ++	{ 17, 17, 17,  7,  3, 16, ZSTD_btopt   },  /* level 15.*/
    ++	{ 17, 18, 17,  7,  3, 32, ZSTD_btopt   },  /* level 16.*/
    ++	{ 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
    ++	{ 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
    ++	{ 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
    ++	{ 17, 18, 17,  9,  3,256, ZSTD_btopt2  },  /* level 20.*/
    ++	{ 17, 18, 17, 10,  3,256, ZSTD_btopt2  },  /* level 21.*/
    ++	{ 17, 18, 17, 11,  3,512, ZSTD_btopt2  },  /* level 22.*/
    ++},
    ++{   /* for srcSize <= 16 KB */
    ++	/* W,  C,  H,  S,  L,  T, strat */
    ++	{ 14, 12, 12,  1,  7,  6, ZSTD_fast    },  /* level  0 - not used */
    ++	{ 14, 14, 14,  1,  6,  6, ZSTD_fast    },  /* level  1 */
    ++	{ 14, 14, 14,  1,  4,  6, ZSTD_fast    },  /* level  2 */
    ++	{ 14, 14, 14,  1,  4,  6, ZSTD_dfast   },  /* level  3.*/
    ++	{ 14, 14, 14,  4,  4,  6, ZSTD_greedy  },  /* level  4.*/
    ++	{ 14, 14, 14,  3,  4,  6, ZSTD_lazy    },  /* level  5.*/
    ++	{ 14, 14, 14,  4,  4,  6, ZSTD_lazy2   },  /* level  6 */
    ++	{ 14, 14, 14,  5,  4,  6, ZSTD_lazy2   },  /* level  7 */
    ++	{ 14, 14, 14,  6,  4,  6, ZSTD_lazy2   },  /* level  8.*/
    ++	{ 14, 15, 14,  6,  4,  6, ZSTD_btlazy2 },  /* level  9.*/
    ++	{ 14, 15, 14,  3,  3,  6, ZSTD_btopt   },  /* level 10.*/
    ++	{ 14, 15, 14,  6,  3,  8, ZSTD_btopt   },  /* level 11.*/
    ++	{ 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
    ++	{ 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
    ++	{ 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
    ++	{ 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
    ++	{ 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
    ++	{ 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
    ++	{ 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
    ++	{ 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
    ++	{ 14, 15, 15,  8,  3,256, ZSTD_btopt2  },  /* level 20.*/
    ++	{ 14, 15, 15,  9,  3,256, ZSTD_btopt2  },  /* level 21.*/
    ++	{ 14, 15, 15, 10,  3,256, ZSTD_btopt2  },  /* level 22.*/
    ++},
    ++};
    ++
    ++/*! ZSTD_getCParams() :
    ++*   @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
    ++*   Size values are optional, provide 0 if not known or unused */
    ++ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
    ++{
    ++	ZSTD_compressionParameters cp;
    ++	size_t const addedSize = srcSize ? 0 : 500;
    ++	U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
    ++	U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
    ++	if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL;   /* 0 == default; no negative compressionLevel yet */
    ++	if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
    ++	cp = ZSTD_defaultCParameters[tableID][compressionLevel];
    ++	if (MEM_32bits()) {   /* auto-correction, for 32-bits mode */
    ++		if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
    ++		if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
    ++		if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
    ++	}
    ++	cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
    ++	return cp;
    ++}
    ++
    ++/*! ZSTD_getParams() :
    ++*   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
    ++*   All fields of `ZSTD_frameParameters` are set to default (0) */
    ++ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
    ++	ZSTD_parameters params;
    ++	ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
    ++	memset(¶ms, 0, sizeof(params));
    ++	params.cParams = cParams;
    ++	return params;
    ++}
    ++
    ++EXPORT_SYMBOL(ZSTD_maxCLevel);
    ++EXPORT_SYMBOL(ZSTD_compressBound);
    ++
    ++EXPORT_SYMBOL(ZSTD_CCtxWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initCCtx);
    ++EXPORT_SYMBOL(ZSTD_compressCCtx);
    ++EXPORT_SYMBOL(ZSTD_compress_usingDict);
    ++
    ++EXPORT_SYMBOL(ZSTD_CDictWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initCDict);
    ++EXPORT_SYMBOL(ZSTD_compress_usingCDict);
    ++
    ++EXPORT_SYMBOL(ZSTD_CStreamWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initCStream);
    ++EXPORT_SYMBOL(ZSTD_initCStream_usingCDict);
    ++EXPORT_SYMBOL(ZSTD_resetCStream);
    ++EXPORT_SYMBOL(ZSTD_compressStream);
    ++EXPORT_SYMBOL(ZSTD_flushStream);
    ++EXPORT_SYMBOL(ZSTD_endStream);
    ++EXPORT_SYMBOL(ZSTD_CStreamInSize);
    ++EXPORT_SYMBOL(ZSTD_CStreamOutSize);
    ++
    ++EXPORT_SYMBOL(ZSTD_getCParams);
    ++EXPORT_SYMBOL(ZSTD_getParams);
    ++EXPORT_SYMBOL(ZSTD_checkCParams);
    ++EXPORT_SYMBOL(ZSTD_adjustCParams);
    ++
    ++EXPORT_SYMBOL(ZSTD_compressBegin);
    ++EXPORT_SYMBOL(ZSTD_compressBegin_usingDict);
    ++EXPORT_SYMBOL(ZSTD_compressBegin_advanced);
    ++EXPORT_SYMBOL(ZSTD_copyCCtx);
    ++EXPORT_SYMBOL(ZSTD_compressBegin_usingCDict);
    ++EXPORT_SYMBOL(ZSTD_compressContinue);
    ++EXPORT_SYMBOL(ZSTD_compressEnd);
    ++
    ++EXPORT_SYMBOL(ZSTD_getBlockSizeMax);
    ++EXPORT_SYMBOL(ZSTD_compressBlock);
    ++
    ++MODULE_LICENSE("BSD");
    ++MODULE_DESCRIPTION("Zstd Compressor");
    +diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
    +new file mode 100644
    +index 0000000..98508b1
    +--- /dev/null
    ++++ b/lib/zstd/decompress.c
    +@@ -0,0 +1,2377 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++
    ++/* ***************************************************************
    ++*  Tuning parameters
    ++*****************************************************************/
    ++/*!
    ++*  MAXWINDOWSIZE_DEFAULT :
    ++*  maximum window size accepted by DStream, by default.
    ++*  Frames requiring more memory will be rejected.
    ++*/
    ++#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
    ++#  define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1)   /* defined within zstd.h */
    ++#endif
    ++
    ++
    ++/*-*******************************************************
    ++*  Dependencies
    ++*********************************************************/
    ++#include 
    ++#include 
    ++#include       /* memcpy, memmove, memset */
    ++#include "mem.h"         /* low level memory routines */
    ++#include "fse.h"
    ++#include "huf.h"
    ++#include "zstd_internal.h"
    ++
    ++#define ZSTD_PREFETCH(ptr)   __builtin_prefetch(ptr, 0, 0)
    ++
    ++/*-*************************************
    ++*  Macros
    ++***************************************/
    ++#define ZSTD_isError ERR_isError   /* for inlining */
    ++#define FSE_isError  ERR_isError
    ++#define HUF_isError  ERR_isError
    ++
    ++
    ++/*_*******************************************************
    ++*  Memory operations
    ++**********************************************************/
    ++static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
    ++
    ++
    ++/*-*************************************************************
    ++*   Context management
    ++***************************************************************/
    ++typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
    ++			   ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
    ++			   ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
    ++			   ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
    ++
    ++typedef struct {
    ++	FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
    ++	FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
    ++	FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
    ++	HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)];  /* can accommodate HUF_decompress4X */
    ++	U32 rep[ZSTD_REP_NUM];
    ++} ZSTD_entropyTables_t;
    ++
    ++struct ZSTD_DCtx_s
    ++{
    ++	const FSE_DTable* LLTptr;
    ++	const FSE_DTable* MLTptr;
    ++	const FSE_DTable* OFTptr;
    ++	const HUF_DTable* HUFptr;
    ++	ZSTD_entropyTables_t entropy;
    ++	const void* previousDstEnd;   /* detect continuity */
    ++	const void* base;             /* start of current segment */
    ++	const void* vBase;            /* virtual start of previous segment if it was just before current one */
    ++	const void* dictEnd;          /* end of previous segment */
    ++	size_t expected;
    ++	ZSTD_frameParams fParams;
    ++	blockType_e bType;   /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
    ++	ZSTD_dStage stage;
    ++	U32 litEntropy;
    ++	U32 fseEntropy;
    ++	struct xxh64_state xxhState;
    ++	size_t headerSize;
    ++	U32 dictID;
    ++	const BYTE* litPtr;
    ++	ZSTD_customMem customMem;
    ++	size_t litSize;
    ++	size_t rleSize;
    ++	BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
    ++	BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
    ++};  /* typedef'd to ZSTD_DCtx within "zstd.h" */
    ++
    ++size_t ZSTD_DCtxWorkspaceBound(void)
    ++{
    ++	return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx));
    ++}
    ++
    ++size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
    ++{
    ++	dctx->expected = ZSTD_frameHeaderSize_prefix;
    ++	dctx->stage = ZSTDds_getFrameHeaderSize;
    ++	dctx->previousDstEnd = NULL;
    ++	dctx->base = NULL;
    ++	dctx->vBase = NULL;
    ++	dctx->dictEnd = NULL;
    ++	dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    ++	dctx->litEntropy = dctx->fseEntropy = 0;
    ++	dctx->dictID = 0;
    ++	MEM_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
    ++	memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue));  /* initial repcodes */
    ++	dctx->LLTptr = dctx->entropy.LLTable;
    ++	dctx->MLTptr = dctx->entropy.MLTable;
    ++	dctx->OFTptr = dctx->entropy.OFTable;
    ++	dctx->HUFptr = dctx->entropy.hufTable;
    ++	return 0;
    ++}
    ++
    ++ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
    ++{
    ++	ZSTD_DCtx* dctx;
    ++
    ++	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    ++
    ++	dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
    ++	if (!dctx) return NULL;
    ++	memcpy(&dctx->customMem, &customMem, sizeof(customMem));
    ++	ZSTD_decompressBegin(dctx);
    ++	return dctx;
    ++}
    ++
    ++ZSTD_DCtx* ZSTD_initDCtx(void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	return ZSTD_createDCtx_advanced(stackMem);
    ++}
    ++
    ++size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
    ++{
    ++	if (dctx==NULL) return 0;   /* support free on NULL */
    ++	ZSTD_free(dctx, dctx->customMem);
    ++	return 0;   /* reserved as a potential error code in the future */
    ++}
    ++
    ++void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    ++{
    ++	size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
    ++	memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
    ++}
    ++
    ++#if 0
    ++/* deprecated */
    ++static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    ++{
    ++	ZSTD_decompressBegin(dstDCtx);  /* init */
    ++	if (srcDCtx) {   /* support refDCtx on NULL */
    ++		dstDCtx->dictEnd = srcDCtx->dictEnd;
    ++		dstDCtx->vBase = srcDCtx->vBase;
    ++		dstDCtx->base = srcDCtx->base;
    ++		dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
    ++		dstDCtx->dictID = srcDCtx->dictID;
    ++		dstDCtx->litEntropy = srcDCtx->litEntropy;
    ++		dstDCtx->fseEntropy = srcDCtx->fseEntropy;
    ++		dstDCtx->LLTptr = srcDCtx->entropy.LLTable;
    ++		dstDCtx->MLTptr = srcDCtx->entropy.MLTable;
    ++		dstDCtx->OFTptr = srcDCtx->entropy.OFTable;
    ++		dstDCtx->HUFptr = srcDCtx->entropy.hufTable;
    ++		dstDCtx->entropy.rep[0] = srcDCtx->entropy.rep[0];
    ++		dstDCtx->entropy.rep[1] = srcDCtx->entropy.rep[1];
    ++		dstDCtx->entropy.rep[2] = srcDCtx->entropy.rep[2];
    ++	}
    ++}
    ++#endif
    ++
    ++static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
    ++
    ++
    ++/*-*************************************************************
    ++*   Decompression section
    ++***************************************************************/
    ++
    ++/*! ZSTD_isFrame() :
    ++ *  Tells if the content of `buffer` starts with a valid Frame Identifier.
    ++ *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
    ++ *  Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
    ++ *  Note 3 : Skippable Frame Identifiers are considered valid. */
    ++unsigned ZSTD_isFrame(const void* buffer, size_t size)
    ++{
    ++	if (size < 4) return 0;
    ++	{   U32 const magic = MEM_readLE32(buffer);
    ++		if (magic == ZSTD_MAGICNUMBER) return 1;
    ++		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
    ++	}
    ++	return 0;
    ++}
    ++
    ++
    ++/** ZSTD_frameHeaderSize() :
    ++*   srcSize must be >= ZSTD_frameHeaderSize_prefix.
    ++*   @return : size of the Frame Header */
    ++static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
    ++{
    ++	if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
    ++	{   BYTE const fhd = ((const BYTE*)src)[4];
    ++		U32 const dictID= fhd & 3;
    ++		U32 const singleSegment = (fhd >> 5) & 1;
    ++		U32 const fcsId = fhd >> 6;
    ++		return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
    ++				+ (singleSegment && !fcsId);
    ++	}
    ++}
    ++
    ++
    ++/** ZSTD_getFrameParams() :
    ++*   decode Frame Header, or require larger `srcSize`.
    ++*   @return : 0, `fparamsPtr` is correctly filled,
    ++*            >0, `srcSize` is too small, result is expected `srcSize`,
    ++*             or an error code, which can be tested using ZSTD_isError() */
    ++size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*)src;
    ++
    ++	if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
    ++	if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
    ++		if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    ++			if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
    ++			memset(fparamsPtr, 0, sizeof(*fparamsPtr));
    ++			fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    ++			fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
    ++			return 0;
    ++		}
    ++		return ERROR(prefix_unknown);
    ++	}
    ++
    ++	/* ensure there is enough `srcSize` to fully read/decode frame header */
    ++	{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
    ++	  if (srcSize < fhsize) return fhsize; }
    ++
    ++	{   BYTE const fhdByte = ip[4];
    ++		size_t pos = 5;
    ++		U32 const dictIDSizeCode = fhdByte&3;
    ++		U32 const checksumFlag = (fhdByte>>2)&1;
    ++		U32 const singleSegment = (fhdByte>>5)&1;
    ++		U32 const fcsID = fhdByte>>6;
    ++		U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
    ++		U32 windowSize = 0;
    ++		U32 dictID = 0;
    ++		U64 frameContentSize = 0;
    ++		if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported);   /* reserved bits, which must be zero */
    ++		if (!singleSegment) {
    ++			BYTE const wlByte = ip[pos++];
    ++			U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
    ++			if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge);  /* avoids issue with 1 << windowLog */
    ++			windowSize = (1U << windowLog);
    ++			windowSize += (windowSize >> 3) * (wlByte&7);
    ++		}
    ++
    ++		switch(dictIDSizeCode)
    ++		{
    ++			default:   /* impossible */
    ++			case 0 : break;
    ++			case 1 : dictID = ip[pos]; pos++; break;
    ++			case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
    ++			case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
    ++		}
    ++		switch(fcsID)
    ++		{
    ++			default:   /* impossible */
    ++			case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
    ++			case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
    ++			case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
    ++			case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
    ++		}
    ++		if (!windowSize) windowSize = (U32)frameContentSize;
    ++		if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
    ++		fparamsPtr->frameContentSize = frameContentSize;
    ++		fparamsPtr->windowSize = windowSize;
    ++		fparamsPtr->dictID = dictID;
    ++		fparamsPtr->checksumFlag = checksumFlag;
    ++	}
    ++	return 0;
    ++}
    ++
    ++/** ZSTD_getFrameContentSize() :
    ++*   compatible with legacy mode
    ++*   @return : decompressed size of the single frame pointed to be `src` if known, otherwise
    ++*             - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
    ++*             - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
    ++unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
    ++{
    ++	{
    ++		ZSTD_frameParams fParams;
    ++		if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0) return ZSTD_CONTENTSIZE_ERROR;
    ++		if (fParams.windowSize == 0) {
    ++			/* Either skippable or empty frame, size == 0 either way */
    ++			return 0;
    ++		} else if (fParams.frameContentSize != 0) {
    ++			return fParams.frameContentSize;
    ++		} else {
    ++			return ZSTD_CONTENTSIZE_UNKNOWN;
    ++		}
    ++	}
    ++}
    ++
    ++/** ZSTD_findDecompressedSize() :
    ++ *  compatible with legacy mode
    ++ *  `srcSize` must be the exact length of some number of ZSTD compressed and/or
    ++ *      skippable frames
    ++ *  @return : decompressed size of the frames contained */
    ++unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
    ++{
    ++	{
    ++		unsigned long long totalDstSize = 0;
    ++		while (srcSize >= ZSTD_frameHeaderSize_prefix) {
    ++			const U32 magicNumber = MEM_readLE32(src);
    ++
    ++			if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    ++				size_t skippableSize;
    ++				if (srcSize < ZSTD_skippableHeaderSize)
    ++					return ERROR(srcSize_wrong);
    ++				skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    ++								ZSTD_skippableHeaderSize;
    ++				if (srcSize < skippableSize) {
    ++					return ZSTD_CONTENTSIZE_ERROR;
    ++				}
    ++
    ++				src = (const BYTE *)src + skippableSize;
    ++				srcSize -= skippableSize;
    ++				continue;
    ++			}
    ++
    ++			{
    ++				unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
    ++				if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
    ++
    ++				/* check for overflow */
    ++				if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
    ++				totalDstSize += ret;
    ++			}
    ++			{
    ++				size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
    ++				if (ZSTD_isError(frameSrcSize)) {
    ++					return ZSTD_CONTENTSIZE_ERROR;
    ++				}
    ++
    ++				src = (const BYTE *)src + frameSrcSize;
    ++				srcSize -= frameSrcSize;
    ++			}
    ++		}
    ++
    ++		if (srcSize) {
    ++			return ZSTD_CONTENTSIZE_ERROR;
    ++		}
    ++
    ++		return totalDstSize;
    ++	}
    ++}
    ++
    ++/** ZSTD_decodeFrameHeader() :
    ++*   `headerSize` must be the size provided by ZSTD_frameHeaderSize().
    ++*   @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
    ++static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
    ++{
    ++	size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
    ++	if (ZSTD_isError(result)) return result;  /* invalid header */
    ++	if (result>0) return ERROR(srcSize_wrong);   /* headerSize too small */
    ++	if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
    ++	if (dctx->fParams.checksumFlag) xxh64_reset(&dctx->xxhState, 0);
    ++	return 0;
    ++}
    ++
    ++
    ++typedef struct
    ++{
    ++	blockType_e blockType;
    ++	U32 lastBlock;
    ++	U32 origSize;
    ++} blockProperties_t;
    ++
    ++/*! ZSTD_getcBlockSize() :
    ++*   Provides the size of compressed block from block header `src` */
    ++size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
    ++{
    ++	if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    ++	{   U32 const cBlockHeader = MEM_readLE24(src);
    ++		U32 const cSize = cBlockHeader >> 3;
    ++		bpPtr->lastBlock = cBlockHeader & 1;
    ++		bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
    ++		bpPtr->origSize = cSize;   /* only useful for RLE */
    ++		if (bpPtr->blockType == bt_rle) return 1;
    ++		if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
    ++		return cSize;
    ++	}
    ++}
    ++
    ++
    ++static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
    ++	memcpy(dst, src, srcSize);
    ++	return srcSize;
    ++}
    ++
    ++
    ++static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
    ++{
    ++	if (srcSize != 1) return ERROR(srcSize_wrong);
    ++	if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
    ++	memset(dst, *(const BYTE*)src, regenSize);
    ++	return regenSize;
    ++}
    ++
    ++/*! ZSTD_decodeLiteralsBlock() :
    ++	@return : nb of bytes read from src (< srcSize ) */
    ++size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
    ++						  const void* src, size_t srcSize)   /* note : srcSize < BLOCKSIZE */
    ++{
    ++	if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
    ++
    ++	{   const BYTE* const istart = (const BYTE*) src;
    ++		symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
    ++
    ++		switch(litEncType)
    ++		{
    ++		case set_repeat:
    ++			if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
    ++			/* fall-through */
    ++		case set_compressed:
    ++			if (srcSize < 5) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
    ++			{   size_t lhSize, litSize, litCSize;
    ++				U32 singleStream=0;
    ++				U32 const lhlCode = (istart[0] >> 2) & 3;
    ++				U32 const lhc = MEM_readLE32(istart);
    ++				switch(lhlCode)
    ++				{
    ++				case 0: case 1: default:   /* note : default is impossible, since lhlCode into [0..3] */
    ++					/* 2 - 2 - 10 - 10 */
    ++					singleStream = !lhlCode;
    ++					lhSize = 3;
    ++					litSize  = (lhc >> 4) & 0x3FF;
    ++					litCSize = (lhc >> 14) & 0x3FF;
    ++					break;
    ++				case 2:
    ++					/* 2 - 2 - 14 - 14 */
    ++					lhSize = 4;
    ++					litSize  = (lhc >> 4) & 0x3FFF;
    ++					litCSize = lhc >> 18;
    ++					break;
    ++				case 3:
    ++					/* 2 - 2 - 18 - 18 */
    ++					lhSize = 5;
    ++					litSize  = (lhc >> 4) & 0x3FFFF;
    ++					litCSize = (lhc >> 22) + (istart[4] << 10);
    ++					break;
    ++				}
    ++				if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    ++				if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
    ++
    ++				if (HUF_isError((litEncType==set_repeat) ?
    ++									( singleStream ?
    ++										HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
    ++										HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
    ++									( singleStream ?
    ++										HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
    ++										HUF_decompress4X_hufOnly (dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
    ++					return ERROR(corruption_detected);
    ++
    ++				dctx->litPtr = dctx->litBuffer;
    ++				dctx->litSize = litSize;
    ++				dctx->litEntropy = 1;
    ++				if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
    ++				memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
    ++				return litCSize + lhSize;
    ++			}
    ++
    ++		case set_basic:
    ++			{   size_t litSize, lhSize;
    ++				U32 const lhlCode = ((istart[0]) >> 2) & 3;
    ++				switch(lhlCode)
    ++				{
    ++				case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
    ++					lhSize = 1;
    ++					litSize = istart[0] >> 3;
    ++					break;
    ++				case 1:
    ++					lhSize = 2;
    ++					litSize = MEM_readLE16(istart) >> 4;
    ++					break;
    ++				case 3:
    ++					lhSize = 3;
    ++					litSize = MEM_readLE24(istart) >> 4;
    ++					break;
    ++				}
    ++
    ++				if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */
    ++					if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
    ++					memcpy(dctx->litBuffer, istart+lhSize, litSize);
    ++					dctx->litPtr = dctx->litBuffer;
    ++					dctx->litSize = litSize;
    ++					memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
    ++					return lhSize+litSize;
    ++				}
    ++				/* direct reference into compressed stream */
    ++				dctx->litPtr = istart+lhSize;
    ++				dctx->litSize = litSize;
    ++				return lhSize+litSize;
    ++			}
    ++
    ++		case set_rle:
    ++			{   U32 const lhlCode = ((istart[0]) >> 2) & 3;
    ++				size_t litSize, lhSize;
    ++				switch(lhlCode)
    ++				{
    ++				case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
    ++					lhSize = 1;
    ++					litSize = istart[0] >> 3;
    ++					break;
    ++				case 1:
    ++					lhSize = 2;
    ++					litSize = MEM_readLE16(istart) >> 4;
    ++					break;
    ++				case 3:
    ++					lhSize = 3;
    ++					litSize = MEM_readLE24(istart) >> 4;
    ++					if (srcSize<4) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
    ++					break;
    ++				}
    ++				if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    ++				memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
    ++				dctx->litPtr = dctx->litBuffer;
    ++				dctx->litSize = litSize;
    ++				return lhSize+1;
    ++			}
    ++		default:
    ++			return ERROR(corruption_detected);   /* impossible */
    ++		}
    ++	}
    ++}
    ++
    ++
    ++typedef union {
    ++	FSE_decode_t realData;
    ++	U32 alignedBy4;
    ++} FSE_decode_t4;
    ++
    ++static const FSE_decode_t4 LL_defaultDTable[(1< max) return ERROR(corruption_detected);
    ++		FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
    ++		*DTablePtr = DTableSpace;
    ++		return 1;
    ++	case set_basic :
    ++		*DTablePtr = (const FSE_DTable*)tmpPtr;
    ++		return 0;
    ++	case set_repeat:
    ++		if (!flagRepeatTable) return ERROR(corruption_detected);
    ++		return 0;
    ++	default :   /* impossible */
    ++	case set_compressed :
    ++		{   U32 tableLog;
    ++			S16 norm[MaxSeq+1];
    ++			size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
    ++			if (FSE_isError(headerSize)) return ERROR(corruption_detected);
    ++			if (tableLog > maxLog) return ERROR(corruption_detected);
    ++			FSE_buildDTable(DTableSpace, norm, max, tableLog);
    ++			*DTablePtr = DTableSpace;
    ++			return headerSize;
    ++	}   }
    ++}
    ++
    ++size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
    ++							 const void* src, size_t srcSize)
    ++{
    ++	const BYTE* const istart = (const BYTE* const)src;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* ip = istart;
    ++
    ++	/* check */
    ++	if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
    ++
    ++	/* SeqHead */
    ++	{   int nbSeq = *ip++;
    ++		if (!nbSeq) { *nbSeqPtr=0; return 1; }
    ++		if (nbSeq > 0x7F) {
    ++			if (nbSeq == 0xFF) {
    ++				if (ip+2 > iend) return ERROR(srcSize_wrong);
    ++				nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
    ++			} else {
    ++				if (ip >= iend) return ERROR(srcSize_wrong);
    ++				nbSeq = ((nbSeq-0x80)<<8) + *ip++;
    ++			}
    ++		}
    ++		*nbSeqPtr = nbSeq;
    ++	}
    ++
    ++	/* FSE table descriptors */
    ++	if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
    ++	{   symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
    ++		symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
    ++		symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
    ++		ip++;
    ++
    ++		/* Build DTables */
    ++		{   size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
    ++													  LLtype, MaxLL, LLFSELog,
    ++													  ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
    ++			if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
    ++			ip += llhSize;
    ++		}
    ++		{   size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
    ++													  OFtype, MaxOff, OffFSELog,
    ++													  ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
    ++			if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
    ++			ip += ofhSize;
    ++		}
    ++		{   size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
    ++													  MLtype, MaxML, MLFSELog,
    ++													  ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
    ++			if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
    ++			ip += mlhSize;
    ++		}
    ++	}
    ++
    ++	return ip-istart;
    ++}
    ++
    ++
    ++typedef struct {
    ++	size_t litLength;
    ++	size_t matchLength;
    ++	size_t offset;
    ++	const BYTE* match;
    ++} seq_t;
    ++
    ++typedef struct {
    ++	BIT_DStream_t DStream;
    ++	FSE_DState_t stateLL;
    ++	FSE_DState_t stateOffb;
    ++	FSE_DState_t stateML;
    ++	size_t prevOffset[ZSTD_REP_NUM];
    ++	const BYTE* base;
    ++	size_t pos;
    ++	uPtrDiff gotoDict;
    ++} seqState_t;
    ++
    ++
    ++FORCE_NOINLINE
    ++size_t ZSTD_execSequenceLast7(BYTE* op,
    ++							  BYTE* const oend, seq_t sequence,
    ++							  const BYTE** litPtr, const BYTE* const litLimit,
    ++							  const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    ++{
    ++	BYTE* const oLitEnd = op + sequence.litLength;
    ++	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    ++	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    ++	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    ++	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    ++	const BYTE* match = oLitEnd - sequence.offset;
    ++
    ++	/* check */
    ++	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    ++	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    ++	if (oLitEnd <= oend_w) return ERROR(GENERIC);   /* Precondition */
    ++
    ++	/* copy literals */
    ++	if (op < oend_w) {
    ++		ZSTD_wildcopy(op, *litPtr, oend_w - op);
    ++		*litPtr += oend_w - op;
    ++		op = oend_w;
    ++	}
    ++	while (op < oLitEnd) *op++ = *(*litPtr)++;
    ++
    ++	/* copy Match */
    ++	if (sequence.offset > (size_t)(oLitEnd - base)) {
    ++		/* offset beyond prefix */
    ++		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    ++		match = dictEnd - (base-match);
    ++		if (match + sequence.matchLength <= dictEnd) {
    ++			memmove(oLitEnd, match, sequence.matchLength);
    ++			return sequenceLength;
    ++		}
    ++		/* span extDict & currentPrefixSegment */
    ++		{   size_t const length1 = dictEnd - match;
    ++			memmove(oLitEnd, match, length1);
    ++			op = oLitEnd + length1;
    ++			sequence.matchLength -= length1;
    ++			match = base;
    ++	}   }
    ++	while (op < oMatchEnd) *op++ = *match++;
    ++	return sequenceLength;
    ++}
    ++
    ++
    ++
    ++
    ++static seq_t ZSTD_decodeSequence(seqState_t* seqState)
    ++{
    ++	seq_t seq;
    ++
    ++	U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
    ++	U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
    ++	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb);   /* <= maxOff, by table construction */
    ++
    ++	U32 const llBits = LL_bits[llCode];
    ++	U32 const mlBits = ML_bits[mlCode];
    ++	U32 const ofBits = ofCode;
    ++	U32 const totalBits = llBits+mlBits+ofBits;
    ++
    ++	static const U32 LL_base[MaxLL+1] = {
    ++							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,   10,    11,    12,    13,    14,     15,
    ++							16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
    ++							0x2000, 0x4000, 0x8000, 0x10000 };
    ++
    ++	static const U32 ML_base[MaxML+1] = {
    ++							 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,   14,    15,    16,    17,    18,
    ++							19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,   30,    31,    32,    33,    34,
    ++							35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
    ++							0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
    ++
    ++	static const U32 OF_base[MaxOff+1] = {
    ++							 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
    ++							 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
    ++							 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
    ++							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
    ++
    ++	/* sequence */
    ++	{   size_t offset;
    ++		if (!ofCode)
    ++			offset = 0;
    ++		else {
    ++			offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    ++			if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
    ++		}
    ++
    ++		if (ofCode <= 1) {
    ++			offset += (llCode==0);
    ++			if (offset) {
    ++				size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    ++				temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */
    ++				if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
    ++				seqState->prevOffset[1] = seqState->prevOffset[0];
    ++				seqState->prevOffset[0] = offset = temp;
    ++			} else {
    ++				offset = seqState->prevOffset[0];
    ++			}
    ++		} else {
    ++			seqState->prevOffset[2] = seqState->prevOffset[1];
    ++			seqState->prevOffset[1] = seqState->prevOffset[0];
    ++			seqState->prevOffset[0] = offset;
    ++		}
    ++		seq.offset = offset;
    ++	}
    ++
    ++	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    ++	if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    ++
    ++	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    ++	if (MEM_32bits() ||
    ++	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
    ++
    ++	/* ANS state update */
    ++	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
    ++	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    ++	if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    ++	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
    ++
    ++	return seq;
    ++}
    ++
    ++
    ++FORCE_INLINE
    ++size_t ZSTD_execSequence(BYTE* op,
    ++						 BYTE* const oend, seq_t sequence,
    ++						 const BYTE** litPtr, const BYTE* const litLimit,
    ++						 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    ++{
    ++	BYTE* const oLitEnd = op + sequence.litLength;
    ++	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    ++	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    ++	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    ++	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    ++	const BYTE* match = oLitEnd - sequence.offset;
    ++
    ++	/* check */
    ++	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    ++	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    ++	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    ++
    ++	/* copy Literals */
    ++	ZSTD_copy8(op, *litPtr);
    ++	if (sequence.litLength > 8)
    ++		ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8);   /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
    ++	op = oLitEnd;
    ++	*litPtr = iLitEnd;   /* update for next sequence */
    ++
    ++	/* copy Match */
    ++	if (sequence.offset > (size_t)(oLitEnd - base)) {
    ++		/* offset beyond prefix */
    ++		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    ++		match = dictEnd + (match - base);
    ++		if (match + sequence.matchLength <= dictEnd) {
    ++			memmove(oLitEnd, match, sequence.matchLength);
    ++			return sequenceLength;
    ++		}
    ++		/* span extDict & currentPrefixSegment */
    ++		{   size_t const length1 = dictEnd - match;
    ++			memmove(oLitEnd, match, length1);
    ++			op = oLitEnd + length1;
    ++			sequence.matchLength -= length1;
    ++			match = base;
    ++			if (op > oend_w || sequence.matchLength < MINMATCH) {
    ++			  U32 i;
    ++			  for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
    ++			  return sequenceLength;
    ++			}
    ++	}   }
    ++	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
    ++
    ++	/* match within prefix */
    ++	if (sequence.offset < 8) {
    ++		/* close range match, overlap */
    ++		static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */
    ++		static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */
    ++		int const sub2 = dec64table[sequence.offset];
    ++		op[0] = match[0];
    ++		op[1] = match[1];
    ++		op[2] = match[2];
    ++		op[3] = match[3];
    ++		match += dec32table[sequence.offset];
    ++		ZSTD_copy4(op+4, match);
    ++		match -= sub2;
    ++	} else {
    ++		ZSTD_copy8(op, match);
    ++	}
    ++	op += 8; match += 8;
    ++
    ++	if (oMatchEnd > oend-(16-MINMATCH)) {
    ++		if (op < oend_w) {
    ++			ZSTD_wildcopy(op, match, oend_w - op);
    ++			match += oend_w - op;
    ++			op = oend_w;
    ++		}
    ++		while (op < oMatchEnd) *op++ = *match++;
    ++	} else {
    ++		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8);   /* works even if matchLength < 8 */
    ++	}
    ++	return sequenceLength;
    ++}
    ++
    ++
    ++static size_t ZSTD_decompressSequences(
    ++							   ZSTD_DCtx* dctx,
    ++							   void* dst, size_t maxDstSize,
    ++						 const void* seqStart, size_t seqSize)
    ++{
    ++	const BYTE* ip = (const BYTE*)seqStart;
    ++	const BYTE* const iend = ip + seqSize;
    ++	BYTE* const ostart = (BYTE* const)dst;
    ++	BYTE* const oend = ostart + maxDstSize;
    ++	BYTE* op = ostart;
    ++	const BYTE* litPtr = dctx->litPtr;
    ++	const BYTE* const litEnd = litPtr + dctx->litSize;
    ++	const BYTE* const base = (const BYTE*) (dctx->base);
    ++	const BYTE* const vBase = (const BYTE*) (dctx->vBase);
    ++	const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
    ++	int nbSeq;
    ++
    ++	/* Build Decoding Tables */
    ++	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    ++		if (ZSTD_isError(seqHSize)) return seqHSize;
    ++		ip += seqHSize;
    ++	}
    ++
    ++	/* Regen sequences */
    ++	if (nbSeq) {
    ++		seqState_t seqState;
    ++		dctx->fseEntropy = 1;
    ++		{ U32 i; for (i=0; ientropy.rep[i]; }
    ++		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
    ++		FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
    ++		FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
    ++		FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
    ++
    ++		for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
    ++			nbSeq--;
    ++			{   seq_t const sequence = ZSTD_decodeSequence(&seqState);
    ++				size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
    ++				if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
    ++				op += oneSeqSize;
    ++		}   }
    ++
    ++		/* check if reached exact end */
    ++		if (nbSeq) return ERROR(corruption_detected);
    ++		/* save reps for next block */
    ++		{ U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); }
    ++	}
    ++
    ++	/* last literal segment */
    ++	{   size_t const lastLLSize = litEnd - litPtr;
    ++		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
    ++		memcpy(op, litPtr, lastLLSize);
    ++		op += lastLLSize;
    ++	}
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int const longOffsets)
    ++{
    ++	seq_t seq;
    ++
    ++	U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
    ++	U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
    ++	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb);   /* <= maxOff, by table construction */
    ++
    ++	U32 const llBits = LL_bits[llCode];
    ++	U32 const mlBits = ML_bits[mlCode];
    ++	U32 const ofBits = ofCode;
    ++	U32 const totalBits = llBits+mlBits+ofBits;
    ++
    ++	static const U32 LL_base[MaxLL+1] = {
    ++							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,   10,    11,    12,    13,    14,     15,
    ++							16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
    ++							0x2000, 0x4000, 0x8000, 0x10000 };
    ++
    ++	static const U32 ML_base[MaxML+1] = {
    ++							 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,   14,    15,    16,    17,    18,
    ++							19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,   30,    31,    32,    33,    34,
    ++							35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
    ++							0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
    ++
    ++	static const U32 OF_base[MaxOff+1] = {
    ++							 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
    ++							 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
    ++							 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
    ++							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
    ++
    ++	/* sequence */
    ++	{   size_t offset;
    ++		if (!ofCode)
    ++			offset = 0;
    ++		else {
    ++			if (longOffsets) {
    ++				int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
    ++				offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
    ++				if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
    ++				if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
    ++			} else {
    ++				offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    ++				if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
    ++			}
    ++		}
    ++
    ++		if (ofCode <= 1) {
    ++			offset += (llCode==0);
    ++			if (offset) {
    ++				size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    ++				temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */
    ++				if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
    ++				seqState->prevOffset[1] = seqState->prevOffset[0];
    ++				seqState->prevOffset[0] = offset = temp;
    ++			} else {
    ++				offset = seqState->prevOffset[0];
    ++			}
    ++		} else {
    ++			seqState->prevOffset[2] = seqState->prevOffset[1];
    ++			seqState->prevOffset[1] = seqState->prevOffset[0];
    ++			seqState->prevOffset[0] = offset;
    ++		}
    ++		seq.offset = offset;
    ++	}
    ++
    ++	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    ++	if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    ++
    ++	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    ++	if (MEM_32bits() ||
    ++	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
    ++
    ++	{   size_t const pos = seqState->pos + seq.litLength;
    ++		seq.match = seqState->base + pos - seq.offset;    /* single memory segment */
    ++		if (seq.offset > pos) seq.match += seqState->gotoDict;   /* separate memory segment */
    ++		seqState->pos = pos + seq.matchLength;
    ++	}
    ++
    ++	/* ANS state update */
    ++	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
    ++	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    ++	if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    ++	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
    ++
    ++	return seq;
    ++}
    ++
    ++static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
    ++	if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
    ++		return ZSTD_decodeSequenceLong_generic(seqState, 1);
    ++	} else {
    ++		return ZSTD_decodeSequenceLong_generic(seqState, 0);
    ++	}
    ++}
    ++
    ++FORCE_INLINE
    ++size_t ZSTD_execSequenceLong(BYTE* op,
    ++								BYTE* const oend, seq_t sequence,
    ++								const BYTE** litPtr, const BYTE* const litLimit,
    ++								const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    ++{
    ++	BYTE* const oLitEnd = op + sequence.litLength;
    ++	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    ++	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    ++	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    ++	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    ++	const BYTE* match = sequence.match;
    ++
    ++	/* check */
    ++#if 1
    ++	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    ++	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    ++	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    ++#endif
    ++
    ++	/* copy Literals */
    ++	ZSTD_copy8(op, *litPtr);
    ++	if (sequence.litLength > 8)
    ++		ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8);   /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
    ++	op = oLitEnd;
    ++	*litPtr = iLitEnd;   /* update for next sequence */
    ++
    ++	/* copy Match */
    ++#if 1
    ++	if (sequence.offset > (size_t)(oLitEnd - base)) {
    ++		/* offset beyond prefix */
    ++		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    ++		if (match + sequence.matchLength <= dictEnd) {
    ++			memmove(oLitEnd, match, sequence.matchLength);
    ++			return sequenceLength;
    ++		}
    ++		/* span extDict & currentPrefixSegment */
    ++		{   size_t const length1 = dictEnd - match;
    ++			memmove(oLitEnd, match, length1);
    ++			op = oLitEnd + length1;
    ++			sequence.matchLength -= length1;
    ++			match = base;
    ++			if (op > oend_w || sequence.matchLength < MINMATCH) {
    ++			  U32 i;
    ++			  for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
    ++			  return sequenceLength;
    ++			}
    ++	}   }
    ++	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
    ++#endif
    ++
    ++	/* match within prefix */
    ++	if (sequence.offset < 8) {
    ++		/* close range match, overlap */
    ++		static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */
    ++		static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */
    ++		int const sub2 = dec64table[sequence.offset];
    ++		op[0] = match[0];
    ++		op[1] = match[1];
    ++		op[2] = match[2];
    ++		op[3] = match[3];
    ++		match += dec32table[sequence.offset];
    ++		ZSTD_copy4(op+4, match);
    ++		match -= sub2;
    ++	} else {
    ++		ZSTD_copy8(op, match);
    ++	}
    ++	op += 8; match += 8;
    ++
    ++	if (oMatchEnd > oend-(16-MINMATCH)) {
    ++		if (op < oend_w) {
    ++			ZSTD_wildcopy(op, match, oend_w - op);
    ++			match += oend_w - op;
    ++			op = oend_w;
    ++		}
    ++		while (op < oMatchEnd) *op++ = *match++;
    ++	} else {
    ++		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8);   /* works even if matchLength < 8 */
    ++	}
    ++	return sequenceLength;
    ++}
    ++
    ++static size_t ZSTD_decompressSequencesLong(
    ++							   ZSTD_DCtx* dctx,
    ++							   void* dst, size_t maxDstSize,
    ++						 const void* seqStart, size_t seqSize)
    ++{
    ++	const BYTE* ip = (const BYTE*)seqStart;
    ++	const BYTE* const iend = ip + seqSize;
    ++	BYTE* const ostart = (BYTE* const)dst;
    ++	BYTE* const oend = ostart + maxDstSize;
    ++	BYTE* op = ostart;
    ++	const BYTE* litPtr = dctx->litPtr;
    ++	const BYTE* const litEnd = litPtr + dctx->litSize;
    ++	const BYTE* const base = (const BYTE*) (dctx->base);
    ++	const BYTE* const vBase = (const BYTE*) (dctx->vBase);
    ++	const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
    ++	unsigned const windowSize = dctx->fParams.windowSize;
    ++	int nbSeq;
    ++
    ++	/* Build Decoding Tables */
    ++	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    ++		if (ZSTD_isError(seqHSize)) return seqHSize;
    ++		ip += seqHSize;
    ++	}
    ++
    ++	/* Regen sequences */
    ++	if (nbSeq) {
    ++#define STORED_SEQS 4
    ++#define STOSEQ_MASK (STORED_SEQS-1)
    ++#define ADVANCED_SEQS 4
    ++		seq_t sequences[STORED_SEQS];
    ++		int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
    ++		seqState_t seqState;
    ++		int seqNb;
    ++		dctx->fseEntropy = 1;
    ++		{ U32 i; for (i=0; ientropy.rep[i]; }
    ++		seqState.base = base;
    ++		seqState.pos = (size_t)(op-base);
    ++		seqState.gotoDict = (uPtrDiff)dictEnd - (uPtrDiff)base; /* cast to avoid undefined behaviour */
    ++		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
    ++		FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
    ++		FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
    ++		FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
    ++
    ++		/* prepare in advance */
    ++		for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbentropy.rep[i] = (U32)(seqState.prevOffset[i]); }
    ++	}
    ++
    ++	/* last literal segment */
    ++	{   size_t const lastLLSize = litEnd - litPtr;
    ++		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
    ++		memcpy(op, litPtr, lastLLSize);
    ++		op += lastLLSize;
    ++	}
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
    ++							void* dst, size_t dstCapacity,
    ++					  const void* src, size_t srcSize)
    ++{   /* blockType == blockCompressed */
    ++	const BYTE* ip = (const BYTE*)src;
    ++
    ++	if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
    ++
    ++	/* Decode literals section */
    ++	{   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    ++		if (ZSTD_isError(litCSize)) return litCSize;
    ++		ip += litCSize;
    ++		srcSize -= litCSize;
    ++	}
    ++	if (sizeof(size_t) > 4)  /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
    ++							 /* likely because of register pressure */
    ++							 /* if that's the correct cause, then 32-bits ARM should be affected differently */
    ++							 /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
    ++		if (dctx->fParams.windowSize > (1<<23))
    ++			return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
    ++	return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
    ++}
    ++
    ++
    ++static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
    ++{
    ++	if (dst != dctx->previousDstEnd) {   /* not contiguous */
    ++		dctx->dictEnd = dctx->previousDstEnd;
    ++		dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
    ++		dctx->base = dst;
    ++		dctx->previousDstEnd = dst;
    ++	}
    ++}
    ++
    ++size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
    ++							void* dst, size_t dstCapacity,
    ++					  const void* src, size_t srcSize)
    ++{
    ++	size_t dSize;
    ++	ZSTD_checkContinuity(dctx, dst);
    ++	dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
    ++	dctx->previousDstEnd = (char*)dst + dSize;
    ++	return dSize;
    ++}
    ++
    ++
    ++/** ZSTD_insertBlock() :
    ++	insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
    ++size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
    ++{
    ++	ZSTD_checkContinuity(dctx, blockStart);
    ++	dctx->previousDstEnd = (const char*)blockStart + blockSize;
    ++	return blockSize;
    ++}
    ++
    ++
    ++size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
    ++{
    ++	if (length > dstCapacity) return ERROR(dstSize_tooSmall);
    ++	memset(dst, byte, length);
    ++	return length;
    ++}
    ++
    ++/** ZSTD_findFrameCompressedSize() :
    ++ *  compatible with legacy mode
    ++ *  `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
    ++ *  `srcSize` must be at least as large as the frame contained
    ++ *  @return : the compressed size of the frame starting at `src` */
    ++size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
    ++{
    ++	if (srcSize >= ZSTD_skippableHeaderSize &&
    ++			(MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    ++		return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4);
    ++	} else {
    ++		const BYTE* ip = (const BYTE*)src;
    ++		const BYTE* const ipstart = ip;
    ++		size_t remainingSize = srcSize;
    ++		ZSTD_frameParams fParams;
    ++
    ++		size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize);
    ++		if (ZSTD_isError(headerSize)) return headerSize;
    ++
    ++		/* Frame Header */
    ++		{   size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    ++			if (ZSTD_isError(ret)) return ret;
    ++			if (ret > 0) return ERROR(srcSize_wrong);
    ++		}
    ++
    ++		ip += headerSize;
    ++		remainingSize -= headerSize;
    ++
    ++		/* Loop on each block */
    ++		while (1) {
    ++			blockProperties_t blockProperties;
    ++			size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
    ++			if (ZSTD_isError(cBlockSize)) return cBlockSize;
    ++
    ++			if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) return ERROR(srcSize_wrong);
    ++
    ++			ip += ZSTD_blockHeaderSize + cBlockSize;
    ++			remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
    ++
    ++			if (blockProperties.lastBlock) break;
    ++		}
    ++
    ++		if (fParams.checksumFlag) {   /* Frame content checksum */
    ++			if (remainingSize < 4) return ERROR(srcSize_wrong);
    ++			ip += 4;
    ++			remainingSize -= 4;
    ++		}
    ++
    ++		return ip - ipstart;
    ++	}
    ++}
    ++
    ++/*! ZSTD_decompressFrame() :
    ++*   @dctx must be properly initialized */
    ++static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
    ++								 void* dst, size_t dstCapacity,
    ++								 const void** srcPtr, size_t *srcSizePtr)
    ++{
    ++	const BYTE* ip = (const BYTE*)(*srcPtr);
    ++	BYTE* const ostart = (BYTE* const)dst;
    ++	BYTE* const oend = ostart + dstCapacity;
    ++	BYTE* op = ostart;
    ++	size_t remainingSize = *srcSizePtr;
    ++
    ++	/* check */
    ++	if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    ++
    ++	/* Frame Header */
    ++	{   size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
    ++		if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
    ++		if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    ++		CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
    ++		ip += frameHeaderSize; remainingSize -= frameHeaderSize;
    ++	}
    ++
    ++	/* Loop on each block */
    ++	while (1) {
    ++		size_t decodedSize;
    ++		blockProperties_t blockProperties;
    ++		size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
    ++		if (ZSTD_isError(cBlockSize)) return cBlockSize;
    ++
    ++		ip += ZSTD_blockHeaderSize;
    ++		remainingSize -= ZSTD_blockHeaderSize;
    ++		if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
    ++
    ++		switch(blockProperties.blockType)
    ++		{
    ++		case bt_compressed:
    ++			decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
    ++			break;
    ++		case bt_raw :
    ++			decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
    ++			break;
    ++		case bt_rle :
    ++			decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
    ++			break;
    ++		case bt_reserved :
    ++		default:
    ++			return ERROR(corruption_detected);
    ++		}
    ++
    ++		if (ZSTD_isError(decodedSize)) return decodedSize;
    ++		if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, op, decodedSize);
    ++		op += decodedSize;
    ++		ip += cBlockSize;
    ++		remainingSize -= cBlockSize;
    ++		if (blockProperties.lastBlock) break;
    ++	}
    ++
    ++	if (dctx->fParams.checksumFlag) {   /* Frame content checksum verification */
    ++		U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState);
    ++		U32 checkRead;
    ++		if (remainingSize<4) return ERROR(checksum_wrong);
    ++		checkRead = MEM_readLE32(ip);
    ++		if (checkRead != checkCalc) return ERROR(checksum_wrong);
    ++		ip += 4;
    ++		remainingSize -= 4;
    ++	}
    ++
    ++	/* Allow caller to get size read */
    ++	*srcPtr = ip;
    ++	*srcSizePtr = remainingSize;
    ++	return op-ostart;
    ++}
    ++
    ++static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict);
    ++static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict);
    ++
    ++static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
    ++										void* dst, size_t dstCapacity,
    ++								  const void* src, size_t srcSize,
    ++								  const void *dict, size_t dictSize,
    ++								  const ZSTD_DDict* ddict)
    ++{
    ++	void* const dststart = dst;
    ++
    ++	if (ddict) {
    ++		if (dict) {
    ++			/* programmer error, these two cases should be mutually exclusive */
    ++			return ERROR(GENERIC);
    ++		}
    ++
    ++		dict = ZSTD_DDictDictContent(ddict);
    ++		dictSize = ZSTD_DDictDictSize(ddict);
    ++	}
    ++
    ++	while (srcSize >= ZSTD_frameHeaderSize_prefix) {
    ++		U32 magicNumber;
    ++
    ++		magicNumber = MEM_readLE32(src);
    ++		if (magicNumber != ZSTD_MAGICNUMBER) {
    ++			if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    ++				size_t skippableSize;
    ++				if (srcSize < ZSTD_skippableHeaderSize)
    ++					return ERROR(srcSize_wrong);
    ++				skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    ++								ZSTD_skippableHeaderSize;
    ++				if (srcSize < skippableSize) {
    ++					return ERROR(srcSize_wrong);
    ++				}
    ++
    ++				src = (const BYTE *)src + skippableSize;
    ++				srcSize -= skippableSize;
    ++				continue;
    ++			} else {
    ++				return ERROR(prefix_unknown);
    ++			}
    ++		}
    ++
    ++		if (ddict) {
    ++			/* we were called from ZSTD_decompress_usingDDict */
    ++			ZSTD_refDDict(dctx, ddict);
    ++		} else {
    ++			/* this will initialize correctly with no dict if dict == NULL, so
    ++			 * use this in all cases but ddict */
    ++			CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
    ++		}
    ++		ZSTD_checkContinuity(dctx, dst);
    ++
    ++		{   const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
    ++													&src, &srcSize);
    ++			if (ZSTD_isError(res)) return res;
    ++			/* don't need to bounds check this, ZSTD_decompressFrame will have
    ++			 * already */
    ++			dst = (BYTE*)dst + res;
    ++			dstCapacity -= res;
    ++		}
    ++	}
    ++
    ++	if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */
    ++
    ++	return (BYTE*)dst - (BYTE*)dststart;
    ++}
    ++
    ++size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void *dict, size_t dictSize)
    ++{
    ++	return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
    ++}
    ++
    ++
    ++size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
    ++}
    ++
    ++
    ++/*-**************************************
    ++*   Advanced Streaming Decompression API
    ++*   Bufferless and synchronous
    ++****************************************/
    ++size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
    ++
    ++ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
    ++	switch(dctx->stage)
    ++	{
    ++	default:   /* should not happen */
    ++	case ZSTDds_getFrameHeaderSize:
    ++	case ZSTDds_decodeFrameHeader:
    ++		return ZSTDnit_frameHeader;
    ++	case ZSTDds_decodeBlockHeader:
    ++		return ZSTDnit_blockHeader;
    ++	case ZSTDds_decompressBlock:
    ++		return ZSTDnit_block;
    ++	case ZSTDds_decompressLastBlock:
    ++		return ZSTDnit_lastBlock;
    ++	case ZSTDds_checkChecksum:
    ++		return ZSTDnit_checksum;
    ++	case ZSTDds_decodeSkippableHeader:
    ++	case ZSTDds_skipFrame:
    ++		return ZSTDnit_skippableFrame;
    ++	}
    ++}
    ++
    ++int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }   /* for zbuff */
    ++
    ++/** ZSTD_decompressContinue() :
    ++*   @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
    ++*             or an error code, which can be tested using ZSTD_isError() */
    ++size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	/* Sanity check */
    ++	if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
    ++	if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
    ++
    ++	switch (dctx->stage)
    ++	{
    ++	case ZSTDds_getFrameHeaderSize :
    ++		if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);      /* impossible */
    ++		if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */
    ++			memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
    ++			dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix;  /* magic number + skippable frame length */
    ++			dctx->stage = ZSTDds_decodeSkippableHeader;
    ++			return 0;
    ++		}
    ++		dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
    ++		if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
    ++		memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
    ++		if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
    ++			dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
    ++			dctx->stage = ZSTDds_decodeFrameHeader;
    ++			return 0;
    ++		}
    ++		dctx->expected = 0;   /* not necessary to copy more */
    ++
    ++	case ZSTDds_decodeFrameHeader:
    ++		memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    ++		CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
    ++		dctx->expected = ZSTD_blockHeaderSize;
    ++		dctx->stage = ZSTDds_decodeBlockHeader;
    ++		return 0;
    ++
    ++	case ZSTDds_decodeBlockHeader:
    ++		{   blockProperties_t bp;
    ++			size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
    ++			if (ZSTD_isError(cBlockSize)) return cBlockSize;
    ++			dctx->expected = cBlockSize;
    ++			dctx->bType = bp.blockType;
    ++			dctx->rleSize = bp.origSize;
    ++			if (cBlockSize) {
    ++				dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
    ++				return 0;
    ++			}
    ++			/* empty block */
    ++			if (bp.lastBlock) {
    ++				if (dctx->fParams.checksumFlag) {
    ++					dctx->expected = 4;
    ++					dctx->stage = ZSTDds_checkChecksum;
    ++				} else {
    ++					dctx->expected = 0; /* end of frame */
    ++					dctx->stage = ZSTDds_getFrameHeaderSize;
    ++				}
    ++			} else {
    ++				dctx->expected = 3;  /* go directly to next header */
    ++				dctx->stage = ZSTDds_decodeBlockHeader;
    ++			}
    ++			return 0;
    ++		}
    ++	case ZSTDds_decompressLastBlock:
    ++	case ZSTDds_decompressBlock:
    ++		{   size_t rSize;
    ++			switch(dctx->bType)
    ++			{
    ++			case bt_compressed:
    ++				rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
    ++				break;
    ++			case bt_raw :
    ++				rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
    ++				break;
    ++			case bt_rle :
    ++				rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
    ++				break;
    ++			case bt_reserved :   /* should never happen */
    ++			default:
    ++				return ERROR(corruption_detected);
    ++			}
    ++			if (ZSTD_isError(rSize)) return rSize;
    ++			if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, dst, rSize);
    ++
    ++			if (dctx->stage == ZSTDds_decompressLastBlock) {   /* end of frame */
    ++				if (dctx->fParams.checksumFlag) {  /* another round for frame checksum */
    ++					dctx->expected = 4;
    ++					dctx->stage = ZSTDds_checkChecksum;
    ++				} else {
    ++					dctx->expected = 0;   /* ends here */
    ++					dctx->stage = ZSTDds_getFrameHeaderSize;
    ++				}
    ++			} else {
    ++				dctx->stage = ZSTDds_decodeBlockHeader;
    ++				dctx->expected = ZSTD_blockHeaderSize;
    ++				dctx->previousDstEnd = (char*)dst + rSize;
    ++			}
    ++			return rSize;
    ++		}
    ++	case ZSTDds_checkChecksum:
    ++		{   U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    ++			U32 const check32 = MEM_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
    ++			if (check32 != h32) return ERROR(checksum_wrong);
    ++			dctx->expected = 0;
    ++			dctx->stage = ZSTDds_getFrameHeaderSize;
    ++			return 0;
    ++		}
    ++	case ZSTDds_decodeSkippableHeader:
    ++		{   memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    ++			dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
    ++			dctx->stage = ZSTDds_skipFrame;
    ++			return 0;
    ++		}
    ++	case ZSTDds_skipFrame:
    ++		{   dctx->expected = 0;
    ++			dctx->stage = ZSTDds_getFrameHeaderSize;
    ++			return 0;
    ++		}
    ++	default:
    ++		return ERROR(GENERIC);   /* impossible */
    ++	}
    ++}
    ++
    ++
    ++static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    ++{
    ++	dctx->dictEnd = dctx->previousDstEnd;
    ++	dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
    ++	dctx->base = dict;
    ++	dctx->previousDstEnd = (const char*)dict + dictSize;
    ++	return 0;
    ++}
    ++
    ++/* ZSTD_loadEntropy() :
    ++ * dict : must point at beginning of a valid zstd dictionary
    ++ * @return : size of entropy tables read */
    ++static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const dict, size_t const dictSize)
    ++{
    ++	const BYTE* dictPtr = (const BYTE*)dict;
    ++	const BYTE* const dictEnd = dictPtr + dictSize;
    ++
    ++	if (dictSize <= 8) return ERROR(dictionary_corrupted);
    ++	dictPtr += 8;   /* skip header = magic + dictID */
    ++
    ++
    ++	{   size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
    ++		if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
    ++		dictPtr += hSize;
    ++	}
    ++
    ++	{   short offcodeNCount[MaxOff+1];
    ++		U32 offcodeMaxValue = MaxOff, offcodeLog;
    ++		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    ++		CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
    ++		dictPtr += offcodeHeaderSize;
    ++	}
    ++
    ++	{   short matchlengthNCount[MaxML+1];
    ++		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
    ++		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
    ++		CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
    ++		dictPtr += matchlengthHeaderSize;
    ++	}
    ++
    ++	{   short litlengthNCount[MaxLL+1];
    ++		unsigned litlengthMaxValue = MaxLL, litlengthLog;
    ++		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
    ++		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    ++		if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
    ++		CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
    ++		dictPtr += litlengthHeaderSize;
    ++	}
    ++
    ++	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    ++	{   int i;
    ++		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
    ++		for (i=0; i<3; i++) {
    ++			U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
    ++			if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted);
    ++			entropy->rep[i] = rep;
    ++	}   }
    ++
    ++	return dictPtr - (const BYTE*)dict;
    ++}
    ++
    ++static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    ++{
    ++	if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
    ++	{   U32 const magic = MEM_readLE32(dict);
    ++		if (magic != ZSTD_DICT_MAGIC) {
    ++			return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
    ++	}   }
    ++	dctx->dictID = MEM_readLE32((const char*)dict + 4);
    ++
    ++	/* load entropy tables */
    ++	{   size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    ++		if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
    ++		dict = (const char*)dict + eSize;
    ++		dictSize -= eSize;
    ++	}
    ++	dctx->litEntropy = dctx->fseEntropy = 1;
    ++
    ++	/* reference dictionary content */
    ++	return ZSTD_refDictContent(dctx, dict, dictSize);
    ++}
    ++
    ++size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    ++{
    ++	CHECK_F(ZSTD_decompressBegin(dctx));
    ++	if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
    ++	return 0;
    ++}
    ++
    ++
    ++/* ======   ZSTD_DDict   ====== */
    ++
    ++struct ZSTD_DDict_s {
    ++	void* dictBuffer;
    ++	const void* dictContent;
    ++	size_t dictSize;
    ++	ZSTD_entropyTables_t entropy;
    ++	U32 dictID;
    ++	U32 entropyPresent;
    ++	ZSTD_customMem cMem;
    ++};  /* typedef'd to ZSTD_DDict within "zstd.h" */
    ++
    ++size_t ZSTD_DDictWorkspaceBound(void)
    ++{
    ++	return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DDict));
    ++}
    ++
    ++static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict)
    ++{
    ++	return ddict->dictContent;
    ++}
    ++
    ++static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict)
    ++{
    ++	return ddict->dictSize;
    ++}
    ++
    ++static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
    ++{
    ++	ZSTD_decompressBegin(dstDCtx);  /* init */
    ++	if (ddict) {   /* support refDDict on NULL */
    ++		dstDCtx->dictID = ddict->dictID;
    ++		dstDCtx->base = ddict->dictContent;
    ++		dstDCtx->vBase = ddict->dictContent;
    ++		dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
    ++		dstDCtx->previousDstEnd = dstDCtx->dictEnd;
    ++		if (ddict->entropyPresent) {
    ++			dstDCtx->litEntropy = 1;
    ++			dstDCtx->fseEntropy = 1;
    ++			dstDCtx->LLTptr = ddict->entropy.LLTable;
    ++			dstDCtx->MLTptr = ddict->entropy.MLTable;
    ++			dstDCtx->OFTptr = ddict->entropy.OFTable;
    ++			dstDCtx->HUFptr = ddict->entropy.hufTable;
    ++			dstDCtx->entropy.rep[0] = ddict->entropy.rep[0];
    ++			dstDCtx->entropy.rep[1] = ddict->entropy.rep[1];
    ++			dstDCtx->entropy.rep[2] = ddict->entropy.rep[2];
    ++		} else {
    ++			dstDCtx->litEntropy = 0;
    ++			dstDCtx->fseEntropy = 0;
    ++		}
    ++	}
    ++}
    ++
    ++static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
    ++{
    ++	ddict->dictID = 0;
    ++	ddict->entropyPresent = 0;
    ++	if (ddict->dictSize < 8) return 0;
    ++	{   U32 const magic = MEM_readLE32(ddict->dictContent);
    ++		if (magic != ZSTD_DICT_MAGIC) return 0;   /* pure content mode */
    ++	}
    ++	ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
    ++
    ++	/* load entropy tables */
    ++	CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
    ++	ddict->entropyPresent = 1;
    ++	return 0;
    ++}
    ++
    ++
    ++static ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
    ++{
    ++	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    ++
    ++	{   ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
    ++		if (!ddict) return NULL;
    ++		ddict->cMem = customMem;
    ++
    ++		if ((byReference) || (!dict) || (!dictSize)) {
    ++			ddict->dictBuffer = NULL;
    ++			ddict->dictContent = dict;
    ++		} else {
    ++			void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    ++			if (!internalBuffer) { ZSTD_freeDDict(ddict); return NULL; }
    ++			memcpy(internalBuffer, dict, dictSize);
    ++			ddict->dictBuffer = internalBuffer;
    ++			ddict->dictContent = internalBuffer;
    ++		}
    ++		ddict->dictSize = dictSize;
    ++		ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    ++		/* parse dictionary content */
    ++		{   size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
    ++			if (ZSTD_isError(errorCode)) {
    ++				ZSTD_freeDDict(ddict);
    ++				return NULL;
    ++		}   }
    ++
    ++		return ddict;
    ++	}
    ++}
    ++
    ++/*! ZSTD_initDDict() :
    ++*   Create a digested dictionary, to start decompression without startup delay.
    ++*   `dict` content is copied inside DDict.
    ++*   Consequently, `dict` can be released after `ZSTD_DDict` creation */
    ++ZSTD_DDict* ZSTD_initDDict(const void* dict, size_t dictSize, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	return ZSTD_createDDict_advanced(dict, dictSize, 1, stackMem);
    ++}
    ++
    ++
    ++size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
    ++{
    ++	if (ddict==NULL) return 0;   /* support free on NULL */
    ++	{   ZSTD_customMem const cMem = ddict->cMem;
    ++		ZSTD_free(ddict->dictBuffer, cMem);
    ++		ZSTD_free(ddict, cMem);
    ++		return 0;
    ++	}
    ++}
    ++
    ++/*! ZSTD_getDictID_fromDict() :
    ++ *  Provides the dictID stored within dictionary.
    ++ *  if @return == 0, the dictionary is not conformant with Zstandard specification.
    ++ *  It can still be loaded, but as a content-only dictionary. */
    ++unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
    ++{
    ++	if (dictSize < 8) return 0;
    ++	if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
    ++	return MEM_readLE32((const char*)dict + 4);
    ++}
    ++
    ++/*! ZSTD_getDictID_fromDDict() :
    ++ *  Provides the dictID of the dictionary loaded into `ddict`.
    ++ *  If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
    ++ *  Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
    ++unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
    ++{
    ++	if (ddict==NULL) return 0;
    ++	return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
    ++}
    ++
    ++/*! ZSTD_getDictID_fromFrame() :
    ++ *  Provides the dictID required to decompressed the frame stored within `src`.
    ++ *  If @return == 0, the dictID could not be decoded.
    ++ *  This could for one of the following reasons :
    ++ *  - The frame does not require a dictionary to be decoded (most common case).
    ++ *  - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
    ++ *    Note : this use case also happens when using a non-conformant dictionary.
    ++ *  - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
    ++ *  - This is not a Zstandard frame.
    ++ *  When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
    ++unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
    ++{
    ++	ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
    ++	size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
    ++	if (ZSTD_isError(hError)) return 0;
    ++	return zfp.dictID;
    ++}
    ++
    ++
    ++/*! ZSTD_decompress_usingDDict() :
    ++*   Decompression using a pre-digested Dictionary
    ++*   Use dictionary without significant overhead. */
    ++size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
    ++								  void* dst, size_t dstCapacity,
    ++							const void* src, size_t srcSize,
    ++							const ZSTD_DDict* ddict)
    ++{
    ++	/* pass content and size in case legacy frames are encountered */
    ++	return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
    ++									 NULL, 0,
    ++									 ddict);
    ++}
    ++
    ++
    ++/*=====================================
    ++*   Streaming decompression
    ++*====================================*/
    ++
    ++typedef enum { zdss_init, zdss_loadHeader,
    ++			   zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
    ++
    ++/* *** Resource management *** */
    ++struct ZSTD_DStream_s {
    ++	ZSTD_DCtx* dctx;
    ++	ZSTD_DDict* ddictLocal;
    ++	const ZSTD_DDict* ddict;
    ++	ZSTD_frameParams fParams;
    ++	ZSTD_dStreamStage stage;
    ++	char*  inBuff;
    ++	size_t inBuffSize;
    ++	size_t inPos;
    ++	size_t maxWindowSize;
    ++	char*  outBuff;
    ++	size_t outBuffSize;
    ++	size_t outStart;
    ++	size_t outEnd;
    ++	size_t blockSize;
    ++	BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];   /* tmp buffer to store frame header */
    ++	size_t lhSize;
    ++	ZSTD_customMem customMem;
    ++	void* legacyContext;
    ++	U32 previousLegacyVersion;
    ++	U32 legacyVersion;
    ++	U32 hostageByte;
    ++};   /* typedef'd to ZSTD_DStream within "zstd.h" */
    ++
    ++size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize) {
    ++	size_t const blockSize = MIN(maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    ++	size_t const inBuffSize = blockSize;
    ++	size_t const outBuffSize = maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
    ++	return ZSTD_DCtxWorkspaceBound() + ZSTD_ALIGN(sizeof(ZSTD_DStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize);
    ++}
    ++
    ++static ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
    ++{
    ++	ZSTD_DStream* zds;
    ++
    ++	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    ++
    ++	zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
    ++	if (zds==NULL) return NULL;
    ++	memset(zds, 0, sizeof(ZSTD_DStream));
    ++	memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
    ++	zds->dctx = ZSTD_createDCtx_advanced(customMem);
    ++	if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
    ++	zds->stage = zdss_init;
    ++	zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
    ++	return zds;
    ++}
    ++
    ++ZSTD_DStream* ZSTD_initDStream(size_t maxWindowSize, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    ++	ZSTD_DStream* zds = ZSTD_createDStream_advanced(stackMem);
    ++	if (!zds) { return NULL; }
    ++
    ++	zds->maxWindowSize = maxWindowSize;
    ++	zds->stage = zdss_loadHeader;
    ++	zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
    ++	ZSTD_freeDDict(zds->ddictLocal);
    ++	zds->ddictLocal = NULL;
    ++	zds->ddict = zds->ddictLocal;
    ++	zds->legacyVersion = 0;
    ++	zds->hostageByte = 0;
    ++	return zds;
    ++}
    ++
    ++ZSTD_DStream* ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict* ddict, void* workspace, size_t workspaceSize)
    ++{
    ++	ZSTD_DStream* zds = ZSTD_initDStream(maxWindowSize, workspace, workspaceSize);
    ++	if (zds) {
    ++		zds->ddict = ddict;
    ++	}
    ++	return zds;
    ++}
    ++
    ++size_t ZSTD_freeDStream(ZSTD_DStream* zds)
    ++{
    ++	if (zds==NULL) return 0;   /* support free on null */
    ++	{   ZSTD_customMem const cMem = zds->customMem;
    ++		ZSTD_freeDCtx(zds->dctx);
    ++		zds->dctx = NULL;
    ++		ZSTD_freeDDict(zds->ddictLocal);
    ++		zds->ddictLocal = NULL;
    ++		ZSTD_free(zds->inBuff, cMem);
    ++		zds->inBuff = NULL;
    ++		ZSTD_free(zds->outBuff, cMem);
    ++		zds->outBuff = NULL;
    ++		ZSTD_free(zds, cMem);
    ++		return 0;
    ++	}
    ++}
    ++
    ++
    ++/* *** Initialization *** */
    ++
    ++size_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
    ++size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    ++
    ++size_t ZSTD_resetDStream(ZSTD_DStream* zds)
    ++{
    ++	zds->stage = zdss_loadHeader;
    ++	zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
    ++	zds->legacyVersion = 0;
    ++	zds->hostageByte = 0;
    ++	return ZSTD_frameHeaderSize_prefix;
    ++}
    ++
    ++/* *****   Decompression   ***** */
    ++
    ++MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    ++{
    ++	size_t const length = MIN(dstCapacity, srcSize);
    ++	memcpy(dst, src, length);
    ++	return length;
    ++}
    ++
    ++
    ++size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
    ++{
    ++	const char* const istart = (const char*)(input->src) + input->pos;
    ++	const char* const iend = (const char*)(input->src) + input->size;
    ++	const char* ip = istart;
    ++	char* const ostart = (char*)(output->dst) + output->pos;
    ++	char* const oend = (char*)(output->dst) + output->size;
    ++	char* op = ostart;
    ++	U32 someMoreWork = 1;
    ++
    ++	while (someMoreWork) {
    ++		switch(zds->stage)
    ++		{
    ++		case zdss_init :
    ++			ZSTD_resetDStream(zds);   /* transparent reset on starting decoding a new frame */
    ++			/* fall-through */
    ++
    ++		case zdss_loadHeader :
    ++			{   size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    ++				if (ZSTD_isError(hSize))
    ++				return hSize;
    ++				if (hSize != 0) {   /* need more input */
    ++					size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */
    ++					if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */
    ++						memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
    ++						zds->lhSize += iend-ip;
    ++						input->pos = input->size;
    ++						return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize;   /* remaining header bytes + next block header */
    ++					}
    ++					memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
    ++					break;
    ++			}   }
    ++
    ++			/* check for single-pass mode opportunity */
    ++			if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    ++				&& (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
    ++				size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
    ++				if (cSize <= (size_t)(iend-istart)) {
    ++					size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
    ++					if (ZSTD_isError(decompressedSize)) return decompressedSize;
    ++					ip = istart + cSize;
    ++					op += decompressedSize;
    ++					zds->dctx->expected = 0;
    ++					zds->stage = zdss_init;
    ++					someMoreWork = 0;
    ++					break;
    ++			}   }
    ++
    ++			/* Consume header */
    ++			ZSTD_refDDict(zds->dctx, zds->ddict);
    ++			{   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    ++				CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    ++				{   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++					CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
    ++			}   }
    ++
    ++			zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
    ++			if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
    ++
    ++			/* Adapt buffer sizes to frame header instructions */
    ++			{   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    ++				size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
    ++				zds->blockSize = blockSize;
    ++				if (zds->inBuffSize < blockSize) {
    ++					ZSTD_free(zds->inBuff, zds->customMem);
    ++					zds->inBuffSize = blockSize;
    ++					zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    ++					if (zds->inBuff == NULL) return ERROR(memory_allocation);
    ++				}
    ++				if (zds->outBuffSize < neededOutSize) {
    ++					ZSTD_free(zds->outBuff, zds->customMem);
    ++					zds->outBuffSize = neededOutSize;
    ++					zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
    ++					if (zds->outBuff == NULL) return ERROR(memory_allocation);
    ++			}   }
    ++			zds->stage = zdss_read;
    ++			/* pass-through */
    ++
    ++		case zdss_read:
    ++			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++				if (neededInSize==0) {  /* end of frame */
    ++					zds->stage = zdss_init;
    ++					someMoreWork = 0;
    ++					break;
    ++				}
    ++				if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
    ++					const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    ++					size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    ++						zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
    ++						ip, neededInSize);
    ++					if (ZSTD_isError(decodedSize)) return decodedSize;
    ++					ip += neededInSize;
    ++					if (!decodedSize && !isSkipFrame) break;   /* this was just a header */
    ++					zds->outEnd = zds->outStart + decodedSize;
    ++					zds->stage = zdss_flush;
    ++					break;
    ++				}
    ++				if (ip==iend) { someMoreWork = 0; break; }   /* no more input */
    ++				zds->stage = zdss_load;
    ++				/* pass-through */
    ++			}
    ++
    ++		case zdss_load:
    ++			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++				size_t const toLoad = neededInSize - zds->inPos;   /* should always be <= remaining space within inBuff */
    ++				size_t loadedSize;
    ++				if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected);   /* should never happen */
    ++				loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
    ++				ip += loadedSize;
    ++				zds->inPos += loadedSize;
    ++				if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */
    ++
    ++				/* decode loaded input */
    ++				{  const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    ++				   size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    ++						zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
    ++						zds->inBuff, neededInSize);
    ++					if (ZSTD_isError(decodedSize)) return decodedSize;
    ++					zds->inPos = 0;   /* input is consumed */
    ++					if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; }   /* this was just a header */
    ++					zds->outEnd = zds->outStart +  decodedSize;
    ++					zds->stage = zdss_flush;
    ++					/* pass-through */
    ++			}   }
    ++
    ++		case zdss_flush:
    ++			{   size_t const toFlushSize = zds->outEnd - zds->outStart;
    ++				size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
    ++				op += flushedSize;
    ++				zds->outStart += flushedSize;
    ++				if (flushedSize == toFlushSize) {  /* flush completed */
    ++					zds->stage = zdss_read;
    ++					if (zds->outStart + zds->blockSize > zds->outBuffSize)
    ++						zds->outStart = zds->outEnd = 0;
    ++					break;
    ++				}
    ++				/* cannot complete flush */
    ++				someMoreWork = 0;
    ++				break;
    ++			}
    ++		default: return ERROR(GENERIC);   /* impossible */
    ++	}   }
    ++
    ++	/* result */
    ++	input->pos += (size_t)(ip-istart);
    ++	output->pos += (size_t)(op-ostart);
    ++	{   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++		if (!nextSrcSizeHint) {   /* frame fully decoded */
    ++			if (zds->outEnd == zds->outStart) {  /* output fully flushed */
    ++				if (zds->hostageByte) {
    ++					if (input->pos >= input->size) { zds->stage = zdss_read; return 1; }  /* can't release hostage (not present) */
    ++					input->pos++;  /* release hostage */
    ++				}
    ++				return 0;
    ++			}
    ++			if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
    ++				input->pos--;   /* note : pos > 0, otherwise, impossible to finish reading last block */
    ++				zds->hostageByte=1;
    ++			}
    ++			return 1;
    ++		}
    ++		nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block);   /* preload header of next block */
    ++		if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC);   /* should never happen */
    ++		nextSrcSizeHint -= zds->inPos;   /* already loaded*/
    ++		return nextSrcSizeHint;
    ++	}
    ++}
    ++
    ++EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initDCtx);
    ++EXPORT_SYMBOL(ZSTD_decompressDCtx);
    ++EXPORT_SYMBOL(ZSTD_decompress_usingDict);
    ++
    ++EXPORT_SYMBOL(ZSTD_DDictWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initDDict);
    ++EXPORT_SYMBOL(ZSTD_decompress_usingDDict);
    ++
    ++EXPORT_SYMBOL(ZSTD_DStreamWorkspaceBound);
    ++EXPORT_SYMBOL(ZSTD_initDStream);
    ++EXPORT_SYMBOL(ZSTD_initDStream_usingDDict);
    ++EXPORT_SYMBOL(ZSTD_resetDStream);
    ++EXPORT_SYMBOL(ZSTD_decompressStream);
    ++EXPORT_SYMBOL(ZSTD_DStreamInSize);
    ++EXPORT_SYMBOL(ZSTD_DStreamOutSize);
    ++
    ++EXPORT_SYMBOL(ZSTD_findFrameCompressedSize);
    ++EXPORT_SYMBOL(ZSTD_getFrameContentSize);
    ++EXPORT_SYMBOL(ZSTD_findDecompressedSize);
    ++
    ++EXPORT_SYMBOL(ZSTD_isFrame);
    ++EXPORT_SYMBOL(ZSTD_getDictID_fromDict);
    ++EXPORT_SYMBOL(ZSTD_getDictID_fromDDict);
    ++EXPORT_SYMBOL(ZSTD_getDictID_fromFrame);
    ++
    ++EXPORT_SYMBOL(ZSTD_getFrameParams);
    ++EXPORT_SYMBOL(ZSTD_decompressBegin);
    ++EXPORT_SYMBOL(ZSTD_decompressBegin_usingDict);
    ++EXPORT_SYMBOL(ZSTD_copyDCtx);
    ++EXPORT_SYMBOL(ZSTD_nextSrcSizeToDecompress);
    ++EXPORT_SYMBOL(ZSTD_decompressContinue);
    ++EXPORT_SYMBOL(ZSTD_nextInputType);
    ++
    ++EXPORT_SYMBOL(ZSTD_decompressBlock);
    ++EXPORT_SYMBOL(ZSTD_insertBlock);
    ++
    ++MODULE_LICENSE("BSD");
    ++MODULE_DESCRIPTION("Zstd Decompressor");
    +diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c
    +new file mode 100644
    +index 0000000..68d88082
    +--- /dev/null
    ++++ b/lib/zstd/entropy_common.c
    +@@ -0,0 +1,217 @@
    ++/*
    ++   Common functions of New Generation Entropy library
    ++   Copyright (C) 2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++	You can contact the author at :
    ++	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    ++*************************************************************************** */
    ++
    ++/* *************************************
    ++*  Dependencies
    ++***************************************/
    ++#include "mem.h"
    ++#include "error_private.h"       /* ERR_*, ERROR */
    ++#include "fse.h"
    ++#include "huf.h"
    ++
    ++
    ++/*===   Version   ===*/
    ++unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
    ++
    ++
    ++/*===   Error Management   ===*/
    ++unsigned FSE_isError(size_t code) { return ERR_isError(code); }
    ++
    ++unsigned HUF_isError(size_t code) { return ERR_isError(code); }
    ++
    ++
    ++/*-**************************************************************
    ++*  FSE NCount encoding-decoding
    ++****************************************************************/
    ++size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
    ++				 const void* headerBuffer, size_t hbSize)
    ++{
    ++	const BYTE* const istart = (const BYTE*) headerBuffer;
    ++	const BYTE* const iend = istart + hbSize;
    ++	const BYTE* ip = istart;
    ++	int nbBits;
    ++	int remaining;
    ++	int threshold;
    ++	U32 bitStream;
    ++	int bitCount;
    ++	unsigned charnum = 0;
    ++	int previous0 = 0;
    ++
    ++	if (hbSize < 4) return ERROR(srcSize_wrong);
    ++	bitStream = MEM_readLE32(ip);
    ++	nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG;   /* extract tableLog */
    ++	if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
    ++	bitStream >>= 4;
    ++	bitCount = 4;
    ++	*tableLogPtr = nbBits;
    ++	remaining = (1<1) & (charnum<=*maxSVPtr)) {
    ++		if (previous0) {
    ++			unsigned n0 = charnum;
    ++			while ((bitStream & 0xFFFF) == 0xFFFF) {
    ++				n0 += 24;
    ++				if (ip < iend-5) {
    ++					ip += 2;
    ++					bitStream = MEM_readLE32(ip) >> bitCount;
    ++				} else {
    ++					bitStream >>= 16;
    ++					bitCount   += 16;
    ++			}   }
    ++			while ((bitStream & 3) == 3) {
    ++				n0 += 3;
    ++				bitStream >>= 2;
    ++				bitCount += 2;
    ++			}
    ++			n0 += bitStream & 3;
    ++			bitCount += 2;
    ++			if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
    ++			while (charnum < n0) normalizedCounter[charnum++] = 0;
    ++			if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
    ++				ip += bitCount>>3;
    ++				bitCount &= 7;
    ++				bitStream = MEM_readLE32(ip) >> bitCount;
    ++			} else {
    ++				bitStream >>= 2;
    ++		}   }
    ++		{   int const max = (2*threshold-1) - remaining;
    ++			int count;
    ++
    ++			if ((bitStream & (threshold-1)) < (U32)max) {
    ++				count = bitStream & (threshold-1);
    ++				bitCount += nbBits-1;
    ++			} else {
    ++				count = bitStream & (2*threshold-1);
    ++				if (count >= threshold) count -= max;
    ++				bitCount += nbBits;
    ++			}
    ++
    ++			count--;   /* extra accuracy */
    ++			remaining -= count < 0 ? -count : count;   /* -1 means +1 */
    ++			normalizedCounter[charnum++] = (short)count;
    ++			previous0 = !count;
    ++			while (remaining < threshold) {
    ++				nbBits--;
    ++				threshold >>= 1;
    ++			}
    ++
    ++			if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
    ++				ip += bitCount>>3;
    ++				bitCount &= 7;
    ++			} else {
    ++				bitCount -= (int)(8 * (iend - 4 - ip));
    ++				ip = iend - 4;
    ++			}
    ++			bitStream = MEM_readLE32(ip) >> (bitCount & 31);
    ++	}   }   /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
    ++	if (remaining != 1) return ERROR(corruption_detected);
    ++	if (bitCount > 32) return ERROR(corruption_detected);
    ++	*maxSVPtr = charnum-1;
    ++
    ++	ip += (bitCount+7)>>3;
    ++	return ip-istart;
    ++}
    ++
    ++
    ++/*! HUF_readStats() :
    ++	Read compact Huffman tree, saved by HUF_writeCTable().
    ++	`huffWeight` is destination buffer.
    ++	`rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32.
    ++	@return : size read from `src` , or an error Code .
    ++	Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
    ++*/
    ++size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
    ++					 U32* nbSymbolsPtr, U32* tableLogPtr,
    ++					 const void* src, size_t srcSize)
    ++{
    ++	U32 weightTotal;
    ++	const BYTE* ip = (const BYTE*) src;
    ++	size_t iSize;
    ++	size_t oSize;
    ++
    ++	if (!srcSize) return ERROR(srcSize_wrong);
    ++	iSize = ip[0];
    ++	/* memset(huffWeight, 0, hwSize);   *//* is not necessary, even though some analyzer complain ... */
    ++
    ++	if (iSize >= 128) {  /* special header */
    ++		oSize = iSize - 127;
    ++		iSize = ((oSize+1)/2);
    ++		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
    ++		if (oSize >= hwSize) return ERROR(corruption_detected);
    ++		ip += 1;
    ++		{   U32 n;
    ++			for (n=0; n> 4;
    ++				huffWeight[n+1] = ip[n/2] & 15;
    ++	}   }   }
    ++	else  {   /* header compressed with FSE (normal case) */
    ++		FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)];  /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
    ++		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
    ++		oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6);   /* max (hwSize-1) values decoded, as last one is implied */
    ++		if (FSE_isError(oSize)) return oSize;
    ++	}
    ++
    ++	/* collect weight stats */
    ++	memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
    ++	weightTotal = 0;
    ++	{   U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
    ++			rankStats[huffWeight[n]]++;
    ++			weightTotal += (1 << huffWeight[n]) >> 1;
    ++	}   }
    ++	if (weightTotal == 0) return ERROR(corruption_detected);
    ++
    ++	/* get last non-null symbol weight (implied, total must be 2^n) */
    ++	{   U32 const tableLog = BIT_highbit32(weightTotal) + 1;
    ++		if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
    ++		*tableLogPtr = tableLog;
    ++		/* determine last weight */
    ++		{   U32 const total = 1 << tableLog;
    ++			U32 const rest = total - weightTotal;
    ++			U32 const verif = 1 << BIT_highbit32(rest);
    ++			U32 const lastWeight = BIT_highbit32(rest) + 1;
    ++			if (verif != rest) return ERROR(corruption_detected);    /* last value must be a clean power of 2 */
    ++			huffWeight[oSize] = (BYTE)lastWeight;
    ++			rankStats[lastWeight]++;
    ++	}   }
    ++
    ++	/* check tree construction validity */
    ++	if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected);   /* by construction : at least 2 elts of rank 1, must be even */
    ++
    ++	/* results */
    ++	*nbSymbolsPtr = (U32)(oSize+1);
    ++	return iSize+1;
    ++}
    +diff --git a/lib/zstd/error_private.h b/lib/zstd/error_private.h
    +new file mode 100644
    +index 0000000..8cf148b
    +--- /dev/null
    ++++ b/lib/zstd/error_private.h
    +@@ -0,0 +1,44 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++/* Note : this module is expected to remain private, do not expose it */
    ++
    ++#ifndef ERROR_H_MODULE
    ++#define ERROR_H_MODULE
    ++
    ++/* ****************************************
    ++*  Dependencies
    ++******************************************/
    ++#include         /* size_t */
    ++#include   /* enum list */
    ++
    ++
    ++/* ****************************************
    ++*  Compiler-specific
    ++******************************************/
    ++#define ERR_STATIC static __attribute__((unused))
    ++
    ++
    ++/*-****************************************
    ++*  Customization (error_public.h)
    ++******************************************/
    ++typedef ZSTD_ErrorCode ERR_enum;
    ++#define PREFIX(name) ZSTD_error_##name
    ++
    ++
    ++/*-****************************************
    ++*  Error codes handling
    ++******************************************/
    ++#define ERROR(name) ((size_t)-PREFIX(name))
    ++
    ++ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
    ++
    ++ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
    ++
    ++#endif /* ERROR_H_MODULE */
    +diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h
    +new file mode 100644
    +index 0000000..14fa439
    +--- /dev/null
    ++++ b/lib/zstd/fse.h
    +@@ -0,0 +1,606 @@
    ++/* ******************************************************************
    ++   FSE : Finite State Entropy codec
    ++   Public Prototypes declaration
    ++   Copyright (C) 2013-2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++   You can contact the author at :
    ++   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++****************************************************************** */
    ++#ifndef FSE_H
    ++#define FSE_H
    ++
    ++
    ++/*-*****************************************
    ++*  Dependencies
    ++******************************************/
    ++#include     /* size_t, ptrdiff_t */
    ++
    ++
    ++/*-*****************************************
    ++*  FSE_PUBLIC_API : control library symbols visibility
    ++******************************************/
    ++#define FSE_PUBLIC_API
    ++
    ++/*------   Version   ------*/
    ++#define FSE_VERSION_MAJOR    0
    ++#define FSE_VERSION_MINOR    9
    ++#define FSE_VERSION_RELEASE  0
    ++
    ++#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
    ++#define FSE_QUOTE(str) #str
    ++#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
    ++#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
    ++
    ++#define FSE_VERSION_NUMBER  (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
    ++FSE_PUBLIC_API unsigned FSE_versionNumber(void);   /**< library version number; to be used when checking dll version */
    ++
    ++/*-*****************************************
    ++*  Tool functions
    ++******************************************/
    ++FSE_PUBLIC_API size_t FSE_compressBound(size_t size);       /* maximum compressed size */
    ++
    ++/* Error Management */
    ++FSE_PUBLIC_API unsigned    FSE_isError(size_t code);        /* tells if a return value is an error code */
    ++
    ++
    ++/*-*****************************************
    ++*  FSE detailed API
    ++******************************************/
    ++/*!
    ++FSE_compress() does the following:
    ++1. count symbol occurrence from source[] into table count[]
    ++2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog)
    ++3. save normalized counters to memory buffer using writeNCount()
    ++4. build encoding table 'CTable' from normalized counters
    ++5. encode the data stream using encoding table 'CTable'
    ++
    ++FSE_decompress() does the following:
    ++1. read normalized counters with readNCount()
    ++2. build decoding table 'DTable' from normalized counters
    ++3. decode the data stream using decoding table 'DTable'
    ++
    ++The following API allows targeting specific sub-functions for advanced tasks.
    ++For example, it's possible to compress several blocks using the same 'CTable',
    ++or to save and provide normalized distribution using external method.
    ++*/
    ++
    ++/* *** COMPRESSION *** */
    ++/*! FSE_optimalTableLog():
    ++	dynamically downsize 'tableLog' when conditions are met.
    ++	It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
    ++	@return : recommended tableLog (necessarily <= 'maxTableLog') */
    ++FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
    ++
    ++/*! FSE_normalizeCount():
    ++	normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
    ++	'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
    ++	@return : tableLog,
    ++			  or an errorCode, which can be tested using FSE_isError() */
    ++FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
    ++
    ++/*! FSE_NCountWriteBound():
    ++	Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
    ++	Typically useful for allocation purpose. */
    ++FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
    ++
    ++/*! FSE_writeNCount():
    ++	Compactly save 'normalizedCounter' into 'buffer'.
    ++	@return : size of the compressed table,
    ++			  or an errorCode, which can be tested using FSE_isError(). */
    ++FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
    ++
    ++
    ++/*! Constructor and Destructor of FSE_CTable.
    ++	Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
    ++typedef unsigned FSE_CTable;   /* don't allocate that. It's only meant to be more restrictive than void* */
    ++
    ++/*! FSE_compress_usingCTable():
    ++	Compress `src` using `ct` into `dst` which must be already allocated.
    ++	@return : size of compressed data (<= `dstCapacity`),
    ++			  or 0 if compressed data could not fit into `dst`,
    ++			  or an errorCode, which can be tested using FSE_isError() */
    ++FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
    ++
    ++/*!
    ++Tutorial :
    ++----------
    ++The first step is to count all symbols. FSE_count() does this job very fast.
    ++Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells.
    ++'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0]
    ++maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value)
    ++FSE_count() will return the number of occurrence of the most frequent symbol.
    ++This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility.
    ++If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
    ++
    ++The next step is to normalize the frequencies.
    ++FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'.
    ++It also guarantees a minimum of 1 to any Symbol with frequency >= 1.
    ++You can use 'tableLog'==0 to mean "use default tableLog value".
    ++If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(),
    ++which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default").
    ++
    ++The result of FSE_normalizeCount() will be saved into a table,
    ++called 'normalizedCounter', which is a table of signed short.
    ++'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells.
    ++The return value is tableLog if everything proceeded as expected.
    ++It is 0 if there is a single symbol within distribution.
    ++If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()).
    ++
    ++'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount().
    ++'buffer' must be already allocated.
    ++For guaranteed success, buffer size must be at least FSE_headerBound().
    ++The result of the function is the number of bytes written into 'buffer'.
    ++If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small).
    ++
    ++'normalizedCounter' can then be used to create the compression table 'CTable'.
    ++The space required by 'CTable' must be already allocated, using FSE_createCTable().
    ++You can then use FSE_buildCTable() to fill 'CTable'.
    ++If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()).
    ++
    ++'CTable' can then be used to compress 'src', with FSE_compress_usingCTable().
    ++Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize'
    ++The function returns the size of compressed data (without header), necessarily <= `dstCapacity`.
    ++If it returns '0', compressed data could not fit into 'dst'.
    ++If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
    ++*/
    ++
    ++
    ++/* *** DECOMPRESSION *** */
    ++
    ++/*! FSE_readNCount():
    ++	Read compactly saved 'normalizedCounter' from 'rBuffer'.
    ++	@return : size read from 'rBuffer',
    ++			  or an errorCode, which can be tested using FSE_isError().
    ++			  maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
    ++FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
    ++
    ++/*! Constructor and Destructor of FSE_DTable.
    ++	Note that its size depends on 'tableLog' */
    ++typedef unsigned FSE_DTable;   /* don't allocate that. It's just a way to be more restrictive than void* */
    ++
    ++/*! FSE_buildDTable():
    ++	Builds 'dt', which must be already allocated, using FSE_createDTable().
    ++	return : 0, or an errorCode, which can be tested using FSE_isError() */
    ++FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
    ++
    ++/*! FSE_decompress_usingDTable():
    ++	Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
    ++	into `dst` which must be already allocated.
    ++	@return : size of regenerated data (necessarily <= `dstCapacity`),
    ++			  or an errorCode, which can be tested using FSE_isError() */
    ++FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
    ++
    ++/*!
    ++Tutorial :
    ++----------
    ++(Note : these functions only decompress FSE-compressed blocks.
    ++ If block is uncompressed, use memcpy() instead
    ++ If block is a single repeated byte, use memset() instead )
    ++
    ++The first step is to obtain the normalized frequencies of symbols.
    ++This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount().
    ++'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.
    ++In practice, that means it's necessary to know 'maxSymbolValue' beforehand,
    ++or size the table to handle worst case situations (typically 256).
    ++FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'.
    ++The result of FSE_readNCount() is the number of bytes read from 'rBuffer'.
    ++Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.
    ++If there is an error, the function will return an error code, which can be tested using FSE_isError().
    ++
    ++The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'.
    ++This is performed by the function FSE_buildDTable().
    ++The space required by 'FSE_DTable' must be already allocated using FSE_createDTable().
    ++If there is an error, the function will return an error code, which can be tested using FSE_isError().
    ++
    ++`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable().
    ++`cSrcSize` must be strictly correct, otherwise decompression will fail.
    ++FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).
    ++If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)
    ++*/
    ++
    ++
    ++/* *** Dependency *** */
    ++#include "bitstream.h"
    ++
    ++
    ++/* *****************************************
    ++*  Static allocation
    ++*******************************************/
    ++/* FSE buffer bounds */
    ++#define FSE_NCOUNTBOUND 512
    ++#define FSE_BLOCKBOUND(size) (size + (size>>7))
    ++#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size))   /* Macro version, useful for static allocation */
    ++
    ++/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
    ++#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue)   (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
    ++#define FSE_DTABLE_SIZE_U32(maxTableLog)                   (1 + (1<= `1024` unsigned
    ++ */
    ++size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    ++				 const void* source, size_t sourceSize, unsigned* workSpace);
    ++
    ++/* FSE_countFast_wksp() :
    ++ * Same as FSE_countFast(), but using an externally provided scratch buffer.
    ++ * `workSpace` must be a table of minimum `1024` unsigned
    ++ */
    ++size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* workSpace);
    ++
    ++/*! FSE_count_simple
    ++ * Same as FSE_countFast(), but does not use any additional memory (not even on stack).
    ++ * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`).
    ++*/
    ++size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
    ++
    ++
    ++
    ++unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
    ++/**< same as FSE_optimalTableLog(), which used `minus==2` */
    ++
    ++/* FSE_compress_wksp() :
    ++ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
    ++ * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
    ++ */
    ++#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue)   ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
    ++size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
    ++
    ++size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
    ++/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */
    ++
    ++size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
    ++/**< build a fake FSE_CTable, designed to compress always the same symbolValue */
    ++
    ++/* FSE_buildCTable_wksp() :
    ++ * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
    ++ * `wkspSize` must be >= `(1<= BIT_DStream_completed
    ++
    ++When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
    ++Checking if DStream has reached its end is performed by :
    ++	BIT_endOfDStream(&DStream);
    ++Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
    ++	FSE_endOfDState(&DState);
    ++*/
    ++
    ++
    ++/* *****************************************
    ++*  FSE unsafe API
    ++*******************************************/
    ++static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
    ++/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
    ++
    ++
    ++/* *****************************************
    ++*  Implementation of inlined functions
    ++*******************************************/
    ++typedef struct {
    ++	int deltaFindState;
    ++	U32 deltaNbBits;
    ++} FSE_symbolCompressionTransform; /* total 8 bytes */
    ++
    ++MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
    ++{
    ++	const void* ptr = ct;
    ++	const U16* u16ptr = (const U16*) ptr;
    ++	const U32 tableLog = MEM_read16(ptr);
    ++	statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2;
    ++	statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
    ++	statePtr->stateLog = tableLog;
    ++}
    ++
    ++
    ++/*! FSE_initCState2() :
    ++*   Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
    ++*   uses the smallest state value possible, saving the cost of this symbol */
    ++MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
    ++{
    ++	FSE_initCState(statePtr, ct);
    ++	{   const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    ++		const U16* stateTable = (const U16*)(statePtr->stateTable);
    ++		U32 nbBitsOut  = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
    ++		statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
    ++		statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
    ++	}
    ++}
    ++
    ++MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
    ++{
    ++	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    ++	const U16* const stateTable = (const U16*)(statePtr->stateTable);
    ++	U32 nbBitsOut  = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
    ++	BIT_addBits(bitC, statePtr->value, nbBitsOut);
    ++	statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
    ++}
    ++
    ++MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
    ++{
    ++	BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
    ++	BIT_flushBits(bitC);
    ++}
    ++
    ++
    ++/* ======    Decompression    ====== */
    ++
    ++typedef struct {
    ++	U16 tableLog;
    ++	U16 fastMode;
    ++} FSE_DTableHeader;   /* sizeof U32 */
    ++
    ++typedef struct
    ++{
    ++	unsigned short newState;
    ++	unsigned char  symbol;
    ++	unsigned char  nbBits;
    ++} FSE_decode_t;   /* size == U32 */
    ++
    ++MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
    ++{
    ++	const void* ptr = dt;
    ++	const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
    ++	DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
    ++	BIT_reloadDStream(bitD);
    ++	DStatePtr->table = dt + 1;
    ++}
    ++
    ++MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
    ++{
    ++	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    ++	return DInfo.symbol;
    ++}
    ++
    ++MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    ++{
    ++	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    ++	U32 const nbBits = DInfo.nbBits;
    ++	size_t const lowBits = BIT_readBits(bitD, nbBits);
    ++	DStatePtr->state = DInfo.newState + lowBits;
    ++}
    ++
    ++MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    ++{
    ++	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    ++	U32 const nbBits = DInfo.nbBits;
    ++	BYTE const symbol = DInfo.symbol;
    ++	size_t const lowBits = BIT_readBits(bitD, nbBits);
    ++
    ++	DStatePtr->state = DInfo.newState + lowBits;
    ++	return symbol;
    ++}
    ++
    ++/*! FSE_decodeSymbolFast() :
    ++	unsafe, only works if no symbol has a probability > 50% */
    ++MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    ++{
    ++	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    ++	U32 const nbBits = DInfo.nbBits;
    ++	BYTE const symbol = DInfo.symbol;
    ++	size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
    ++
    ++	DStatePtr->state = DInfo.newState + lowBits;
    ++	return symbol;
    ++}
    ++
    ++MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
    ++{
    ++	return DStatePtr->state == 0;
    ++}
    ++
    ++
    ++
    ++#ifndef FSE_COMMONDEFS_ONLY
    ++
    ++/* **************************************************************
    ++*  Tuning parameters
    ++****************************************************************/
    ++/*!MEMORY_USAGE :
    ++*  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
    ++*  Increasing memory usage improves compression ratio
    ++*  Reduced memory usage can improve speed, due to cache effect
    ++*  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
    ++#ifndef FSE_MAX_MEMORY_USAGE
    ++#  define FSE_MAX_MEMORY_USAGE 14
    ++#endif
    ++#ifndef FSE_DEFAULT_MEMORY_USAGE
    ++#  define FSE_DEFAULT_MEMORY_USAGE 13
    ++#endif
    ++
    ++/*!FSE_MAX_SYMBOL_VALUE :
    ++*  Maximum symbol value authorized.
    ++*  Required for proper stack allocation */
    ++#ifndef FSE_MAX_SYMBOL_VALUE
    ++#  define FSE_MAX_SYMBOL_VALUE 255
    ++#endif
    ++
    ++/* **************************************************************
    ++*  template functions type & suffix
    ++****************************************************************/
    ++#define FSE_FUNCTION_TYPE BYTE
    ++#define FSE_FUNCTION_EXTENSION
    ++#define FSE_DECODE_TYPE FSE_decode_t
    ++
    ++
    ++#endif   /* !FSE_COMMONDEFS_ONLY */
    ++
    ++
    ++/* ***************************************************************
    ++*  Constants
    ++*****************************************************************/
    ++#define FSE_MAX_TABLELOG  (FSE_MAX_MEMORY_USAGE-2)
    ++#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX
    ++#  error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
    ++#endif
    ++
    ++#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
    ++
    ++
    ++#endif  /* FSE_H */
    +diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c
    +new file mode 100644
    +index 0000000..b6a6d46
    +--- /dev/null
    ++++ b/lib/zstd/fse_compress.c
    +@@ -0,0 +1,788 @@
    ++/* ******************************************************************
    ++   FSE : Finite State Entropy encoder
    ++   Copyright (C) 2013-2015, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++	You can contact the author at :
    ++	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    ++****************************************************************** */
    ++
    ++/* **************************************************************
    ++*  Compiler specifics
    ++****************************************************************/
    ++#define FORCE_INLINE static __always_inline
    ++
    ++
    ++/* **************************************************************
    ++*  Includes
    ++****************************************************************/
    ++#include 
    ++#include      /* memcpy, memset */
    ++#include "bitstream.h"
    ++#include "fse.h"
    ++
    ++
    ++/* **************************************************************
    ++*  Error Management
    ++****************************************************************/
    ++#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    ++
    ++
    ++/* **************************************************************
    ++*  Templates
    ++****************************************************************/
    ++/*
    ++  designed to be included
    ++  for type-specific functions (template emulation in C)
    ++  Objective is to write these functions only once, for improved maintenance
    ++*/
    ++
    ++/* safety checks */
    ++#ifndef FSE_FUNCTION_EXTENSION
    ++#  error "FSE_FUNCTION_EXTENSION must be defined"
    ++#endif
    ++#ifndef FSE_FUNCTION_TYPE
    ++#  error "FSE_FUNCTION_TYPE must be defined"
    ++#endif
    ++
    ++/* Function names */
    ++#define FSE_CAT(X,Y) X##Y
    ++#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    ++#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
    ++
    ++
    ++/* Function templates */
    ++
    ++/* FSE_buildCTable_wksp() :
    ++ * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
    ++ * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ;
    ++	FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
    ++	U32 const step = FSE_TABLESTEP(tableSize);
    ++	U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
    ++
    ++	FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
    ++	U32 highThreshold = tableSize-1;
    ++
    ++	/* CTable header */
    ++	if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
    ++	tableU16[-2] = (U16) tableLog;
    ++	tableU16[-1] = (U16) maxSymbolValue;
    ++
    ++	/* For explanations on how to distribute symbol values over the table :
    ++	*  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
    ++
    ++	/* symbol start positions */
    ++	{   U32 u;
    ++		cumul[0] = 0;
    ++		for (u=1; u<=maxSymbolValue+1; u++) {
    ++			if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */
    ++				cumul[u] = cumul[u-1] + 1;
    ++				tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
    ++			} else {
    ++				cumul[u] = cumul[u-1] + normalizedCounter[u-1];
    ++		}   }
    ++		cumul[maxSymbolValue+1] = tableSize+1;
    ++	}
    ++
    ++	/* Spread symbols */
    ++	{   U32 position = 0;
    ++		U32 symbol;
    ++		for (symbol=0; symbol<=maxSymbolValue; symbol++) {
    ++			int nbOccurences;
    ++			for (nbOccurences=0; nbOccurences highThreshold) position = (position + step) & tableMask;   /* Low proba area */
    ++		}   }
    ++
    ++		if (position!=0) return ERROR(GENERIC);   /* Must have gone through all positions */
    ++	}
    ++
    ++	/* Build table */
    ++	{   U32 u; for (u=0; u> 3) + 3;
    ++	return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
    ++}
    ++
    ++static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
    ++									   const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
    ++									   unsigned writeIsSafe)
    ++{
    ++	BYTE* const ostart = (BYTE*) header;
    ++	BYTE* out = ostart;
    ++	BYTE* const oend = ostart + headerBufferSize;
    ++	int nbBits;
    ++	const int tableSize = 1 << tableLog;
    ++	int remaining;
    ++	int threshold;
    ++	U32 bitStream;
    ++	int bitCount;
    ++	unsigned charnum = 0;
    ++	int previous0 = 0;
    ++
    ++	bitStream = 0;
    ++	bitCount  = 0;
    ++	/* Table Size */
    ++	bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
    ++	bitCount  += 4;
    ++
    ++	/* Init */
    ++	remaining = tableSize+1;   /* +1 for extra accuracy */
    ++	threshold = tableSize;
    ++	nbBits = tableLog+1;
    ++
    ++	while (remaining>1) {  /* stops at 1 */
    ++		if (previous0) {
    ++			unsigned start = charnum;
    ++			while (!normalizedCounter[charnum]) charnum++;
    ++			while (charnum >= start+24) {
    ++				start+=24;
    ++				bitStream += 0xFFFFU << bitCount;
    ++				if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    ++				out[0] = (BYTE) bitStream;
    ++				out[1] = (BYTE)(bitStream>>8);
    ++				out+=2;
    ++				bitStream>>=16;
    ++			}
    ++			while (charnum >= start+3) {
    ++				start+=3;
    ++				bitStream += 3 << bitCount;
    ++				bitCount += 2;
    ++			}
    ++			bitStream += (charnum-start) << bitCount;
    ++			bitCount += 2;
    ++			if (bitCount>16) {
    ++				if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    ++				out[0] = (BYTE)bitStream;
    ++				out[1] = (BYTE)(bitStream>>8);
    ++				out += 2;
    ++				bitStream >>= 16;
    ++				bitCount -= 16;
    ++		}   }
    ++		{   int count = normalizedCounter[charnum++];
    ++			int const max = (2*threshold-1)-remaining;
    ++			remaining -= count < 0 ? -count : count;
    ++			count++;   /* +1 for extra accuracy */
    ++			if (count>=threshold) count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
    ++			bitStream += count << bitCount;
    ++			bitCount  += nbBits;
    ++			bitCount  -= (count>=1;
    ++		}
    ++		if (bitCount>16) {
    ++			if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    ++			out[0] = (BYTE)bitStream;
    ++			out[1] = (BYTE)(bitStream>>8);
    ++			out += 2;
    ++			bitStream >>= 16;
    ++			bitCount -= 16;
    ++	}   }
    ++
    ++	/* flush remaining bitStream */
    ++	if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    ++	out[0] = (BYTE)bitStream;
    ++	out[1] = (BYTE)(bitStream>>8);
    ++	out+= (bitCount+7) /8;
    ++
    ++	if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
    ++
    ++	return (out-ostart);
    ++}
    ++
    ++
    ++size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
    ++{
    ++	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported */
    ++	if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
    ++
    ++	if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
    ++		return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
    ++
    ++	return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
    ++}
    ++
    ++
    ++
    ++/*-**************************************************************
    ++*  Counting histogram
    ++****************************************************************/
    ++/*! FSE_count_simple
    ++	This function counts byte values within `src`, and store the histogram into table `count`.
    ++	It doesn't use any additional memory.
    ++	But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
    ++	For this reason, prefer using a table `count` with 256 elements.
    ++	@return : count of most numerous element
    ++*/
    ++size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
    ++						const void* src, size_t srcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*)src;
    ++	const BYTE* const end = ip + srcSize;
    ++	unsigned maxSymbolValue = *maxSymbolValuePtr;
    ++	unsigned max=0;
    ++
    ++	memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
    ++	if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
    ++
    ++	while (ip max) max = count[s]; }
    ++
    ++	return (size_t)max;
    ++}
    ++
    ++
    ++/* FSE_count_parallel_wksp() :
    ++ * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
    ++ * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
    ++static size_t FSE_count_parallel_wksp(
    ++								unsigned* count, unsigned* maxSymbolValuePtr,
    ++								const void* source, size_t sourceSize,
    ++								unsigned checkMax, unsigned* const workSpace)
    ++{
    ++	const BYTE* ip = (const BYTE*)source;
    ++	const BYTE* const iend = ip+sourceSize;
    ++	unsigned maxSymbolValue = *maxSymbolValuePtr;
    ++	unsigned max=0;
    ++	U32* const Counting1 = workSpace;
    ++	U32* const Counting2 = Counting1 + 256;
    ++	U32* const Counting3 = Counting2 + 256;
    ++	U32* const Counting4 = Counting3 + 256;
    ++
    ++	memset(Counting1, 0, 4*256*sizeof(unsigned));
    ++
    ++	/* safety checks */
    ++	if (!sourceSize) {
    ++		memset(count, 0, maxSymbolValue + 1);
    ++		*maxSymbolValuePtr = 0;
    ++		return 0;
    ++	}
    ++	if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
    ++
    ++	/* by stripes of 16 bytes */
    ++	{   U32 cached = MEM_read32(ip); ip += 4;
    ++		while (ip < iend-15) {
    ++			U32 c = cached; cached = MEM_read32(ip); ip += 4;
    ++			Counting1[(BYTE) c     ]++;
    ++			Counting2[(BYTE)(c>>8) ]++;
    ++			Counting3[(BYTE)(c>>16)]++;
    ++			Counting4[       c>>24 ]++;
    ++			c = cached; cached = MEM_read32(ip); ip += 4;
    ++			Counting1[(BYTE) c     ]++;
    ++			Counting2[(BYTE)(c>>8) ]++;
    ++			Counting3[(BYTE)(c>>16)]++;
    ++			Counting4[       c>>24 ]++;
    ++			c = cached; cached = MEM_read32(ip); ip += 4;
    ++			Counting1[(BYTE) c     ]++;
    ++			Counting2[(BYTE)(c>>8) ]++;
    ++			Counting3[(BYTE)(c>>16)]++;
    ++			Counting4[       c>>24 ]++;
    ++			c = cached; cached = MEM_read32(ip); ip += 4;
    ++			Counting1[(BYTE) c     ]++;
    ++			Counting2[(BYTE)(c>>8) ]++;
    ++			Counting3[(BYTE)(c>>16)]++;
    ++			Counting4[       c>>24 ]++;
    ++		}
    ++		ip-=4;
    ++	}
    ++
    ++	/* finish last symbols */
    ++	while (ipmaxSymbolValue; s--) {
    ++			Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
    ++			if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
    ++	}   }
    ++
    ++	{   U32 s; for (s=0; s<=maxSymbolValue; s++) {
    ++			count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
    ++			if (count[s] > max) max = count[s];
    ++	}   }
    ++
    ++	while (!count[maxSymbolValue]) maxSymbolValue--;
    ++	*maxSymbolValuePtr = maxSymbolValue;
    ++	return (size_t)max;
    ++}
    ++
    ++/* FSE_countFast_wksp() :
    ++ * Same as FSE_countFast(), but using an externally provided scratch buffer.
    ++ * `workSpace` size must be table of >= `1024` unsigned */
    ++size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    ++					 const void* source, size_t sourceSize, unsigned* workSpace)
    ++{
    ++	if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
    ++	return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
    ++}
    ++
    ++/* FSE_count_wksp() :
    ++ * Same as FSE_count(), but using an externally provided scratch buffer.
    ++ * `workSpace` size must be table of >= `1024` unsigned */
    ++size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    ++				 const void* source, size_t sourceSize, unsigned* workSpace)
    ++{
    ++	if (*maxSymbolValuePtr < 255)
    ++		return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
    ++	*maxSymbolValuePtr = 255;
    ++	return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
    ++}
    ++
    ++
    ++/*-**************************************************************
    ++*  FSE Compression Code
    ++****************************************************************/
    ++/*! FSE_sizeof_CTable() :
    ++	FSE_CTable is a variable size structure which contains :
    ++	`U16 tableLog;`
    ++	`U16 maxSymbolValue;`
    ++	`U16 nextStateNumber[1 << tableLog];`                         // This size is variable
    ++	`FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
    ++Allocation is manual (C standard does not support variable-size structures).
    ++*/
    ++size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
    ++{
    ++	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
    ++	return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
    ++}
    ++
    ++/* provides the minimum logSize to safely represent a distribution */
    ++static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
    ++{
    ++	U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
    ++	U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
    ++	U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
    ++	return minBits;
    ++}
    ++
    ++unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
    ++{
    ++	U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
    ++	U32 tableLog = maxTableLog;
    ++	U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
    ++	if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
    ++	if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
    ++	if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
    ++	if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
    ++	if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
    ++	return tableLog;
    ++}
    ++
    ++unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
    ++{
    ++	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
    ++}
    ++
    ++
    ++/* Secondary normalization method.
    ++   To be used when primary method fails. */
    ++
    ++static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
    ++{
    ++	short const NOT_YET_ASSIGNED = -2;
    ++	U32 s;
    ++	U32 distributed = 0;
    ++	U32 ToDistribute;
    ++
    ++	/* Init */
    ++	U32 const lowThreshold = (U32)(total >> tableLog);
    ++	U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
    ++
    ++	for (s=0; s<=maxSymbolValue; s++) {
    ++		if (count[s] == 0) {
    ++			norm[s]=0;
    ++			continue;
    ++		}
    ++		if (count[s] <= lowThreshold) {
    ++			norm[s] = -1;
    ++			distributed++;
    ++			total -= count[s];
    ++			continue;
    ++		}
    ++		if (count[s] <= lowOne) {
    ++			norm[s] = 1;
    ++			distributed++;
    ++			total -= count[s];
    ++			continue;
    ++		}
    ++
    ++		norm[s]=NOT_YET_ASSIGNED;
    ++	}
    ++	ToDistribute = (1 << tableLog) - distributed;
    ++
    ++	if ((total / ToDistribute) > lowOne) {
    ++		/* risk of rounding to zero */
    ++		lowOne = (U32)((total * 3) / (ToDistribute * 2));
    ++		for (s=0; s<=maxSymbolValue; s++) {
    ++			if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
    ++				norm[s] = 1;
    ++				distributed++;
    ++				total -= count[s];
    ++				continue;
    ++		}   }
    ++		ToDistribute = (1 << tableLog) - distributed;
    ++	}
    ++
    ++	if (distributed == maxSymbolValue+1) {
    ++		/* all values are pretty poor;
    ++		   probably incompressible data (should have already been detected);
    ++		   find max, then give all remaining points to max */
    ++		U32 maxV = 0, maxC = 0;
    ++		for (s=0; s<=maxSymbolValue; s++)
    ++			if (count[s] > maxC) maxV=s, maxC=count[s];
    ++		norm[maxV] += (short)ToDistribute;
    ++		return 0;
    ++	}
    ++
    ++	if (total == 0) {
    ++		/* all of the symbols were low enough for the lowOne or lowThreshold */
    ++		for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
    ++			if (norm[s] > 0) ToDistribute--, norm[s]++;
    ++		return 0;
    ++	}
    ++
    ++	{   U64 const vStepLog = 62 - tableLog;
    ++		U64 const mid = (1ULL << (vStepLog-1)) - 1;
    ++		U64 const rStep = ((((U64)1<> vStepLog);
    ++				U32 const sEnd = (U32)(end >> vStepLog);
    ++				U32 const weight = sEnd - sStart;
    ++				if (weight < 1)
    ++					return ERROR(GENERIC);
    ++				norm[s] = (short)weight;
    ++				tmpTotal = end;
    ++	}   }   }
    ++
    ++	return 0;
    ++}
    ++
    ++
    ++size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
    ++						   const unsigned* count, size_t total,
    ++						   unsigned maxSymbolValue)
    ++{
    ++	/* Sanity checks */
    ++	if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
    ++	if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
    ++	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
    ++	if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
    ++
    ++	{   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
    ++		U64 const scale = 62 - tableLog;
    ++		U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
    ++		U64 const vStep = 1ULL<<(scale-20);
    ++		int stillToDistribute = 1<> tableLog);
    ++
    ++		for (s=0; s<=maxSymbolValue; s++) {
    ++			if (count[s] == total) return 0;   /* rle special case */
    ++			if (count[s] == 0) { normalizedCounter[s]=0; continue; }
    ++			if (count[s] <= lowThreshold) {
    ++				normalizedCounter[s] = -1;
    ++				stillToDistribute--;
    ++			} else {
    ++				short proba = (short)((count[s]*step) >> scale);
    ++				if (proba<8) {
    ++					U64 restToBeat = vStep * rtbTable[proba];
    ++					proba += (count[s]*step) - ((U64)proba< restToBeat;
    ++				}
    ++				if (proba > largestP) largestP=proba, largest=s;
    ++				normalizedCounter[s] = proba;
    ++				stillToDistribute -= proba;
    ++		}   }
    ++		if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
    ++			/* corner case, need another normalization method */
    ++			size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
    ++			if (FSE_isError(errorCode)) return errorCode;
    ++		}
    ++		else normalizedCounter[largest] += (short)stillToDistribute;
    ++	}
    ++
    ++#if 0
    ++	{   /* Print Table (debug) */
    ++		U32 s;
    ++		U32 nTotal = 0;
    ++		for (s=0; s<=maxSymbolValue; s++)
    ++			printf("%3i: %4i \n", s, normalizedCounter[s]);
    ++		for (s=0; s<=maxSymbolValue; s++)
    ++			nTotal += abs(normalizedCounter[s]);
    ++		if (nTotal != (1U<>1);   /* assumption : tableLog >= 1 */
    ++	FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
    ++	unsigned s;
    ++
    ++	/* Sanity checks */
    ++	if (nbBits < 1) return ERROR(GENERIC);             /* min size */
    ++
    ++	/* header */
    ++	tableU16[-2] = (U16) nbBits;
    ++	tableU16[-1] = (U16) maxSymbolValue;
    ++
    ++	/* Build table */
    ++	for (s=0; s FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) {  /* test bit 2 */
    ++		FSE_encodeSymbol(&bitC, &CState2, *--ip);
    ++		FSE_encodeSymbol(&bitC, &CState1, *--ip);
    ++		FSE_FLUSHBITS(&bitC);
    ++	}
    ++
    ++	/* 2 or 4 encoding per loop */
    ++	while ( ip>istart ) {
    ++
    ++		FSE_encodeSymbol(&bitC, &CState2, *--ip);
    ++
    ++		if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */
    ++			FSE_FLUSHBITS(&bitC);
    ++
    ++		FSE_encodeSymbol(&bitC, &CState1, *--ip);
    ++
    ++		if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) {  /* this test must be static */
    ++			FSE_encodeSymbol(&bitC, &CState2, *--ip);
    ++			FSE_encodeSymbol(&bitC, &CState1, *--ip);
    ++		}
    ++
    ++		FSE_FLUSHBITS(&bitC);
    ++	}
    ++
    ++	FSE_flushCState(&bitC, &CState2);
    ++	FSE_flushCState(&bitC, &CState1);
    ++	return BIT_closeCStream(&bitC);
    ++}
    ++
    ++size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
    ++						   const void* src, size_t srcSize,
    ++						   const FSE_CTable* ct)
    ++{
    ++	unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
    ++
    ++	if (fast)
    ++		return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
    ++	else
    ++		return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
    ++}
    ++
    ++
    ++size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
    ++
    ++#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
    ++#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
    ++
    ++/* FSE_compress_wksp() :
    ++ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
    ++ * `wkspSize` size must be `(1< not compressible */
    ++		if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
    ++	}
    ++
    ++	tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
    ++	CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
    ++
    ++	/* Write table description header */
    ++	{   CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    ++		op += nc_err;
    ++	}
    ++
    ++	/* Compress */
    ++	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
    ++	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
    ++		if (cSize == 0) return 0;   /* not enough space for compressed data */
    ++		op += cSize;
    ++	}
    ++
    ++	/* check compressibility */
    ++	if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++#endif   /* FSE_COMMONDEFS_ONLY */
    +diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c
    +new file mode 100644
    +index 0000000..2a35f17
    +--- /dev/null
    ++++ b/lib/zstd/fse_decompress.c
    +@@ -0,0 +1,292 @@
    ++/* ******************************************************************
    ++   FSE : Finite State Entropy decoder
    ++   Copyright (C) 2013-2015, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++	You can contact the author at :
    ++	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    ++****************************************************************** */
    ++
    ++
    ++/* **************************************************************
    ++*  Compiler specifics
    ++****************************************************************/
    ++#define FORCE_INLINE static __always_inline
    ++
    ++
    ++/* **************************************************************
    ++*  Includes
    ++****************************************************************/
    ++#include 
    ++#include      /* memcpy, memset */
    ++#include "bitstream.h"
    ++#include "fse.h"
    ++
    ++
    ++/* **************************************************************
    ++*  Error Management
    ++****************************************************************/
    ++#define FSE_isError ERR_isError
    ++#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    ++
    ++/* check and forward error code */
    ++#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
    ++
    ++
    ++/* **************************************************************
    ++*  Templates
    ++****************************************************************/
    ++/*
    ++  designed to be included
    ++  for type-specific functions (template emulation in C)
    ++  Objective is to write these functions only once, for improved maintenance
    ++*/
    ++
    ++/* safety checks */
    ++#ifndef FSE_FUNCTION_EXTENSION
    ++#  error "FSE_FUNCTION_EXTENSION must be defined"
    ++#endif
    ++#ifndef FSE_FUNCTION_TYPE
    ++#  error "FSE_FUNCTION_TYPE must be defined"
    ++#endif
    ++
    ++/* Function names */
    ++#define FSE_CAT(X,Y) X##Y
    ++#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    ++#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
    ++
    ++
    ++/* Function templates */
    ++
    ++size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
    ++{
    ++	void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */
    ++	FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
    ++	U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
    ++
    ++	U32 const maxSV1 = maxSymbolValue + 1;
    ++	U32 const tableSize = 1 << tableLog;
    ++	U32 highThreshold = tableSize-1;
    ++
    ++	/* Sanity Checks */
    ++	if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
    ++	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
    ++
    ++	/* Init, lay down lowprob symbols */
    ++	{   FSE_DTableHeader DTableH;
    ++		DTableH.tableLog = (U16)tableLog;
    ++		DTableH.fastMode = 1;
    ++		{   S16 const largeLimit= (S16)(1 << (tableLog-1));
    ++			U32 s;
    ++			for (s=0; s= largeLimit) DTableH.fastMode=0;
    ++					symbolNext[s] = normalizedCounter[s];
    ++		}   }   }
    ++		memcpy(dt, &DTableH, sizeof(DTableH));
    ++	}
    ++
    ++	/* Spread symbols */
    ++	{   U32 const tableMask = tableSize-1;
    ++		U32 const step = FSE_TABLESTEP(tableSize);
    ++		U32 s, position = 0;
    ++		for (s=0; s highThreshold) position = (position + step) & tableMask;   /* lowprob area */
    ++		}   }
    ++		if (position!=0) return ERROR(GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */
    ++	}
    ++
    ++	/* Build Decoding table */
    ++	{   U32 u;
    ++		for (u=0; utableLog = 0;
    ++	DTableH->fastMode = 0;
    ++
    ++	cell->newState = 0;
    ++	cell->symbol = symbolValue;
    ++	cell->nbBits = 0;
    ++
    ++	return 0;
    ++}
    ++
    ++
    ++size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
    ++{
    ++	void* ptr = dt;
    ++	FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
    ++	void* dPtr = dt + 1;
    ++	FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
    ++	const unsigned tableSize = 1 << nbBits;
    ++	const unsigned tableMask = tableSize - 1;
    ++	const unsigned maxSV1 = tableMask+1;
    ++	unsigned s;
    ++
    ++	/* Sanity checks */
    ++	if (nbBits < 1) return ERROR(GENERIC);         /* min size */
    ++
    ++	/* Build Decoding Table */
    ++	DTableH->tableLog = (U16)nbBits;
    ++	DTableH->fastMode = 1;
    ++	for (s=0; s sizeof(bitD.bitContainer)*8)    /* This test must be static */
    ++			BIT_reloadDStream(&bitD);
    ++
    ++		op[1] = FSE_GETSYMBOL(&state2);
    ++
    ++		if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
    ++			{ if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
    ++
    ++		op[2] = FSE_GETSYMBOL(&state1);
    ++
    ++		if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
    ++			BIT_reloadDStream(&bitD);
    ++
    ++		op[3] = FSE_GETSYMBOL(&state2);
    ++	}
    ++
    ++	/* tail */
    ++	/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
    ++	while (1) {
    ++		if (op>(omax-2)) return ERROR(dstSize_tooSmall);
    ++		*op++ = FSE_GETSYMBOL(&state1);
    ++		if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
    ++			*op++ = FSE_GETSYMBOL(&state2);
    ++			break;
    ++		}
    ++
    ++		if (op>(omax-2)) return ERROR(dstSize_tooSmall);
    ++		*op++ = FSE_GETSYMBOL(&state2);
    ++		if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
    ++			*op++ = FSE_GETSYMBOL(&state1);
    ++			break;
    ++	}   }
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
    ++							const void* cSrc, size_t cSrcSize,
    ++							const FSE_DTable* dt)
    ++{
    ++	const void* ptr = dt;
    ++	const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
    ++	const U32 fastMode = DTableH->fastMode;
    ++
    ++	/* select fast mode (static) */
    ++	if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
    ++	return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
    ++}
    ++
    ++
    ++size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)
    ++{
    ++	const BYTE* const istart = (const BYTE*)cSrc;
    ++	const BYTE* ip = istart;
    ++	short counting[FSE_MAX_SYMBOL_VALUE+1];
    ++	unsigned tableLog;
    ++	unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
    ++
    ++	/* normal FSE decoding mode */
    ++	size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
    ++	if (FSE_isError(NCountLength)) return NCountLength;
    ++	//if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
    ++	if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
    ++	ip += NCountLength;
    ++	cSrcSize -= NCountLength;
    ++
    ++	CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );
    ++
    ++	return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace);   /* always return, even if it is an error code */
    ++}
    ++
    ++
    ++#endif   /* FSE_COMMONDEFS_ONLY */
    +diff --git a/lib/zstd/huf.h b/lib/zstd/huf.h
    +new file mode 100644
    +index 0000000..f36aded
    +--- /dev/null
    ++++ b/lib/zstd/huf.h
    +@@ -0,0 +1,203 @@
    ++/* ******************************************************************
    ++   Huffman coder, part of New Generation Entropy library
    ++   header file
    ++   Copyright (C) 2013-2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++   You can contact the author at :
    ++   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++****************************************************************** */
    ++#ifndef HUF_H_298734234
    ++#define HUF_H_298734234
    ++
    ++
    ++/* *** Dependencies *** */
    ++#include     /* size_t */
    ++
    ++
    ++/* ***   Tool functions *** */
    ++#define HUF_BLOCKSIZE_MAX (128 * 1024)       /**< maximum input size for a single block compressed with HUF_compress */
    ++size_t HUF_compressBound(size_t size);       /**< maximum compressed size (worst case) */
    ++
    ++/* Error Management */
    ++unsigned    HUF_isError(size_t code);        /**< tells if a return value is an error code */
    ++
    ++
    ++/* ***   Advanced function   *** */
    ++
    ++/** HUF_compress4X_wksp() :
    ++*   Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */
    ++size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    ++
    ++
    ++
    ++/* *** Dependencies *** */
    ++#include "mem.h"   /* U32 */
    ++
    ++
    ++/* *** Constants *** */
    ++#define HUF_TABLELOG_MAX      12       /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
    ++#define HUF_TABLELOG_DEFAULT  11       /* tableLog by default, when not specified */
    ++#define HUF_SYMBOLVALUE_MAX  255
    ++
    ++#define HUF_TABLELOG_ABSOLUTEMAX  15   /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
    ++#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
    ++#  error "HUF_TABLELOG_MAX is too large !"
    ++#endif
    ++
    ++
    ++/* ****************************************
    ++*  Static allocation
    ++******************************************/
    ++/* HUF buffer bounds */
    ++#define HUF_CTABLEBOUND 129
    ++#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8)   /* only true if incompressible pre-filtered with fast heuristic */
    ++#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size))   /* Macro version, useful for static allocation */
    ++
    ++/* static allocation of HUF's Compression Table */
    ++#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
    ++	U32 name##hb[maxSymbolValue+1]; \
    ++	void* name##hv = &(name##hb); \
    ++	HUF_CElt* name = (HUF_CElt*)(name##hv)   /* no final ; */
    ++
    ++/* static allocation of HUF's DTable */
    ++typedef U32 HUF_DTable;
    ++#define HUF_DTABLE_SIZE(maxTableLog)   (1 + (1<<(maxTableLog)))
    ++#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
    ++		HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
    ++#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
    ++		HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
    ++
    ++/* The workspace must have alignment at least 4 and be at least this large */
    ++#define HUF_WORKSPACE_SIZE (6 << 10)
    ++#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
    ++
    ++
    ++/* ****************************************
    ++*  Advanced decompression functions
    ++******************************************/
    ++size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< decodes RLE and uncompressed */
    ++size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
    ++size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
    ++size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
    ++
    ++
    ++/* ****************************************
    ++*  HUF detailed API
    ++******************************************/
    ++/*!
    ++HUF_compress() does the following:
    ++1. count symbol occurrence from source[] into table count[] using FSE_count()
    ++2. (optional) refine tableLog using HUF_optimalTableLog()
    ++3. build Huffman table from count using HUF_buildCTable()
    ++4. save Huffman table to memory buffer using HUF_writeCTable()
    ++5. encode the data stream using HUF_compress4X_usingCTable()
    ++
    ++The following API allows targeting specific sub-functions for advanced tasks.
    ++For example, it's possible to compress several blocks using the same 'CTable',
    ++or to save and regenerate 'CTable' using external methods.
    ++*/
    ++/* FSE_count() : find it within "fse.h" */
    ++unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
    ++typedef struct HUF_CElt_s HUF_CElt;   /* incomplete type */
    ++size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
    ++size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
    ++
    ++typedef enum {
    ++   HUF_repeat_none,  /**< Cannot use the previous table */
    ++   HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
    ++   HUF_repeat_valid  /**< Can use the previous table and it is asumed to be valid */
    ++ } HUF_repeat;
    ++/** HUF_compress4X_repeat() :
    ++*   Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
    ++*   If it uses hufTable it does not modify hufTable or repeat.
    ++*   If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
    ++*   If preferRepeat then the old table will always be used if valid. */
    ++size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    ++
    ++/** HUF_buildCTable_wksp() :
    ++ *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.
    ++ *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
    ++ */
    ++size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize);
    ++
    ++/*! HUF_readStats() :
    ++	Read compact Huffman tree, saved by HUF_writeCTable().
    ++	`huffWeight` is destination buffer.
    ++	@return : size read from `src` , or an error Code .
    ++	Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
    ++size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
    ++					 U32* nbSymbolsPtr, U32* tableLogPtr,
    ++					 const void* src, size_t srcSize);
    ++
    ++/** HUF_readCTable() :
    ++*   Loading a CTable saved with HUF_writeCTable() */
    ++size_t HUF_readCTable (HUF_CElt* CTable, unsigned maxSymbolValue, const void* src, size_t srcSize);
    ++
    ++
    ++/*
    ++HUF_decompress() does the following:
    ++1. select the decompression algorithm (X2, X4) based on pre-computed heuristics
    ++2. build Huffman table from save, using HUF_readDTableXn()
    ++3. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable
    ++*/
    ++
    ++/** HUF_selectDecoder() :
    ++*   Tells which decoder is likely to decode faster,
    ++*   based on a set of pre-determined metrics.
    ++*   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
    ++*   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
    ++U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
    ++
    ++size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
    ++size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize);
    ++
    ++size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    ++size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    ++size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    ++
    ++
    ++/* single stream variants */
    ++
    ++size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    ++size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
    ++/** HUF_compress1X_repeat() :
    ++*   Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
    ++*   If it uses hufTable it does not modify hufTable or repeat.
    ++*   If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
    ++*   If preferRepeat then the old table will always be used if valid. */
    ++size_t HUF_compress1X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    ++
    ++size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
    ++size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
    ++size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
    ++
    ++size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);   /**< automatic selection of sing or double symbol decoder, based on DTable */
    ++size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    ++size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    ++
    ++#endif   /* HUF_H_298734234 */
    +diff --git a/lib/zstd/huf_compress.c b/lib/zstd/huf_compress.c
    +new file mode 100644
    +index 0000000..a1a1d45
    +--- /dev/null
    ++++ b/lib/zstd/huf_compress.c
    +@@ -0,0 +1,644 @@
    ++/* ******************************************************************
    ++   Huffman encoder, part of New Generation Entropy library
    ++   Copyright (C) 2013-2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++	You can contact the author at :
    ++	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    ++****************************************************************** */
    ++
    ++
    ++/* **************************************************************
    ++*  Includes
    ++****************************************************************/
    ++#include      /* memcpy, memset */
    ++#include "bitstream.h"
    ++#include "fse.h"        /* header compression */
    ++#include "huf.h"
    ++
    ++
    ++/* **************************************************************
    ++*  Error Management
    ++****************************************************************/
    ++#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    ++#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
    ++#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
    ++
    ++
    ++/* **************************************************************
    ++*  Utils
    ++****************************************************************/
    ++unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
    ++{
    ++	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
    ++}
    ++
    ++
    ++/* *******************************************************
    ++*  HUF : Huffman block compression
    ++*********************************************************/
    ++/* HUF_compressWeights() :
    ++ * Same as FSE_compress(), but dedicated to huff0's weights compression.
    ++ * The use case needs much less stack memory.
    ++ * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
    ++ */
    ++#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
    ++size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
    ++{
    ++	BYTE* const ostart = (BYTE*) dst;
    ++	BYTE* op = ostart;
    ++	BYTE* const oend = ostart + dstSize;
    ++
    ++	U32 maxSymbolValue = HUF_TABLELOG_MAX;
    ++	U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
    ++
    ++	FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
    ++	BYTE scratchBuffer[1< not compressible */
    ++	}
    ++
    ++	tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
    ++	CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
    ++
    ++	/* Write table description header */
    ++	{   CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    ++		op += hSize;
    ++	}
    ++
    ++	/* Compress */
    ++	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
    ++	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
    ++		if (cSize == 0) return 0;   /* not enough space for compressed data */
    ++		op += cSize;
    ++	}
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++struct HUF_CElt_s {
    ++  U16  val;
    ++  BYTE nbBits;
    ++};   /* typedef'd to HUF_CElt within "huf.h" */
    ++
    ++/*! HUF_writeCTable() :
    ++	`CTable` : Huffman tree to save, using huf representation.
    ++	@return : size of saved CTable */
    ++size_t HUF_writeCTable (void* dst, size_t maxDstSize,
    ++						const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
    ++{
    ++	BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];   /* precomputed conversion table */
    ++	BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
    ++	BYTE* op = (BYTE*)dst;
    ++	U32 n;
    ++
    ++	 /* check conditions */
    ++	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
    ++
    ++	/* convert to weight */
    ++	bitsToWeight[0] = 0;
    ++	for (n=1; n1) & (hSize < maxSymbolValue/2)) {   /* FSE compressed */
    ++			op[0] = (BYTE)hSize;
    ++			return hSize+1;
    ++	}   }
    ++
    ++	/* write raw values as 4-bits (max : 15) */
    ++	if (maxSymbolValue > (256-128)) return ERROR(GENERIC);   /* should not happen : likely means source cannot be compressed */
    ++	if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall);   /* not enough space within dst buffer */
    ++	op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
    ++	huffWeight[maxSymbolValue] = 0;   /* to be sure it doesn't cause msan issue in final combination */
    ++	for (n=0; n HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    ++	if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
    ++
    ++	/* Prepare base value per rank */
    ++	{   U32 n, nextRankStart = 0;
    ++		for (n=1; n<=tableLog; n++) {
    ++			U32 current = nextRankStart;
    ++			nextRankStart += (rankVal[n] << (n-1));
    ++			rankVal[n] = current;
    ++	}   }
    ++
    ++	/* fill nbBits */
    ++	{   U32 n; for (n=0; nn=tableLog+1 */
    ++		U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
    ++		{ U32 n; for (n=0; n0; n--) {  /* start at n=tablelog <-> w=1 */
    ++				valPerRank[n] = min;     /* get starting value within each rank */
    ++				min += nbPerRank[n];
    ++				min >>= 1;
    ++		}   }
    ++		/* assign value within rank, symbol order */
    ++		{ U32 n; for (n=0; n<=maxSymbolValue; n++) CTable[n].val = valPerRank[CTable[n].nbBits]++; }
    ++	}
    ++
    ++	return readSize;
    ++}
    ++
    ++
    ++typedef struct nodeElt_s {
    ++	U32 count;
    ++	U16 parent;
    ++	BYTE byte;
    ++	BYTE nbBits;
    ++} nodeElt;
    ++
    ++static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
    ++{
    ++	const U32 largestBits = huffNode[lastNonNull].nbBits;
    ++	if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */
    ++
    ++	/* there are several too large elements (at least >= 2) */
    ++	{   int totalCost = 0;
    ++		const U32 baseCost = 1 << (largestBits - maxNbBits);
    ++		U32 n = lastNonNull;
    ++
    ++		while (huffNode[n].nbBits > maxNbBits) {
    ++			totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
    ++			huffNode[n].nbBits = (BYTE)maxNbBits;
    ++			n --;
    ++		}  /* n stops at huffNode[n].nbBits <= maxNbBits */
    ++		while (huffNode[n].nbBits == maxNbBits) n--;   /* n end at index of smallest symbol using < maxNbBits */
    ++
    ++		/* renorm totalCost */
    ++		totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */
    ++
    ++		/* repay normalized cost */
    ++		{   U32 const noSymbol = 0xF0F0F0F0;
    ++			U32 rankLast[HUF_TABLELOG_MAX+2];
    ++			int pos;
    ++
    ++			/* Get pos of last (smallest) symbol per rank */
    ++			memset(rankLast, 0xF0, sizeof(rankLast));
    ++			{   U32 currentNbBits = maxNbBits;
    ++				for (pos=n ; pos >= 0; pos--) {
    ++					if (huffNode[pos].nbBits >= currentNbBits) continue;
    ++					currentNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    ++					rankLast[maxNbBits-currentNbBits] = pos;
    ++			}   }
    ++
    ++			while (totalCost > 0) {
    ++				U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
    ++				for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
    ++					U32 highPos = rankLast[nBitsToDecrease];
    ++					U32 lowPos = rankLast[nBitsToDecrease-1];
    ++					if (highPos == noSymbol) continue;
    ++					if (lowPos == noSymbol) break;
    ++					{   U32 const highTotal = huffNode[highPos].count;
    ++						U32 const lowTotal = 2 * huffNode[lowPos].count;
    ++						if (highTotal <= lowTotal) break;
    ++				}   }
    ++				/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
    ++				while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))  /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    ++					nBitsToDecrease ++;
    ++				totalCost -= 1 << (nBitsToDecrease-1);
    ++				if (rankLast[nBitsToDecrease-1] == noSymbol)
    ++					rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];   /* this rank is no longer empty */
    ++				huffNode[rankLast[nBitsToDecrease]].nbBits ++;
    ++				if (rankLast[nBitsToDecrease] == 0)    /* special case, reached largest symbol */
    ++					rankLast[nBitsToDecrease] = noSymbol;
    ++				else {
    ++					rankLast[nBitsToDecrease]--;
    ++					if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
    ++						rankLast[nBitsToDecrease] = noSymbol;   /* this rank is now empty */
    ++			}   }   /* while (totalCost > 0) */
    ++
    ++			while (totalCost < 0) {  /* Sometimes, cost correction overshoot */
    ++				if (rankLast[1] == noSymbol) {  /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
    ++					while (huffNode[n].nbBits == maxNbBits) n--;
    ++					huffNode[n+1].nbBits--;
    ++					rankLast[1] = n+1;
    ++					totalCost++;
    ++					continue;
    ++				}
    ++				huffNode[ rankLast[1] + 1 ].nbBits--;
    ++				rankLast[1]++;
    ++				totalCost ++;
    ++	}   }   }   /* there are several too large elements (at least >= 2) */
    ++
    ++	return maxNbBits;
    ++}
    ++
    ++
    ++typedef struct {
    ++	U32 base;
    ++	U32 current;
    ++} rankPos;
    ++
    ++static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
    ++{
    ++	rankPos rank[32];
    ++	U32 n;
    ++
    ++	memset(rank, 0, sizeof(rank));
    ++	for (n=0; n<=maxSymbolValue; n++) {
    ++		U32 r = BIT_highbit32(count[n] + 1);
    ++		rank[r].base ++;
    ++	}
    ++	for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
    ++	for (n=0; n<32; n++) rank[n].current = rank[n].base;
    ++	for (n=0; n<=maxSymbolValue; n++) {
    ++		U32 const c = count[n];
    ++		U32 const r = BIT_highbit32(c+1) + 1;
    ++		U32 pos = rank[r].current++;
    ++		while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
    ++		huffNode[pos].count = c;
    ++		huffNode[pos].byte  = (BYTE)n;
    ++	}
    ++}
    ++
    ++
    ++/** HUF_buildCTable_wksp() :
    ++ *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.
    ++ *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
    ++ */
    ++#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
    ++typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1];
    ++size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
    ++{
    ++	nodeElt* const huffNode0 = (nodeElt*)workSpace;
    ++	nodeElt* const huffNode = huffNode0+1;
    ++	U32 n, nonNullRank;
    ++	int lowS, lowN;
    ++	U16 nodeNb = STARTNODE;
    ++	U32 nodeRoot;
    ++
    ++	/* safety checks */
    ++	if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC);   /* workSpace is not large enough */
    ++	if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
    ++	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
    ++	memset(huffNode0, 0, sizeof(huffNodeTable));
    ++
    ++	/* sort, decreasing order */
    ++	HUF_sort(huffNode, count, maxSymbolValue);
    ++
    ++	/* init for parents */
    ++	nonNullRank = maxSymbolValue;
    ++	while(huffNode[nonNullRank].count == 0) nonNullRank--;
    ++	lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
    ++	huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
    ++	huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
    ++	nodeNb++; lowS-=2;
    ++	for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
    ++	huffNode0[0].count = (U32)(1U<<31);  /* fake entry, strong barrier */
    ++
    ++	/* create parents */
    ++	while (nodeNb <= nodeRoot) {
    ++		U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
    ++		U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
    ++		huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
    ++		huffNode[n1].parent = huffNode[n2].parent = nodeNb;
    ++		nodeNb++;
    ++	}
    ++
    ++	/* distribute weights (unlimited tree height) */
    ++	huffNode[nodeRoot].nbBits = 0;
    ++	for (n=nodeRoot-1; n>=STARTNODE; n--)
    ++		huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
    ++	for (n=0; n<=nonNullRank; n++)
    ++		huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
    ++
    ++	/* enforce maxTableLog */
    ++	maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
    ++
    ++	/* fill result into tree (val, nbBits) */
    ++	{   U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
    ++		U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
    ++		if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC);   /* check fit into table */
    ++		for (n=0; n<=nonNullRank; n++)
    ++			nbPerRank[huffNode[n].nbBits]++;
    ++		/* determine stating value per rank */
    ++		{   U16 min = 0;
    ++			for (n=maxNbBits; n>0; n--) {
    ++				valPerRank[n] = min;      /* get starting value within each rank */
    ++				min += nbPerRank[n];
    ++				min >>= 1;
    ++		}   }
    ++		for (n=0; n<=maxSymbolValue; n++)
    ++			tree[huffNode[n].byte].nbBits = huffNode[n].nbBits;   /* push nbBits per symbol, symbol order */
    ++		for (n=0; n<=maxSymbolValue; n++)
    ++			tree[n].val = valPerRank[tree[n].nbBits]++;   /* assign value within rank, symbol order */
    ++	}
    ++
    ++	return maxNbBits;
    ++}
    ++
    ++static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
    ++{
    ++	size_t nbBits = 0;
    ++	int s;
    ++	for (s = 0; s <= (int)maxSymbolValue; ++s) {
    ++		nbBits += CTable[s].nbBits * count[s];
    ++	}
    ++	return nbBits >> 3;
    ++}
    ++
    ++static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
    ++  int bad = 0;
    ++  int s;
    ++  for (s = 0; s <= (int)maxSymbolValue; ++s) {
    ++	bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
    ++  }
    ++  return !bad;
    ++}
    ++
    ++static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
    ++{
    ++	BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
    ++}
    ++
    ++size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
    ++
    ++#define HUF_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
    ++
    ++#define HUF_FLUSHBITS_1(stream) \
    ++	if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)
    ++
    ++#define HUF_FLUSHBITS_2(stream) \
    ++	if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
    ++
    ++size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
    ++{
    ++	const BYTE* ip = (const BYTE*) src;
    ++	BYTE* const ostart = (BYTE*)dst;
    ++	BYTE* const oend = ostart + dstSize;
    ++	BYTE* op = ostart;
    ++	size_t n;
    ++	const unsigned fast = (dstSize >= HUF_BLOCKBOUND(srcSize));
    ++	BIT_CStream_t bitC;
    ++
    ++	/* init */
    ++	if (dstSize < 8) return 0;   /* not enough space to compress */
    ++	{ size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
    ++	  if (HUF_isError(initErr)) return 0; }
    ++
    ++	n = srcSize & ~3;  /* join to mod 4 */
    ++	switch (srcSize & 3)
    ++	{
    ++		case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
    ++				 HUF_FLUSHBITS_2(&bitC);
    ++		case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
    ++				 HUF_FLUSHBITS_1(&bitC);
    ++		case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
    ++				 HUF_FLUSHBITS(&bitC);
    ++		case 0 :
    ++		default: ;
    ++	}
    ++
    ++	for (; n>0; n-=4) {  /* note : n&3==0 at this stage */
    ++		HUF_encodeSymbol(&bitC, ip[n- 1], CTable);
    ++		HUF_FLUSHBITS_1(&bitC);
    ++		HUF_encodeSymbol(&bitC, ip[n- 2], CTable);
    ++		HUF_FLUSHBITS_2(&bitC);
    ++		HUF_encodeSymbol(&bitC, ip[n- 3], CTable);
    ++		HUF_FLUSHBITS_1(&bitC);
    ++		HUF_encodeSymbol(&bitC, ip[n- 4], CTable);
    ++		HUF_FLUSHBITS(&bitC);
    ++	}
    ++
    ++	return BIT_closeCStream(&bitC);
    ++}
    ++
    ++
    ++size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
    ++{
    ++	size_t const segmentSize = (srcSize+3)/4;   /* first 3 segments */
    ++	const BYTE* ip = (const BYTE*) src;
    ++	const BYTE* const iend = ip + srcSize;
    ++	BYTE* const ostart = (BYTE*) dst;
    ++	BYTE* const oend = ostart + dstSize;
    ++	BYTE* op = ostart;
    ++
    ++	if (dstSize < 6 + 1 + 1 + 1 + 8) return 0;   /* minimum space to compress successfully */
    ++	if (srcSize < 12) return 0;   /* no saving possible : too small input */
    ++	op += 6;   /* jumpTable */
    ++
    ++	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++		if (cSize==0) return 0;
    ++		MEM_writeLE16(ostart, (U16)cSize);
    ++		op += cSize;
    ++	}
    ++
    ++	ip += segmentSize;
    ++	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++		if (cSize==0) return 0;
    ++		MEM_writeLE16(ostart+2, (U16)cSize);
    ++		op += cSize;
    ++	}
    ++
    ++	ip += segmentSize;
    ++	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++		if (cSize==0) return 0;
    ++		MEM_writeLE16(ostart+4, (U16)cSize);
    ++		op += cSize;
    ++	}
    ++
    ++	ip += segmentSize;
    ++	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
    ++		if (cSize==0) return 0;
    ++		op += cSize;
    ++	}
    ++
    ++	return op-ostart;
    ++}
    ++
    ++
    ++static size_t HUF_compressCTable_internal(
    ++				BYTE* const ostart, BYTE* op, BYTE* const oend,
    ++				const void* src, size_t srcSize,
    ++				unsigned singleStream, const HUF_CElt* CTable)
    ++{
    ++	size_t const cSize = singleStream ?
    ++						 HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) :
    ++						 HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
    ++	if (HUF_isError(cSize)) { return cSize; }
    ++	if (cSize==0) { return 0; }   /* uncompressible */
    ++	op += cSize;
    ++	/* check compressibility */
    ++	if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
    ++	return op-ostart;
    ++}
    ++
    ++
    ++/* `workSpace` must a table of at least 1024 unsigned */
    ++static size_t HUF_compress_internal (
    ++				void* dst, size_t dstSize,
    ++				const void* src, size_t srcSize,
    ++				unsigned maxSymbolValue, unsigned huffLog,
    ++				unsigned singleStream,
    ++				void* workSpace, size_t wkspSize,
    ++				HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat)
    ++{
    ++	BYTE* const ostart = (BYTE*)dst;
    ++	BYTE* const oend = ostart + dstSize;
    ++	BYTE* op = ostart;
    ++
    ++	U32* count;
    ++	size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1);
    ++	HUF_CElt* CTable;
    ++	size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1);
    ++
    ++	/* checks & inits */
    ++	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
    ++	if (!srcSize) return 0;  /* Uncompressed (note : 1 means rle, so first byte must be correct) */
    ++	if (!dstSize) return 0;  /* cannot fit within dst budget */
    ++	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* current block size limit */
    ++	if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    ++	if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
    ++	if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
    ++
    ++	count = (U32*)workSpace;
    ++	workSpace = (BYTE*)workSpace + countSize;
    ++	wkspSize -= countSize;
    ++	CTable = (HUF_CElt*)workSpace;
    ++	workSpace = (BYTE*)workSpace + CTableSize;
    ++	wkspSize -= CTableSize;
    ++
    ++	/* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */
    ++	if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
    ++		return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
    ++	}
    ++
    ++	/* Scan input and build symbol stats */
    ++	{   CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
    ++		if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */
    ++		if (largest <= (srcSize >> 7)+1) return 0;   /* Fast heuristic : not compressible enough */
    ++	}
    ++
    ++	/* Check validity of previous table */
    ++	if (repeat && *repeat == HUF_repeat_check && !HUF_validateCTable(oldHufTable, count, maxSymbolValue)) {
    ++		*repeat = HUF_repeat_none;
    ++	}
    ++	/* Heuristic : use existing table for small inputs */
    ++	if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
    ++		return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
    ++	}
    ++
    ++	/* Build Huffman Tree */
    ++	huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
    ++	{   CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
    ++		huffLog = (U32)maxBits;
    ++		/* Zero the unused symbols so we can check it for validity */
    ++		memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
    ++	}
    ++
    ++	/* Write table description header */
    ++	{   CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
    ++		/* Check if using the previous table will be beneficial */
    ++		if (repeat && *repeat != HUF_repeat_none) {
    ++			size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
    ++			size_t const newSize = HUF_estimateCompressedSize(CTable, count, maxSymbolValue);
    ++			if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
    ++				return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
    ++			}
    ++		}
    ++		/* Use the new table */
    ++		if (hSize + 12ul >= srcSize) { return 0; }
    ++		op += hSize;
    ++		if (repeat) { *repeat = HUF_repeat_none; }
    ++		if (oldHufTable) { memcpy(oldHufTable, CTable, CTableSize); } /* Save the new table */
    ++	}
    ++	return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable);
    ++}
    ++
    ++
    ++size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
    ++					  const void* src, size_t srcSize,
    ++					  unsigned maxSymbolValue, unsigned huffLog,
    ++					  void* workSpace, size_t wkspSize)
    ++{
    ++	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0);
    ++}
    ++
    ++size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
    ++					  const void* src, size_t srcSize,
    ++					  unsigned maxSymbolValue, unsigned huffLog,
    ++					  void* workSpace, size_t wkspSize,
    ++					  HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
    ++{
    ++	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
    ++}
    ++
    ++size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
    ++					  const void* src, size_t srcSize,
    ++					  unsigned maxSymbolValue, unsigned huffLog,
    ++					  void* workSpace, size_t wkspSize)
    ++{
    ++	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0);
    ++}
    ++
    ++size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
    ++					  const void* src, size_t srcSize,
    ++					  unsigned maxSymbolValue, unsigned huffLog,
    ++					  void* workSpace, size_t wkspSize,
    ++					  HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
    ++{
    ++	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
    ++}
    +diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c
    +new file mode 100644
    +index 0000000..f73223c
    +--- /dev/null
    ++++ b/lib/zstd/huf_decompress.c
    +@@ -0,0 +1,835 @@
    ++/* ******************************************************************
    ++   Huffman decoder, part of New Generation Entropy library
    ++   Copyright (C) 2013-2016, Yann Collet.
    ++
    ++   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++
    ++   Redistribution and use in source and binary forms, with or without
    ++   modification, are permitted provided that the following conditions are
    ++   met:
    ++
    ++	   * Redistributions of source code must retain the above copyright
    ++   notice, this list of conditions and the following disclaimer.
    ++	   * Redistributions in binary form must reproduce the above
    ++   copyright notice, this list of conditions and the following disclaimer
    ++   in the documentation and/or other materials provided with the
    ++   distribution.
    ++
    ++   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++
    ++	You can contact the author at :
    ++	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    ++****************************************************************** */
    ++
    ++/* **************************************************************
    ++*  Compiler specifics
    ++****************************************************************/
    ++#define FORCE_INLINE static __always_inline
    ++
    ++
    ++/* **************************************************************
    ++*  Dependencies
    ++****************************************************************/
    ++#include 
    ++#include      /* memcpy, memset */
    ++#include "bitstream.h"  /* BIT_* */
    ++#include "fse.h"        /* header compression */
    ++#include "huf.h"
    ++
    ++
    ++/* **************************************************************
    ++*  Error Management
    ++****************************************************************/
    ++#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    ++
    ++
    ++/*-***************************/
    ++/*  generic DTableDesc       */
    ++/*-***************************/
    ++
    ++typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
    ++
    ++static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
    ++{
    ++	DTableDesc dtd;
    ++	memcpy(&dtd, table, sizeof(dtd));
    ++	return dtd;
    ++}
    ++
    ++
    ++/*-***************************/
    ++/*  single-symbol decoding   */
    ++/*-***************************/
    ++
    ++typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2;   /* single-symbol decoding */
    ++
    ++size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
    ++{
    ++	BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
    ++	U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */
    ++	U32 tableLog = 0;
    ++	U32 nbSymbols = 0;
    ++	size_t iSize;
    ++	void* const dtPtr = DTable + 1;
    ++	HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
    ++
    ++	HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
    ++	/* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
    ++
    ++	iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
    ++	if (HUF_isError(iSize)) return iSize;
    ++
    ++	/* Table header */
    ++	{   DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++		if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
    ++		dtd.tableType = 0;
    ++		dtd.tableLog = (BYTE)tableLog;
    ++		memcpy(DTable, &dtd, sizeof(dtd));
    ++	}
    ++
    ++	/* Calculate starting value for each rank */
    ++	{   U32 n, nextRankStart = 0;
    ++		for (n=1; n> 1;
    ++			U32 u;
    ++			HUF_DEltX2 D;
    ++			D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
    ++			for (u = rankVal[w]; u < rankVal[w] + length; u++)
    ++				dt[u] = D;
    ++			rankVal[w] += length;
    ++	}   }
    ++
    ++	return iSize;
    ++}
    ++
    ++
    ++static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
    ++{
    ++	size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
    ++	BYTE const c = dt[val].byte;
    ++	BIT_skipBits(Dstream, dt[val].nbBits);
    ++	return c;
    ++}
    ++
    ++#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
    ++	*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
    ++
    ++#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
    ++	if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
    ++		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
    ++
    ++#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
    ++	if (MEM_64bits()) \
    ++		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
    ++
    ++FORCE_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)
    ++{
    ++	BYTE* const pStart = p;
    ++
    ++	/* up to 4 symbols at a time */
    ++	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4)) {
    ++		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
    ++	}
    ++
    ++	/* closer to the end */
    ++	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))
    ++		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
    ++
    ++	/* no more data to retrieve from bitstream, hence no need to reload */
    ++	while (p < pEnd)
    ++		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
    ++
    ++	return pEnd-pStart;
    ++}
    ++
    ++static size_t HUF_decompress1X2_usingDTable_internal(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	BYTE* op = (BYTE*)dst;
    ++	BYTE* const oend = op + dstSize;
    ++	const void* dtPtr = DTable + 1;
    ++	const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
    ++	BIT_DStream_t bitD;
    ++	DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++	U32 const dtLog = dtd.tableLog;
    ++
    ++	{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    ++	  if (HUF_isError(errorCode)) return errorCode; }
    ++
    ++	HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);
    ++
    ++	/* check */
    ++	if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
    ++
    ++	return dstSize;
    ++}
    ++
    ++size_t HUF_decompress1X2_usingDTable(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	if (dtd.tableType != 0) return ERROR(GENERIC);
    ++	return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*) cSrc;
    ++
    ++	size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize);
    ++	if (HUF_isError(hSize)) return hSize;
    ++	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    ++	ip += hSize; cSrcSize -= hSize;
    ++
    ++	return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
    ++}
    ++
    ++
    ++static size_t HUF_decompress4X2_usingDTable_internal(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	/* Check */
    ++	if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
    ++
    ++	{   const BYTE* const istart = (const BYTE*) cSrc;
    ++		BYTE* const ostart = (BYTE*) dst;
    ++		BYTE* const oend = ostart + dstSize;
    ++		const void* const dtPtr = DTable + 1;
    ++		const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
    ++
    ++		/* Init */
    ++		BIT_DStream_t bitD1;
    ++		BIT_DStream_t bitD2;
    ++		BIT_DStream_t bitD3;
    ++		BIT_DStream_t bitD4;
    ++		size_t const length1 = MEM_readLE16(istart);
    ++		size_t const length2 = MEM_readLE16(istart+2);
    ++		size_t const length3 = MEM_readLE16(istart+4);
    ++		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
    ++		const BYTE* const istart1 = istart + 6;  /* jumpTable */
    ++		const BYTE* const istart2 = istart1 + length1;
    ++		const BYTE* const istart3 = istart2 + length2;
    ++		const BYTE* const istart4 = istart3 + length3;
    ++		const size_t segmentSize = (dstSize+3) / 4;
    ++		BYTE* const opStart2 = ostart + segmentSize;
    ++		BYTE* const opStart3 = opStart2 + segmentSize;
    ++		BYTE* const opStart4 = opStart3 + segmentSize;
    ++		BYTE* op1 = ostart;
    ++		BYTE* op2 = opStart2;
    ++		BYTE* op3 = opStart3;
    ++		BYTE* op4 = opStart4;
    ++		U32 endSignal;
    ++		DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++		U32 const dtLog = dtd.tableLog;
    ++
    ++		if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
    ++		{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++
    ++		/* 16-32 symbols per loop (4-8 symbols per stream) */
    ++		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    ++		for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) {
    ++			HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
    ++			endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    ++		}
    ++
    ++		/* check corruption */
    ++		if (op1 > opStart2) return ERROR(corruption_detected);
    ++		if (op2 > opStart3) return ERROR(corruption_detected);
    ++		if (op3 > opStart4) return ERROR(corruption_detected);
    ++		/* note : op4 supposed already verified within main loop */
    ++
    ++		/* finish bitStreams one by one */
    ++		HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
    ++		HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
    ++		HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
    ++		HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
    ++
    ++		/* check */
    ++		endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
    ++		if (!endSignal) return ERROR(corruption_detected);
    ++
    ++		/* decoded size */
    ++		return dstSize;
    ++	}
    ++}
    ++
    ++
    ++size_t HUF_decompress4X2_usingDTable(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	if (dtd.tableType != 0) return ERROR(GENERIC);
    ++	return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++
    ++size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*) cSrc;
    ++
    ++	size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize);
    ++	if (HUF_isError(hSize)) return hSize;
    ++	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    ++	ip += hSize; cSrcSize -= hSize;
    ++
    ++	return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
    ++}
    ++
    ++/* *************************/
    ++/* double-symbols decoding */
    ++/* *************************/
    ++typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4;  /* double-symbols decoding */
    ++
    ++typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
    ++
    ++/* HUF_fillDTableX4Level2() :
    ++ * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
    ++static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
    ++						   const U32* rankValOrigin, const int minWeight,
    ++						   const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
    ++						   U32 nbBitsBaseline, U16 baseSeq)
    ++{
    ++	HUF_DEltX4 DElt;
    ++	U32 rankVal[HUF_TABLELOG_MAX + 1];
    ++
    ++	/* get pre-calculated rankVal */
    ++	memcpy(rankVal, rankValOrigin, sizeof(rankVal));
    ++
    ++	/* fill skipped values */
    ++	if (minWeight>1) {
    ++		U32 i, skipSize = rankVal[minWeight];
    ++		MEM_writeLE16(&(DElt.sequence), baseSeq);
    ++		DElt.nbBits   = (BYTE)(consumed);
    ++		DElt.length   = 1;
    ++		for (i = 0; i < skipSize; i++)
    ++			DTable[i] = DElt;
    ++	}
    ++
    ++	/* fill DTable */
    ++	{   U32 s; for (s=0; s= 1 */
    ++
    ++			rankVal[weight] += length;
    ++	}   }
    ++}
    ++
    ++typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
    ++
    ++static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
    ++						   const sortedSymbol_t* sortedList, const U32 sortedListSize,
    ++						   const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
    ++						   const U32 nbBitsBaseline)
    ++{
    ++	U32 rankVal[HUF_TABLELOG_MAX + 1];
    ++	const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
    ++	const U32 minBits  = nbBitsBaseline - maxWeight;
    ++	U32 s;
    ++
    ++	memcpy(rankVal, rankValOrigin, sizeof(rankVal));
    ++
    ++	/* fill DTable */
    ++	for (s=0; s= minBits) {   /* enough room for a second symbol */
    ++			U32 sortedRank;
    ++			int minWeight = nbBits + scaleLog;
    ++			if (minWeight < 1) minWeight = 1;
    ++			sortedRank = rankStart[minWeight];
    ++			HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
    ++						   rankValOrigin[nbBits], minWeight,
    ++						   sortedList+sortedRank, sortedListSize-sortedRank,
    ++						   nbBitsBaseline, symbol);
    ++		} else {
    ++			HUF_DEltX4 DElt;
    ++			MEM_writeLE16(&(DElt.sequence), symbol);
    ++			DElt.nbBits = (BYTE)(nbBits);
    ++			DElt.length = 1;
    ++			{   U32 const end = start + length;
    ++				U32 u;
    ++				for (u = start; u < end; u++) DTable[u] = DElt;
    ++		}   }
    ++		rankVal[weight] += length;
    ++	}
    ++}
    ++
    ++size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
    ++{
    ++	BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
    ++	sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
    ++	U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 };
    ++	U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 };
    ++	U32* const rankStart = rankStart0+1;
    ++	rankVal_t rankVal;
    ++	U32 tableLog, maxW, sizeOfSort, nbSymbols;
    ++	DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	U32 const maxTableLog = dtd.maxTableLog;
    ++	size_t iSize;
    ++	void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
    ++	HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
    ++
    ++	HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */
    ++	if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    ++	/* memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */
    ++
    ++	iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
    ++	if (HUF_isError(iSize)) return iSize;
    ++
    ++	/* check result */
    ++	if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
    ++
    ++	/* find maxWeight */
    ++	for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
    ++
    ++	/* Get start index of each weight */
    ++	{   U32 w, nextRankStart = 0;
    ++		for (w=1; w> consumed;
    ++	}   }   }   }
    ++
    ++	HUF_fillDTableX4(dt, maxTableLog,
    ++				   sortedSymbol, sizeOfSort,
    ++				   rankStart0, rankVal, maxW,
    ++				   tableLog+1);
    ++
    ++	dtd.tableLog = (BYTE)maxTableLog;
    ++	dtd.tableType = 1;
    ++	memcpy(DTable, &dtd, sizeof(dtd));
    ++	return iSize;
    ++}
    ++
    ++
    ++static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
    ++{
    ++	size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
    ++	memcpy(op, dt+val, 2);
    ++	BIT_skipBits(DStream, dt[val].nbBits);
    ++	return dt[val].length;
    ++}
    ++
    ++static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
    ++{
    ++	size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
    ++	memcpy(op, dt+val, 1);
    ++	if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
    ++	else {
    ++		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
    ++			BIT_skipBits(DStream, dt[val].nbBits);
    ++			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
    ++				DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);   /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    ++	}   }
    ++	return 1;
    ++}
    ++
    ++
    ++#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
    ++	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
    ++
    ++#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
    ++	if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
    ++		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
    ++
    ++#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
    ++	if (MEM_64bits()) \
    ++		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
    ++
    ++FORCE_INLINE size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)
    ++{
    ++	BYTE* const pStart = p;
    ++
    ++	/* up to 8 symbols at a time */
    ++	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
    ++		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
    ++		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
    ++	}
    ++
    ++	/* closer to end : up to 2 symbols at a time */
    ++	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
    ++		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
    ++
    ++	while (p <= pEnd-2)
    ++		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
    ++
    ++	if (p < pEnd)
    ++		p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
    ++
    ++	return p-pStart;
    ++}
    ++
    ++
    ++static size_t HUF_decompress1X4_usingDTable_internal(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	BIT_DStream_t bitD;
    ++
    ++	/* Init */
    ++	{   size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    ++		if (HUF_isError(errorCode)) return errorCode;
    ++	}
    ++
    ++	/* decode */
    ++	{   BYTE* const ostart = (BYTE*) dst;
    ++		BYTE* const oend = ostart + dstSize;
    ++		const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
    ++		const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
    ++		DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++		HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
    ++	}
    ++
    ++	/* check */
    ++	if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
    ++
    ++	/* decoded size */
    ++	return dstSize;
    ++}
    ++
    ++size_t HUF_decompress1X4_usingDTable(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	if (dtd.tableType != 1) return ERROR(GENERIC);
    ++	return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*) cSrc;
    ++
    ++	size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize);
    ++	if (HUF_isError(hSize)) return hSize;
    ++	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    ++	ip += hSize; cSrcSize -= hSize;
    ++
    ++	return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
    ++}
    ++
    ++static size_t HUF_decompress4X4_usingDTable_internal(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
    ++
    ++	{   const BYTE* const istart = (const BYTE*) cSrc;
    ++		BYTE* const ostart = (BYTE*) dst;
    ++		BYTE* const oend = ostart + dstSize;
    ++		const void* const dtPtr = DTable+1;
    ++		const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
    ++
    ++		/* Init */
    ++		BIT_DStream_t bitD1;
    ++		BIT_DStream_t bitD2;
    ++		BIT_DStream_t bitD3;
    ++		BIT_DStream_t bitD4;
    ++		size_t const length1 = MEM_readLE16(istart);
    ++		size_t const length2 = MEM_readLE16(istart+2);
    ++		size_t const length3 = MEM_readLE16(istart+4);
    ++		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
    ++		const BYTE* const istart1 = istart + 6;  /* jumpTable */
    ++		const BYTE* const istart2 = istart1 + length1;
    ++		const BYTE* const istart3 = istart2 + length2;
    ++		const BYTE* const istart4 = istart3 + length3;
    ++		size_t const segmentSize = (dstSize+3) / 4;
    ++		BYTE* const opStart2 = ostart + segmentSize;
    ++		BYTE* const opStart3 = opStart2 + segmentSize;
    ++		BYTE* const opStart4 = opStart3 + segmentSize;
    ++		BYTE* op1 = ostart;
    ++		BYTE* op2 = opStart2;
    ++		BYTE* op3 = opStart3;
    ++		BYTE* op4 = opStart4;
    ++		U32 endSignal;
    ++		DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++		U32 const dtLog = dtd.tableLog;
    ++
    ++		if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
    ++		{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++		{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    ++		  if (HUF_isError(errorCode)) return errorCode; }
    ++
    ++		/* 16-32 symbols per loop (4-8 symbols per stream) */
    ++		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    ++		for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
    ++			HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX4_1(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX4_1(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX4_1(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX4_1(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
    ++			HUF_DECODE_SYMBOLX4_0(op1, &bitD1);
    ++			HUF_DECODE_SYMBOLX4_0(op2, &bitD2);
    ++			HUF_DECODE_SYMBOLX4_0(op3, &bitD3);
    ++			HUF_DECODE_SYMBOLX4_0(op4, &bitD4);
    ++
    ++			endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    ++		}
    ++
    ++		/* check corruption */
    ++		if (op1 > opStart2) return ERROR(corruption_detected);
    ++		if (op2 > opStart3) return ERROR(corruption_detected);
    ++		if (op3 > opStart4) return ERROR(corruption_detected);
    ++		/* note : op4 already verified within main loop */
    ++
    ++		/* finish bitStreams one by one */
    ++		HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
    ++		HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
    ++		HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
    ++		HUF_decodeStreamX4(op4, &bitD4, oend,     dt, dtLog);
    ++
    ++		/* check */
    ++		{ U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
    ++		  if (!endCheck) return ERROR(corruption_detected); }
    ++
    ++		/* decoded size */
    ++		return dstSize;
    ++	}
    ++}
    ++
    ++
    ++size_t HUF_decompress4X4_usingDTable(
    ++		  void* dst,  size_t dstSize,
    ++	const void* cSrc, size_t cSrcSize,
    ++	const HUF_DTable* DTable)
    ++{
    ++	DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	if (dtd.tableType != 1) return ERROR(GENERIC);
    ++	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++
    ++size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	const BYTE* ip = (const BYTE*) cSrc;
    ++
    ++	size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize);
    ++	if (HUF_isError(hSize)) return hSize;
    ++	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    ++	ip += hSize; cSrcSize -= hSize;
    ++
    ++	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
    ++}
    ++
    ++
    ++/* ********************************/
    ++/* Generic decompression selector */
    ++/* ********************************/
    ++
    ++size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
    ++									const void* cSrc, size_t cSrcSize,
    ++									const HUF_DTable* DTable)
    ++{
    ++	DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++	return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
    ++						   HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
    ++									const void* cSrc, size_t cSrcSize,
    ++									const HUF_DTable* DTable)
    ++{
    ++	DTableDesc const dtd = HUF_getDTableDesc(DTable);
    ++	return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
    ++						   HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
    ++}
    ++
    ++
    ++typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
    ++static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
    ++{
    ++	/* single, double, quad */
    ++	{{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */
    ++	{{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */
    ++	{{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */
    ++	{{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */
    ++	{{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */
    ++	{{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */
    ++	{{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */
    ++	{{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */
    ++	{{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */
    ++	{{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */
    ++	{{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
    ++	{{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
    ++	{{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
    ++	{{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */
    ++	{{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */
    ++	{{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */
    ++};
    ++
    ++/** HUF_selectDecoder() :
    ++*   Tells which decoder is likely to decode faster,
    ++*   based on a set of pre-determined metrics.
    ++*   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
    ++*   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
    ++U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
    ++{
    ++	/* decoder timing evaluation */
    ++	U32 const Q = (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 since dstSize > cSrcSize */
    ++	U32 const D256 = (U32)(dstSize >> 8);
    ++	U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
    ++	U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
    ++	DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, for cache eviction */
    ++
    ++	return DTime1 < DTime0;
    ++}
    ++
    ++
    ++typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
    ++
    ++size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	/* validation checks */
    ++	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    ++	if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
    ++	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
    ++	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
    ++
    ++	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    ++		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    ++						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    ++	}
    ++}
    ++
    ++size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	/* validation checks */
    ++	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    ++	if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
    ++
    ++	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    ++		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    ++						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    ++	}
    ++}
    ++
    ++size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    ++{
    ++	/* validation checks */
    ++	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    ++	if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
    ++	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
    ++	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
    ++
    ++	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    ++		return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    ++						HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    ++	}
    ++}
    +diff --git a/lib/zstd/mem.h b/lib/zstd/mem.h
    +new file mode 100644
    +index 0000000..76cae04
    +--- /dev/null
    ++++ b/lib/zstd/mem.h
    +@@ -0,0 +1,209 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++#ifndef MEM_H_MODULE
    ++#define MEM_H_MODULE
    ++
    ++/*-****************************************
    ++*  Dependencies
    ++******************************************/
    ++#include 
    ++#include      /* size_t, ptrdiff_t */
    ++#include      /* memcpy */
    ++
    ++
    ++/*-****************************************
    ++*  Compiler specifics
    ++******************************************/
    ++#define MEM_STATIC static __inline __attribute__((unused))
    ++
    ++/* code only tested on 32 and 64 bits systems */
    ++#define MEM_STATIC_ASSERT(c)   { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
    ++MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
    ++
    ++
    ++/*-**************************************************************
    ++*  Basic Types
    ++*****************************************************************/
    ++typedef   uint8_t BYTE;
    ++typedef  uint16_t U16;
    ++typedef   int16_t S16;
    ++typedef  uint32_t U32;
    ++typedef   int32_t S32;
    ++typedef  uint64_t U64;
    ++typedef   int64_t S64;
    ++typedef ptrdiff_t iPtrDiff;
    ++typedef uintptr_t uPtrDiff;
    ++
    ++
    ++/*-**************************************************************
    ++*  Memory I/O
    ++*****************************************************************/
    ++MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
    ++MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
    ++
    ++#if defined(__LITTLE_ENDIAN)
    ++#   define MEM_LITTLE_ENDIAN 1
    ++#else
    ++#   define MEM_LITTLE_ENDIAN 0
    ++#endif
    ++
    ++MEM_STATIC unsigned MEM_isLittleEndian(void)
    ++{
    ++	return MEM_LITTLE_ENDIAN;
    ++}
    ++
    ++MEM_STATIC U16 MEM_read16(const void* memPtr)
    ++{
    ++	return get_unaligned((const U16*)memPtr);
    ++}
    ++
    ++MEM_STATIC U32 MEM_read32(const void* memPtr)
    ++{
    ++	return get_unaligned((const U32*)memPtr);
    ++}
    ++
    ++MEM_STATIC U64 MEM_read64(const void* memPtr)
    ++{
    ++	return get_unaligned((const U64*)memPtr);
    ++}
    ++
    ++MEM_STATIC size_t MEM_readST(const void* memPtr)
    ++{
    ++	return get_unaligned((const size_t*)memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_write16(void* memPtr, U16 value)
    ++{
    ++	put_unaligned(value, (U16*)memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_write32(void* memPtr, U32 value)
    ++{
    ++	put_unaligned(value, (U32*)memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_write64(void* memPtr, U64 value)
    ++{
    ++	put_unaligned(value, (U64*)memPtr);
    ++}
    ++
    ++/*=== Little endian r/w ===*/
    ++
    ++MEM_STATIC U16 MEM_readLE16(const void* memPtr)
    ++{
    ++	return get_unaligned_le16(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
    ++{
    ++	put_unaligned_le16(val, memPtr);
    ++}
    ++
    ++MEM_STATIC U32 MEM_readLE24(const void* memPtr)
    ++{
    ++	return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
    ++}
    ++
    ++MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
    ++{
    ++	MEM_writeLE16(memPtr, (U16)val);
    ++	((BYTE*)memPtr)[2] = (BYTE)(val>>16);
    ++}
    ++
    ++MEM_STATIC U32 MEM_readLE32(const void* memPtr)
    ++{
    ++	return get_unaligned_le32(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
    ++{
    ++	put_unaligned_le32(val32, memPtr);
    ++}
    ++
    ++MEM_STATIC U64 MEM_readLE64(const void* memPtr)
    ++{
    ++	return get_unaligned_le64(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
    ++{
    ++	put_unaligned_le64(val64, memPtr);
    ++}
    ++
    ++MEM_STATIC size_t MEM_readLEST(const void* memPtr)
    ++{
    ++	if (MEM_32bits())
    ++		return (size_t)MEM_readLE32(memPtr);
    ++	else
    ++		return (size_t)MEM_readLE64(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
    ++{
    ++	if (MEM_32bits())
    ++		MEM_writeLE32(memPtr, (U32)val);
    ++	else
    ++		MEM_writeLE64(memPtr, (U64)val);
    ++}
    ++
    ++/*=== Big endian r/w ===*/
    ++
    ++MEM_STATIC U32 MEM_readBE32(const void* memPtr)
    ++{
    ++	return get_unaligned_be32(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
    ++{
    ++	put_unaligned_be32(val32, memPtr);
    ++}
    ++
    ++MEM_STATIC U64 MEM_readBE64(const void* memPtr)
    ++{
    ++	return get_unaligned_be64(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
    ++{
    ++	put_unaligned_be64(val64, memPtr);
    ++}
    ++
    ++MEM_STATIC size_t MEM_readBEST(const void* memPtr)
    ++{
    ++	if (MEM_32bits())
    ++		return (size_t)MEM_readBE32(memPtr);
    ++	else
    ++		return (size_t)MEM_readBE64(memPtr);
    ++}
    ++
    ++MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
    ++{
    ++	if (MEM_32bits())
    ++		MEM_writeBE32(memPtr, (U32)val);
    ++	else
    ++		MEM_writeBE64(memPtr, (U64)val);
    ++}
    ++
    ++
    ++/* function safe only for comparisons */
    ++MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
    ++{
    ++	switch (length)
    ++	{
    ++	default :
    ++	case 4 : return MEM_read32(memPtr);
    ++	case 3 : if (MEM_isLittleEndian())
    ++				return MEM_read32(memPtr)<<8;
    ++			 else
    ++				return MEM_read32(memPtr)>>8;
    ++	}
    ++}
    ++
    ++#endif /* MEM_H_MODULE */
    +diff --git a/lib/zstd/zstd_common.c b/lib/zstd/zstd_common.c
    +new file mode 100644
    +index 0000000..106f540
    +--- /dev/null
    ++++ b/lib/zstd/zstd_common.c
    +@@ -0,0 +1,69 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++
    ++
    ++/*-*************************************
    ++*  Dependencies
    ++***************************************/
    ++#include "error_private.h"
    ++#include "zstd_internal.h"           /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
    ++#include 
    ++
    ++
    ++/*=**************************************************************
    ++*  Custom allocator
    ++****************************************************************/
    ++
    ++#define stack_push(stack, size) ({                                             \
    ++		void* const ptr = ZSTD_PTR_ALIGN((stack)->ptr);                            \
    ++		(stack)->ptr = (char*)ptr + (size);                                        \
    ++		(stack)->ptr <= (stack)->end ? ptr : NULL;                                 \
    ++	})
    ++
    ++ZSTD_customMem ZSTD_initStack(void* workspace, size_t workspaceSize) {
    ++	ZSTD_customMem stackMem = { ZSTD_stackAlloc, ZSTD_stackFree, workspace };
    ++	ZSTD_stack* stack = (ZSTD_stack*) workspace;
    ++	/* Verify preconditions */
    ++	if (!workspace || workspaceSize < sizeof(ZSTD_stack) || workspace != ZSTD_PTR_ALIGN(workspace)) {
    ++		ZSTD_customMem error = {NULL, NULL, NULL};
    ++		return error;
    ++	}
    ++	/* Initialize the stack */
    ++	stack->ptr = workspace;
    ++	stack->end = (char*)workspace + workspaceSize;
    ++	stack_push(stack, sizeof(ZSTD_stack));
    ++	return stackMem;
    ++}
    ++
    ++void* ZSTD_stackAllocAll(void* opaque, size_t* size) {
    ++	ZSTD_stack* stack = (ZSTD_stack*)opaque;
    ++	*size = stack->end - ZSTD_PTR_ALIGN(stack->ptr);
    ++	return stack_push(stack, *size);
    ++}
    ++
    ++void* ZSTD_stackAlloc(void* opaque, size_t size) {
    ++	ZSTD_stack* stack = (ZSTD_stack*)opaque;
    ++	return stack_push(stack, size);
    ++}
    ++void ZSTD_stackFree(void* opaque, void* address) {
    ++	(void)opaque;
    ++	(void)address;
    ++}
    ++
    ++void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
    ++{
    ++	return customMem.customAlloc(customMem.opaque, size);
    ++}
    ++
    ++void ZSTD_free(void* ptr, ZSTD_customMem customMem)
    ++{
    ++	if (ptr!=NULL)
    ++		customMem.customFree(customMem.opaque, ptr);
    ++}
    +diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h
    +new file mode 100644
    +index 0000000..a61bd27
    +--- /dev/null
    ++++ b/lib/zstd/zstd_internal.h
    +@@ -0,0 +1,274 @@
    ++/**
    ++ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++#ifndef ZSTD_CCOMMON_H_MODULE
    ++#define ZSTD_CCOMMON_H_MODULE
    ++
    ++/*-*******************************************************
    ++*  Compiler specifics
    ++*********************************************************/
    ++#define FORCE_INLINE static __always_inline
    ++#define FORCE_NOINLINE static noinline
    ++
    ++
    ++/*-*************************************
    ++*  Dependencies
    ++***************************************/
    ++#include 
    ++#include 
    ++#include 
    ++#include 
    ++#include "mem.h"
    ++#include "error_private.h"
    ++
    ++
    ++/*-*************************************
    ++*  shared macros
    ++***************************************/
    ++#define MIN(a,b) ((a)<(b) ? (a) : (b))
    ++#define MAX(a,b) ((a)>(b) ? (a) : (b))
    ++#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; }  /* check and Forward error code */
    ++#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); }  /* check and send Error code */
    ++
    ++
    ++/*-*************************************
    ++*  Common constants
    ++***************************************/
    ++#define ZSTD_OPT_NUM    (1<<12)
    ++#define ZSTD_DICT_MAGIC  0xEC30A437   /* v0.7+ */
    ++
    ++#define ZSTD_REP_NUM      3                 /* number of repcodes */
    ++#define ZSTD_REP_CHECK    (ZSTD_REP_NUM)    /* number of repcodes to check by the optimal parser */
    ++#define ZSTD_REP_MOVE     (ZSTD_REP_NUM-1)
    ++#define ZSTD_REP_MOVE_OPT (ZSTD_REP_NUM)
    ++static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
    ++
    ++#define KB *(1 <<10)
    ++#define MB *(1 <<20)
    ++#define GB *(1U<<30)
    ++
    ++#define BIT7 128
    ++#define BIT6  64
    ++#define BIT5  32
    ++#define BIT4  16
    ++#define BIT1   2
    ++#define BIT0   1
    ++
    ++#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
    ++static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
    ++static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
    ++
    ++#define ZSTD_BLOCKHEADERSIZE 3   /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
    ++static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
    ++typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
    ++
    ++#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
    ++#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */
    ++
    ++#define HufLog 12
    ++typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
    ++
    ++#define LONGNBSEQ 0x7F00
    ++
    ++#define MINMATCH 3
    ++#define EQUAL_READ32 4
    ++
    ++#define Litbits  8
    ++#define MaxLit ((1<= 3)   /* GCC Intrinsic */
    ++	return 31 - __builtin_clz(val);
    ++#   else   /* Software version */
    ++	static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    ++	U32 v = val;
    ++	int r;
    ++	v |= v >> 1;
    ++	v |= v >> 2;
    ++	v |= v >> 4;
    ++	v |= v >> 8;
    ++	v |= v >> 16;
    ++	r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
    ++	return r;
    ++#   endif
    ++}
    ++
    ++
    ++/* hidden functions */
    ++
    ++/* ZSTD_invalidateRepCodes() :
    ++ * ensures next compression will not use repcodes from previous block.
    ++ * Note : only works with regular variant;
    ++ *        do not use with extDict variant ! */
    ++void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
    ++
    ++size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
    ++size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
    ++size_t ZSTD_freeCDict(ZSTD_CDict* cdict);
    ++size_t ZSTD_freeDDict(ZSTD_DDict* cdict);
    ++size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
    ++size_t ZSTD_freeDStream(ZSTD_DStream* zds);
    ++
    ++
    ++#endif   /* ZSTD_CCOMMON_H_MODULE */
    +diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h
    +new file mode 100644
    +index 0000000..297a715
    +--- /dev/null
    ++++ b/lib/zstd/zstd_opt.h
    +@@ -0,0 +1,921 @@
    ++/**
    ++ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This source code is licensed under the BSD-style license found in the
    ++ * LICENSE file in the root directory of this source tree. An additional grant
    ++ * of patent rights can be found in the PATENTS file in the same directory.
    ++ */
    ++
    ++
    ++/* Note : this file is intended to be included within zstd_compress.c */
    ++
    ++
    ++#ifndef ZSTD_OPT_H_91842398743
    ++#define ZSTD_OPT_H_91842398743
    ++
    ++
    ++#define ZSTD_LITFREQ_ADD    2
    ++#define ZSTD_FREQ_DIV       4
    ++#define ZSTD_MAX_PRICE      (1<<30)
    ++
    ++/*-*************************************
    ++*  Price functions for optimal parser
    ++***************************************/
    ++FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr)
    ++{
    ++	ssPtr->log2matchLengthSum = ZSTD_highbit32(ssPtr->matchLengthSum+1);
    ++	ssPtr->log2litLengthSum = ZSTD_highbit32(ssPtr->litLengthSum+1);
    ++	ssPtr->log2litSum = ZSTD_highbit32(ssPtr->litSum+1);
    ++	ssPtr->log2offCodeSum = ZSTD_highbit32(ssPtr->offCodeSum+1);
    ++	ssPtr->factor = 1 + ((ssPtr->litSum>>5) / ssPtr->litLengthSum) + ((ssPtr->litSum<<1) / (ssPtr->litSum + ssPtr->matchSum));
    ++}
    ++
    ++
    ++MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t srcSize)
    ++{
    ++	unsigned u;
    ++
    ++	ssPtr->cachedLiterals = NULL;
    ++	ssPtr->cachedPrice = ssPtr->cachedLitLength = 0;
    ++	ssPtr->staticPrices = 0;
    ++
    ++	if (ssPtr->litLengthSum == 0) {
    ++		if (srcSize <= 1024) ssPtr->staticPrices = 1;
    ++
    ++		for (u=0; u<=MaxLit; u++)
    ++			ssPtr->litFreq[u] = 0;
    ++		for (u=0; ulitFreq[src[u]]++;
    ++
    ++		ssPtr->litSum = 0;
    ++		ssPtr->litLengthSum = MaxLL+1;
    ++		ssPtr->matchLengthSum = MaxML+1;
    ++		ssPtr->offCodeSum = (MaxOff+1);
    ++		ssPtr->matchSum = (ZSTD_LITFREQ_ADD<litFreq[u] = 1 + (ssPtr->litFreq[u]>>ZSTD_FREQ_DIV);
    ++			ssPtr->litSum += ssPtr->litFreq[u];
    ++		}
    ++		for (u=0; u<=MaxLL; u++)
    ++			ssPtr->litLengthFreq[u] = 1;
    ++		for (u=0; u<=MaxML; u++)
    ++			ssPtr->matchLengthFreq[u] = 1;
    ++		for (u=0; u<=MaxOff; u++)
    ++			ssPtr->offCodeFreq[u] = 1;
    ++	} else {
    ++		ssPtr->matchLengthSum = 0;
    ++		ssPtr->litLengthSum = 0;
    ++		ssPtr->offCodeSum = 0;
    ++		ssPtr->matchSum = 0;
    ++		ssPtr->litSum = 0;
    ++
    ++		for (u=0; u<=MaxLit; u++) {
    ++			ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>(ZSTD_FREQ_DIV+1));
    ++			ssPtr->litSum += ssPtr->litFreq[u];
    ++		}
    ++		for (u=0; u<=MaxLL; u++) {
    ++			ssPtr->litLengthFreq[u] = 1 + (ssPtr->litLengthFreq[u]>>(ZSTD_FREQ_DIV+1));
    ++			ssPtr->litLengthSum += ssPtr->litLengthFreq[u];
    ++		}
    ++		for (u=0; u<=MaxML; u++) {
    ++			ssPtr->matchLengthFreq[u] = 1 + (ssPtr->matchLengthFreq[u]>>ZSTD_FREQ_DIV);
    ++			ssPtr->matchLengthSum += ssPtr->matchLengthFreq[u];
    ++			ssPtr->matchSum += ssPtr->matchLengthFreq[u] * (u + 3);
    ++		}
    ++		ssPtr->matchSum *= ZSTD_LITFREQ_ADD;
    ++		for (u=0; u<=MaxOff; u++) {
    ++			ssPtr->offCodeFreq[u] = 1 + (ssPtr->offCodeFreq[u]>>ZSTD_FREQ_DIV);
    ++			ssPtr->offCodeSum += ssPtr->offCodeFreq[u];
    ++		}
    ++	}
    ++
    ++	ZSTD_setLog2Prices(ssPtr);
    ++}
    ++
    ++
    ++FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BYTE* literals)
    ++{
    ++	U32 price, u;
    ++
    ++	if (ssPtr->staticPrices)
    ++		return ZSTD_highbit32((U32)litLength+1) + (litLength*6);
    ++
    ++	if (litLength == 0)
    ++		return ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[0]+1);
    ++
    ++	/* literals */
    ++	if (ssPtr->cachedLiterals == literals) {
    ++		U32 const additional = litLength - ssPtr->cachedLitLength;
    ++		const BYTE* literals2 = ssPtr->cachedLiterals + ssPtr->cachedLitLength;
    ++		price = ssPtr->cachedPrice + additional * ssPtr->log2litSum;
    ++		for (u=0; u < additional; u++)
    ++			price -= ZSTD_highbit32(ssPtr->litFreq[literals2[u]]+1);
    ++		ssPtr->cachedPrice = price;
    ++		ssPtr->cachedLitLength = litLength;
    ++	} else {
    ++		price = litLength * ssPtr->log2litSum;
    ++		for (u=0; u < litLength; u++)
    ++			price -= ZSTD_highbit32(ssPtr->litFreq[literals[u]]+1);
    ++
    ++		if (litLength >= 12) {
    ++			ssPtr->cachedLiterals = literals;
    ++			ssPtr->cachedPrice = price;
    ++			ssPtr->cachedLitLength = litLength;
    ++		}
    ++	}
    ++
    ++	/* literal Length */
    ++	{   const BYTE LL_deltaCode = 19;
    ++		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
    ++		price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
    ++	}
    ++
    ++	return price;
    ++}
    ++
    ++
    ++FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra)
    ++{
    ++	/* offset */
    ++	U32 price;
    ++	BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
    ++
    ++	if (seqStorePtr->staticPrices)
    ++		return ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + ZSTD_highbit32((U32)matchLength+1) + 16 + offCode;
    ++
    ++	price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
    ++	if (!ultra && offCode >= 20) price += (offCode-19)*2;
    ++
    ++	/* match Length */
    ++	{   const BYTE ML_deltaCode = 36;
    ++		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
    ++		price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
    ++	}
    ++
    ++	return price + ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + seqStorePtr->factor;
    ++}
    ++
    ++
    ++MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
    ++{
    ++	U32 u;
    ++
    ++	/* literals */
    ++	seqStorePtr->litSum += litLength*ZSTD_LITFREQ_ADD;
    ++	for (u=0; u < litLength; u++)
    ++		seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
    ++
    ++	/* literal Length */
    ++	{   const BYTE LL_deltaCode = 19;
    ++		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
    ++		seqStorePtr->litLengthFreq[llCode]++;
    ++		seqStorePtr->litLengthSum++;
    ++	}
    ++
    ++	/* match offset */
    ++	{   BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
    ++		seqStorePtr->offCodeSum++;
    ++		seqStorePtr->offCodeFreq[offCode]++;
    ++	}
    ++
    ++	/* match Length */
    ++	{   const BYTE ML_deltaCode = 36;
    ++		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
    ++		seqStorePtr->matchLengthFreq[mlCode]++;
    ++		seqStorePtr->matchLengthSum++;
    ++	}
    ++
    ++	ZSTD_setLog2Prices(seqStorePtr);
    ++}
    ++
    ++
    ++#define SET_PRICE(pos, mlen_, offset_, litlen_, price_)   \
    ++	{                                                 \
    ++		while (last_pos < pos)  { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
    ++		opt[pos].mlen = mlen_;                         \
    ++		opt[pos].off = offset_;                        \
    ++		opt[pos].litlen = litlen_;                     \
    ++		opt[pos].price = price_;                       \
    ++	}
    ++
    ++
    ++
    ++/* Update hashTable3 up to ip (excluded)
    ++   Assumption : always within prefix (i.e. not within extDict) */
    ++FORCE_INLINE
    ++U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip)
    ++{
    ++	U32* const hashTable3  = zc->hashTable3;
    ++	U32 const hashLog3  = zc->hashLog3;
    ++	const BYTE* const base = zc->base;
    ++	U32 idx = zc->nextToUpdate3;
    ++	const U32 target = zc->nextToUpdate3 = (U32)(ip - base);
    ++	const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3);
    ++
    ++	while(idx < target) {
    ++		hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
    ++		idx++;
    ++	}
    ++
    ++	return hashTable3[hash3];
    ++}
    ++
    ++
    ++/*-*************************************
    ++*  Binary Tree search
    ++***************************************/
    ++static U32 ZSTD_insertBtAndGetAllMatches (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						U32 nbCompares, const U32 mls,
    ++						U32 extDict, ZSTD_match_t* matches, const U32 minMatchLen)
    ++{
    ++	const BYTE* const base = zc->base;
    ++	const U32 current = (U32)(ip-base);
    ++	const U32 hashLog = zc->params.cParams.hashLog;
    ++	const size_t h  = ZSTD_hashPtr(ip, hashLog, mls);
    ++	U32* const hashTable = zc->hashTable;
    ++	U32 matchIndex  = hashTable[h];
    ++	U32* const bt   = zc->chainTable;
    ++	const U32 btLog = zc->params.cParams.chainLog - 1;
    ++	const U32 btMask= (1U << btLog) - 1;
    ++	size_t commonLengthSmaller=0, commonLengthLarger=0;
    ++	const BYTE* const dictBase = zc->dictBase;
    ++	const U32 dictLimit = zc->dictLimit;
    ++	const BYTE* const dictEnd = dictBase + dictLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const U32 btLow = btMask >= current ? 0 : current - btMask;
    ++	const U32 windowLow = zc->lowLimit;
    ++	U32* smallerPtr = bt + 2*(current&btMask);
    ++	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    ++	U32 matchEndIdx = current+8;
    ++	U32 dummy32;   /* to be nullified at the end */
    ++	U32 mnum = 0;
    ++
    ++	const U32 minMatch = (mls == 3) ? 3 : 4;
    ++	size_t bestLength = minMatchLen-1;
    ++
    ++	if (minMatch == 3) { /* HC3 match finder */
    ++		U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
    ++		if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
    ++			const BYTE* match;
    ++			size_t currentMl=0;
    ++			if ((!extDict) || matchIndex3 >= dictLimit) {
    ++				match = base + matchIndex3;
    ++				if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
    ++			} else {
    ++				match = dictBase + matchIndex3;
    ++				if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
    ++					currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
    ++			}
    ++
    ++			/* save best solution */
    ++			if (currentMl > bestLength) {
    ++				bestLength = currentMl;
    ++				matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
    ++				matches[mnum].len = (U32)currentMl;
    ++				mnum++;
    ++				if (currentMl > ZSTD_OPT_NUM) goto update;
    ++				if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
    ++			}
    ++		}
    ++	}
    ++
    ++	hashTable[h] = current;   /* Update Hash Table */
    ++
    ++	while (nbCompares-- && (matchIndex > windowLow)) {
    ++		U32* nextPtr = bt + 2*(matchIndex & btMask);
    ++		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
    ++		const BYTE* match;
    ++
    ++		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
    ++			match = base + matchIndex;
    ++			if (match[matchLength] == ip[matchLength]) {
    ++				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
    ++			}
    ++		} else {
    ++			match = dictBase + matchIndex;
    ++			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
    ++			if (matchIndex+matchLength >= dictLimit)
    ++				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
    ++		}
    ++
    ++		if (matchLength > bestLength) {
    ++			if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
    ++			bestLength = matchLength;
    ++			matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
    ++			matches[mnum].len = (U32)matchLength;
    ++			mnum++;
    ++			if (matchLength > ZSTD_OPT_NUM) break;
    ++			if (ip+matchLength == iLimit)   /* equal : no way to know if inf or sup */
    ++				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
    ++		}
    ++
    ++		if (match[matchLength] < ip[matchLength]) {
    ++			/* match is smaller than current */
    ++			*smallerPtr = matchIndex;             /* update smaller idx */
    ++			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
    ++			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++		} else {
    ++			/* match is larger than current */
    ++			*largerPtr = matchIndex;
    ++			commonLengthLarger = matchLength;
    ++			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    ++			largerPtr = nextPtr;
    ++			matchIndex = nextPtr[0];
    ++	}   }
    ++
    ++	*smallerPtr = *largerPtr = 0;
    ++
    ++update:
    ++	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    ++	return mnum;
    ++}
    ++
    ++
    ++/** Tree updater, providing best match */
    ++static U32 ZSTD_BtGetAllMatches (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
    ++{
    ++	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    ++	ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
    ++	return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minMatchLen);
    ++}
    ++
    ++
    ++static U32 ZSTD_BtGetAllMatches_selectMLS (
    ++						ZSTD_CCtx* zc,   /* Index table will be updated */
    ++						const BYTE* ip, const BYTE* const iHighLimit,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	case 3 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
    ++	default :
    ++	case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
    ++	case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
    ++	case 7 :
    ++	case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
    ++	}
    ++}
    ++
    ++/** Tree updater, providing best match */
    ++static U32 ZSTD_BtGetAllMatches_extDict (
    ++						ZSTD_CCtx* zc,
    ++						const BYTE* const ip, const BYTE* const iLimit,
    ++						const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
    ++{
    ++	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    ++	ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
    ++	return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 1, matches, minMatchLen);
    ++}
    ++
    ++
    ++static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
    ++						ZSTD_CCtx* zc,   /* Index table will be updated */
    ++						const BYTE* ip, const BYTE* const iHighLimit,
    ++						const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
    ++{
    ++	switch(matchLengthSearch)
    ++	{
    ++	case 3 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
    ++	default :
    ++	case 4 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
    ++	case 5 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
    ++	case 7 :
    ++	case 6 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
    ++	}
    ++}
    ++
    ++
    ++/*-*******************************
    ++*  Optimal parser
    ++*********************************/
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
    ++									const void* src, size_t srcSize, const int ultra)
    ++{
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	const BYTE* const base = ctx->base;
    ++	const BYTE* const prefixStart = base + ctx->dictLimit;
    ++
    ++	const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
    ++	const U32 sufficient_len = ctx->params.cParams.targetLength;
    ++	const U32 mls = ctx->params.cParams.searchLength;
    ++	const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
    ++
    ++	ZSTD_optimal_t* opt = seqStorePtr->priceTable;
    ++	ZSTD_match_t* matches = seqStorePtr->matchTable;
    ++	const BYTE* inr;
    ++	U32 offset, rep[ZSTD_REP_NUM];
    ++
    ++	/* init */
    ++	ctx->nextToUpdate3 = ctx->nextToUpdate;
    ++	ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize);
    ++	ip += (ip==prefixStart);
    ++	{ U32 i; for (i=0; irep[i]; }
    ++
    ++	/* Match Loop */
    ++	while (ip < ilimit) {
    ++		U32 cur, match_num, last_pos, litlen, price;
    ++		U32 u, mlen, best_mlen, best_off, litLength;
    ++		memset(opt, 0, sizeof(ZSTD_optimal_t));
    ++		last_pos = 0;
    ++		litlen = (U32)(ip - anchor);
    ++
    ++		/* check repCode */
    ++		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    ++			for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
    ++					&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
    ++					mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
    ++					if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
    ++						best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
    ++						goto _storeSequence;
    ++					}
    ++					best_off = i - (ip == anchor);
    ++					do {
    ++						price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
    ++						if (mlen > last_pos || price < opt[mlen].price)
    ++							SET_PRICE(mlen, mlen, i, litlen, price);   /* note : macro modifies last_pos */
    ++						mlen--;
    ++					} while (mlen >= minMatch);
    ++		}   }   }
    ++
    ++		match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
    ++
    ++		if (!last_pos && !match_num) { ip++; continue; }
    ++
    ++		if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
    ++			best_mlen = matches[match_num-1].len;
    ++			best_off = matches[match_num-1].off;
    ++			cur = 0;
    ++			last_pos = 1;
    ++			goto _storeSequence;
    ++		}
    ++
    ++		/* set prices using matches at position = 0 */
    ++		best_mlen = (last_pos) ? last_pos : minMatch;
    ++		for (u = 0; u < match_num; u++) {
    ++			mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
    ++			best_mlen = matches[u].len;
    ++			while (mlen <= best_mlen) {
    ++				price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
    ++				if (mlen > last_pos || price < opt[mlen].price)
    ++					SET_PRICE(mlen, mlen, matches[u].off, litlen, price);   /* note : macro modifies last_pos */
    ++				mlen++;
    ++		}   }
    ++
    ++		if (last_pos < minMatch) { ip++; continue; }
    ++
    ++		/* initialize opt[0] */
    ++		{ U32 i ; for (i=0; i litlen) {
    ++					price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen);
    ++				} else
    ++					price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor);
    ++		   } else {
    ++				litlen = 1;
    ++				price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
    ++		   }
    ++
    ++		   if (cur > last_pos || price <= opt[cur].price)
    ++				SET_PRICE(cur, 1, 0, litlen, price);
    ++
    ++		   if (cur == last_pos) break;
    ++
    ++		   if (inr > ilimit)  /* last match must start at a minimum distance of 8 from oend */
    ++			   continue;
    ++
    ++		   mlen = opt[cur].mlen;
    ++		   if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
    ++				opt[cur].rep[2] = opt[cur-mlen].rep[1];
    ++				opt[cur].rep[1] = opt[cur-mlen].rep[0];
    ++				opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
    ++		   } else {
    ++				opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
    ++				opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
    ++				opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
    ++		   }
    ++
    ++			best_mlen = minMatch;
    ++			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
    ++				for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
    ++					   && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
    ++					   mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
    ++
    ++					   if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
    ++							best_mlen = mlen; best_off = i; last_pos = cur + 1;
    ++							goto _storeSequence;
    ++					   }
    ++
    ++					   best_off = i - (opt[cur].mlen != 1);
    ++					   if (mlen > best_mlen) best_mlen = mlen;
    ++
    ++					   do {
    ++						   if (opt[cur].mlen == 1) {
    ++								litlen = opt[cur].litlen;
    ++								if (cur > litlen) {
    ++									price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
    ++								} else
    ++									price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
    ++							} else {
    ++								litlen = 0;
    ++								price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
    ++							}
    ++
    ++							if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
    ++								SET_PRICE(cur + mlen, mlen, i, litlen, price);
    ++							mlen--;
    ++						} while (mlen >= minMatch);
    ++			}   }   }
    ++
    ++			match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
    ++
    ++			if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
    ++				best_mlen = matches[match_num-1].len;
    ++				best_off = matches[match_num-1].off;
    ++				last_pos = cur + 1;
    ++				goto _storeSequence;
    ++			}
    ++
    ++			/* set prices using matches at position = cur */
    ++			for (u = 0; u < match_num; u++) {
    ++				mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
    ++				best_mlen = matches[u].len;
    ++
    ++				while (mlen <= best_mlen) {
    ++					if (opt[cur].mlen == 1) {
    ++						litlen = opt[cur].litlen;
    ++						if (cur > litlen)
    ++							price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
    ++						else
    ++							price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
    ++					} else {
    ++						litlen = 0;
    ++						price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
    ++					}
    ++
    ++					if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
    ++						SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
    ++
    ++					mlen++;
    ++		}   }   }
    ++
    ++		best_mlen = opt[last_pos].mlen;
    ++		best_off = opt[last_pos].off;
    ++		cur = last_pos - best_mlen;
    ++
    ++		/* store sequence */
    ++_storeSequence:   /* cur, last_pos, best_mlen, best_off have to be set */
    ++		opt[0].mlen = 1;
    ++
    ++		while (1) {
    ++			mlen = opt[cur].mlen;
    ++			offset = opt[cur].off;
    ++			opt[cur].mlen = best_mlen;
    ++			opt[cur].off = best_off;
    ++			best_mlen = mlen;
    ++			best_off = offset;
    ++			if (mlen > cur) break;
    ++			cur -= mlen;
    ++		}
    ++
    ++		for (u = 0; u <= last_pos;) {
    ++			u += opt[u].mlen;
    ++		}
    ++
    ++		for (cur=0; cur < last_pos; ) {
    ++			mlen = opt[cur].mlen;
    ++			if (mlen == 1) { ip++; cur++; continue; }
    ++			offset = opt[cur].off;
    ++			cur += mlen;
    ++			litLength = (U32)(ip - anchor);
    ++
    ++			if (offset > ZSTD_REP_MOVE_OPT) {
    ++				rep[2] = rep[1];
    ++				rep[1] = rep[0];
    ++				rep[0] = offset - ZSTD_REP_MOVE_OPT;
    ++				offset--;
    ++			} else {
    ++				if (offset != 0) {
    ++					best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
    ++					if (offset != 1) rep[2] = rep[1];
    ++					rep[1] = rep[0];
    ++					rep[0] = best_off;
    ++				}
    ++				if (litLength==0) offset--;
    ++			}
    ++
    ++			ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
    ++			ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
    ++			anchor = ip = ip + mlen;
    ++	}    }   /* for (cur=0; cur < last_pos; ) */
    ++
    ++	/* Save reps for next block */
    ++	{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
    ++
    ++	/* Last Literals */
    ++	{   size_t const lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++
    ++FORCE_INLINE
    ++void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
    ++									 const void* src, size_t srcSize, const int ultra)
    ++{
    ++	seqStore_t* seqStorePtr = &(ctx->seqStore);
    ++	const BYTE* const istart = (const BYTE*)src;
    ++	const BYTE* ip = istart;
    ++	const BYTE* anchor = istart;
    ++	const BYTE* const iend = istart + srcSize;
    ++	const BYTE* const ilimit = iend - 8;
    ++	const BYTE* const base = ctx->base;
    ++	const U32 lowestIndex = ctx->lowLimit;
    ++	const U32 dictLimit = ctx->dictLimit;
    ++	const BYTE* const prefixStart = base + dictLimit;
    ++	const BYTE* const dictBase = ctx->dictBase;
    ++	const BYTE* const dictEnd  = dictBase + dictLimit;
    ++
    ++	const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
    ++	const U32 sufficient_len = ctx->params.cParams.targetLength;
    ++	const U32 mls = ctx->params.cParams.searchLength;
    ++	const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
    ++
    ++	ZSTD_optimal_t* opt = seqStorePtr->priceTable;
    ++	ZSTD_match_t* matches = seqStorePtr->matchTable;
    ++	const BYTE* inr;
    ++
    ++	/* init */
    ++	U32 offset, rep[ZSTD_REP_NUM];
    ++	{ U32 i; for (i=0; irep[i]; }
    ++
    ++	ctx->nextToUpdate3 = ctx->nextToUpdate;
    ++	ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize);
    ++	ip += (ip==prefixStart);
    ++
    ++	/* Match Loop */
    ++	while (ip < ilimit) {
    ++		U32 cur, match_num, last_pos, litlen, price;
    ++		U32 u, mlen, best_mlen, best_off, litLength;
    ++		U32 current = (U32)(ip-base);
    ++		memset(opt, 0, sizeof(ZSTD_optimal_t));
    ++		last_pos = 0;
    ++		opt[0].litlen = (U32)(ip - anchor);
    ++
    ++		/* check repCode */
    ++		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    ++			for (i = (ip==anchor); i 0 && repCur <= (S32)current)
    ++				   && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    ++				   && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    ++					/* repcode detected we should take it */
    ++					const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++					mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    ++
    ++					if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
    ++						best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
    ++						goto _storeSequence;
    ++					}
    ++
    ++					best_off = i - (ip==anchor);
    ++					litlen = opt[0].litlen;
    ++					do {
    ++						price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
    ++						if (mlen > last_pos || price < opt[mlen].price)
    ++							SET_PRICE(mlen, mlen, i, litlen, price);   /* note : macro modifies last_pos */
    ++						mlen--;
    ++					} while (mlen >= minMatch);
    ++		}   }   }
    ++
    ++		match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch);  /* first search (depth 0) */
    ++
    ++		if (!last_pos && !match_num) { ip++; continue; }
    ++
    ++		{ U32 i; for (i=0; i sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
    ++			best_mlen = matches[match_num-1].len;
    ++			best_off = matches[match_num-1].off;
    ++			cur = 0;
    ++			last_pos = 1;
    ++			goto _storeSequence;
    ++		}
    ++
    ++		best_mlen = (last_pos) ? last_pos : minMatch;
    ++
    ++		/* set prices using matches at position = 0 */
    ++		for (u = 0; u < match_num; u++) {
    ++			mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
    ++			best_mlen = matches[u].len;
    ++			litlen = opt[0].litlen;
    ++			while (mlen <= best_mlen) {
    ++				price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
    ++				if (mlen > last_pos || price < opt[mlen].price)
    ++					SET_PRICE(mlen, mlen, matches[u].off, litlen, price);
    ++				mlen++;
    ++		}   }
    ++
    ++		if (last_pos < minMatch) {
    ++			ip++; continue;
    ++		}
    ++
    ++		/* check further positions */
    ++		for (cur = 1; cur <= last_pos; cur++) {
    ++			inr = ip + cur;
    ++
    ++			if (opt[cur-1].mlen == 1) {
    ++				litlen = opt[cur-1].litlen + 1;
    ++				if (cur > litlen) {
    ++					price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen);
    ++				} else
    ++					price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor);
    ++			} else {
    ++				litlen = 1;
    ++				price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
    ++			}
    ++
    ++			if (cur > last_pos || price <= opt[cur].price)
    ++				SET_PRICE(cur, 1, 0, litlen, price);
    ++
    ++			if (cur == last_pos) break;
    ++
    ++			if (inr > ilimit)  /* last match must start at a minimum distance of 8 from oend */
    ++				continue;
    ++
    ++			mlen = opt[cur].mlen;
    ++			if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
    ++				opt[cur].rep[2] = opt[cur-mlen].rep[1];
    ++				opt[cur].rep[1] = opt[cur-mlen].rep[0];
    ++				opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
    ++			} else {
    ++				opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
    ++				opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
    ++				opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
    ++			}
    ++
    ++			best_mlen = minMatch;
    ++			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
    ++				for (i = (mlen != 1); i 0 && repCur <= (S32)(current+cur))
    ++					  && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    ++					  && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    ++						/* repcode detected */
    ++						const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    ++						mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    ++
    ++						if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
    ++							best_mlen = mlen; best_off = i; last_pos = cur + 1;
    ++							goto _storeSequence;
    ++						}
    ++
    ++						best_off = i - (opt[cur].mlen != 1);
    ++						if (mlen > best_mlen) best_mlen = mlen;
    ++
    ++						do {
    ++							if (opt[cur].mlen == 1) {
    ++								litlen = opt[cur].litlen;
    ++								if (cur > litlen) {
    ++									price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
    ++								} else
    ++									price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
    ++							} else {
    ++								litlen = 0;
    ++								price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
    ++							}
    ++
    ++							if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
    ++								SET_PRICE(cur + mlen, mlen, i, litlen, price);
    ++							mlen--;
    ++						} while (mlen >= minMatch);
    ++			}   }   }
    ++
    ++			match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
    ++
    ++			if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
    ++				best_mlen = matches[match_num-1].len;
    ++				best_off = matches[match_num-1].off;
    ++				last_pos = cur + 1;
    ++				goto _storeSequence;
    ++			}
    ++
    ++			/* set prices using matches at position = cur */
    ++			for (u = 0; u < match_num; u++) {
    ++				mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
    ++				best_mlen = matches[u].len;
    ++
    ++				while (mlen <= best_mlen) {
    ++					if (opt[cur].mlen == 1) {
    ++						litlen = opt[cur].litlen;
    ++						if (cur > litlen)
    ++							price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
    ++						else
    ++							price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
    ++					} else {
    ++						litlen = 0;
    ++						price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
    ++					}
    ++
    ++					if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
    ++						SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
    ++
    ++					mlen++;
    ++		}   }   }   /* for (cur = 1; cur <= last_pos; cur++) */
    ++
    ++		best_mlen = opt[last_pos].mlen;
    ++		best_off = opt[last_pos].off;
    ++		cur = last_pos - best_mlen;
    ++
    ++		/* store sequence */
    ++_storeSequence:   /* cur, last_pos, best_mlen, best_off have to be set */
    ++		opt[0].mlen = 1;
    ++
    ++		while (1) {
    ++			mlen = opt[cur].mlen;
    ++			offset = opt[cur].off;
    ++			opt[cur].mlen = best_mlen;
    ++			opt[cur].off = best_off;
    ++			best_mlen = mlen;
    ++			best_off = offset;
    ++			if (mlen > cur) break;
    ++			cur -= mlen;
    ++		}
    ++
    ++		for (u = 0; u <= last_pos; ) {
    ++			u += opt[u].mlen;
    ++		}
    ++
    ++		for (cur=0; cur < last_pos; ) {
    ++			mlen = opt[cur].mlen;
    ++			if (mlen == 1) { ip++; cur++; continue; }
    ++			offset = opt[cur].off;
    ++			cur += mlen;
    ++			litLength = (U32)(ip - anchor);
    ++
    ++			if (offset > ZSTD_REP_MOVE_OPT) {
    ++				rep[2] = rep[1];
    ++				rep[1] = rep[0];
    ++				rep[0] = offset - ZSTD_REP_MOVE_OPT;
    ++				offset--;
    ++			} else {
    ++				if (offset != 0) {
    ++					best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
    ++					if (offset != 1) rep[2] = rep[1];
    ++					rep[1] = rep[0];
    ++					rep[0] = best_off;
    ++				}
    ++
    ++				if (litLength==0) offset--;
    ++			}
    ++
    ++			ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
    ++			ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
    ++			anchor = ip = ip + mlen;
    ++	}    }   /* for (cur=0; cur < last_pos; ) */
    ++
    ++	/* Save reps for next block */
    ++	{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
    ++
    ++	/* Last Literals */
    ++	{   size_t lastLLSize = iend - anchor;
    ++		memcpy(seqStorePtr->lit, anchor, lastLLSize);
    ++		seqStorePtr->lit += lastLLSize;
    ++	}
    ++}
    ++
    ++#endif  /* ZSTD_OPT_H_91842398743 */
    
    From 4eff8136aa006abdab8ac1407c350f567d23d442 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 16:05:27 -0700
    Subject: [PATCH 056/400] added prototype ZSTD_decompressBegin_usingDDict
     (#700)
    
    ---
     lib/decompress/zstd_decompress.c | 13 ++++++-------
     lib/zstd.h                       |  5 ++++-
     2 files changed, 10 insertions(+), 8 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 379842b57..c1ba53ea9 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -177,8 +177,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
         memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
     }
     
    -static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
    -
     
     /*-*************************************************************
     *   Decompression section
    @@ -1540,7 +1538,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
     
             if (ddict) {
                 /* we were called from ZSTD_decompress_usingDDict */
    -            ZSTD_refDDict(dctx, ddict);
    +            CHECK_F(ZSTD_decompressBegin_usingDDict(dctx, ddict));
             } else {
                 /* this will initialize correctly with no dict if dict == NULL, so
                  * use this in all cases but ddict */
    @@ -1862,10 +1860,10 @@ static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict)
         return ddict->dictSize;
     }
     
    -static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
    +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
     {
    -    ZSTD_decompressBegin(dstDCtx);  /* init */
    -    if (ddict) {   /* support refDDict on NULL */
    +    CHECK_F(ZSTD_decompressBegin(dstDCtx));
    +    if (ddict) {   /* support begin on NULL */
             dstDCtx->dictID = ddict->dictID;
             dstDCtx->base = ddict->dictContent;
             dstDCtx->vBase = ddict->dictContent;
    @@ -1886,6 +1884,7 @@ static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
                 dstDCtx->fseEntropy = 0;
             }
         }
    +    return 0;
     }
     
     static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
    @@ -2271,7 +2270,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }   }
     
                 /* Consume header */
    -            ZSTD_refDDict(zds->dctx, zds->ddict);
    +            ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict);
                 {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
                     CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
                     {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 256117662..b2e9a67b6 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -710,7 +710,8 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
                >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
                errorCode, which can be tested using ZSTD_isError().
     
    -  Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
    +  Start decompression, with ZSTD_decompressBegin().
    +  If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict().
       Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
     
       Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
    @@ -753,7 +754,9 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
     ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
     ZSTDLIB_API void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    +
     ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
    
    From 90a1c9496547398111cd6be130dd5cddc7a9cd95 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 16:03:36 -0700
    Subject: [PATCH 057/400] [linux-kernel] Update header comments
    
    ---
     contrib/linux-kernel/include/linux/xxhash.h | 12 ++++++------
     contrib/linux-kernel/xxhash.diff            | 14 +++++++-------
     2 files changed, 13 insertions(+), 13 deletions(-)
    
    diff --git a/contrib/linux-kernel/include/linux/xxhash.h b/contrib/linux-kernel/include/linux/xxhash.h
    index 464433704..c77b12b86 100644
    --- a/contrib/linux-kernel/include/linux/xxhash.h
    +++ b/contrib/linux-kernel/include/linux/xxhash.h
    @@ -78,7 +78,7 @@
     /**
      * xxh32() - calculate the 32-bit hash of the input with a given seed.
      *
    - * @input:  The data to hash. Must not be NULL.
    + * @input:  The data to hash.
      * @length: The length of the data to hash.
      * @seed:   The seed can be used to alter the result predictably.
      *
    @@ -89,9 +89,9 @@
     uint32_t xxh32(const void *input, size_t length, uint32_t seed);
     
     /**
    - * xxh32() - calculate the 64-bit hash of the input with a given seed.
    + * xxh64() - calculate the 64-bit hash of the input with a given seed.
      *
    - * @input:  The data to hash. Must not be NULL.
    + * @input:  The data to hash.
      * @length: The length of the data to hash.
      * @seed:   The seed can be used to alter the result predictably.
      *
    @@ -152,7 +152,7 @@ void xxh32_reset(struct xxh32_state *state, uint32_t seed);
      * xxh32_update() - hash the data given and update the xxh32 state
      *
      * @state:  The xxh32 state to update.
    - * @input:  The data to hash. Must not be NULL.
    + * @input:  The data to hash.
      * @length: The length of the data to hash.
      *
      * After calling xxh32_reset() call xxh32_update() as many times as necessary.
    @@ -177,7 +177,7 @@ uint32_t xxh32_digest(const struct xxh32_state *state);
     /**
      * xxh64_reset() - reset the xxh64 state to start a new hashing operation
      *
    - * @state: The xxh32 state to reset.
    + * @state: The xxh64 state to reset.
      * @seed:  Initialize the hash state with this seed.
      */
     void xxh64_reset(struct xxh64_state *state, uint64_t seed);
    @@ -185,7 +185,7 @@ void xxh64_reset(struct xxh64_state *state, uint64_t seed);
     /**
      * xxh64_update() - hash the data given and update the xxh64 state
      * @state:  The xxh64 state to update.
    - * @input:  The data to hash. Must not be NULL.
    + * @input:  The data to hash.
      * @length: The length of the data to hash.
      *
      * After calling xxh64_reset() call xxh64_update() as many times as necessary.
    diff --git a/contrib/linux-kernel/xxhash.diff b/contrib/linux-kernel/xxhash.diff
    index bbd5771b6..1f1d4899e 100644
    --- a/contrib/linux-kernel/xxhash.diff
    +++ b/contrib/linux-kernel/xxhash.diff
    @@ -1,6 +1,6 @@
     diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h
     new file mode 100644
    -index 0000000..4644337
    +index 0000000..c77b12b
     --- /dev/null
     +++ b/include/linux/xxhash.h
     @@ -0,0 +1,230 @@
    @@ -84,7 +84,7 @@ index 0000000..4644337
     +/**
     + * xxh32() - calculate the 32-bit hash of the input with a given seed.
     + *
    -+ * @input:  The data to hash. Must not be NULL.
    ++ * @input:  The data to hash.
     + * @length: The length of the data to hash.
     + * @seed:   The seed can be used to alter the result predictably.
     + *
    @@ -95,9 +95,9 @@ index 0000000..4644337
     +uint32_t xxh32(const void *input, size_t length, uint32_t seed);
     +
     +/**
    -+ * xxh32() - calculate the 64-bit hash of the input with a given seed.
    ++ * xxh64() - calculate the 64-bit hash of the input with a given seed.
     + *
    -+ * @input:  The data to hash. Must not be NULL.
    ++ * @input:  The data to hash.
     + * @length: The length of the data to hash.
     + * @seed:   The seed can be used to alter the result predictably.
     + *
    @@ -158,7 +158,7 @@ index 0000000..4644337
     + * xxh32_update() - hash the data given and update the xxh32 state
     + *
     + * @state:  The xxh32 state to update.
    -+ * @input:  The data to hash. Must not be NULL.
    ++ * @input:  The data to hash.
     + * @length: The length of the data to hash.
     + *
     + * After calling xxh32_reset() call xxh32_update() as many times as necessary.
    @@ -183,7 +183,7 @@ index 0000000..4644337
     +/**
     + * xxh64_reset() - reset the xxh64 state to start a new hashing operation
     + *
    -+ * @state: The xxh32 state to reset.
    ++ * @state: The xxh64 state to reset.
     + * @seed:  Initialize the hash state with this seed.
     + */
     +void xxh64_reset(struct xxh64_state *state, uint64_t seed);
    @@ -191,7 +191,7 @@ index 0000000..4644337
     +/**
     + * xxh64_update() - hash the data given and update the xxh64 state
     + * @state:  The xxh64 state to update.
    -+ * @input:  The data to hash. Must not be NULL.
    ++ * @input:  The data to hash.
     + * @length: The length of the data to hash.
     + *
     + * After calling xxh64_reset() call xxh64_update() as many times as necessary.
    
    From bfff8999c5a397e799681b1c43df1c9c7f5f1782 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 16:12:23 -0700
    Subject: [PATCH 058/400] added prototype ZSTD_versionString()
    
    ---
     lib/common/zstd_common.c | 4 +++-
     lib/zstd.h               | 7 ++++---
     2 files changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
    index 8408a589a..5e207e7d1 100644
    --- a/lib/common/zstd_common.c
    +++ b/lib/common/zstd_common.c
    @@ -15,7 +15,7 @@
     #include          /* malloc */
     #include "error_private.h"
     #define ZSTD_STATIC_LINKING_ONLY
    -#include "zstd.h"           /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
    +#include "zstd.h"
     
     
     /*-****************************************
    @@ -23,6 +23,8 @@
     ******************************************/
     unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
     
    +const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }
    +
     
     /*-****************************************
     *  ZSTD Error Management
    diff --git a/lib/zstd.h b/lib/zstd.h
    index b2e9a67b6..d96a535f3 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -58,13 +58,14 @@ extern "C" {
     #define ZSTD_VERSION_MINOR    3
     #define ZSTD_VERSION_RELEASE  0
     
    +#define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
    +ZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< to be used when checking dll version */
    +
     #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
     #define ZSTD_QUOTE(str) #str
     #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
     #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
    -
    -#define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
    -ZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< library version number; to be used when checking dll version */
    +ZSTDLIB_API const char* ZSTD_versionString(void);
     
     
     /***************************************
    
    From f3c9bd014cddc6e02c136703bb59af6bdcbe6d04 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 16:13:51 -0700
    Subject: [PATCH 059/400] [linux-kernel] Remove unused variables in test
    
    ---
     contrib/linux-kernel/test/XXHashUserlandTest.cpp | 12 ------------
     1 file changed, 12 deletions(-)
    
    diff --git a/contrib/linux-kernel/test/XXHashUserlandTest.cpp b/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    index 4ded2ae5e..f50401a2e 100644
    --- a/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    +++ b/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    @@ -26,18 +26,6 @@ const std::array kTestInputs = {
       "0123456789abcdef0123456789abcdef0",
       "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
     };
    -char const kEmpty[] = "";
    -char const kOne[] = "0";
    -char const kFive[] = "01234";
    -char const kFifteen[] = "0123456789abcde";
    -char const kSixteen[] = "0123456789abcdef";
    -char const kSeventeen[] = "0123456789abcdef0";
    -char const kTwenty[] = "0123456789abcdef0123";
    -char const kThirtyOne[] = "0123456789abcdef0123456789abcde";
    -char const kThirtyTwo[] = "0123456789abcdef0123456789abcdef";
    -char const kThirtyThree[] = "0123456789abcdef0123456789abcdef0";
    -char const kSixtyFour[] = "0123456789abcdef0123456789abcdef"
    -                          "0123456789abcdef0123456789abcdef";
     
     bool testXXH32(const void *input, const size_t length, uint32_t seed) {
       return XXH32(input, length, seed) == xxh32(input, length, seed);
    
    From 7101434ec91e80e744e2bb8a01232aa60c0c4571 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 16:28:24 -0700
    Subject: [PATCH 060/400] pedantic : added one error check
    
    on a function which (today) never fails.
    But who knows, maybe tomorrow ...
    ---
     lib/decompress/zstd_decompress.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index c1ba53ea9..0c61960ec 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -2270,7 +2270,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }   }
     
                 /* Consume header */
    -            ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict);
    +            CHECK_F(ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict));
                 {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
                     CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
                     {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    
    From 0d26da2f253308edcf45937d1a30eed45cd15438 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 16:47:49 -0700
    Subject: [PATCH 061/400] [linux-kernel] Don't undef current (use curr)
    
    ---
     contrib/linux-kernel/lib/zstd/compress.c      | 154 +++++++++---------
     contrib/linux-kernel/lib/zstd/decompress.c    |  10 +-
     contrib/linux-kernel/lib/zstd/huf_compress.c  |  20 +--
     .../linux-kernel/lib/zstd/huf_decompress.c    |  12 +-
     contrib/linux-kernel/lib/zstd/zstd_opt.h      |  52 +++---
     .../linux-kernel/test/include/linux/kernel.h  |   2 +
     6 files changed, 124 insertions(+), 126 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index 79c3207fe..cd184b78b 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -19,10 +19,6 @@
     #include "huf.h"
     #include "zstd_internal.h"  /* includes zstd.h */
     
    -#ifdef current
    -#  undef current
    -#endif
    -
     /*-*************************************
     *  Constants
     ***************************************/
    @@ -53,7 +49,7 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
     *  Context memory management
     ***************************************/
     struct ZSTD_CCtx_s {
    -	const BYTE* nextSrc;    /* next block here to continue on current prefix */
    +	const BYTE* nextSrc;    /* next block here to continue on curr prefix */
     	const BYTE* base;       /* All regular indexes relative to this position */
     	const BYTE* dictBase;   /* extDict indexes relative to this position */
     	U32   dictLimit;        /* below that point, need extDict */
    @@ -1002,10 +998,10 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
     		size_t mLength;
     		size_t const h = ZSTD_hashPtr(ip, hBits, mls);
    -		U32 const current = (U32)(ip-base);
    +		U32 const curr = (U32)(ip-base);
     		U32 const matchIndex = hashTable[h];
     		const BYTE* match = base + matchIndex;
    -		hashTable[h] = current;   /* update hash table */
    +		hashTable[h] = curr;   /* update hash table */
     
     		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
     			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    @@ -1032,7 +1028,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    +			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
     			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
     			/* check immediate repcode */
     			while ( (ip <= ilimit)
    @@ -1106,12 +1102,12 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     		const U32 matchIndex = hashTable[h];
     		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
     		const BYTE* match = matchBase + matchIndex;
    -		const U32 current = (U32)(ip-base);
    -		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    +		const U32 curr = (U32)(ip-base);
    +		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
     		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
     		const BYTE* repMatch = repBase + repIndex;
     		size_t mLength;
    -		hashTable[h] = current;   /* update hash table */
    +		hashTable[h] = curr;   /* update hash table */
     
     		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
     		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    @@ -1130,7 +1126,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     				U32 offset;
     				mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
     				while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    -				offset = current - matchIndex;
    +				offset = curr - matchIndex;
     				offset_2 = offset_1;
     				offset_1 = offset;
     				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    @@ -1142,12 +1138,12 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
    +			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;
     			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
     			/* check immediate repcode */
     			while (ip <= ilimit) {
    -				U32 const current2 = (U32)(ip-base);
    -				U32 const repIndex2 = current2 - offset_2;
    +				U32 const curr2 = (U32)(ip-base);
    +				U32 const repIndex2 = curr2 - offset_2;
     				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
     				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    @@ -1155,7 +1151,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     					size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
     					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    -					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
    +					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = curr2;
     					ip += repLength2;
     					anchor = ip;
     					continue;
    @@ -1248,14 +1244,14 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     		size_t mLength;
     		size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
     		size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
    -		U32 const current = (U32)(ip-base);
    +		U32 const curr = (U32)(ip-base);
     		U32 const matchIndexL = hashLong[h2];
     		U32 const matchIndexS = hashSmall[h];
     		const BYTE* matchLong = base + matchIndexL;
     		const BYTE* match = base + matchIndexS;
    -		hashLong[h2] = hashSmall[h] = current;   /* update hash tables */
    +		hashLong[h2] = hashSmall[h] = curr;   /* update hash tables */
     
    -		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
    +		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= curr */
     			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
     			ip++;
     			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    @@ -1269,7 +1265,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
     				U32 const matchIndex3 = hashLong[h3];
     				const BYTE* match3 = base + matchIndex3;
    -				hashLong[h3] = current + 1;
    +				hashLong[h3] = curr + 1;
     				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
     					mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
     					ip++;
    @@ -1297,8 +1293,8 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
    -				hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    +			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] =
    +				hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
     			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
     				hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
     
    @@ -1382,12 +1378,12 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     		const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
     		const BYTE* matchLong = matchLongBase + matchLongIndex;
     
    -		const U32 current = (U32)(ip-base);
    -		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    +		const U32 curr = (U32)(ip-base);
    +		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
     		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
     		const BYTE* repMatch = repBase + repIndex;
     		size_t mLength;
    -		hashSmall[hSmall] = hashLong[hLong] = current;   /* update hash table */
    +		hashSmall[hSmall] = hashLong[hLong] = curr;   /* update hash table */
     
     		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
     		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    @@ -1401,7 +1397,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     				const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
     				U32 offset;
     				mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
    -				offset = current - matchLongIndex;
    +				offset = curr - matchLongIndex;
     				while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
     				offset_2 = offset_1;
     				offset_1 = offset;
    @@ -1413,19 +1409,19 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     				const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
     				const BYTE* match3 = match3Base + matchIndex3;
     				U32 offset;
    -				hashLong[h3] = current + 1;
    +				hashLong[h3] = curr + 1;
     				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
     					const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
     					const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
     					mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
     					ip++;
    -					offset = current+1 - matchIndex3;
    +					offset = curr+1 - matchIndex3;
     					while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
     				} else {
     					const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
     					const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
     					mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
    -					offset = current - matchIndex;
    +					offset = curr - matchIndex;
     					while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
     				}
     				offset_2 = offset_1;
    @@ -1443,14 +1439,14 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
    -			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
    +			hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;
    +			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] = curr+2;
     			hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
     			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
     			/* check immediate repcode */
     			while (ip <= ilimit) {
    -				U32 const current2 = (U32)(ip-base);
    -				U32 const repIndex2 = current2 - offset_2;
    +				U32 const curr2 = (U32)(ip-base);
    +				U32 const repIndex2 = curr2 - offset_2;
     				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
     				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    @@ -1458,8 +1454,8 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     					size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
     					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    -					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
    -					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
    +					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = curr2;
    +					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = curr2;
     					ip += repLength2;
     					anchor = ip;
     					continue;
    @@ -1520,22 +1516,22 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     	const BYTE* const dictEnd = dictBase + dictLimit;
     	const BYTE* const prefixStart = base + dictLimit;
     	const BYTE* match;
    -	const U32 current = (U32)(ip-base);
    -	const U32 btLow = btMask >= current ? 0 : current - btMask;
    -	U32* smallerPtr = bt + 2*(current&btMask);
    +	const U32 curr = (U32)(ip-base);
    +	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
    +	U32* smallerPtr = bt + 2*(curr&btMask);
     	U32* largerPtr  = smallerPtr + 1;
     	U32 dummy32;   /* to be nullified at the end */
     	U32 const windowLow = zc->lowLimit;
    -	U32 matchEndIdx = current+8;
    +	U32 matchEndIdx = curr+8;
     	size_t bestLength = 8;
     #ifdef ZSTD_C_PREDICT
    -	U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
    -	U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
    +	U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
    +	U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
     	predictedSmall += (predictedSmall>0);
     	predictedLarge += (predictedLarge>0);
     #endif /* ZSTD_C_PREDICT */
     
    -	hashTable[h] = current;   /* Update Hash Table */
    +	hashTable[h] = curr;   /* Update Hash Table */
     
     	while (nbCompares-- && (matchIndex > windowLow)) {
     		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    @@ -1548,7 +1544,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     			*smallerPtr = matchIndex;
     			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    +			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     			predictedSmall = predictPtr[1] + (predictPtr[1]>0);
     			continue;
     		}
    @@ -1582,14 +1578,14 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     			break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
     
     		if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
    -			/* match is smaller than current */
    +			/* match is smaller than curr */
     			*smallerPtr = matchIndex;             /* update smaller idx */
     			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    +			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     		} else {
    -			/* match is larger than current */
    +			/* match is larger than curr */
     			*largerPtr = matchIndex;
     			commonLengthLarger = matchLength;
     			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -1599,7 +1595,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     
     	*smallerPtr = *largerPtr = 0;
     	if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
    -	if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
    +	if (matchEndIdx > curr + 8) return matchEndIdx - curr - 8;
     	return 1;
     }
     
    @@ -1624,16 +1620,16 @@ static size_t ZSTD_insertBtAndFindBestMatch (
     	const U32 dictLimit = zc->dictLimit;
     	const BYTE* const dictEnd = dictBase + dictLimit;
     	const BYTE* const prefixStart = base + dictLimit;
    -	const U32 current = (U32)(ip-base);
    -	const U32 btLow = btMask >= current ? 0 : current - btMask;
    +	const U32 curr = (U32)(ip-base);
    +	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
     	const U32 windowLow = zc->lowLimit;
    -	U32* smallerPtr = bt + 2*(current&btMask);
    -	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    -	U32 matchEndIdx = current+8;
    +	U32* smallerPtr = bt + 2*(curr&btMask);
    +	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
    +	U32 matchEndIdx = curr+8;
     	U32 dummy32;   /* to be nullified at the end */
     	size_t bestLength = 0;
     
    -	hashTable[h] = current;   /* Update Hash Table */
    +	hashTable[h] = curr;   /* Update Hash Table */
     
     	while (nbCompares-- && (matchIndex > windowLow)) {
     		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    @@ -1654,21 +1650,21 @@ static size_t ZSTD_insertBtAndFindBestMatch (
     		if (matchLength > bestLength) {
     			if (matchLength > matchEndIdx - matchIndex)
     				matchEndIdx = matchIndex + (U32)matchLength;
    -			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    -				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
    +			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    +				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
     			if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
     				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
     		}
     
     		if (match[matchLength] < ip[matchLength]) {
    -			/* match is smaller than current */
    +			/* match is smaller than curr */
     			*smallerPtr = matchIndex;             /* update smaller idx */
     			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    +			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     		} else {
    -			/* match is larger than current */
    +			/* match is larger than curr */
     			*largerPtr = matchIndex;
     			commonLengthLarger = matchLength;
     			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -1678,7 +1674,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
     
     	*smallerPtr = *largerPtr = 0;
     
    -	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    +	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
     	return bestLength;
     }
     
    @@ -1811,8 +1807,8 @@ size_t ZSTD_HcFindBestMatch_generic (
     	const BYTE* const prefixStart = base + dictLimit;
     	const BYTE* const dictEnd = dictBase + dictLimit;
     	const U32 lowLimit = zc->lowLimit;
    -	const U32 current = (U32)(ip-base);
    -	const U32 minChain = current > chainSize ? current - chainSize : 0;
    +	const U32 curr = (U32)(ip-base);
    +	const U32 minChain = curr > chainSize ? curr - chainSize : 0;
     	int nbAttempts=maxNbAttempts;
     	size_t ml=EQUAL_READ32-1;
     
    @@ -1821,19 +1817,19 @@ size_t ZSTD_HcFindBestMatch_generic (
     
     	for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
     		const BYTE* match;
    -		size_t currentMl=0;
    +		size_t currMl=0;
     		if ((!extDict) || matchIndex >= dictLimit) {
     			match = base + matchIndex;
     			if (match[ml] == ip[ml])   /* potentially better */
    -				currentMl = ZSTD_count(ip, match, iLimit);
    +				currMl = ZSTD_count(ip, match, iLimit);
     		} else {
     			match = dictBase + matchIndex;
     			if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    -				currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
    +				currMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
     		}
     
     		/* save best solution */
    -		if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
    +		if (currMl > ml) { ml = currMl; *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE; if (ip+currMl == iLimit) break; /* best possible, and avoid read overflow*/ }
     
     		if (matchIndex <= minChain) break;
     		matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
    @@ -2074,10 +2070,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     		size_t matchLength=0;
     		size_t offset=0;
     		const BYTE* start=ip+1;
    -		U32 current = (U32)(ip-base);
    +		U32 curr = (U32)(ip-base);
     
     		/* check repCode */
    -		{   const U32 repIndex = (U32)(current+1 - offset_1);
    +		{   const U32 repIndex = (U32)(curr+1 - offset_1);
     			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     			const BYTE* const repMatch = repBase + repIndex;
     			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    @@ -2104,10 +2100,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     		if (depth>=1)
     		while (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    @@ -2134,10 +2130,10 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     			/* let's find an even better one */
     			if ((depth==2) && (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    @@ -2292,11 +2288,11 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
     	ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
     	const BYTE* const base = zc->base;
     	const BYTE* const istart = (const BYTE*)src;
    -	const U32 current = (U32)(istart-base);
    +	const U32 curr = (U32)(istart-base);
     	if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0;   /* don't even attempt compression below a certain srcSize */
     	ZSTD_resetSeqStore(&(zc->seqStore));
    -	if (current > zc->nextToUpdate + 384)
    -		zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
    +	if (curr > zc->nextToUpdate + 384)
    +		zc->nextToUpdate = curr - MIN(192, (U32)(curr - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
     	blockCompressor(zc, src, srcSize);
     	return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
     }
    @@ -2334,9 +2330,9 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     		/* preemptive overflow correction */
     		if (cctx->lowLimit > (3U<<29)) {
     			U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
    -			U32 const current = (U32)(ip - cctx->base);
    -			U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
    -			U32 const correction = current - newCurrent;
    +			U32 const curr = (U32)(ip - cctx->base);
    +			U32 const newCurr = (curr & cycleMask) + (1 << cctx->params.cParams.windowLog);
    +			U32 const correction = curr - newCurr;
     			ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
     			ZSTD_reduceIndex(cctx, correction);
     			cctx->base += correction;
    @@ -2497,7 +2493,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
     	const BYTE* const ip = (const BYTE*) src;
     	const BYTE* const iend = ip + srcSize;
     
    -	/* input becomes current prefix */
    +	/* input becomes curr prefix */
     	zc->lowLimit = zc->dictLimit;
     	zc->dictLimit = (U32)(zc->nextSrc - zc->base);
     	zc->dictBase = zc->base;
    @@ -3072,7 +3068,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     				if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
     					someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
     			}   }
    -			/* compress current block (note : this stage cannot be stopped in the middle) */
    +			/* compress curr block (note : this stage cannot be stopped in the middle) */
     			{   void* cDst;
     				size_t cSize;
     				size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 98508b10d..73cf06f5f 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -72,8 +72,8 @@ struct ZSTD_DCtx_s
     	const HUF_DTable* HUFptr;
     	ZSTD_entropyTables_t entropy;
     	const void* previousDstEnd;   /* detect continuity */
    -	const void* base;             /* start of current segment */
    -	const void* vBase;            /* virtual start of previous segment if it was just before current one */
    +	const void* base;             /* start of curr segment */
    +	const void* vBase;            /* virtual start of previous segment if it was just before curr one */
     	const void* dictEnd;          /* end of previous segment */
     	size_t expected;
     	ZSTD_frameParams fParams;
    @@ -864,7 +864,7 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
    -		/* span extDict & currentPrefixSegment */
    +		/* span extDict & currPrefixSegment */
     		{   size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
    @@ -987,7 +987,7 @@ size_t ZSTD_execSequence(BYTE* op,
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
    -		/* span extDict & currentPrefixSegment */
    +		/* span extDict & currPrefixSegment */
     		{   size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
    @@ -1222,7 +1222,7 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
    -		/* span extDict & currentPrefixSegment */
    +		/* span extDict & currPrefixSegment */
     		{   size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
    diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c
    index a1a1d454a..a0bfb8aee 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c
    @@ -172,9 +172,9 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
     	/* Prepare base value per rank */
     	{   U32 n, nextRankStart = 0;
     		for (n=1; n<=tableLog; n++) {
    -			U32 current = nextRankStart;
    +			U32 curr = nextRankStart;
     			nextRankStart += (rankVal[n] << (n-1));
    -			rankVal[n] = current;
    +			rankVal[n] = curr;
     	}   }
     
     	/* fill nbBits */
    @@ -237,11 +237,11 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
     
     			/* Get pos of last (smallest) symbol per rank */
     			memset(rankLast, 0xF0, sizeof(rankLast));
    -			{   U32 currentNbBits = maxNbBits;
    +			{   U32 currNbBits = maxNbBits;
     				for (pos=n ; pos >= 0; pos--) {
    -					if (huffNode[pos].nbBits >= currentNbBits) continue;
    -					currentNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    -					rankLast[maxNbBits-currentNbBits] = pos;
    +					if (huffNode[pos].nbBits >= currNbBits) continue;
    +					currNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    +					rankLast[maxNbBits-currNbBits] = pos;
     			}   }
     
     			while (totalCost > 0) {
    @@ -289,7 +289,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
     
     typedef struct {
     	U32 base;
    -	U32 current;
    +	U32 curr;
     } rankPos;
     
     static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
    @@ -303,11 +303,11 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
     		rank[r].base ++;
     	}
     	for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
    -	for (n=0; n<32; n++) rank[n].current = rank[n].base;
    +	for (n=0; n<32; n++) rank[n].curr = rank[n].base;
     	for (n=0; n<=maxSymbolValue; n++) {
     		U32 const c = count[n];
     		U32 const r = BIT_highbit32(c+1) + 1;
    -		U32 pos = rank[r].current++;
    +		U32 pos = rank[r].curr++;
     		while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
     		huffNode[pos].count = c;
     		huffNode[pos].byte  = (BYTE)n;
    @@ -549,7 +549,7 @@ static size_t HUF_compress_internal (
     	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
     	if (!srcSize) return 0;  /* Uncompressed (note : 1 means rle, so first byte must be correct) */
     	if (!dstSize) return 0;  /* cannot fit within dst budget */
    -	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* current block size limit */
    +	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* curr block size limit */
     	if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
     	if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
     	if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index f73223c4e..a47cb72ff 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -101,9 +101,9 @@ size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
     	/* Calculate starting value for each rank */
     	{   U32 n, nextRankStart = 0;
     		for (n=1; nbase;
    -	const U32 current = (U32)(ip-base);
    +	const U32 curr = (U32)(ip-base);
     	const U32 hashLog = zc->params.cParams.hashLog;
     	const size_t h  = ZSTD_hashPtr(ip, hashLog, mls);
     	U32* const hashTable = zc->hashTable;
    @@ -246,11 +246,11 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     	const U32 dictLimit = zc->dictLimit;
     	const BYTE* const dictEnd = dictBase + dictLimit;
     	const BYTE* const prefixStart = base + dictLimit;
    -	const U32 btLow = btMask >= current ? 0 : current - btMask;
    +	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
     	const U32 windowLow = zc->lowLimit;
    -	U32* smallerPtr = bt + 2*(current&btMask);
    -	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    -	U32 matchEndIdx = current+8;
    +	U32* smallerPtr = bt + 2*(curr&btMask);
    +	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
    +	U32 matchEndIdx = curr+8;
     	U32 dummy32;   /* to be nullified at the end */
     	U32 mnum = 0;
     
    @@ -259,31 +259,31 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     
     	if (minMatch == 3) { /* HC3 match finder */
     		U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
    -		if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
    +		if (matchIndex3>windowLow && (curr - matchIndex3 < (1<<18))) {
     			const BYTE* match;
    -			size_t currentMl=0;
    +			size_t currMl=0;
     			if ((!extDict) || matchIndex3 >= dictLimit) {
     				match = base + matchIndex3;
    -				if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
    +				if (match[bestLength] == ip[bestLength]) currMl = ZSTD_count(ip, match, iLimit);
     			} else {
     				match = dictBase + matchIndex3;
     				if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
    -					currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
    +					currMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
     			}
     
     			/* save best solution */
    -			if (currentMl > bestLength) {
    -				bestLength = currentMl;
    -				matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
    -				matches[mnum].len = (U32)currentMl;
    +			if (currMl > bestLength) {
    +				bestLength = currMl;
    +				matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex3;
    +				matches[mnum].len = (U32)currMl;
     				mnum++;
    -				if (currentMl > ZSTD_OPT_NUM) goto update;
    -				if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
    +				if (currMl > ZSTD_OPT_NUM) goto update;
    +				if (ip+currMl == iLimit) goto update; /* best possible, and avoid read overflow*/
     			}
     		}
     	}
     
    -	hashTable[h] = current;   /* Update Hash Table */
    +	hashTable[h] = curr;   /* Update Hash Table */
     
     	while (nbCompares-- && (matchIndex > windowLow)) {
     		U32* nextPtr = bt + 2*(matchIndex & btMask);
    @@ -305,7 +305,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     		if (matchLength > bestLength) {
     			if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
     			bestLength = matchLength;
    -			matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
    +			matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex;
     			matches[mnum].len = (U32)matchLength;
     			mnum++;
     			if (matchLength > ZSTD_OPT_NUM) break;
    @@ -314,14 +314,14 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     		}
     
     		if (match[matchLength] < ip[matchLength]) {
    -			/* match is smaller than current */
    +			/* match is smaller than curr */
     			*smallerPtr = matchIndex;             /* update smaller idx */
     			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    +			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     		} else {
    -			/* match is larger than current */
    +			/* match is larger than curr */
     			*largerPtr = matchIndex;
     			commonLengthLarger = matchLength;
     			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -332,7 +332,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     	*smallerPtr = *largerPtr = 0;
     
     update:
    -	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    +	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
     	return mnum;
     }
     
    @@ -684,7 +684,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     	while (ip < ilimit) {
     		U32 cur, match_num, last_pos, litlen, price;
     		U32 u, mlen, best_mlen, best_off, litLength;
    -		U32 current = (U32)(ip-base);
    +		U32 curr = (U32)(ip-base);
     		memset(opt, 0, sizeof(ZSTD_optimal_t));
     		last_pos = 0;
     		opt[0].litlen = (U32)(ip - anchor);
    @@ -693,10 +693,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
     			for (i = (ip==anchor); i 0 && repCur <= (S32)current)
    +				if ( (repCur > 0 && repCur <= (S32)curr)
     				   && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
     				   && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
     					/* repcode detected we should take it */
    @@ -789,10 +789,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
     				for (i = (mlen != 1); i 0 && repCur <= (S32)(current+cur))
    +					if ( (repCur > 0 && repCur <= (S32)(curr+cur))
     					  && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
     					  && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
     						/* repcode detected */
    diff --git a/contrib/linux-kernel/test/include/linux/kernel.h b/contrib/linux-kernel/test/include/linux/kernel.h
    index b208e23ba..3ef2f7fe8 100644
    --- a/contrib/linux-kernel/test/include/linux/kernel.h
    +++ b/contrib/linux-kernel/test/include/linux/kernel.h
    @@ -11,4 +11,6 @@
     
     #define PTR_ALIGN(p, a) (typeof(p))ALIGN((unsigned long long)(p), (a))
     
    +#define current Something that doesn't compile :)
    +
     #endif // LINUX_KERNEL_H_
    
    From 0ce0782c970f3d0afac117695bc0285278846cec Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 16:55:03 -0700
    Subject: [PATCH 062/400] [linux-kernel] Update kernelize.sh script for edge
     cases
    
    ---
     contrib/linux-kernel/kernelize.sh      | 56 ++++++++++++++++++++++++++
     contrib/linux-kernel/spaces_to_tabs.sh | 28 -------------
     2 files changed, 56 insertions(+), 28 deletions(-)
     create mode 100755 contrib/linux-kernel/kernelize.sh
     delete mode 100755 contrib/linux-kernel/spaces_to_tabs.sh
    
    diff --git a/contrib/linux-kernel/kernelize.sh b/contrib/linux-kernel/kernelize.sh
    new file mode 100755
    index 000000000..ce24f92f6
    --- /dev/null
    +++ b/contrib/linux-kernel/kernelize.sh
    @@ -0,0 +1,56 @@
    +#!/bin/sh
    +set -e
    +
    +# Constants
    +INCLUDE='include/linux/'
    +LIB='lib/zstd/'
    +SPACES='    '
    +TAB=$'\t'
    +TMP="replacements.tmp"
    +
    +function prompt() {
    +  while true; do
    +    read -p "$1 [Y/n]" yn
    +    case $yn in
    +        '' ) yes='yes'; break;;
    +        [Yy]* ) yes='yes'; break;;
    +        [Nn]* ) yes=''; break;;
    +        * ) echo "Please answer yes or no.";;
    +    esac
    +done
    +}
    +
    +echo "Files: " $INCLUDE*.h $LIB*.{h,c}
    +
    +prompt "Do you wish to replace 4 spaces with a tab?"
    +if [ ! -z "$yes" ]
    +then
    +  # Check files for existing tabs
    +  grep "$TAB" $INCLUDE*.h $LIB*.{h,c} && exit 1 || true
    +  # Replace the first tab on every line
    +  sed -i '' "s/^$SPACES/$TAB/" $INCLUDE*.h $LIB*.{h,c}
    +
    +  # Execute once and then execute as long as replacements are happening
    +  more_work="yes"
    +  while [ ! -z "$more_work" ]
    +  do
    +    rm -f $TMP
    +    # Replaces $SPACES that directly follow a $TAB with a $TAB.
    +    # $TMP will be non-empty if any replacements took place.
    +    sed -i '' "s/$TAB$SPACES/$TAB$TAB/w $TMP" $INCLUDE*.h $LIB*.{h,c}
    +    more_work=$(cat "$TMP")
    +  done
    +  rm -f $TMP
    +fi
    +
    +prompt "Do you wish to replace '{   ' with a tab?"
    +if [ ! -z "$yes" ]
    +then
    +  sed -i '' "s/$TAB{   /$TAB{$TAB/g" $INCLUDE*.h $LIB*.{h,c}
    +fi
    +
    +prompt "Do you wish to replace 'current' with 'curr'?"
    +if [ ! -z "$yes" ]
    +then
    +  sed -i '' "s/current/curr/g" $LIB*.{h,c}
    +fi
    diff --git a/contrib/linux-kernel/spaces_to_tabs.sh b/contrib/linux-kernel/spaces_to_tabs.sh
    deleted file mode 100755
    index ebde5fbaa..000000000
    --- a/contrib/linux-kernel/spaces_to_tabs.sh
    +++ /dev/null
    @@ -1,28 +0,0 @@
    -#!/bin/sh
    -set -e
    -
    -# Constants
    -INCLUDE='include/'
    -LIB='lib/'
    -SPACES='    '
    -TAB=$'\t'
    -TMP="replacements.tmp"
    -
    -echo "Files: " $INCLUDE* $LIB*
    -
    -# Check files for existing tabs
    -grep "$TAB" $INCLUDE* $LIB* && exit 1 || true
    -# Replace the first tab on every line
    -sed -i '' "s/^$SPACES/$TAB/" $INCLUDE* $LIB*
    -
    -# Execute once and then execute as long as replacements are happening
    -more_work="yes"
    -while [ ! -z "$more_work" ]
    -do
    -  rm -f $TMP
    -  # Replaces $SPACES that directly follow a $TAB with a $TAB.
    -  # $TMP will be non-empty if any replacements took place.
    -  sed -i '' "s/$TAB$SPACES/$TAB$TAB/w $TMP" $INCLUDE* $LIB*
    -  more_work=$(cat "$TMP")
    -done
    -rm -f $TMP
    
    From 8eb7a325278199fa790769ba669935c3238619f0 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 16:55:52 -0700
    Subject: [PATCH 063/400] [linux-kernel] Fix whitespace edge case with script
    
    ---
     contrib/linux-kernel/lib/zstd/bitstream.h     |   2 +-
     contrib/linux-kernel/lib/zstd/compress.c      | 108 +++++++++---------
     contrib/linux-kernel/lib/zstd/decompress.c    | 108 +++++++++---------
     .../linux-kernel/lib/zstd/entropy_common.c    |  10 +-
     contrib/linux-kernel/lib/zstd/fse.h           |   2 +-
     contrib/linux-kernel/lib/zstd/fse_compress.c  |  28 ++---
     .../linux-kernel/lib/zstd/fse_decompress.c    |   8 +-
     contrib/linux-kernel/lib/zstd/huf_compress.c  |  42 +++----
     .../linux-kernel/lib/zstd/huf_decompress.c    |  34 +++---
     contrib/linux-kernel/lib/zstd/zstd_opt.h      |  24 ++--
     10 files changed, 183 insertions(+), 183 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/bitstream.h b/contrib/linux-kernel/lib/zstd/bitstream.h
    index 9d2154082..fc2fe1189 100644
    --- a/contrib/linux-kernel/lib/zstd/bitstream.h
    +++ b/contrib/linux-kernel/lib/zstd/bitstream.h
    @@ -367,7 +367,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     		if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
     		return BIT_DStream_completed;
     	}
    -	{   U32 nbBytes = bitD->bitsConsumed >> 3;
    +	{	U32 nbBytes = bitD->bitsConsumed >> 3;
     		BIT_DStream_status result = BIT_DStream_unfinished;
     		if (bitD->ptr - nbBytes < bitD->start) {
     			nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index cd184b78b..b419274d7 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -177,14 +177,14 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
     	if (srcSize+dictSize == 0) return cPar;   /* no size information available : no adjustment */
     
     	/* resize params, to use less memory when necessary */
    -	{   U32 const minSrcSize = (srcSize==0) ? 500 : 0;
    +	{	U32 const minSrcSize = (srcSize==0) ? 500 : 0;
     		U64 const rSize = srcSize + dictSize + minSrcSize;
     		if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog;
     	}   }
     	if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
    -	{   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
    +	{	U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
     		if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
     	}
     
    @@ -236,7 +236,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
     			return ZSTD_continueCCtx(zc, params, frameContentSize);
     		}
     
    -	{   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    +	{	size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
     		U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
     		size_t const maxNbSeq = blockSize / divider;
     		size_t const tokenSpace = blockSize + 11*maxNbSeq;
    @@ -248,7 +248,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
     		void* ptr;
     
     		/* Check if workSpace is large enough, alloc a new one if needed */
    -		{   size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    -	{   ZSTD_parameters params = srcCCtx->params;
    +	{	ZSTD_parameters params = srcCCtx->params;
     		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
     		ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
     	}
     
     	/* copy tables */
    -	{   size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
    +	{	size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
     		size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
     		size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
     		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    @@ -476,12 +476,12 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
     
     	/* small ? don't even attempt compression (speed opt) */
     #   define LITERAL_NOENTROPY 63
    -	{   size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
    +	{	size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
     		if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
     	}
     
     	if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
    -	{   HUF_repeat repeat = zc->flagStaticHufTable;
    +	{	HUF_repeat repeat = zc->flagStaticHufTable;
     		int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
     		if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
     		cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
    @@ -503,18 +503,18 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
     	switch(lhSize)
     	{
     	case 3: /* 2 - 2 - 10 - 10 */
    -		{   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
    +		{	U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
     			MEM_writeLE24(ostart, lhc);
     			break;
     		}
     	case 4: /* 2 - 2 - 14 - 14 */
    -		{   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
    +		{	U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
     			MEM_writeLE32(ostart, lhc);
     			break;
     		}
     	default:   /* should not be necessary, lhSize is only {3,4,5} */
     	case 5: /* 2 - 2 - 18 - 18 */
    -		{   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
    +		{	U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
     			MEM_writeLE32(ostart, lhc);
     			ostart[4] = (BYTE)(cLitSize >> 10);
     			break;
    @@ -589,7 +589,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	BYTE scratchBuffer[1<litStart;
    +	{	const BYTE* const literals = seqStorePtr->litStart;
     		size_t const litSize = seqStorePtr->lit - literals;
     		size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
     		if (ZSTD_isError(cSize)) return cSize;
    @@ -613,7 +613,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	ZSTD_seqToCodes(seqStorePtr);
     
     	/* CTable for Literal Lengths */
    -	{   U32 max = MaxLL;
    +	{	U32 max = MaxLL;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = llCodeTable[0];
    @@ -637,7 +637,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	}   }
     
     	/* CTable for Offsets */
    -	{   U32 max = MaxOff;
    +	{	U32 max = MaxOff;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = ofCodeTable[0];
    @@ -661,7 +661,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	}   }
     
     	/* CTable for MatchLengths */
    -	{   U32 max = MaxML;
    +	{	U32 max = MaxML;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = *mlCodeTable;
    @@ -688,7 +688,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	zc->flagStaticTables = 0;
     
     	/* Encoding Sequences */
    -	{   BIT_CStream_t blockStream;
    +	{	BIT_CStream_t blockStream;
     		FSE_CState_t  stateMatchLength;
     		FSE_CState_t  stateOffsetBits;
     		FSE_CState_t  stateLitLength;
    @@ -717,7 +717,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     		}
     		BIT_flushBits(&blockStream);
     
    -		{   size_t n;
    +		{	size_t n;
     			for (n=nbSeq-2 ; n= maxCSize) {
     			zc->flagStaticHufTable = HUF_repeat_none;
    @@ -989,7 +989,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     
     	/* init */
     	ip += (ip==lowest);
    -	{   U32 const maxRep = (U32)(ip-lowest);
    +	{	U32 const maxRep = (U32)(ip-lowest);
     		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
     		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
     	}
    @@ -1049,7 +1049,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -1121,7 +1121,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     				ip += ((ip-anchor) >> g_searchStrength) + 1;
     				continue;
     			}
    -			{   const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    +			{	const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
     				const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
     				U32 offset;
     				mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
    @@ -1163,7 +1163,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -1234,7 +1234,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     
     	/* init */
     	ip += (ip==lowest);
    -	{   U32 const maxRep = (U32)(ip-lowest);
    +	{	U32 const maxRep = (U32)(ip-lowest);
     		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
     		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
     	}
    @@ -1318,7 +1318,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -1467,7 +1467,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -1901,7 +1901,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     	/* init */
     	ip += (ip==base);
     	ctx->nextToUpdate3 = ctx->nextToUpdate;
    -	{   U32 const maxRep = (U32)(ip-base);
    +	{	U32 const maxRep = (U32)(ip-base);
     		if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
     		if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
     	}
    @@ -1920,7 +1920,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     		}
     
     		/* first search (depth 0) */
    -		{   size_t offsetFound = 99999999;
    +		{	size_t offsetFound = 99999999;
     			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
     			if (ml2 > matchLength)
     				matchLength = ml2, start = ip, offset=offsetFound;
    @@ -1942,7 +1942,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     				if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
     					matchLength = mlRep, offset = 0, start = ip;
     			}
    -			{   size_t offset2=99999999;
    +			{	size_t offset2=99999999;
     				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    @@ -1961,7 +1961,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
     						matchLength = ml2, offset = 0, start = ip;
     				}
    -				{   size_t offset2=99999999;
    +				{	size_t offset2=99999999;
     					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    @@ -1981,7 +1981,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     
     		/* store sequence */
     _storeSequence:
    -		{   size_t const litLength = start - anchor;
    +		{	size_t const litLength = start - anchor;
     			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
     			anchor = ip = start + matchLength;
     		}
    @@ -2004,7 +2004,7 @@ _storeSequence:
     	ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -2073,7 +2073,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     		U32 curr = (U32)(ip-base);
     
     		/* check repCode */
    -		{   const U32 repIndex = (U32)(curr+1 - offset_1);
    +		{	const U32 repIndex = (U32)(curr+1 - offset_1);
     			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     			const BYTE* const repMatch = repBase + repIndex;
     			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    @@ -2085,7 +2085,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     		}   }
     
     		/* first search (depth 0) */
    -		{   size_t offsetFound = 99999999;
    +		{	size_t offsetFound = 99999999;
     			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
     			if (ml2 > matchLength)
     				matchLength = ml2, start = ip, offset=offsetFound;
    @@ -2118,7 +2118,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     			}   }
     
     			/* search match, depth 1 */
    -			{   size_t offset2=99999999;
    +			{	size_t offset2=99999999;
     				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    @@ -2148,7 +2148,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     				}   }
     
     				/* search match, depth 2 */
    -				{   size_t offset2=99999999;
    +				{	size_t offset2=99999999;
     					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    @@ -2170,7 +2170,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     
     		/* store sequence */
     _storeSequence:
    -		{   size_t const litLength = start - anchor;
    +		{	size_t const litLength = start - anchor;
     			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
     			anchor = ip = start + matchLength;
     		}
    @@ -2198,7 +2198,7 @@ _storeSequence:
     	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -2572,12 +2572,12 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     	cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
     	dictPtr += 4;
     
    -	{   size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
    +	{	size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
     		if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
     		dictPtr += hufHeaderSize;
     	}
     
    -	{   unsigned offcodeLog;
    +	{	unsigned offcodeLog;
     		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
     		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    @@ -2586,7 +2586,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     		dictPtr += offcodeHeaderSize;
     	}
     
    -	{   short matchlengthNCount[MaxML+1];
    +	{	short matchlengthNCount[MaxML+1];
     		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
     		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -2597,7 +2597,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     		dictPtr += matchlengthHeaderSize;
     	}
     
    -	{   short litlengthNCount[MaxLL+1];
    +	{	short litlengthNCount[MaxLL+1];
     		unsigned litlengthMaxValue = MaxLL, litlengthLog;
     		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -2614,7 +2614,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     	cctx->rep[2] = MEM_readLE32(dictPtr+8);
     	dictPtr += 12;
     
    -	{   size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
    +	{	size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
     		U32 offcodeMax = MaxOff;
     		if (dictContentSize <= ((U32)-1) - 128 KB) {
     			U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
    @@ -2623,7 +2623,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     		/* All offset values <= dictContentSize + 128 KB must be representable */
     		CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
     		/* All repCodes must be <= dictContentSize and != 0*/
    -		{   U32 u;
    +		{	U32 u;
     			for (u=0; u<3; u++) {
     				if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
     				if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
    @@ -2781,7 +2781,7 @@ static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dict
     {
     	if (!customMem.customAlloc || !customMem.customFree) return NULL;
     
    -	{   ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    +	{	ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
     		ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
     
     		if (!cdict || !cctx) {
    @@ -2801,7 +2801,7 @@ static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dict
     			cdict->dictContent = internalBuffer;
     		}
     
    -		{   size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
    +		{	size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
     			if (ZSTD_isError(errorCode)) {
     				ZSTD_free(cdict->dictBuffer, customMem);
     				ZSTD_free(cdict, customMem);
    @@ -2824,7 +2824,7 @@ ZSTD_CDict* ZSTD_initCDict(const void* dict, size_t dictSize, ZSTD_parameters pa
     size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
     {
     	if (cdict==NULL) return 0;   /* support free on NULL */
    -	{   ZSTD_customMem const cMem = cdict->refContext->customMem;
    +	{	ZSTD_customMem const cMem = cdict->refContext->customMem;
     		ZSTD_freeCCtx(cdict->refContext);
     		ZSTD_free(cdict->dictBuffer, cMem);
     		ZSTD_free(cdict, cMem);
    @@ -2926,7 +2926,7 @@ ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
     size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
     {
     	if (zcs==NULL) return 0;   /* support free on NULL */
    -	{   ZSTD_customMem const cMem = zcs->customMem;
    +	{	ZSTD_customMem const cMem = zcs->customMem;
     		ZSTD_freeCCtx(zcs->cctx);
     		zcs->cctx = NULL;
     		ZSTD_freeCDict(zcs->cdictLocal);
    @@ -2977,7 +2977,7 @@ static size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
     								 ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
     	/* allocate buffers */
    -	{   size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
    +	{	size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
     		if (zcs->inBuffSize < neededInBuffSize) {
     			zcs->inBuffSize = neededInBuffSize;
     			ZSTD_free(zcs->inBuff, zcs->customMem);
    @@ -3061,7 +3061,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     
     		case zcss_load:
     			/* complete inBuffer */
    -			{   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    +			{	size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
     				size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
     				zcs->inBuffPos += loaded;
     				ip += loaded;
    @@ -3069,7 +3069,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     					someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
     			}   }
     			/* compress curr block (note : this stage cannot be stopped in the middle) */
    -			{   void* cDst;
    +			{	void* cDst;
     				size_t cSize;
     				size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
     				size_t oSize = oend-op;
    @@ -3094,7 +3094,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     			}
     
     		case zcss_flush:
    -			{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    +			{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     				size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
     				op += flushed;
     				zcs->outBuffFlushedSize += flushed;
    @@ -3117,7 +3117,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     	*dstCapacityPtr = op - ostart;
     	zcs->inputProcessed += *srcSizePtr;
     	if (zcs->frameEnded) return 0;
    -	{   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
    +	{	size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
     		if (hintInSize==0) hintInSize = zcs->blockSize;
     		return hintInSize;
     	}
    @@ -3181,7 +3181,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     	}
     
     	/* flush epilogue */
    -	{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    +	{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     		size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
     		op += flushed;
     		zcs->outBuffFlushedSize += flushed;
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 73cf06f5f..688d68539 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -188,7 +188,7 @@ static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
     unsigned ZSTD_isFrame(const void* buffer, size_t size)
     {
     	if (size < 4) return 0;
    -	{   U32 const magic = MEM_readLE32(buffer);
    +	{	U32 const magic = MEM_readLE32(buffer);
     		if (magic == ZSTD_MAGICNUMBER) return 1;
     		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
     	}
    @@ -202,7 +202,7 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
     static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
     {
     	if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
    -	{   BYTE const fhd = ((const BYTE*)src)[4];
    +	{	BYTE const fhd = ((const BYTE*)src)[4];
     		U32 const dictID= fhd & 3;
     		U32 const singleSegment = (fhd >> 5) & 1;
     		U32 const fcsId = fhd >> 6;
    @@ -237,7 +237,7 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
     	{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
     	  if (srcSize < fhsize) return fhsize; }
     
    -	{   BYTE const fhdByte = ip[4];
    +	{	BYTE const fhdByte = ip[4];
     		size_t pos = 5;
     		U32 const dictIDSizeCode = fhdByte&3;
     		U32 const checksumFlag = (fhdByte>>2)&1;
    @@ -383,7 +383,7 @@ typedef struct
     size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
     {
     	if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    -	{   U32 const cBlockHeader = MEM_readLE24(src);
    +	{	U32 const cBlockHeader = MEM_readLE24(src);
     		U32 const cSize = cBlockHeader >> 3;
     		bpPtr->lastBlock = cBlockHeader & 1;
     		bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
    @@ -418,7 +418,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     {
     	if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
     
    -	{   const BYTE* const istart = (const BYTE*) src;
    +	{	const BYTE* const istart = (const BYTE*) src;
     		symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
     
     		switch(litEncType)
    @@ -428,7 +428,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     			/* fall-through */
     		case set_compressed:
     			if (srcSize < 5) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
    -			{   size_t lhSize, litSize, litCSize;
    +			{	size_t lhSize, litSize, litCSize;
     				U32 singleStream=0;
     				U32 const lhlCode = (istart[0] >> 2) & 3;
     				U32 const lhc = MEM_readLE32(istart);
    @@ -475,7 +475,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     			}
     
     		case set_basic:
    -			{   size_t litSize, lhSize;
    +			{	size_t litSize, lhSize;
     				U32 const lhlCode = ((istart[0]) >> 2) & 3;
     				switch(lhlCode)
     				{
    @@ -508,7 +508,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     			}
     
     		case set_rle:
    -			{   U32 const lhlCode = ((istart[0]) >> 2) & 3;
    +			{	U32 const lhlCode = ((istart[0]) >> 2) & 3;
     				size_t litSize, lhSize;
     				switch(lhlCode)
     				{
    @@ -742,7 +742,7 @@ static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTa
     		return 0;
     	default :   /* impossible */
     	case set_compressed :
    -		{   U32 tableLog;
    +		{	U32 tableLog;
     			S16 norm[MaxSeq+1];
     			size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
     			if (FSE_isError(headerSize)) return ERROR(corruption_detected);
    @@ -764,7 +764,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
     	if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
     
     	/* SeqHead */
    -	{   int nbSeq = *ip++;
    +	{	int nbSeq = *ip++;
     		if (!nbSeq) { *nbSeqPtr=0; return 1; }
     		if (nbSeq > 0x7F) {
     			if (nbSeq == 0xFF) {
    @@ -780,25 +780,25 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
     
     	/* FSE table descriptors */
     	if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
    -	{   symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
    +	{	symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
     		symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
     		symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
     		ip++;
     
     		/* Build DTables */
    -		{   size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
    +		{	size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
     													  LLtype, MaxLL, LLFSELog,
     													  ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
     			if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
     			ip += llhSize;
     		}
    -		{   size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
    +		{	size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
     													  OFtype, MaxOff, OffFSELog,
     													  ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
     			if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
     			ip += ofhSize;
     		}
    -		{   size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
    +		{	size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
     													  MLtype, MaxML, MLFSELog,
     													  ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
     			if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
    @@ -865,7 +865,7 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{   size_t const length1 = dictEnd - match;
    +		{	size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
    @@ -909,7 +909,7 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
     							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
     
     	/* sequence */
    -	{   size_t offset;
    +	{	size_t offset;
     		if (!ofCode)
     			offset = 0;
     		else {
    @@ -988,7 +988,7 @@ size_t ZSTD_execSequence(BYTE* op,
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{   size_t const length1 = dictEnd - match;
    +		{	size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
    @@ -1051,7 +1051,7 @@ static size_t ZSTD_decompressSequences(
     	int nbSeq;
     
     	/* Build Decoding Tables */
    -	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    +	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
     		if (ZSTD_isError(seqHSize)) return seqHSize;
     		ip += seqHSize;
     	}
    @@ -1068,7 +1068,7 @@ static size_t ZSTD_decompressSequences(
     
     		for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
     			nbSeq--;
    -			{   seq_t const sequence = ZSTD_decodeSequence(&seqState);
    +			{	seq_t const sequence = ZSTD_decodeSequence(&seqState);
     				size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
     				if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
     				op += oneSeqSize;
    @@ -1081,7 +1081,7 @@ static size_t ZSTD_decompressSequences(
     	}
     
     	/* last literal segment */
    -	{   size_t const lastLLSize = litEnd - litPtr;
    +	{	size_t const lastLLSize = litEnd - litPtr;
     		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
     		memcpy(op, litPtr, lastLLSize);
     		op += lastLLSize;
    @@ -1122,7 +1122,7 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
     
     	/* sequence */
    -	{   size_t offset;
    +	{	size_t offset;
     		if (!ofCode)
     			offset = 0;
     		else {
    @@ -1163,7 +1163,7 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     	if (MEM_32bits() ||
     	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
     
    -	{   size_t const pos = seqState->pos + seq.litLength;
    +	{	size_t const pos = seqState->pos + seq.litLength;
     		seq.match = seqState->base + pos - seq.offset;    /* single memory segment */
     		if (seq.offset > pos) seq.match += seqState->gotoDict;   /* separate memory segment */
     		seqState->pos = pos + seq.matchLength;
    @@ -1223,7 +1223,7 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{   size_t const length1 = dictEnd - match;
    +		{	size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
    @@ -1287,7 +1287,7 @@ static size_t ZSTD_decompressSequencesLong(
     	int nbSeq;
     
     	/* Build Decoding Tables */
    -	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    +	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
     		if (ZSTD_isError(seqHSize)) return seqHSize;
     		ip += seqHSize;
     	}
    @@ -1341,7 +1341,7 @@ static size_t ZSTD_decompressSequencesLong(
     	}
     
     	/* last literal segment */
    -	{   size_t const lastLLSize = litEnd - litPtr;
    +	{	size_t const lastLLSize = litEnd - litPtr;
     		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
     		memcpy(op, litPtr, lastLLSize);
     		op += lastLLSize;
    @@ -1360,7 +1360,7 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
     	if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
     
     	/* Decode literals section */
    -	{   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    +	{	size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
     		if (ZSTD_isError(litCSize)) return litCSize;
     		ip += litCSize;
     		srcSize -= litCSize;
    @@ -1434,7 +1434,7 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
     		if (ZSTD_isError(headerSize)) return headerSize;
     
     		/* Frame Header */
    -		{   size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    +		{	size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
     			if (ZSTD_isError(ret)) return ret;
     			if (ret > 0) return ERROR(srcSize_wrong);
     		}
    @@ -1482,7 +1482,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     	if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
     
     	/* Frame Header */
    -	{   size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
    +	{	size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
     		if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
     		if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
     		CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
    @@ -1594,7 +1594,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
     		}
     		ZSTD_checkContinuity(dctx, dst);
     
    -		{   const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
    +		{	const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
     													&src, &srcSize);
     			if (ZSTD_isError(res)) return res;
     			/* don't need to bounds check this, ZSTD_decompressFrame will have
    @@ -1687,7 +1687,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     		return 0;
     
     	case ZSTDds_decodeBlockHeader:
    -		{   blockProperties_t bp;
    +		{	blockProperties_t bp;
     			size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
     			if (ZSTD_isError(cBlockSize)) return cBlockSize;
     			dctx->expected = cBlockSize;
    @@ -1714,7 +1714,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     		}
     	case ZSTDds_decompressLastBlock:
     	case ZSTDds_decompressBlock:
    -		{   size_t rSize;
    +		{	size_t rSize;
     			switch(dctx->bType)
     			{
     			case bt_compressed:
    @@ -1749,7 +1749,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     			return rSize;
     		}
     	case ZSTDds_checkChecksum:
    -		{   U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    +		{	U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
     			U32 const check32 = MEM_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
     			if (check32 != h32) return ERROR(checksum_wrong);
     			dctx->expected = 0;
    @@ -1757,13 +1757,13 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     			return 0;
     		}
     	case ZSTDds_decodeSkippableHeader:
    -		{   memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    +		{	memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
     			dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
     			dctx->stage = ZSTDds_skipFrame;
     			return 0;
     		}
     	case ZSTDds_skipFrame:
    -		{   dctx->expected = 0;
    +		{	dctx->expected = 0;
     			dctx->stage = ZSTDds_getFrameHeaderSize;
     			return 0;
     		}
    @@ -1794,12 +1794,12 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     	dictPtr += 8;   /* skip header = magic + dictID */
     
     
    -	{   size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
    +	{	size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
     		if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
     		dictPtr += hSize;
     	}
     
    -	{   short offcodeNCount[MaxOff+1];
    +	{	short offcodeNCount[MaxOff+1];
     		U32 offcodeMaxValue = MaxOff, offcodeLog;
     		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -1808,7 +1808,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     		dictPtr += offcodeHeaderSize;
     	}
     
    -	{   short matchlengthNCount[MaxML+1];
    +	{	short matchlengthNCount[MaxML+1];
     		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
     		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -1817,7 +1817,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     		dictPtr += matchlengthHeaderSize;
     	}
     
    -	{   short litlengthNCount[MaxLL+1];
    +	{	short litlengthNCount[MaxLL+1];
     		unsigned litlengthMaxValue = MaxLL, litlengthLog;
     		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
     		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -1827,7 +1827,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     	}
     
     	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    -	{   int i;
    +	{	int i;
     		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
     		for (i=0; i<3; i++) {
     			U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
    @@ -1841,14 +1841,14 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
     {
     	if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
    -	{   U32 const magic = MEM_readLE32(dict);
    +	{	U32 const magic = MEM_readLE32(dict);
     		if (magic != ZSTD_DICT_MAGIC) {
     			return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
     	}   }
     	dctx->dictID = MEM_readLE32((const char*)dict + 4);
     
     	/* load entropy tables */
    -	{   size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    +	{	size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
     		if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
     		dict = (const char*)dict + eSize;
     		dictSize -= eSize;
    @@ -1925,7 +1925,7 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
     	ddict->dictID = 0;
     	ddict->entropyPresent = 0;
     	if (ddict->dictSize < 8) return 0;
    -	{   U32 const magic = MEM_readLE32(ddict->dictContent);
    +	{	U32 const magic = MEM_readLE32(ddict->dictContent);
     		if (magic != ZSTD_DICT_MAGIC) return 0;   /* pure content mode */
     	}
     	ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
    @@ -1941,7 +1941,7 @@ static ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
     {
     	if (!customMem.customAlloc || !customMem.customFree) return NULL;
     
    -	{   ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
    +	{	ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
     		if (!ddict) return NULL;
     		ddict->cMem = customMem;
     
    @@ -1958,7 +1958,7 @@ static ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
     		ddict->dictSize = dictSize;
     		ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
     		/* parse dictionary content */
    -		{   size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
    +		{	size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
     			if (ZSTD_isError(errorCode)) {
     				ZSTD_freeDDict(ddict);
     				return NULL;
    @@ -1982,7 +1982,7 @@ ZSTD_DDict* ZSTD_initDDict(const void* dict, size_t dictSize, void* workspace, s
     size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
     {
     	if (ddict==NULL) return 0;   /* support free on NULL */
    -	{   ZSTD_customMem const cMem = ddict->cMem;
    +	{	ZSTD_customMem const cMem = ddict->cMem;
     		ZSTD_free(ddict->dictBuffer, cMem);
     		ZSTD_free(ddict, cMem);
     		return 0;
    @@ -2129,7 +2129,7 @@ ZSTD_DStream* ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict
     size_t ZSTD_freeDStream(ZSTD_DStream* zds)
     {
     	if (zds==NULL) return 0;   /* support free on null */
    -	{   ZSTD_customMem const cMem = zds->customMem;
    +	{	ZSTD_customMem const cMem = zds->customMem;
     		ZSTD_freeDCtx(zds->dctx);
     		zds->dctx = NULL;
     		ZSTD_freeDDict(zds->ddictLocal);
    @@ -2186,7 +2186,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     			/* fall-through */
     
     		case zdss_loadHeader :
    -			{   size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    +			{	size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
     				if (ZSTD_isError(hSize))
     				return hSize;
     				if (hSize != 0) {   /* need more input */
    @@ -2218,9 +2218,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     
     			/* Consume header */
     			ZSTD_refDDict(zds->dctx, zds->ddict);
    -			{   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    +			{	size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
     				CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    -				{   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +				{	size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     					CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
     			}   }
     
    @@ -2228,7 +2228,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     			if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
     
     			/* Adapt buffer sizes to frame header instructions */
    -			{   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +			{	size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
     				size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
     				zds->blockSize = blockSize;
     				if (zds->inBuffSize < blockSize) {
    @@ -2247,7 +2247,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     			/* pass-through */
     
     		case zdss_read:
    -			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     				if (neededInSize==0) {  /* end of frame */
     					zds->stage = zdss_init;
     					someMoreWork = 0;
    @@ -2271,7 +2271,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     			}
     
     		case zdss_load:
    -			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     				size_t const toLoad = neededInSize - zds->inPos;   /* should always be <= remaining space within inBuff */
     				size_t loadedSize;
     				if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected);   /* should never happen */
    @@ -2294,7 +2294,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     			}   }
     
     		case zdss_flush:
    -			{   size_t const toFlushSize = zds->outEnd - zds->outStart;
    +			{	size_t const toFlushSize = zds->outEnd - zds->outStart;
     				size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
     				op += flushedSize;
     				zds->outStart += flushedSize;
    @@ -2314,7 +2314,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     	/* result */
     	input->pos += (size_t)(ip-istart);
     	output->pos += (size_t)(op-ostart);
    -	{   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +	{	size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     		if (!nextSrcSizeHint) {   /* frame fully decoded */
     			if (zds->outEnd == zds->outStart) {  /* output fully flushed */
     				if (zds->hostageByte) {
    diff --git a/contrib/linux-kernel/lib/zstd/entropy_common.c b/contrib/linux-kernel/lib/zstd/entropy_common.c
    index 68d880827..36ad26653 100644
    --- a/contrib/linux-kernel/lib/zstd/entropy_common.c
    +++ b/contrib/linux-kernel/lib/zstd/entropy_common.c
    @@ -107,7 +107,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     			} else {
     				bitStream >>= 2;
     		}   }
    -		{   int const max = (2*threshold-1) - remaining;
    +		{	int const max = (2*threshold-1) - remaining;
     			int count;
     
     			if ((bitStream & (threshold-1)) < (U32)max) {
    @@ -172,7 +172,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
     		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
     		if (oSize >= hwSize) return ERROR(corruption_detected);
     		ip += 1;
    -		{   U32 n;
    +		{	U32 n;
     			for (n=0; n> 4;
     				huffWeight[n+1] = ip[n/2] & 15;
    @@ -187,7 +187,7 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
     	/* collect weight stats */
     	memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
     	weightTotal = 0;
    -	{   U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
     			rankStats[huffWeight[n]]++;
     			weightTotal += (1 << huffWeight[n]) >> 1;
    @@ -195,11 +195,11 @@ size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
     	if (weightTotal == 0) return ERROR(corruption_detected);
     
     	/* get last non-null symbol weight (implied, total must be 2^n) */
    -	{   U32 const tableLog = BIT_highbit32(weightTotal) + 1;
    +	{	U32 const tableLog = BIT_highbit32(weightTotal) + 1;
     		if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
     		*tableLogPtr = tableLog;
     		/* determine last weight */
    -		{   U32 const total = 1 << tableLog;
    +		{	U32 const total = 1 << tableLog;
     			U32 const rest = total - weightTotal;
     			U32 const verif = 1 << BIT_highbit32(rest);
     			U32 const lastWeight = BIT_highbit32(rest) + 1;
    diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h
    index 14fa439ee..6a7895722 100644
    --- a/contrib/linux-kernel/lib/zstd/fse.h
    +++ b/contrib/linux-kernel/lib/zstd/fse.h
    @@ -459,7 +459,7 @@ MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
     MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
     {
     	FSE_initCState(statePtr, ct);
    -	{   const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    +	{	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
     		const U16* stateTable = (const U16*)(statePtr->stateTable);
     		U32 nbBitsOut  = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
     		statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index b6a6d4693..672c72d94 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -106,7 +106,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi
     	*  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
     
     	/* symbol start positions */
    -	{   U32 u;
    +	{	U32 u;
     		cumul[0] = 0;
     		for (u=1; u<=maxSymbolValue+1; u++) {
     			if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */
    @@ -119,7 +119,7 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi
     	}
     
     	/* Spread symbols */
    -	{   U32 position = 0;
    +	{	U32 position = 0;
     		U32 symbol;
     		for (symbol=0; symbol<=maxSymbolValue; symbol++) {
     			int nbOccurences;
    @@ -133,13 +133,13 @@ size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsi
     	}
     
     	/* Build table */
    -	{   U32 u; for (u=0; u>= 16;
     				bitCount -= 16;
     		}   }
    -		{   int count = normalizedCounter[charnum++];
    +		{	int count = normalizedCounter[charnum++];
     			int const max = (2*threshold-1)-remaining;
     			remaining -= count < 0 ? -count : count;
     			count++;   /* +1 for extra accuracy */
    @@ -337,7 +337,7 @@ static size_t FSE_count_parallel_wksp(
     	if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
     
     	/* by stripes of 16 bytes */
    -	{   U32 cached = MEM_read32(ip); ip += 4;
    +	{	U32 cached = MEM_read32(ip); ip += 4;
     		while (ip < iend-15) {
     			U32 c = cached; cached = MEM_read32(ip); ip += 4;
     			Counting1[(BYTE) c     ]++;
    @@ -372,7 +372,7 @@ static size_t FSE_count_parallel_wksp(
     			if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
     	}   }
     
    -	{   U32 s; for (s=0; s<=maxSymbolValue; s++) {
    +	{	U32 s; for (s=0; s<=maxSymbolValue; s++) {
     			count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
     			if (count[s] > max) max = count[s];
     	}   }
    @@ -517,7 +517,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     		return 0;
     	}
     
    -	{   U64 const vStepLog = 62 - tableLog;
    +	{	U64 const vStepLog = 62 - tableLog;
     		U64 const mid = (1ULL << (vStepLog-1)) - 1;
     		U64 const rStep = ((((U64)1< FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
     	if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
     
    -	{   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
    +	{	U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
     		U64 const scale = 62 - tableLog;
     		U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
     		U64 const vStep = 1ULL<<(scale-20);
    @@ -582,7 +582,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
     	}
     
     #if 0
    -	{   /* Print Table (debug) */
    +	{	/* Print Table (debug) */
     		U32 s;
     		U32 nTotal = 0;
     		for (s=0; s<=maxSymbolValue; s++)
    @@ -623,7 +623,7 @@ size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
     		tableU16[s] = (U16)(tableSize + s);
     
     	/* Build Symbol Transformation Table */
    -	{   const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
    +	{	const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
     		for (s=0; s<=maxSymbolValue; s++) {
     			symbolTT[s].deltaNbBits = deltaNbBits;
     			symbolTT[s].deltaFindState = s-1;
    @@ -757,7 +757,7 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
     	if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
     
     	/* Scan input and build symbol stats */
    -	{   CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) );
    +	{	CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) );
     		if (maxCount == srcSize) return 1;   /* only a single symbol in src : rle */
     		if (maxCount == 1) return 0;         /* each symbol present maximum once => not compressible */
     		if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
    @@ -767,13 +767,13 @@ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t src
     	CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
     
     	/* Write table description header */
    -	{   CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    +	{	CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
     		op += nc_err;
     	}
     
     	/* Compress */
     	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
    -	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
    +	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
     		if (cSize == 0) return 0;   /* not enough space for compressed data */
     		op += cSize;
     	}
    diff --git a/contrib/linux-kernel/lib/zstd/fse_decompress.c b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    index 2a35f1703..6de541131 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    @@ -98,10 +98,10 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned
     	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
     
     	/* Init, lay down lowprob symbols */
    -	{   FSE_DTableHeader DTableH;
    +	{	FSE_DTableHeader DTableH;
     		DTableH.tableLog = (U16)tableLog;
     		DTableH.fastMode = 1;
    -		{   S16 const largeLimit= (S16)(1 << (tableLog-1));
    +		{	S16 const largeLimit= (S16)(1 << (tableLog-1));
     			U32 s;
     			for (s=0; s not compressible */
     	}
    @@ -96,13 +96,13 @@ size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable,
     	CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
     
     	/* Write table description header */
    -	{   CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    +	{	CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
     		op += hSize;
     	}
     
     	/* Compress */
     	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
    -	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
    +	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
     		if (cSize == 0) return 0;   /* not enough space for compressed data */
     		op += cSize;
     	}
    @@ -138,7 +138,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
     		huffWeight[n] = bitsToWeight[CTable[n].nbBits];
     
     	/* attempt weights compression by FSE */
    -	{   CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
    +	{	CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
     		if ((hSize>1) & (hSize < maxSymbolValue/2)) {   /* FSE compressed */
     			op[0] = (BYTE)hSize;
     			return hSize+1;
    @@ -170,7 +170,7 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
     	if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
     
     	/* Prepare base value per rank */
    -	{   U32 n, nextRankStart = 0;
    +	{	U32 n, nextRankStart = 0;
     		for (n=1; n<=tableLog; n++) {
     			U32 curr = nextRankStart;
     			nextRankStart += (rankVal[n] << (n-1));
    @@ -178,18 +178,18 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, si
     	}   }
     
     	/* fill nbBits */
    -	{   U32 n; for (n=0; nn=tableLog+1 */
    +	{	U16 nbPerRank[HUF_TABLELOG_MAX+2]  = {0};  /* support w=0=>n=tableLog+1 */
     		U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
     		{ U32 n; for (n=0; n0; n--) {  /* start at n=tablelog <-> w=1 */
     				valPerRank[n] = min;     /* get starting value within each rank */
     				min += nbPerRank[n];
    @@ -216,7 +216,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
     	if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */
     
     	/* there are several too large elements (at least >= 2) */
    -	{   int totalCost = 0;
    +	{	int totalCost = 0;
     		const U32 baseCost = 1 << (largestBits - maxNbBits);
     		U32 n = lastNonNull;
     
    @@ -231,13 +231,13 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
     		totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */
     
     		/* repay normalized cost */
    -		{   U32 const noSymbol = 0xF0F0F0F0;
    +		{	U32 const noSymbol = 0xF0F0F0F0;
     			U32 rankLast[HUF_TABLELOG_MAX+2];
     			int pos;
     
     			/* Get pos of last (smallest) symbol per rank */
     			memset(rankLast, 0xF0, sizeof(rankLast));
    -			{   U32 currNbBits = maxNbBits;
    +			{	U32 currNbBits = maxNbBits;
     				for (pos=n ; pos >= 0; pos--) {
     					if (huffNode[pos].nbBits >= currNbBits) continue;
     					currNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    @@ -251,7 +251,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
     					U32 lowPos = rankLast[nBitsToDecrease-1];
     					if (highPos == noSymbol) continue;
     					if (lowPos == noSymbol) break;
    -					{   U32 const highTotal = huffNode[highPos].count;
    +					{	U32 const highTotal = huffNode[highPos].count;
     						U32 const lowTotal = 2 * huffNode[lowPos].count;
     						if (highTotal <= lowTotal) break;
     				}   }
    @@ -369,13 +369,13 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValu
     	maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
     
     	/* fill result into tree (val, nbBits) */
    -	{   U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
    +	{	U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
     		U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
     		if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC);   /* check fit into table */
     		for (n=0; n<=nonNullRank; n++)
     			nbPerRank[huffNode[n].nbBits]++;
     		/* determine stating value per rank */
    -		{   U16 min = 0;
    +		{	U16 min = 0;
     			for (n=maxNbBits; n>0; n--) {
     				valPerRank[n] = min;      /* get starting value within each rank */
     				min += nbPerRank[n];
    @@ -480,28 +480,28 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
     	if (srcSize < 12) return 0;   /* no saving possible : too small input */
     	op += 6;   /* jumpTable */
     
    -	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    +	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
     		MEM_writeLE16(ostart, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    +	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
     		MEM_writeLE16(ostart+2, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    +	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
     		MEM_writeLE16(ostart+4, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
    +	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
     		if (cSize==0) return 0;
     		op += cSize;
     	}
    @@ -567,7 +567,7 @@ static size_t HUF_compress_internal (
     	}
     
     	/* Scan input and build symbol stats */
    -	{   CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
    +	{	CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
     		if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */
     		if (largest <= (srcSize >> 7)+1) return 0;   /* Fast heuristic : not compressible enough */
     	}
    @@ -583,14 +583,14 @@ static size_t HUF_compress_internal (
     
     	/* Build Huffman Tree */
     	huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
    -	{   CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
    +	{	CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
     		huffLog = (U32)maxBits;
     		/* Zero the unused symbols so we can check it for validity */
     		memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
     	}
     
     	/* Write table description header */
    -	{   CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
    +	{	CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
     		/* Check if using the previous table will be beneficial */
     		if (repeat && *repeat != HUF_repeat_none) {
     			size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index a47cb72ff..2d9b33b12 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -91,7 +91,7 @@ size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
     	if (HUF_isError(iSize)) return iSize;
     
     	/* Table header */
    -	{   DTableDesc dtd = HUF_getDTableDesc(DTable);
    +	{	DTableDesc dtd = HUF_getDTableDesc(DTable);
     		if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
     		dtd.tableType = 0;
     		dtd.tableLog = (BYTE)tableLog;
    @@ -99,7 +99,7 @@ size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
     	}
     
     	/* Calculate starting value for each rank */
    -	{   U32 n, nextRankStart = 0;
    +	{	U32 n, nextRankStart = 0;
     		for (n=1; n> 1;
    @@ -220,7 +220,7 @@ static size_t HUF_decompress4X2_usingDTable_internal(
     	/* Check */
     	if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
     
    -	{   const BYTE* const istart = (const BYTE*) cSrc;
    +	{	const BYTE* const istart = (const BYTE*) cSrc;
     		BYTE* const ostart = (BYTE*) dst;
     		BYTE* const oend = ostart + dstSize;
     		const void* const dtPtr = DTable + 1;
    @@ -359,7 +359,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
     	}
     
     	/* fill DTable */
    -	{   U32 s; for (s=0; s= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
     
    -	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    +	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     	}
    @@ -828,7 +828,7 @@ size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const
     	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
     	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
     
    -	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    +	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     		return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     						HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     	}
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_opt.h b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    index 321f8c410..9bd5303a6 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_opt.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    @@ -127,7 +127,7 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
     	}
     
     	/* literal Length */
    -	{   const BYTE LL_deltaCode = 19;
    +	{	const BYTE LL_deltaCode = 19;
     		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
     		price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
     	}
    @@ -149,7 +149,7 @@ FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYT
     	if (!ultra && offCode >= 20) price += (offCode-19)*2;
     
     	/* match Length */
    -	{   const BYTE ML_deltaCode = 36;
    +	{	const BYTE ML_deltaCode = 36;
     		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
     		price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
     	}
    @@ -168,20 +168,20 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
     		seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
     
     	/* literal Length */
    -	{   const BYTE LL_deltaCode = 19;
    +	{	const BYTE LL_deltaCode = 19;
     		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
     		seqStorePtr->litLengthFreq[llCode]++;
     		seqStorePtr->litLengthSum++;
     	}
     
     	/* match offset */
    -	{   BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
    +	{	BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
     		seqStorePtr->offCodeSum++;
     		seqStorePtr->offCodeFreq[offCode]++;
     	}
     
     	/* match Length */
    -	{   const BYTE ML_deltaCode = 36;
    +	{	const BYTE ML_deltaCode = 36;
     		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
     		seqStorePtr->matchLengthFreq[mlCode]++;
     		seqStorePtr->matchLengthSum++;
    @@ -192,7 +192,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
     
     
     #define SET_PRICE(pos, mlen_, offset_, litlen_, price_)   \
    -	{                                                 \
    +	{	                                              \
     		while (last_pos < pos)  { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
     		opt[pos].mlen = mlen_;                         \
     		opt[pos].off = offset_;                        \
    @@ -435,7 +435,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
     		litlen = (U32)(ip - anchor);
     
     		/* check repCode */
    -		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    +		{	U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
     			for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
    @@ -520,7 +520,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
     		   }
     
     			best_mlen = minMatch;
    -			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
    +			{	U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
     				for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
    @@ -639,7 +639,7 @@ _storeSequence:   /* cur, last_pos, best_mlen, best_off have to be set */
     	{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
     
     	/* Last Literals */
    -	{   size_t const lastLLSize = iend - anchor;
    +	{	size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    @@ -690,7 +690,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     		opt[0].litlen = (U32)(ip - anchor);
     
     		/* check repCode */
    -		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    +		{	U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
     			for (i = (ip==anchor); irepToConfirm[i] = rep[i]; }
     
     	/* Last Literals */
    -	{   size_t lastLLSize = iend - anchor;
    +	{	size_t lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
    
    From 358280f1074de49c8acb545ed9d9c675eebd4044 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 17:16:00 -0700
    Subject: [PATCH 064/400] Remove cross-platform macros and dead code
    
    ---
     contrib/linux-kernel/lib/zstd/bitstream.h     | 17 +---
     contrib/linux-kernel/lib/zstd/compress.c      | 83 -------------------
     contrib/linux-kernel/lib/zstd/decompress.c    | 28 -------
     contrib/linux-kernel/lib/zstd/fse_compress.c  | 14 ----
     contrib/linux-kernel/lib/zstd/zstd_internal.h | 13 ---
     5 files changed, 1 insertion(+), 154 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/bitstream.h b/contrib/linux-kernel/lib/zstd/bitstream.h
    index fc2fe1189..9b5d2bc82 100644
    --- a/contrib/linux-kernel/lib/zstd/bitstream.h
    +++ b/contrib/linux-kernel/lib/zstd/bitstream.h
    @@ -147,22 +147,7 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
     ****************************************************************/
     MEM_STATIC unsigned BIT_highbit32 (register U32 val)
     {
    -#   if defined(_MSC_VER)   /* Visual */
    -	unsigned long r=0;
    -	_BitScanReverse ( &r, val );
    -	return (unsigned) r;
    -#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* Use GCC Intrinsic */
    -	return 31 - __builtin_clz (val);
    -#   else   /* Software version */
    -	static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    -	U32 v = val;
    -	v |= v >> 1;
    -	v |= v >> 2;
    -	v |= v >> 4;
    -	v |= v >> 8;
    -	v |= v >> 16;
    -	return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
    -#   endif
    +	return 31 - __builtin_clz(val);
     }
     
     /*=====    Local Constants   =====*/
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index b419274d7..4f1e18484 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -774,12 +774,6 @@ _check_compressibility:
     	return op - ostart;
     }
     
    -#if 0 /* for debug */
    -#  define STORESEQ_DEBUG
    -U32 g_startDebug = 0;
    -const BYTE* g_start = NULL;
    -#endif
    -
     /*! ZSTD_storeSeq() :
     	Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
     	`offsetCode` : distance to match, or 0 == repCode.
    @@ -787,15 +781,6 @@ const BYTE* g_start = NULL;
     */
     MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
     {
    -#ifdef STORESEQ_DEBUG
    -	if (g_startDebug) {
    -		const U32 pos = (U32)((const BYTE*)literals - g_start);
    -		if (g_start==NULL) g_start = (const BYTE*)literals;
    -		if ((pos > 1895000) && (pos < 1895300))
    -			fprintf(stderr, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
    -				   pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
    -	}
    -#endif
     	/* copy Literals */
     	ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
     	seqStorePtr->lit += litLength;
    @@ -822,57 +807,15 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
     {
     	if (MEM_isLittleEndian()) {
     		if (MEM_64bits()) {
    -#       if defined(_MSC_VER) && defined(_WIN64)
    -			unsigned long r = 0;
    -			_BitScanForward64( &r, (U64)val );
    -			return (unsigned)(r>>3);
    -#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     			return (__builtin_ctzll((U64)val) >> 3);
    -#       else
    -			static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
    -			return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
    -#       endif
     		} else { /* 32 bits */
    -#       if defined(_MSC_VER)
    -			unsigned long r=0;
    -			_BitScanForward( &r, (U32)val );
    -			return (unsigned)(r>>3);
    -#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     			return (__builtin_ctz((U32)val) >> 3);
    -#       else
    -			static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
    -			return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
    -#       endif
     		}
     	} else {  /* Big Endian CPU */
     		if (MEM_64bits()) {
    -#       if defined(_MSC_VER) && defined(_WIN64)
    -			unsigned long r = 0;
    -			_BitScanReverse64( &r, val );
    -			return (unsigned)(r>>3);
    -#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     			return (__builtin_clzll(val) >> 3);
    -#       else
    -			unsigned r;
    -			const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */
    -			if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
    -			if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
    -			r += (!val);
    -			return r;
    -#       endif
     		} else { /* 32 bits */
    -#       if defined(_MSC_VER)
    -			unsigned long r = 0;
    -			_BitScanReverse( &r, (unsigned long)val );
    -			return (unsigned)(r>>3);
    -#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     			return (__builtin_clz((U32)val) >> 3);
    -#       else
    -			unsigned r;
    -			if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
    -			r += (!val);
    -			return r;
    -#       endif
     	}   }
     }
     
    @@ -1524,12 +1467,6 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     	U32 const windowLow = zc->lowLimit;
     	U32 matchEndIdx = curr+8;
     	size_t bestLength = 8;
    -#ifdef ZSTD_C_PREDICT
    -	U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
    -	U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
    -	predictedSmall += (predictedSmall>0);
    -	predictedLarge += (predictedLarge>0);
    -#endif /* ZSTD_C_PREDICT */
     
     	hashTable[h] = curr;   /* Update Hash Table */
     
    @@ -1537,26 +1474,6 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     		U32* const nextPtr = bt + 2*(matchIndex & btMask);
     		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
     
    -#ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
    -		const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
    -		if (matchIndex == predictedSmall) {
    -			/* no need to check length, result known */
    -			*smallerPtr = matchIndex;
    -			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
    -			predictedSmall = predictPtr[1] + (predictPtr[1]>0);
    -			continue;
    -		}
    -		if (matchIndex == predictedLarge) {
    -			*largerPtr = matchIndex;
    -			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -			largerPtr = nextPtr;
    -			matchIndex = nextPtr[0];
    -			predictedLarge = predictPtr[0] + (predictPtr[0]>0);
    -			continue;
    -		}
    -#endif
     		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
     			match = base + matchIndex;
     			if (match[matchLength] == ip[matchLength])
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 688d68539..378d2c521 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -149,30 +149,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
     	memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
     }
     
    -#if 0
    -/* deprecated */
    -static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    -{
    -	ZSTD_decompressBegin(dstDCtx);  /* init */
    -	if (srcDCtx) {   /* support refDCtx on NULL */
    -		dstDCtx->dictEnd = srcDCtx->dictEnd;
    -		dstDCtx->vBase = srcDCtx->vBase;
    -		dstDCtx->base = srcDCtx->base;
    -		dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
    -		dstDCtx->dictID = srcDCtx->dictID;
    -		dstDCtx->litEntropy = srcDCtx->litEntropy;
    -		dstDCtx->fseEntropy = srcDCtx->fseEntropy;
    -		dstDCtx->LLTptr = srcDCtx->entropy.LLTable;
    -		dstDCtx->MLTptr = srcDCtx->entropy.MLTable;
    -		dstDCtx->OFTptr = srcDCtx->entropy.OFTable;
    -		dstDCtx->HUFptr = srcDCtx->entropy.hufTable;
    -		dstDCtx->entropy.rep[0] = srcDCtx->entropy.rep[0];
    -		dstDCtx->entropy.rep[1] = srcDCtx->entropy.rep[1];
    -		dstDCtx->entropy.rep[2] = srcDCtx->entropy.rep[2];
    -	}
    -}
    -#endif
    -
     static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
     
     
    @@ -1200,11 +1176,9 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     	const BYTE* match = sequence.match;
     
     	/* check */
    -#if 1
     	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
     	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
     	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    -#endif
     
     	/* copy Literals */
     	ZSTD_copy8(op, *litPtr);
    @@ -1214,7 +1188,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     	*litPtr = iLitEnd;   /* update for next sequence */
     
     	/* copy Match */
    -#if 1
     	if (sequence.offset > (size_t)(oLitEnd - base)) {
     		/* offset beyond prefix */
     		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    @@ -1235,7 +1208,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
     			}
     	}   }
     	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
    -#endif
     
     	/* match within prefix */
     	if (sequence.offset < 8) {
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index 672c72d94..d0b5673f3 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -581,20 +581,6 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
     		else normalizedCounter[largest] += (short)stillToDistribute;
     	}
     
    -#if 0
    -	{	/* Print Table (debug) */
    -		U32 s;
    -		U32 nTotal = 0;
    -		for (s=0; s<=maxSymbolValue; s++)
    -			printf("%3i: %4i \n", s, normalizedCounter[s]);
    -		for (s=0; s<=maxSymbolValue; s++)
    -			nTotal += abs(normalizedCounter[s]);
    -		if (nTotal != (1U<= 3)   /* GCC Intrinsic */
     	return 31 - __builtin_clz(val);
    -#   else   /* Software version */
    -	static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    -	U32 v = val;
    -	int r;
    -	v |= v >> 1;
    -	v |= v >> 2;
    -	v |= v >> 4;
    -	v |= v >> 8;
    -	v |= v >> 16;
    -	r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
    -	return r;
    -#   endif
     }
     
     
    
    From fb10c91b4f4897222f9d0f003e050de78cc20758 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Tue, 16 May 2017 17:21:22 -0700
    Subject: [PATCH 065/400] [linux-kernel] Update zstd.diff
    
    ---
     contrib/linux-kernel/zstd.diff | 789 +++++++++++++--------------------
     1 file changed, 316 insertions(+), 473 deletions(-)
    
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff
    index c2775bbbf..7d7bf5537 100644
    --- a/contrib/linux-kernel/zstd.diff
    +++ b/contrib/linux-kernel/zstd.diff
    @@ -1203,10 +1203,10 @@ index 0000000..aa5eb4d
     +				huf_decompress.o decompress.o
     diff --git a/lib/zstd/bitstream.h b/lib/zstd/bitstream.h
     new file mode 100644
    -index 0000000..9d21540
    +index 0000000..9b5d2bc
     --- /dev/null
     +++ b/lib/zstd/bitstream.h
    -@@ -0,0 +1,391 @@
    +@@ -0,0 +1,376 @@
     +/* ******************************************************************
     +   bitstream
     +   Part of FSE library
    @@ -1356,22 +1356,7 @@ index 0000000..9d21540
     +****************************************************************/
     +MEM_STATIC unsigned BIT_highbit32 (register U32 val)
     +{
    -+#   if defined(_MSC_VER)   /* Visual */
    -+	unsigned long r=0;
    -+	_BitScanReverse ( &r, val );
    -+	return (unsigned) r;
    -+#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* Use GCC Intrinsic */
    -+	return 31 - __builtin_clz (val);
    -+#   else   /* Software version */
    -+	static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    -+	U32 v = val;
    -+	v |= v >> 1;
    -+	v |= v >> 2;
    -+	v |= v >> 4;
    -+	v |= v >> 8;
    -+	v |= v >> 16;
    -+	return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
    -+#   endif
    ++	return 31 - __builtin_clz(val);
     +}
     +
     +/*=====    Local Constants   =====*/
    @@ -1576,7 +1561,7 @@ index 0000000..9d21540
     +		if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
     +		return BIT_DStream_completed;
     +	}
    -+	{   U32 nbBytes = bitD->bitsConsumed >> 3;
    ++	{	U32 nbBytes = bitD->bitsConsumed >> 3;
     +		BIT_DStream_status result = BIT_DStream_unfinished;
     +		if (bitD->ptr - nbBytes < bitD->start) {
     +			nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */
    @@ -1600,10 +1585,10 @@ index 0000000..9d21540
     +#endif /* BITSTREAM_H_MODULE */
     diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
     new file mode 100644
    -index 0000000..79c3207
    +index 0000000..4f1e184
     --- /dev/null
     +++ b/lib/zstd/compress.c
    -@@ -0,0 +1,3384 @@
    +@@ -0,0 +1,3297 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
    @@ -1625,10 +1610,6 @@ index 0000000..79c3207
     +#include "huf.h"
     +#include "zstd_internal.h"  /* includes zstd.h */
     +
    -+#ifdef current
    -+#  undef current
    -+#endif
    -+
     +/*-*************************************
     +*  Constants
     +***************************************/
    @@ -1659,7 +1640,7 @@ index 0000000..79c3207
     +*  Context memory management
     +***************************************/
     +struct ZSTD_CCtx_s {
    -+	const BYTE* nextSrc;    /* next block here to continue on current prefix */
    ++	const BYTE* nextSrc;    /* next block here to continue on curr prefix */
     +	const BYTE* base;       /* All regular indexes relative to this position */
     +	const BYTE* dictBase;   /* extDict indexes relative to this position */
     +	U32   dictLimit;        /* below that point, need extDict */
    @@ -1787,14 +1768,14 @@ index 0000000..79c3207
     +	if (srcSize+dictSize == 0) return cPar;   /* no size information available : no adjustment */
     +
     +	/* resize params, to use less memory when necessary */
    -+	{   U32 const minSrcSize = (srcSize==0) ? 500 : 0;
    ++	{	U32 const minSrcSize = (srcSize==0) ? 500 : 0;
     +		U64 const rSize = srcSize + dictSize + minSrcSize;
     +		if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog;
     +	}   }
     +	if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
    -+	{   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
    ++	{	U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
     +		if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
     +	}
     +
    @@ -1846,7 +1827,7 @@ index 0000000..79c3207
     +			return ZSTD_continueCCtx(zc, params, frameContentSize);
     +		}
     +
    -+	{   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    ++	{	size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
     +		U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
     +		size_t const maxNbSeq = blockSize / divider;
     +		size_t const tokenSpace = blockSize + 11*maxNbSeq;
    @@ -1858,7 +1839,7 @@ index 0000000..79c3207
     +		void* ptr;
     +
     +		/* Check if workSpace is large enough, alloc a new one if needed */
    -+		{   size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    -+	{   ZSTD_parameters params = srcCCtx->params;
    ++	{	ZSTD_parameters params = srcCCtx->params;
     +		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
     +		ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
     +	}
     +
     +	/* copy tables */
    -+	{   size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
    ++	{	size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
     +		size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
     +		size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
     +		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    @@ -2086,12 +2067,12 @@ index 0000000..79c3207
     +
     +	/* small ? don't even attempt compression (speed opt) */
     +#   define LITERAL_NOENTROPY 63
    -+	{   size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
    ++	{	size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
     +		if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
     +	}
     +
     +	if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
    -+	{   HUF_repeat repeat = zc->flagStaticHufTable;
    ++	{	HUF_repeat repeat = zc->flagStaticHufTable;
     +		int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
     +		if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
     +		cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
    @@ -2113,18 +2094,18 @@ index 0000000..79c3207
     +	switch(lhSize)
     +	{
     +	case 3: /* 2 - 2 - 10 - 10 */
    -+		{   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
    ++		{	U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
     +			MEM_writeLE24(ostart, lhc);
     +			break;
     +		}
     +	case 4: /* 2 - 2 - 14 - 14 */
    -+		{   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
    ++		{	U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
     +			MEM_writeLE32(ostart, lhc);
     +			break;
     +		}
     +	default:   /* should not be necessary, lhSize is only {3,4,5} */
     +	case 5: /* 2 - 2 - 18 - 18 */
    -+		{   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
    ++		{	U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
     +			MEM_writeLE32(ostart, lhc);
     +			ostart[4] = (BYTE)(cLitSize >> 10);
     +			break;
    @@ -2199,7 +2180,7 @@ index 0000000..79c3207
     +	BYTE scratchBuffer[1<litStart;
    ++	{	const BYTE* const literals = seqStorePtr->litStart;
     +		size_t const litSize = seqStorePtr->lit - literals;
     +		size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
     +		if (ZSTD_isError(cSize)) return cSize;
    @@ -2223,7 +2204,7 @@ index 0000000..79c3207
     +	ZSTD_seqToCodes(seqStorePtr);
     +
     +	/* CTable for Literal Lengths */
    -+	{   U32 max = MaxLL;
    ++	{	U32 max = MaxLL;
     +		size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
     +		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     +			*op++ = llCodeTable[0];
    @@ -2247,7 +2228,7 @@ index 0000000..79c3207
     +	}   }
     +
     +	/* CTable for Offsets */
    -+	{   U32 max = MaxOff;
    ++	{	U32 max = MaxOff;
     +		size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
     +		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     +			*op++ = ofCodeTable[0];
    @@ -2271,7 +2252,7 @@ index 0000000..79c3207
     +	}   }
     +
     +	/* CTable for MatchLengths */
    -+	{   U32 max = MaxML;
    ++	{	U32 max = MaxML;
     +		size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
     +		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     +			*op++ = *mlCodeTable;
    @@ -2298,7 +2279,7 @@ index 0000000..79c3207
     +	zc->flagStaticTables = 0;
     +
     +	/* Encoding Sequences */
    -+	{   BIT_CStream_t blockStream;
    ++	{	BIT_CStream_t blockStream;
     +		FSE_CState_t  stateMatchLength;
     +		FSE_CState_t  stateOffsetBits;
     +		FSE_CState_t  stateLitLength;
    @@ -2327,7 +2308,7 @@ index 0000000..79c3207
     +		}
     +		BIT_flushBits(&blockStream);
     +
    -+		{   size_t n;
    ++		{	size_t n;
     +			for (n=nbSeq-2 ; n= maxCSize) {
     +			zc->flagStaticHufTable = HUF_repeat_none;
    @@ -2384,12 +2365,6 @@ index 0000000..79c3207
     +	return op - ostart;
     +}
     +
    -+#if 0 /* for debug */
    -+#  define STORESEQ_DEBUG
    -+U32 g_startDebug = 0;
    -+const BYTE* g_start = NULL;
    -+#endif
    -+
     +/*! ZSTD_storeSeq() :
     +	Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
     +	`offsetCode` : distance to match, or 0 == repCode.
    @@ -2397,15 +2372,6 @@ index 0000000..79c3207
     +*/
     +MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
     +{
    -+#ifdef STORESEQ_DEBUG
    -+	if (g_startDebug) {
    -+		const U32 pos = (U32)((const BYTE*)literals - g_start);
    -+		if (g_start==NULL) g_start = (const BYTE*)literals;
    -+		if ((pos > 1895000) && (pos < 1895300))
    -+			fprintf(stderr, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
    -+				   pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
    -+	}
    -+#endif
     +	/* copy Literals */
     +	ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
     +	seqStorePtr->lit += litLength;
    @@ -2432,57 +2398,15 @@ index 0000000..79c3207
     +{
     +	if (MEM_isLittleEndian()) {
     +		if (MEM_64bits()) {
    -+#       if defined(_MSC_VER) && defined(_WIN64)
    -+			unsigned long r = 0;
    -+			_BitScanForward64( &r, (U64)val );
    -+			return (unsigned)(r>>3);
    -+#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     +			return (__builtin_ctzll((U64)val) >> 3);
    -+#       else
    -+			static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
    -+			return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
    -+#       endif
     +		} else { /* 32 bits */
    -+#       if defined(_MSC_VER)
    -+			unsigned long r=0;
    -+			_BitScanForward( &r, (U32)val );
    -+			return (unsigned)(r>>3);
    -+#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     +			return (__builtin_ctz((U32)val) >> 3);
    -+#       else
    -+			static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
    -+			return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
    -+#       endif
     +		}
     +	} else {  /* Big Endian CPU */
     +		if (MEM_64bits()) {
    -+#       if defined(_MSC_VER) && defined(_WIN64)
    -+			unsigned long r = 0;
    -+			_BitScanReverse64( &r, val );
    -+			return (unsigned)(r>>3);
    -+#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     +			return (__builtin_clzll(val) >> 3);
    -+#       else
    -+			unsigned r;
    -+			const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */
    -+			if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
    -+			if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
    -+			r += (!val);
    -+			return r;
    -+#       endif
     +		} else { /* 32 bits */
    -+#       if defined(_MSC_VER)
    -+			unsigned long r = 0;
    -+			_BitScanReverse( &r, (unsigned long)val );
    -+			return (unsigned)(r>>3);
    -+#       elif defined(__GNUC__) && (__GNUC__ >= 3)
     +			return (__builtin_clz((U32)val) >> 3);
    -+#       else
    -+			unsigned r;
    -+			if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
    -+			r += (!val);
    -+			return r;
    -+#       endif
     +	}   }
     +}
     +
    @@ -2599,7 +2523,7 @@ index 0000000..79c3207
     +
     +	/* init */
     +	ip += (ip==lowest);
    -+	{   U32 const maxRep = (U32)(ip-lowest);
    ++	{	U32 const maxRep = (U32)(ip-lowest);
     +		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
     +		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
     +	}
    @@ -2608,10 +2532,10 @@ index 0000000..79c3207
     +	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
     +		size_t mLength;
     +		size_t const h = ZSTD_hashPtr(ip, hBits, mls);
    -+		U32 const current = (U32)(ip-base);
    ++		U32 const curr = (U32)(ip-base);
     +		U32 const matchIndex = hashTable[h];
     +		const BYTE* match = base + matchIndex;
    -+		hashTable[h] = current;   /* update hash table */
    ++		hashTable[h] = curr;   /* update hash table */
     +
     +		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
     +			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    @@ -2638,7 +2562,7 @@ index 0000000..79c3207
     +
     +		if (ip <= ilimit) {
     +			/* Fill Table */
    -+			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    ++			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
     +			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
     +			/* check immediate repcode */
     +			while ( (ip <= ilimit)
    @@ -2659,7 +2583,7 @@ index 0000000..79c3207
     +	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -2712,12 +2636,12 @@ index 0000000..79c3207
     +		const U32 matchIndex = hashTable[h];
     +		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
     +		const BYTE* match = matchBase + matchIndex;
    -+		const U32 current = (U32)(ip-base);
    -+		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    ++		const U32 curr = (U32)(ip-base);
    ++		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
     +		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
     +		const BYTE* repMatch = repBase + repIndex;
     +		size_t mLength;
    -+		hashTable[h] = current;   /* update hash table */
    ++		hashTable[h] = curr;   /* update hash table */
     +
     +		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
     +		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    @@ -2731,12 +2655,12 @@ index 0000000..79c3207
     +				ip += ((ip-anchor) >> g_searchStrength) + 1;
     +				continue;
     +			}
    -+			{   const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    ++			{	const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
     +				const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
     +				U32 offset;
     +				mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
     +				while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    -+				offset = current - matchIndex;
    ++				offset = curr - matchIndex;
     +				offset_2 = offset_1;
     +				offset_1 = offset;
     +				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    @@ -2748,12 +2672,12 @@ index 0000000..79c3207
     +
     +		if (ip <= ilimit) {
     +			/* Fill Table */
    -+			hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
    ++			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;
     +			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
     +			/* check immediate repcode */
     +			while (ip <= ilimit) {
    -+				U32 const current2 = (U32)(ip-base);
    -+				U32 const repIndex2 = current2 - offset_2;
    ++				U32 const curr2 = (U32)(ip-base);
    ++				U32 const repIndex2 = curr2 - offset_2;
     +				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     +				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
     +				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    @@ -2761,7 +2685,7 @@ index 0000000..79c3207
     +					size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     +					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
     +					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    -+					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
    ++					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = curr2;
     +					ip += repLength2;
     +					anchor = ip;
     +					continue;
    @@ -2773,7 +2697,7 @@ index 0000000..79c3207
     +	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -2844,7 +2768,7 @@ index 0000000..79c3207
     +
     +	/* init */
     +	ip += (ip==lowest);
    -+	{   U32 const maxRep = (U32)(ip-lowest);
    ++	{	U32 const maxRep = (U32)(ip-lowest);
     +		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
     +		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
     +	}
    @@ -2854,14 +2778,14 @@ index 0000000..79c3207
     +		size_t mLength;
     +		size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
     +		size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
    -+		U32 const current = (U32)(ip-base);
    ++		U32 const curr = (U32)(ip-base);
     +		U32 const matchIndexL = hashLong[h2];
     +		U32 const matchIndexS = hashSmall[h];
     +		const BYTE* matchLong = base + matchIndexL;
     +		const BYTE* match = base + matchIndexS;
    -+		hashLong[h2] = hashSmall[h] = current;   /* update hash tables */
    ++		hashLong[h2] = hashSmall[h] = curr;   /* update hash tables */
     +
    -+		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
    ++		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= curr */
     +			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
     +			ip++;
     +			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    @@ -2875,7 +2799,7 @@ index 0000000..79c3207
     +				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
     +				U32 const matchIndex3 = hashLong[h3];
     +				const BYTE* match3 = base + matchIndex3;
    -+				hashLong[h3] = current + 1;
    ++				hashLong[h3] = curr + 1;
     +				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
     +					mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
     +					ip++;
    @@ -2903,8 +2827,8 @@ index 0000000..79c3207
     +
     +		if (ip <= ilimit) {
     +			/* Fill Table */
    -+			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
    -+				hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;  /* here because current+2 could be > iend-8 */
    ++			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] =
    ++				hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
     +			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
     +				hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
     +
    @@ -2928,7 +2852,7 @@ index 0000000..79c3207
     +	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -2988,12 +2912,12 @@ index 0000000..79c3207
     +		const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
     +		const BYTE* matchLong = matchLongBase + matchLongIndex;
     +
    -+		const U32 current = (U32)(ip-base);
    -+		const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */
    ++		const U32 curr = (U32)(ip-base);
    ++		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
     +		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
     +		const BYTE* repMatch = repBase + repIndex;
     +		size_t mLength;
    -+		hashSmall[hSmall] = hashLong[hLong] = current;   /* update hash table */
    ++		hashSmall[hSmall] = hashLong[hLong] = curr;   /* update hash table */
     +
     +		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
     +		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    @@ -3007,7 +2931,7 @@ index 0000000..79c3207
     +				const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
     +				U32 offset;
     +				mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
    -+				offset = current - matchLongIndex;
    ++				offset = curr - matchLongIndex;
     +				while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
     +				offset_2 = offset_1;
     +				offset_1 = offset;
    @@ -3019,19 +2943,19 @@ index 0000000..79c3207
     +				const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
     +				const BYTE* match3 = match3Base + matchIndex3;
     +				U32 offset;
    -+				hashLong[h3] = current + 1;
    ++				hashLong[h3] = curr + 1;
     +				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
     +					const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
     +					const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
     +					mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
     +					ip++;
    -+					offset = current+1 - matchIndex3;
    ++					offset = curr+1 - matchIndex3;
     +					while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
     +				} else {
     +					const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
     +					const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
     +					mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
    -+					offset = current - matchIndex;
    ++					offset = curr - matchIndex;
     +					while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
     +				}
     +				offset_2 = offset_1;
    @@ -3049,14 +2973,14 @@ index 0000000..79c3207
     +
     +		if (ip <= ilimit) {
     +			/* Fill Table */
    -+			hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
    -+			hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
    ++			hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;
    ++			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] = curr+2;
     +			hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
     +			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
     +			/* check immediate repcode */
     +			while (ip <= ilimit) {
    -+				U32 const current2 = (U32)(ip-base);
    -+				U32 const repIndex2 = current2 - offset_2;
    ++				U32 const curr2 = (U32)(ip-base);
    ++				U32 const repIndex2 = curr2 - offset_2;
     +				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     +				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
     +				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    @@ -3064,8 +2988,8 @@ index 0000000..79c3207
     +					size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     +					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
     +					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    -+					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
    -+					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
    ++					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = curr2;
    ++					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = curr2;
     +					ip += repLength2;
     +					anchor = ip;
     +					continue;
    @@ -3077,7 +3001,7 @@ index 0000000..79c3207
     +	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -3126,47 +3050,21 @@ index 0000000..79c3207
     +	const BYTE* const dictEnd = dictBase + dictLimit;
     +	const BYTE* const prefixStart = base + dictLimit;
     +	const BYTE* match;
    -+	const U32 current = (U32)(ip-base);
    -+	const U32 btLow = btMask >= current ? 0 : current - btMask;
    -+	U32* smallerPtr = bt + 2*(current&btMask);
    ++	const U32 curr = (U32)(ip-base);
    ++	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
    ++	U32* smallerPtr = bt + 2*(curr&btMask);
     +	U32* largerPtr  = smallerPtr + 1;
     +	U32 dummy32;   /* to be nullified at the end */
     +	U32 const windowLow = zc->lowLimit;
    -+	U32 matchEndIdx = current+8;
    ++	U32 matchEndIdx = curr+8;
     +	size_t bestLength = 8;
    -+#ifdef ZSTD_C_PREDICT
    -+	U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
    -+	U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
    -+	predictedSmall += (predictedSmall>0);
    -+	predictedLarge += (predictedLarge>0);
    -+#endif /* ZSTD_C_PREDICT */
     +
    -+	hashTable[h] = current;   /* Update Hash Table */
    ++	hashTable[h] = curr;   /* Update Hash Table */
     +
     +	while (nbCompares-- && (matchIndex > windowLow)) {
     +		U32* const nextPtr = bt + 2*(matchIndex & btMask);
     +		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
     +
    -+#ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
    -+		const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
    -+		if (matchIndex == predictedSmall) {
    -+			/* no need to check length, result known */
    -+			*smallerPtr = matchIndex;
    -+			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -+			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    -+			predictedSmall = predictPtr[1] + (predictPtr[1]>0);
    -+			continue;
    -+		}
    -+		if (matchIndex == predictedLarge) {
    -+			*largerPtr = matchIndex;
    -+			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -+			largerPtr = nextPtr;
    -+			matchIndex = nextPtr[0];
    -+			predictedLarge = predictPtr[0] + (predictPtr[0]>0);
    -+			continue;
    -+		}
    -+#endif
     +		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
     +			match = base + matchIndex;
     +			if (match[matchLength] == ip[matchLength])
    @@ -3188,14 +3086,14 @@ index 0000000..79c3207
     +			break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
     +
     +		if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
    -+			/* match is smaller than current */
    ++			/* match is smaller than curr */
     +			*smallerPtr = matchIndex;             /* update smaller idx */
     +			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     +			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     +			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     +		} else {
    -+			/* match is larger than current */
    ++			/* match is larger than curr */
     +			*largerPtr = matchIndex;
     +			commonLengthLarger = matchLength;
     +			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -3205,7 +3103,7 @@ index 0000000..79c3207
     +
     +	*smallerPtr = *largerPtr = 0;
     +	if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
    -+	if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
    ++	if (matchEndIdx > curr + 8) return matchEndIdx - curr - 8;
     +	return 1;
     +}
     +
    @@ -3230,16 +3128,16 @@ index 0000000..79c3207
     +	const U32 dictLimit = zc->dictLimit;
     +	const BYTE* const dictEnd = dictBase + dictLimit;
     +	const BYTE* const prefixStart = base + dictLimit;
    -+	const U32 current = (U32)(ip-base);
    -+	const U32 btLow = btMask >= current ? 0 : current - btMask;
    ++	const U32 curr = (U32)(ip-base);
    ++	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
     +	const U32 windowLow = zc->lowLimit;
    -+	U32* smallerPtr = bt + 2*(current&btMask);
    -+	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    -+	U32 matchEndIdx = current+8;
    ++	U32* smallerPtr = bt + 2*(curr&btMask);
    ++	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
    ++	U32 matchEndIdx = curr+8;
     +	U32 dummy32;   /* to be nullified at the end */
     +	size_t bestLength = 0;
     +
    -+	hashTable[h] = current;   /* Update Hash Table */
    ++	hashTable[h] = curr;   /* Update Hash Table */
     +
     +	while (nbCompares-- && (matchIndex > windowLow)) {
     +		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    @@ -3260,21 +3158,21 @@ index 0000000..79c3207
     +		if (matchLength > bestLength) {
     +			if (matchLength > matchEndIdx - matchIndex)
     +				matchEndIdx = matchIndex + (U32)matchLength;
    -+			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    -+				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
    ++			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    ++				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
     +			if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
     +				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
     +		}
     +
     +		if (match[matchLength] < ip[matchLength]) {
    -+			/* match is smaller than current */
    ++			/* match is smaller than curr */
     +			*smallerPtr = matchIndex;             /* update smaller idx */
     +			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     +			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     +			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     +		} else {
    -+			/* match is larger than current */
    ++			/* match is larger than curr */
     +			*largerPtr = matchIndex;
     +			commonLengthLarger = matchLength;
     +			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -3284,7 +3182,7 @@ index 0000000..79c3207
     +
     +	*smallerPtr = *largerPtr = 0;
     +
    -+	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    ++	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
     +	return bestLength;
     +}
     +
    @@ -3417,8 +3315,8 @@ index 0000000..79c3207
     +	const BYTE* const prefixStart = base + dictLimit;
     +	const BYTE* const dictEnd = dictBase + dictLimit;
     +	const U32 lowLimit = zc->lowLimit;
    -+	const U32 current = (U32)(ip-base);
    -+	const U32 minChain = current > chainSize ? current - chainSize : 0;
    ++	const U32 curr = (U32)(ip-base);
    ++	const U32 minChain = curr > chainSize ? curr - chainSize : 0;
     +	int nbAttempts=maxNbAttempts;
     +	size_t ml=EQUAL_READ32-1;
     +
    @@ -3427,19 +3325,19 @@ index 0000000..79c3207
     +
     +	for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
     +		const BYTE* match;
    -+		size_t currentMl=0;
    ++		size_t currMl=0;
     +		if ((!extDict) || matchIndex >= dictLimit) {
     +			match = base + matchIndex;
     +			if (match[ml] == ip[ml])   /* potentially better */
    -+				currentMl = ZSTD_count(ip, match, iLimit);
    ++				currMl = ZSTD_count(ip, match, iLimit);
     +		} else {
     +			match = dictBase + matchIndex;
     +			if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    -+				currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
    ++				currMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
     +		}
     +
     +		/* save best solution */
    -+		if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
    ++		if (currMl > ml) { ml = currMl; *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE; if (ip+currMl == iLimit) break; /* best possible, and avoid read overflow*/ }
     +
     +		if (matchIndex <= minChain) break;
     +		matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
    @@ -3511,7 +3409,7 @@ index 0000000..79c3207
     +	/* init */
     +	ip += (ip==base);
     +	ctx->nextToUpdate3 = ctx->nextToUpdate;
    -+	{   U32 const maxRep = (U32)(ip-base);
    ++	{	U32 const maxRep = (U32)(ip-base);
     +		if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
     +		if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
     +	}
    @@ -3530,7 +3428,7 @@ index 0000000..79c3207
     +		}
     +
     +		/* first search (depth 0) */
    -+		{   size_t offsetFound = 99999999;
    ++		{	size_t offsetFound = 99999999;
     +			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
     +			if (ml2 > matchLength)
     +				matchLength = ml2, start = ip, offset=offsetFound;
    @@ -3552,7 +3450,7 @@ index 0000000..79c3207
     +				if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
     +					matchLength = mlRep, offset = 0, start = ip;
     +			}
    -+			{   size_t offset2=99999999;
    ++			{	size_t offset2=99999999;
     +				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     +				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     +				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    @@ -3571,7 +3469,7 @@ index 0000000..79c3207
     +					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
     +						matchLength = ml2, offset = 0, start = ip;
     +				}
    -+				{   size_t offset2=99999999;
    ++				{	size_t offset2=99999999;
     +					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     +					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     +					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    @@ -3591,7 +3489,7 @@ index 0000000..79c3207
     +
     +		/* store sequence */
     +_storeSequence:
    -+		{   size_t const litLength = start - anchor;
    ++		{	size_t const litLength = start - anchor;
     +			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
     +			anchor = ip = start + matchLength;
     +		}
    @@ -3614,7 +3512,7 @@ index 0000000..79c3207
     +	ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -3680,10 +3578,10 @@ index 0000000..79c3207
     +		size_t matchLength=0;
     +		size_t offset=0;
     +		const BYTE* start=ip+1;
    -+		U32 current = (U32)(ip-base);
    ++		U32 curr = (U32)(ip-base);
     +
     +		/* check repCode */
    -+		{   const U32 repIndex = (U32)(current+1 - offset_1);
    ++		{	const U32 repIndex = (U32)(curr+1 - offset_1);
     +			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     +			const BYTE* const repMatch = repBase + repIndex;
     +			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    @@ -3695,7 +3593,7 @@ index 0000000..79c3207
     +		}   }
     +
     +		/* first search (depth 0) */
    -+		{   size_t offsetFound = 99999999;
    ++		{	size_t offsetFound = 99999999;
     +			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
     +			if (ml2 > matchLength)
     +				matchLength = ml2, start = ip, offset=offsetFound;
    @@ -3710,10 +3608,10 @@ index 0000000..79c3207
     +		if (depth>=1)
     +		while (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    @@ -3728,7 +3626,7 @@ index 0000000..79c3207
     +			}   }
     +
     +			/* search match, depth 1 */
    -+			{   size_t offset2=99999999;
    ++			{	size_t offset2=99999999;
     +				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     +				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     +				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    @@ -3740,10 +3638,10 @@ index 0000000..79c3207
     +			/* let's find an even better one */
     +			if ((depth==2) && (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    @@ -3758,7 +3656,7 @@ index 0000000..79c3207
     +				}   }
     +
     +				/* search match, depth 2 */
    -+				{   size_t offset2=99999999;
    ++				{	size_t offset2=99999999;
     +					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
     +					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
     +					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    @@ -3780,7 +3678,7 @@ index 0000000..79c3207
     +
     +		/* store sequence */
     +_storeSequence:
    -+		{   size_t const litLength = start - anchor;
    ++		{	size_t const litLength = start - anchor;
     +			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
     +			anchor = ip = start + matchLength;
     +		}
    @@ -3808,7 +3706,7 @@ index 0000000..79c3207
     +	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -3898,11 +3796,11 @@ index 0000000..79c3207
     +	ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
     +	const BYTE* const base = zc->base;
     +	const BYTE* const istart = (const BYTE*)src;
    -+	const U32 current = (U32)(istart-base);
    ++	const U32 curr = (U32)(istart-base);
     +	if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0;   /* don't even attempt compression below a certain srcSize */
     +	ZSTD_resetSeqStore(&(zc->seqStore));
    -+	if (current > zc->nextToUpdate + 384)
    -+		zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
    ++	if (curr > zc->nextToUpdate + 384)
    ++		zc->nextToUpdate = curr - MIN(192, (U32)(curr - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
     +	blockCompressor(zc, src, srcSize);
     +	return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
     +}
    @@ -3940,9 +3838,9 @@ index 0000000..79c3207
     +		/* preemptive overflow correction */
     +		if (cctx->lowLimit > (3U<<29)) {
     +			U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
    -+			U32 const current = (U32)(ip - cctx->base);
    -+			U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
    -+			U32 const correction = current - newCurrent;
    ++			U32 const curr = (U32)(ip - cctx->base);
    ++			U32 const newCurr = (curr & cycleMask) + (1 << cctx->params.cParams.windowLog);
    ++			U32 const correction = curr - newCurr;
     +			ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
     +			ZSTD_reduceIndex(cctx, correction);
     +			cctx->base += correction;
    @@ -4103,7 +4001,7 @@ index 0000000..79c3207
     +	const BYTE* const ip = (const BYTE*) src;
     +	const BYTE* const iend = ip + srcSize;
     +
    -+	/* input becomes current prefix */
    ++	/* input becomes curr prefix */
     +	zc->lowLimit = zc->dictLimit;
     +	zc->dictLimit = (U32)(zc->nextSrc - zc->base);
     +	zc->dictBase = zc->base;
    @@ -4182,12 +4080,12 @@ index 0000000..79c3207
     +	cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
     +	dictPtr += 4;
     +
    -+	{   size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
    ++	{	size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
     +		if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
     +		dictPtr += hufHeaderSize;
     +	}
     +
    -+	{   unsigned offcodeLog;
    ++	{	unsigned offcodeLog;
     +		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
     +		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    @@ -4196,7 +4094,7 @@ index 0000000..79c3207
     +		dictPtr += offcodeHeaderSize;
     +	}
     +
    -+	{   short matchlengthNCount[MaxML+1];
    ++	{	short matchlengthNCount[MaxML+1];
     +		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
     +		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -4207,7 +4105,7 @@ index 0000000..79c3207
     +		dictPtr += matchlengthHeaderSize;
     +	}
     +
    -+	{   short litlengthNCount[MaxLL+1];
    ++	{	short litlengthNCount[MaxLL+1];
     +		unsigned litlengthMaxValue = MaxLL, litlengthLog;
     +		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -4224,7 +4122,7 @@ index 0000000..79c3207
     +	cctx->rep[2] = MEM_readLE32(dictPtr+8);
     +	dictPtr += 12;
     +
    -+	{   size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
    ++	{	size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
     +		U32 offcodeMax = MaxOff;
     +		if (dictContentSize <= ((U32)-1) - 128 KB) {
     +			U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
    @@ -4233,7 +4131,7 @@ index 0000000..79c3207
     +		/* All offset values <= dictContentSize + 128 KB must be representable */
     +		CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
     +		/* All repCodes must be <= dictContentSize and != 0*/
    -+		{   U32 u;
    ++		{	U32 u;
     +			for (u=0; u<3; u++) {
     +				if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
     +				if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
    @@ -4391,7 +4289,7 @@ index 0000000..79c3207
     +{
     +	if (!customMem.customAlloc || !customMem.customFree) return NULL;
     +
    -+	{   ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    ++	{	ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
     +		ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
     +
     +		if (!cdict || !cctx) {
    @@ -4411,7 +4309,7 @@ index 0000000..79c3207
     +			cdict->dictContent = internalBuffer;
     +		}
     +
    -+		{   size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
    ++		{	size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
     +			if (ZSTD_isError(errorCode)) {
     +				ZSTD_free(cdict->dictBuffer, customMem);
     +				ZSTD_free(cdict, customMem);
    @@ -4434,7 +4332,7 @@ index 0000000..79c3207
     +size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
     +{
     +	if (cdict==NULL) return 0;   /* support free on NULL */
    -+	{   ZSTD_customMem const cMem = cdict->refContext->customMem;
    ++	{	ZSTD_customMem const cMem = cdict->refContext->customMem;
     +		ZSTD_freeCCtx(cdict->refContext);
     +		ZSTD_free(cdict->dictBuffer, cMem);
     +		ZSTD_free(cdict, cMem);
    @@ -4536,7 +4434,7 @@ index 0000000..79c3207
     +size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
     +{
     +	if (zcs==NULL) return 0;   /* support free on NULL */
    -+	{   ZSTD_customMem const cMem = zcs->customMem;
    ++	{	ZSTD_customMem const cMem = zcs->customMem;
     +		ZSTD_freeCCtx(zcs->cctx);
     +		zcs->cctx = NULL;
     +		ZSTD_freeCDict(zcs->cdictLocal);
    @@ -4587,7 +4485,7 @@ index 0000000..79c3207
     +								 ZSTD_parameters params, unsigned long long pledgedSrcSize)
     +{
     +	/* allocate buffers */
    -+	{   size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
    ++	{	size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
     +		if (zcs->inBuffSize < neededInBuffSize) {
     +			zcs->inBuffSize = neededInBuffSize;
     +			ZSTD_free(zcs->inBuff, zcs->customMem);
    @@ -4671,15 +4569,15 @@ index 0000000..79c3207
     +
     +		case zcss_load:
     +			/* complete inBuffer */
    -+			{   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    ++			{	size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
     +				size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
     +				zcs->inBuffPos += loaded;
     +				ip += loaded;
     +				if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
     +					someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
     +			}   }
    -+			/* compress current block (note : this stage cannot be stopped in the middle) */
    -+			{   void* cDst;
    ++			/* compress curr block (note : this stage cannot be stopped in the middle) */
    ++			{	void* cDst;
     +				size_t cSize;
     +				size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
     +				size_t oSize = oend-op;
    @@ -4704,7 +4602,7 @@ index 0000000..79c3207
     +			}
     +
     +		case zcss_flush:
    -+			{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    ++			{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     +				size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
     +				op += flushed;
     +				zcs->outBuffFlushedSize += flushed;
    @@ -4727,7 +4625,7 @@ index 0000000..79c3207
     +	*dstCapacityPtr = op - ostart;
     +	zcs->inputProcessed += *srcSizePtr;
     +	if (zcs->frameEnded) return 0;
    -+	{   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
    ++	{	size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
     +		if (hintInSize==0) hintInSize = zcs->blockSize;
     +		return hintInSize;
     +	}
    @@ -4791,7 +4689,7 @@ index 0000000..79c3207
     +	}
     +
     +	/* flush epilogue */
    -+	{   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    ++	{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     +		size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
     +		op += flushed;
     +		zcs->outBuffFlushedSize += flushed;
    @@ -4990,10 +4888,10 @@ index 0000000..79c3207
     +MODULE_DESCRIPTION("Zstd Compressor");
     diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
     new file mode 100644
    -index 0000000..98508b1
    +index 0000000..378d2c5
     --- /dev/null
     +++ b/lib/zstd/decompress.c
    -@@ -0,0 +1,2377 @@
    +@@ -0,0 +1,2349 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
    @@ -5068,8 +4966,8 @@ index 0000000..98508b1
     +	const HUF_DTable* HUFptr;
     +	ZSTD_entropyTables_t entropy;
     +	const void* previousDstEnd;   /* detect continuity */
    -+	const void* base;             /* start of current segment */
    -+	const void* vBase;            /* virtual start of previous segment if it was just before current one */
    ++	const void* base;             /* start of curr segment */
    ++	const void* vBase;            /* virtual start of previous segment if it was just before curr one */
     +	const void* dictEnd;          /* end of previous segment */
     +	size_t expected;
     +	ZSTD_frameParams fParams;
    @@ -5145,30 +5043,6 @@ index 0000000..98508b1
     +	memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
     +}
     +
    -+#if 0
    -+/* deprecated */
    -+static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    -+{
    -+	ZSTD_decompressBegin(dstDCtx);  /* init */
    -+	if (srcDCtx) {   /* support refDCtx on NULL */
    -+		dstDCtx->dictEnd = srcDCtx->dictEnd;
    -+		dstDCtx->vBase = srcDCtx->vBase;
    -+		dstDCtx->base = srcDCtx->base;
    -+		dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
    -+		dstDCtx->dictID = srcDCtx->dictID;
    -+		dstDCtx->litEntropy = srcDCtx->litEntropy;
    -+		dstDCtx->fseEntropy = srcDCtx->fseEntropy;
    -+		dstDCtx->LLTptr = srcDCtx->entropy.LLTable;
    -+		dstDCtx->MLTptr = srcDCtx->entropy.MLTable;
    -+		dstDCtx->OFTptr = srcDCtx->entropy.OFTable;
    -+		dstDCtx->HUFptr = srcDCtx->entropy.hufTable;
    -+		dstDCtx->entropy.rep[0] = srcDCtx->entropy.rep[0];
    -+		dstDCtx->entropy.rep[1] = srcDCtx->entropy.rep[1];
    -+		dstDCtx->entropy.rep[2] = srcDCtx->entropy.rep[2];
    -+	}
    -+}
    -+#endif
    -+
     +static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
     +
     +
    @@ -5184,7 +5058,7 @@ index 0000000..98508b1
     +unsigned ZSTD_isFrame(const void* buffer, size_t size)
     +{
     +	if (size < 4) return 0;
    -+	{   U32 const magic = MEM_readLE32(buffer);
    ++	{	U32 const magic = MEM_readLE32(buffer);
     +		if (magic == ZSTD_MAGICNUMBER) return 1;
     +		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
     +	}
    @@ -5198,7 +5072,7 @@ index 0000000..98508b1
     +static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
     +{
     +	if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
    -+	{   BYTE const fhd = ((const BYTE*)src)[4];
    ++	{	BYTE const fhd = ((const BYTE*)src)[4];
     +		U32 const dictID= fhd & 3;
     +		U32 const singleSegment = (fhd >> 5) & 1;
     +		U32 const fcsId = fhd >> 6;
    @@ -5233,7 +5107,7 @@ index 0000000..98508b1
     +	{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
     +	  if (srcSize < fhsize) return fhsize; }
     +
    -+	{   BYTE const fhdByte = ip[4];
    ++	{	BYTE const fhdByte = ip[4];
     +		size_t pos = 5;
     +		U32 const dictIDSizeCode = fhdByte&3;
     +		U32 const checksumFlag = (fhdByte>>2)&1;
    @@ -5379,7 +5253,7 @@ index 0000000..98508b1
     +size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
     +{
     +	if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    -+	{   U32 const cBlockHeader = MEM_readLE24(src);
    ++	{	U32 const cBlockHeader = MEM_readLE24(src);
     +		U32 const cSize = cBlockHeader >> 3;
     +		bpPtr->lastBlock = cBlockHeader & 1;
     +		bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
    @@ -5414,7 +5288,7 @@ index 0000000..98508b1
     +{
     +	if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
     +
    -+	{   const BYTE* const istart = (const BYTE*) src;
    ++	{	const BYTE* const istart = (const BYTE*) src;
     +		symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
     +
     +		switch(litEncType)
    @@ -5424,7 +5298,7 @@ index 0000000..98508b1
     +			/* fall-through */
     +		case set_compressed:
     +			if (srcSize < 5) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
    -+			{   size_t lhSize, litSize, litCSize;
    ++			{	size_t lhSize, litSize, litCSize;
     +				U32 singleStream=0;
     +				U32 const lhlCode = (istart[0] >> 2) & 3;
     +				U32 const lhc = MEM_readLE32(istart);
    @@ -5471,7 +5345,7 @@ index 0000000..98508b1
     +			}
     +
     +		case set_basic:
    -+			{   size_t litSize, lhSize;
    ++			{	size_t litSize, lhSize;
     +				U32 const lhlCode = ((istart[0]) >> 2) & 3;
     +				switch(lhlCode)
     +				{
    @@ -5504,7 +5378,7 @@ index 0000000..98508b1
     +			}
     +
     +		case set_rle:
    -+			{   U32 const lhlCode = ((istart[0]) >> 2) & 3;
    ++			{	U32 const lhlCode = ((istart[0]) >> 2) & 3;
     +				size_t litSize, lhSize;
     +				switch(lhlCode)
     +				{
    @@ -5738,7 +5612,7 @@ index 0000000..98508b1
     +		return 0;
     +	default :   /* impossible */
     +	case set_compressed :
    -+		{   U32 tableLog;
    ++		{	U32 tableLog;
     +			S16 norm[MaxSeq+1];
     +			size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
     +			if (FSE_isError(headerSize)) return ERROR(corruption_detected);
    @@ -5760,7 +5634,7 @@ index 0000000..98508b1
     +	if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
     +
     +	/* SeqHead */
    -+	{   int nbSeq = *ip++;
    ++	{	int nbSeq = *ip++;
     +		if (!nbSeq) { *nbSeqPtr=0; return 1; }
     +		if (nbSeq > 0x7F) {
     +			if (nbSeq == 0xFF) {
    @@ -5776,25 +5650,25 @@ index 0000000..98508b1
     +
     +	/* FSE table descriptors */
     +	if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
    -+	{   symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
    ++	{	symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
     +		symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
     +		symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
     +		ip++;
     +
     +		/* Build DTables */
    -+		{   size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
    ++		{	size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
     +													  LLtype, MaxLL, LLFSELog,
     +													  ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
     +			if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
     +			ip += llhSize;
     +		}
    -+		{   size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
    ++		{	size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
     +													  OFtype, MaxOff, OffFSELog,
     +													  ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
     +			if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
     +			ip += ofhSize;
     +		}
    -+		{   size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
    ++		{	size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
     +													  MLtype, MaxML, MLFSELog,
     +													  ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
     +			if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
    @@ -5860,8 +5734,8 @@ index 0000000..98508b1
     +			memmove(oLitEnd, match, sequence.matchLength);
     +			return sequenceLength;
     +		}
    -+		/* span extDict & currentPrefixSegment */
    -+		{   size_t const length1 = dictEnd - match;
    ++		/* span extDict & currPrefixSegment */
    ++		{	size_t const length1 = dictEnd - match;
     +			memmove(oLitEnd, match, length1);
     +			op = oLitEnd + length1;
     +			sequence.matchLength -= length1;
    @@ -5905,7 +5779,7 @@ index 0000000..98508b1
     +							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
     +
     +	/* sequence */
    -+	{   size_t offset;
    ++	{	size_t offset;
     +		if (!ofCode)
     +			offset = 0;
     +		else {
    @@ -5983,8 +5857,8 @@ index 0000000..98508b1
     +			memmove(oLitEnd, match, sequence.matchLength);
     +			return sequenceLength;
     +		}
    -+		/* span extDict & currentPrefixSegment */
    -+		{   size_t const length1 = dictEnd - match;
    ++		/* span extDict & currPrefixSegment */
    ++		{	size_t const length1 = dictEnd - match;
     +			memmove(oLitEnd, match, length1);
     +			op = oLitEnd + length1;
     +			sequence.matchLength -= length1;
    @@ -6047,7 +5921,7 @@ index 0000000..98508b1
     +	int nbSeq;
     +
     +	/* Build Decoding Tables */
    -+	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    ++	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
     +		if (ZSTD_isError(seqHSize)) return seqHSize;
     +		ip += seqHSize;
     +	}
    @@ -6064,7 +5938,7 @@ index 0000000..98508b1
     +
     +		for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
     +			nbSeq--;
    -+			{   seq_t const sequence = ZSTD_decodeSequence(&seqState);
    ++			{	seq_t const sequence = ZSTD_decodeSequence(&seqState);
     +				size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
     +				if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
     +				op += oneSeqSize;
    @@ -6077,7 +5951,7 @@ index 0000000..98508b1
     +	}
     +
     +	/* last literal segment */
    -+	{   size_t const lastLLSize = litEnd - litPtr;
    ++	{	size_t const lastLLSize = litEnd - litPtr;
     +		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
     +		memcpy(op, litPtr, lastLLSize);
     +		op += lastLLSize;
    @@ -6118,7 +5992,7 @@ index 0000000..98508b1
     +							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
     +
     +	/* sequence */
    -+	{   size_t offset;
    ++	{	size_t offset;
     +		if (!ofCode)
     +			offset = 0;
     +		else {
    @@ -6159,7 +6033,7 @@ index 0000000..98508b1
     +	if (MEM_32bits() ||
     +	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
     +
    -+	{   size_t const pos = seqState->pos + seq.litLength;
    ++	{	size_t const pos = seqState->pos + seq.litLength;
     +		seq.match = seqState->base + pos - seq.offset;    /* single memory segment */
     +		if (seq.offset > pos) seq.match += seqState->gotoDict;   /* separate memory segment */
     +		seqState->pos = pos + seq.matchLength;
    @@ -6196,11 +6070,9 @@ index 0000000..98508b1
     +	const BYTE* match = sequence.match;
     +
     +	/* check */
    -+#if 1
     +	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
     +	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
     +	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    -+#endif
     +
     +	/* copy Literals */
     +	ZSTD_copy8(op, *litPtr);
    @@ -6210,7 +6082,6 @@ index 0000000..98508b1
     +	*litPtr = iLitEnd;   /* update for next sequence */
     +
     +	/* copy Match */
    -+#if 1
     +	if (sequence.offset > (size_t)(oLitEnd - base)) {
     +		/* offset beyond prefix */
     +		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    @@ -6218,8 +6089,8 @@ index 0000000..98508b1
     +			memmove(oLitEnd, match, sequence.matchLength);
     +			return sequenceLength;
     +		}
    -+		/* span extDict & currentPrefixSegment */
    -+		{   size_t const length1 = dictEnd - match;
    ++		/* span extDict & currPrefixSegment */
    ++		{	size_t const length1 = dictEnd - match;
     +			memmove(oLitEnd, match, length1);
     +			op = oLitEnd + length1;
     +			sequence.matchLength -= length1;
    @@ -6231,7 +6102,6 @@ index 0000000..98508b1
     +			}
     +	}   }
     +	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
    -+#endif
     +
     +	/* match within prefix */
     +	if (sequence.offset < 8) {
    @@ -6283,7 +6153,7 @@ index 0000000..98508b1
     +	int nbSeq;
     +
     +	/* Build Decoding Tables */
    -+	{   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    ++	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
     +		if (ZSTD_isError(seqHSize)) return seqHSize;
     +		ip += seqHSize;
     +	}
    @@ -6337,7 +6207,7 @@ index 0000000..98508b1
     +	}
     +
     +	/* last literal segment */
    -+	{   size_t const lastLLSize = litEnd - litPtr;
    ++	{	size_t const lastLLSize = litEnd - litPtr;
     +		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
     +		memcpy(op, litPtr, lastLLSize);
     +		op += lastLLSize;
    @@ -6356,7 +6226,7 @@ index 0000000..98508b1
     +	if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
     +
     +	/* Decode literals section */
    -+	{   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    ++	{	size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
     +		if (ZSTD_isError(litCSize)) return litCSize;
     +		ip += litCSize;
     +		srcSize -= litCSize;
    @@ -6430,7 +6300,7 @@ index 0000000..98508b1
     +		if (ZSTD_isError(headerSize)) return headerSize;
     +
     +		/* Frame Header */
    -+		{   size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    ++		{	size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
     +			if (ZSTD_isError(ret)) return ret;
     +			if (ret > 0) return ERROR(srcSize_wrong);
     +		}
    @@ -6478,7 +6348,7 @@ index 0000000..98508b1
     +	if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
     +
     +	/* Frame Header */
    -+	{   size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
    ++	{	size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
     +		if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
     +		if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
     +		CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
    @@ -6590,7 +6460,7 @@ index 0000000..98508b1
     +		}
     +		ZSTD_checkContinuity(dctx, dst);
     +
    -+		{   const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
    ++		{	const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
     +													&src, &srcSize);
     +			if (ZSTD_isError(res)) return res;
     +			/* don't need to bounds check this, ZSTD_decompressFrame will have
    @@ -6683,7 +6553,7 @@ index 0000000..98508b1
     +		return 0;
     +
     +	case ZSTDds_decodeBlockHeader:
    -+		{   blockProperties_t bp;
    ++		{	blockProperties_t bp;
     +			size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
     +			if (ZSTD_isError(cBlockSize)) return cBlockSize;
     +			dctx->expected = cBlockSize;
    @@ -6710,7 +6580,7 @@ index 0000000..98508b1
     +		}
     +	case ZSTDds_decompressLastBlock:
     +	case ZSTDds_decompressBlock:
    -+		{   size_t rSize;
    ++		{	size_t rSize;
     +			switch(dctx->bType)
     +			{
     +			case bt_compressed:
    @@ -6745,7 +6615,7 @@ index 0000000..98508b1
     +			return rSize;
     +		}
     +	case ZSTDds_checkChecksum:
    -+		{   U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    ++		{	U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
     +			U32 const check32 = MEM_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
     +			if (check32 != h32) return ERROR(checksum_wrong);
     +			dctx->expected = 0;
    @@ -6753,13 +6623,13 @@ index 0000000..98508b1
     +			return 0;
     +		}
     +	case ZSTDds_decodeSkippableHeader:
    -+		{   memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    ++		{	memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
     +			dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
     +			dctx->stage = ZSTDds_skipFrame;
     +			return 0;
     +		}
     +	case ZSTDds_skipFrame:
    -+		{   dctx->expected = 0;
    ++		{	dctx->expected = 0;
     +			dctx->stage = ZSTDds_getFrameHeaderSize;
     +			return 0;
     +		}
    @@ -6790,12 +6660,12 @@ index 0000000..98508b1
     +	dictPtr += 8;   /* skip header = magic + dictID */
     +
     +
    -+	{   size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
    ++	{	size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
     +		if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
     +		dictPtr += hSize;
     +	}
     +
    -+	{   short offcodeNCount[MaxOff+1];
    ++	{	short offcodeNCount[MaxOff+1];
     +		U32 offcodeMaxValue = MaxOff, offcodeLog;
     +		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -6804,7 +6674,7 @@ index 0000000..98508b1
     +		dictPtr += offcodeHeaderSize;
     +	}
     +
    -+	{   short matchlengthNCount[MaxML+1];
    ++	{	short matchlengthNCount[MaxML+1];
     +		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
     +		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -6813,7 +6683,7 @@ index 0000000..98508b1
     +		dictPtr += matchlengthHeaderSize;
     +	}
     +
    -+	{   short litlengthNCount[MaxLL+1];
    ++	{	short litlengthNCount[MaxLL+1];
     +		unsigned litlengthMaxValue = MaxLL, litlengthLog;
     +		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
     +		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    @@ -6823,7 +6693,7 @@ index 0000000..98508b1
     +	}
     +
     +	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    -+	{   int i;
    ++	{	int i;
     +		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
     +		for (i=0; i<3; i++) {
     +			U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
    @@ -6837,14 +6707,14 @@ index 0000000..98508b1
     +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
     +{
     +	if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
    -+	{   U32 const magic = MEM_readLE32(dict);
    ++	{	U32 const magic = MEM_readLE32(dict);
     +		if (magic != ZSTD_DICT_MAGIC) {
     +			return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
     +	}   }
     +	dctx->dictID = MEM_readLE32((const char*)dict + 4);
     +
     +	/* load entropy tables */
    -+	{   size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    ++	{	size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
     +		if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
     +		dict = (const char*)dict + eSize;
     +		dictSize -= eSize;
    @@ -6921,7 +6791,7 @@ index 0000000..98508b1
     +	ddict->dictID = 0;
     +	ddict->entropyPresent = 0;
     +	if (ddict->dictSize < 8) return 0;
    -+	{   U32 const magic = MEM_readLE32(ddict->dictContent);
    ++	{	U32 const magic = MEM_readLE32(ddict->dictContent);
     +		if (magic != ZSTD_DICT_MAGIC) return 0;   /* pure content mode */
     +	}
     +	ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
    @@ -6937,7 +6807,7 @@ index 0000000..98508b1
     +{
     +	if (!customMem.customAlloc || !customMem.customFree) return NULL;
     +
    -+	{   ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
    ++	{	ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
     +		if (!ddict) return NULL;
     +		ddict->cMem = customMem;
     +
    @@ -6954,7 +6824,7 @@ index 0000000..98508b1
     +		ddict->dictSize = dictSize;
     +		ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
     +		/* parse dictionary content */
    -+		{   size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
    ++		{	size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
     +			if (ZSTD_isError(errorCode)) {
     +				ZSTD_freeDDict(ddict);
     +				return NULL;
    @@ -6978,7 +6848,7 @@ index 0000000..98508b1
     +size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
     +{
     +	if (ddict==NULL) return 0;   /* support free on NULL */
    -+	{   ZSTD_customMem const cMem = ddict->cMem;
    ++	{	ZSTD_customMem const cMem = ddict->cMem;
     +		ZSTD_free(ddict->dictBuffer, cMem);
     +		ZSTD_free(ddict, cMem);
     +		return 0;
    @@ -7125,7 +6995,7 @@ index 0000000..98508b1
     +size_t ZSTD_freeDStream(ZSTD_DStream* zds)
     +{
     +	if (zds==NULL) return 0;   /* support free on null */
    -+	{   ZSTD_customMem const cMem = zds->customMem;
    ++	{	ZSTD_customMem const cMem = zds->customMem;
     +		ZSTD_freeDCtx(zds->dctx);
     +		zds->dctx = NULL;
     +		ZSTD_freeDDict(zds->ddictLocal);
    @@ -7182,7 +7052,7 @@ index 0000000..98508b1
     +			/* fall-through */
     +
     +		case zdss_loadHeader :
    -+			{   size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    ++			{	size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
     +				if (ZSTD_isError(hSize))
     +				return hSize;
     +				if (hSize != 0) {   /* need more input */
    @@ -7214,9 +7084,9 @@ index 0000000..98508b1
     +
     +			/* Consume header */
     +			ZSTD_refDDict(zds->dctx, zds->ddict);
    -+			{   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    ++			{	size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
     +				CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    -+				{   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++				{	size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     +					CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
     +			}   }
     +
    @@ -7224,7 +7094,7 @@ index 0000000..98508b1
     +			if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
     +
     +			/* Adapt buffer sizes to frame header instructions */
    -+			{   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    ++			{	size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
     +				size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
     +				zds->blockSize = blockSize;
     +				if (zds->inBuffSize < blockSize) {
    @@ -7243,7 +7113,7 @@ index 0000000..98508b1
     +			/* pass-through */
     +
     +		case zdss_read:
    -+			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     +				if (neededInSize==0) {  /* end of frame */
     +					zds->stage = zdss_init;
     +					someMoreWork = 0;
    @@ -7267,7 +7137,7 @@ index 0000000..98508b1
     +			}
     +
     +		case zdss_load:
    -+			{   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     +				size_t const toLoad = neededInSize - zds->inPos;   /* should always be <= remaining space within inBuff */
     +				size_t loadedSize;
     +				if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected);   /* should never happen */
    @@ -7290,7 +7160,7 @@ index 0000000..98508b1
     +			}   }
     +
     +		case zdss_flush:
    -+			{   size_t const toFlushSize = zds->outEnd - zds->outStart;
    ++			{	size_t const toFlushSize = zds->outEnd - zds->outStart;
     +				size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
     +				op += flushedSize;
     +				zds->outStart += flushedSize;
    @@ -7310,7 +7180,7 @@ index 0000000..98508b1
     +	/* result */
     +	input->pos += (size_t)(ip-istart);
     +	output->pos += (size_t)(op-ostart);
    -+	{   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    ++	{	size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
     +		if (!nextSrcSizeHint) {   /* frame fully decoded */
     +			if (zds->outEnd == zds->outStart) {  /* output fully flushed */
     +				if (zds->hostageByte) {
    @@ -7373,7 +7243,7 @@ index 0000000..98508b1
     +MODULE_DESCRIPTION("Zstd Decompressor");
     diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c
     new file mode 100644
    -index 0000000..68d88082
    +index 0000000..36ad266
     --- /dev/null
     +++ b/lib/zstd/entropy_common.c
     @@ -0,0 +1,217 @@
    @@ -7486,7 +7356,7 @@ index 0000000..68d88082
     +			} else {
     +				bitStream >>= 2;
     +		}   }
    -+		{   int const max = (2*threshold-1) - remaining;
    ++		{	int const max = (2*threshold-1) - remaining;
     +			int count;
     +
     +			if ((bitStream & (threshold-1)) < (U32)max) {
    @@ -7551,7 +7421,7 @@ index 0000000..68d88082
     +		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
     +		if (oSize >= hwSize) return ERROR(corruption_detected);
     +		ip += 1;
    -+		{   U32 n;
    ++		{	U32 n;
     +			for (n=0; n> 4;
     +				huffWeight[n+1] = ip[n/2] & 15;
    @@ -7566,7 +7436,7 @@ index 0000000..68d88082
     +	/* collect weight stats */
     +	memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
     +	weightTotal = 0;
    -+	{   U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
     +			rankStats[huffWeight[n]]++;
     +			weightTotal += (1 << huffWeight[n]) >> 1;
    @@ -7574,11 +7444,11 @@ index 0000000..68d88082
     +	if (weightTotal == 0) return ERROR(corruption_detected);
     +
     +	/* get last non-null symbol weight (implied, total must be 2^n) */
    -+	{   U32 const tableLog = BIT_highbit32(weightTotal) + 1;
    ++	{	U32 const tableLog = BIT_highbit32(weightTotal) + 1;
     +		if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
     +		*tableLogPtr = tableLog;
     +		/* determine last weight */
    -+		{   U32 const total = 1 << tableLog;
    ++		{	U32 const total = 1 << tableLog;
     +			U32 const rest = total - weightTotal;
     +			U32 const verif = 1 << BIT_highbit32(rest);
     +			U32 const lastWeight = BIT_highbit32(rest) + 1;
    @@ -7646,7 +7516,7 @@ index 0000000..8cf148b
     +#endif /* ERROR_H_MODULE */
     diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h
     new file mode 100644
    -index 0000000..14fa439
    +index 0000000..6a78957
     --- /dev/null
     +++ b/lib/zstd/fse.h
     @@ -0,0 +1,606 @@
    @@ -8111,7 +7981,7 @@ index 0000000..14fa439
     +MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
     +{
     +	FSE_initCState(statePtr, ct);
    -+	{   const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    ++	{	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
     +		const U16* stateTable = (const U16*)(statePtr->stateTable);
     +		U32 nbBitsOut  = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
     +		statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
    @@ -8258,10 +8128,10 @@ index 0000000..14fa439
     +#endif  /* FSE_H */
     diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c
     new file mode 100644
    -index 0000000..b6a6d46
    +index 0000000..d0b5673
     --- /dev/null
     +++ b/lib/zstd/fse_compress.c
    -@@ -0,0 +1,788 @@
    +@@ -0,0 +1,774 @@
     +/* ******************************************************************
     +   FSE : Finite State Entropy encoder
     +   Copyright (C) 2013-2015, Yann Collet.
    @@ -8370,7 +8240,7 @@ index 0000000..b6a6d46
     +	*  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
     +
     +	/* symbol start positions */
    -+	{   U32 u;
    ++	{	U32 u;
     +		cumul[0] = 0;
     +		for (u=1; u<=maxSymbolValue+1; u++) {
     +			if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */
    @@ -8383,7 +8253,7 @@ index 0000000..b6a6d46
     +	}
     +
     +	/* Spread symbols */
    -+	{   U32 position = 0;
    ++	{	U32 position = 0;
     +		U32 symbol;
     +		for (symbol=0; symbol<=maxSymbolValue; symbol++) {
     +			int nbOccurences;
    @@ -8397,13 +8267,13 @@ index 0000000..b6a6d46
     +	}
     +
     +	/* Build table */
    -+	{   U32 u; for (u=0; u>= 16;
     +				bitCount -= 16;
     +		}   }
    -+		{   int count = normalizedCounter[charnum++];
    ++		{	int count = normalizedCounter[charnum++];
     +			int const max = (2*threshold-1)-remaining;
     +			remaining -= count < 0 ? -count : count;
     +			count++;   /* +1 for extra accuracy */
    @@ -8601,7 +8471,7 @@ index 0000000..b6a6d46
     +	if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
     +
     +	/* by stripes of 16 bytes */
    -+	{   U32 cached = MEM_read32(ip); ip += 4;
    ++	{	U32 cached = MEM_read32(ip); ip += 4;
     +		while (ip < iend-15) {
     +			U32 c = cached; cached = MEM_read32(ip); ip += 4;
     +			Counting1[(BYTE) c     ]++;
    @@ -8636,7 +8506,7 @@ index 0000000..b6a6d46
     +			if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
     +	}   }
     +
    -+	{   U32 s; for (s=0; s<=maxSymbolValue; s++) {
    ++	{	U32 s; for (s=0; s<=maxSymbolValue; s++) {
     +			count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
     +			if (count[s] > max) max = count[s];
     +	}   }
    @@ -8781,7 +8651,7 @@ index 0000000..b6a6d46
     +		return 0;
     +	}
     +
    -+	{   U64 const vStepLog = 62 - tableLog;
    ++	{	U64 const vStepLog = 62 - tableLog;
     +		U64 const mid = (1ULL << (vStepLog-1)) - 1;
     +		U64 const rStep = ((((U64)1< FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
     +	if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
     +
    -+	{   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
    ++	{	U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
     +		U64 const scale = 62 - tableLog;
     +		U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
     +		U64 const vStep = 1ULL<<(scale-20);
    @@ -8845,20 +8715,6 @@ index 0000000..b6a6d46
     +		else normalizedCounter[largest] += (short)stillToDistribute;
     +	}
     +
    -+#if 0
    -+	{   /* Print Table (debug) */
    -+		U32 s;
    -+		U32 nTotal = 0;
    -+		for (s=0; s<=maxSymbolValue; s++)
    -+			printf("%3i: %4i \n", s, normalizedCounter[s]);
    -+		for (s=0; s<=maxSymbolValue; s++)
    -+			nTotal += abs(normalizedCounter[s]);
    -+		if (nTotal != (1U< not compressible */
     +		if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
    @@ -9031,13 +8887,13 @@ index 0000000..b6a6d46
     +	CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
     +
     +	/* Write table description header */
    -+	{   CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    ++	{	CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
     +		op += nc_err;
     +	}
     +
     +	/* Compress */
     +	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
    -+	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
    ++	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
     +		if (cSize == 0) return 0;   /* not enough space for compressed data */
     +		op += cSize;
     +	}
    @@ -9052,7 +8908,7 @@ index 0000000..b6a6d46
     +#endif   /* FSE_COMMONDEFS_ONLY */
     diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c
     new file mode 100644
    -index 0000000..2a35f17
    +index 0000000..6de5411
     --- /dev/null
     +++ b/lib/zstd/fse_decompress.c
     @@ -0,0 +1,292 @@
    @@ -9156,10 +9012,10 @@ index 0000000..2a35f17
     +	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
     +
     +	/* Init, lay down lowprob symbols */
    -+	{   FSE_DTableHeader DTableH;
    ++	{	FSE_DTableHeader DTableH;
     +		DTableH.tableLog = (U16)tableLog;
     +		DTableH.fastMode = 1;
    -+		{   S16 const largeLimit= (S16)(1 << (tableLog-1));
    ++		{	S16 const largeLimit= (S16)(1 << (tableLog-1));
     +			U32 s;
     +			for (s=0; s not compressible */
     +	}
    @@ -9661,13 +9517,13 @@ index 0000000..a1a1d45
     +	CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
     +
     +	/* Write table description header */
    -+	{   CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    ++	{	CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
     +		op += hSize;
     +	}
     +
     +	/* Compress */
     +	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
    -+	{   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
    ++	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
     +		if (cSize == 0) return 0;   /* not enough space for compressed data */
     +		op += cSize;
     +	}
    @@ -9703,7 +9559,7 @@ index 0000000..a1a1d45
     +		huffWeight[n] = bitsToWeight[CTable[n].nbBits];
     +
     +	/* attempt weights compression by FSE */
    -+	{   CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
    ++	{	CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
     +		if ((hSize>1) & (hSize < maxSymbolValue/2)) {   /* FSE compressed */
     +			op[0] = (BYTE)hSize;
     +			return hSize+1;
    @@ -9735,26 +9591,26 @@ index 0000000..a1a1d45
     +	if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
     +
     +	/* Prepare base value per rank */
    -+	{   U32 n, nextRankStart = 0;
    ++	{	U32 n, nextRankStart = 0;
     +		for (n=1; n<=tableLog; n++) {
    -+			U32 current = nextRankStart;
    ++			U32 curr = nextRankStart;
     +			nextRankStart += (rankVal[n] << (n-1));
    -+			rankVal[n] = current;
    ++			rankVal[n] = curr;
     +	}   }
     +
     +	/* fill nbBits */
    -+	{   U32 n; for (n=0; nn=tableLog+1 */
    ++	{	U16 nbPerRank[HUF_TABLELOG_MAX+2]  = {0};  /* support w=0=>n=tableLog+1 */
     +		U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
     +		{ U32 n; for (n=0; n0; n--) {  /* start at n=tablelog <-> w=1 */
     +				valPerRank[n] = min;     /* get starting value within each rank */
     +				min += nbPerRank[n];
    @@ -9781,7 +9637,7 @@ index 0000000..a1a1d45
     +	if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */
     +
     +	/* there are several too large elements (at least >= 2) */
    -+	{   int totalCost = 0;
    ++	{	int totalCost = 0;
     +		const U32 baseCost = 1 << (largestBits - maxNbBits);
     +		U32 n = lastNonNull;
     +
    @@ -9796,17 +9652,17 @@ index 0000000..a1a1d45
     +		totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */
     +
     +		/* repay normalized cost */
    -+		{   U32 const noSymbol = 0xF0F0F0F0;
    ++		{	U32 const noSymbol = 0xF0F0F0F0;
     +			U32 rankLast[HUF_TABLELOG_MAX+2];
     +			int pos;
     +
     +			/* Get pos of last (smallest) symbol per rank */
     +			memset(rankLast, 0xF0, sizeof(rankLast));
    -+			{   U32 currentNbBits = maxNbBits;
    ++			{	U32 currNbBits = maxNbBits;
     +				for (pos=n ; pos >= 0; pos--) {
    -+					if (huffNode[pos].nbBits >= currentNbBits) continue;
    -+					currentNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    -+					rankLast[maxNbBits-currentNbBits] = pos;
    ++					if (huffNode[pos].nbBits >= currNbBits) continue;
    ++					currNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    ++					rankLast[maxNbBits-currNbBits] = pos;
     +			}   }
     +
     +			while (totalCost > 0) {
    @@ -9816,7 +9672,7 @@ index 0000000..a1a1d45
     +					U32 lowPos = rankLast[nBitsToDecrease-1];
     +					if (highPos == noSymbol) continue;
     +					if (lowPos == noSymbol) break;
    -+					{   U32 const highTotal = huffNode[highPos].count;
    ++					{	U32 const highTotal = huffNode[highPos].count;
     +						U32 const lowTotal = 2 * huffNode[lowPos].count;
     +						if (highTotal <= lowTotal) break;
     +				}   }
    @@ -9854,7 +9710,7 @@ index 0000000..a1a1d45
     +
     +typedef struct {
     +	U32 base;
    -+	U32 current;
    ++	U32 curr;
     +} rankPos;
     +
     +static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
    @@ -9868,11 +9724,11 @@ index 0000000..a1a1d45
     +		rank[r].base ++;
     +	}
     +	for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
    -+	for (n=0; n<32; n++) rank[n].current = rank[n].base;
    ++	for (n=0; n<32; n++) rank[n].curr = rank[n].base;
     +	for (n=0; n<=maxSymbolValue; n++) {
     +		U32 const c = count[n];
     +		U32 const r = BIT_highbit32(c+1) + 1;
    -+		U32 pos = rank[r].current++;
    ++		U32 pos = rank[r].curr++;
     +		while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
     +		huffNode[pos].count = c;
     +		huffNode[pos].byte  = (BYTE)n;
    @@ -9934,13 +9790,13 @@ index 0000000..a1a1d45
     +	maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
     +
     +	/* fill result into tree (val, nbBits) */
    -+	{   U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
    ++	{	U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
     +		U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
     +		if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC);   /* check fit into table */
     +		for (n=0; n<=nonNullRank; n++)
     +			nbPerRank[huffNode[n].nbBits]++;
     +		/* determine stating value per rank */
    -+		{   U16 min = 0;
    ++		{	U16 min = 0;
     +			for (n=maxNbBits; n>0; n--) {
     +				valPerRank[n] = min;      /* get starting value within each rank */
     +				min += nbPerRank[n];
    @@ -10045,28 +9901,28 @@ index 0000000..a1a1d45
     +	if (srcSize < 12) return 0;   /* no saving possible : too small input */
     +	op += 6;   /* jumpTable */
     +
    -+	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     +		if (cSize==0) return 0;
     +		MEM_writeLE16(ostart, (U16)cSize);
     +		op += cSize;
     +	}
     +
     +	ip += segmentSize;
    -+	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     +		if (cSize==0) return 0;
     +		MEM_writeLE16(ostart+2, (U16)cSize);
     +		op += cSize;
     +	}
     +
     +	ip += segmentSize;
    -+	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    ++	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     +		if (cSize==0) return 0;
     +		MEM_writeLE16(ostart+4, (U16)cSize);
     +		op += cSize;
     +	}
     +
     +	ip += segmentSize;
    -+	{   CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
    ++	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
     +		if (cSize==0) return 0;
     +		op += cSize;
     +	}
    @@ -10114,7 +9970,7 @@ index 0000000..a1a1d45
     +	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
     +	if (!srcSize) return 0;  /* Uncompressed (note : 1 means rle, so first byte must be correct) */
     +	if (!dstSize) return 0;  /* cannot fit within dst budget */
    -+	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* current block size limit */
    ++	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* curr block size limit */
     +	if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
     +	if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
     +	if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
    @@ -10132,7 +9988,7 @@ index 0000000..a1a1d45
     +	}
     +
     +	/* Scan input and build symbol stats */
    -+	{   CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
    ++	{	CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
     +		if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */
     +		if (largest <= (srcSize >> 7)+1) return 0;   /* Fast heuristic : not compressible enough */
     +	}
    @@ -10148,14 +10004,14 @@ index 0000000..a1a1d45
     +
     +	/* Build Huffman Tree */
     +	huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
    -+	{   CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
    ++	{	CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
     +		huffLog = (U32)maxBits;
     +		/* Zero the unused symbols so we can check it for validity */
     +		memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
     +	}
     +
     +	/* Write table description header */
    -+	{   CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
    ++	{	CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
     +		/* Check if using the previous table will be beneficial */
     +		if (repeat && *repeat != HUF_repeat_none) {
     +			size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
    @@ -10209,7 +10065,7 @@ index 0000000..a1a1d45
     +}
     diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c
     new file mode 100644
    -index 0000000..f73223c
    +index 0000000..2d9b33b
     --- /dev/null
     +++ b/lib/zstd/huf_decompress.c
     @@ -0,0 +1,835 @@
    @@ -10306,7 +10162,7 @@ index 0000000..f73223c
     +	if (HUF_isError(iSize)) return iSize;
     +
     +	/* Table header */
    -+	{   DTableDesc dtd = HUF_getDTableDesc(DTable);
    ++	{	DTableDesc dtd = HUF_getDTableDesc(DTable);
     +		if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
     +		dtd.tableType = 0;
     +		dtd.tableLog = (BYTE)tableLog;
    @@ -10314,15 +10170,15 @@ index 0000000..f73223c
     +	}
     +
     +	/* Calculate starting value for each rank */
    -+	{   U32 n, nextRankStart = 0;
    ++	{	U32 n, nextRankStart = 0;
     +		for (n=1; n> 1;
    @@ -10435,7 +10291,7 @@ index 0000000..f73223c
     +	/* Check */
     +	if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
     +
    -+	{   const BYTE* const istart = (const BYTE*) cSrc;
    ++	{	const BYTE* const istart = (const BYTE*) cSrc;
     +		BYTE* const ostart = (BYTE*) dst;
     +		BYTE* const oend = ostart + dstSize;
     +		const void* const dtPtr = DTable + 1;
    @@ -10574,7 +10430,7 @@ index 0000000..f73223c
     +	}
     +
     +	/* fill DTable */
    -+	{   U32 s; for (s=0; s= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
     +
    -+	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    ++	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     +		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     +						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     +	}
    @@ -11043,7 +10899,7 @@ index 0000000..f73223c
     +	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
     +	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
     +
    -+	{   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    ++	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     +		return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     +						HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     +	}
    @@ -11340,10 +11196,10 @@ index 0000000..106f540
     +}
     diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h
     new file mode 100644
    -index 0000000..a61bd27
    +index 0000000..5ed5419
     --- /dev/null
     +++ b/lib/zstd/zstd_internal.h
    -@@ -0,0 +1,274 @@
    +@@ -0,0 +1,261 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
    @@ -11584,20 +11440,7 @@ index 0000000..a61bd27
     +
     +MEM_STATIC U32 ZSTD_highbit32(U32 val)
     +{
    -+#   if defined(__GNUC__) && (__GNUC__ >= 3)   /* GCC Intrinsic */
     +	return 31 - __builtin_clz(val);
    -+#   else   /* Software version */
    -+	static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
    -+	U32 v = val;
    -+	int r;
    -+	v |= v >> 1;
    -+	v |= v >> 2;
    -+	v |= v >> 4;
    -+	v |= v >> 8;
    -+	v |= v >> 16;
    -+	r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
    -+	return r;
    -+#   endif
     +}
     +
     +
    @@ -11620,7 +11463,7 @@ index 0000000..a61bd27
     +#endif   /* ZSTD_CCOMMON_H_MODULE */
     diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h
     new file mode 100644
    -index 0000000..297a715
    +index 0000000..9bd5303
     --- /dev/null
     +++ b/lib/zstd/zstd_opt.h
     @@ -0,0 +1,921 @@
    @@ -11753,7 +11596,7 @@ index 0000000..297a715
     +	}
     +
     +	/* literal Length */
    -+	{   const BYTE LL_deltaCode = 19;
    ++	{	const BYTE LL_deltaCode = 19;
     +		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
     +		price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
     +	}
    @@ -11775,7 +11618,7 @@ index 0000000..297a715
     +	if (!ultra && offCode >= 20) price += (offCode-19)*2;
     +
     +	/* match Length */
    -+	{   const BYTE ML_deltaCode = 36;
    ++	{	const BYTE ML_deltaCode = 36;
     +		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
     +		price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
     +	}
    @@ -11794,20 +11637,20 @@ index 0000000..297a715
     +		seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
     +
     +	/* literal Length */
    -+	{   const BYTE LL_deltaCode = 19;
    ++	{	const BYTE LL_deltaCode = 19;
     +		const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
     +		seqStorePtr->litLengthFreq[llCode]++;
     +		seqStorePtr->litLengthSum++;
     +	}
     +
     +	/* match offset */
    -+	{   BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
    ++	{	BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
     +		seqStorePtr->offCodeSum++;
     +		seqStorePtr->offCodeFreq[offCode]++;
     +	}
     +
     +	/* match Length */
    -+	{   const BYTE ML_deltaCode = 36;
    ++	{	const BYTE ML_deltaCode = 36;
     +		const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
     +		seqStorePtr->matchLengthFreq[mlCode]++;
     +		seqStorePtr->matchLengthSum++;
    @@ -11818,7 +11661,7 @@ index 0000000..297a715
     +
     +
     +#define SET_PRICE(pos, mlen_, offset_, litlen_, price_)   \
    -+	{                                                 \
    ++	{	                                              \
     +		while (last_pos < pos)  { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
     +		opt[pos].mlen = mlen_;                         \
     +		opt[pos].off = offset_;                        \
    @@ -11859,7 +11702,7 @@ index 0000000..297a715
     +						U32 extDict, ZSTD_match_t* matches, const U32 minMatchLen)
     +{
     +	const BYTE* const base = zc->base;
    -+	const U32 current = (U32)(ip-base);
    ++	const U32 curr = (U32)(ip-base);
     +	const U32 hashLog = zc->params.cParams.hashLog;
     +	const size_t h  = ZSTD_hashPtr(ip, hashLog, mls);
     +	U32* const hashTable = zc->hashTable;
    @@ -11872,11 +11715,11 @@ index 0000000..297a715
     +	const U32 dictLimit = zc->dictLimit;
     +	const BYTE* const dictEnd = dictBase + dictLimit;
     +	const BYTE* const prefixStart = base + dictLimit;
    -+	const U32 btLow = btMask >= current ? 0 : current - btMask;
    ++	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
     +	const U32 windowLow = zc->lowLimit;
    -+	U32* smallerPtr = bt + 2*(current&btMask);
    -+	U32* largerPtr  = bt + 2*(current&btMask) + 1;
    -+	U32 matchEndIdx = current+8;
    ++	U32* smallerPtr = bt + 2*(curr&btMask);
    ++	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
    ++	U32 matchEndIdx = curr+8;
     +	U32 dummy32;   /* to be nullified at the end */
     +	U32 mnum = 0;
     +
    @@ -11885,31 +11728,31 @@ index 0000000..297a715
     +
     +	if (minMatch == 3) { /* HC3 match finder */
     +		U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
    -+		if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
    ++		if (matchIndex3>windowLow && (curr - matchIndex3 < (1<<18))) {
     +			const BYTE* match;
    -+			size_t currentMl=0;
    ++			size_t currMl=0;
     +			if ((!extDict) || matchIndex3 >= dictLimit) {
     +				match = base + matchIndex3;
    -+				if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
    ++				if (match[bestLength] == ip[bestLength]) currMl = ZSTD_count(ip, match, iLimit);
     +			} else {
     +				match = dictBase + matchIndex3;
     +				if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
    -+					currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
    ++					currMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
     +			}
     +
     +			/* save best solution */
    -+			if (currentMl > bestLength) {
    -+				bestLength = currentMl;
    -+				matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
    -+				matches[mnum].len = (U32)currentMl;
    ++			if (currMl > bestLength) {
    ++				bestLength = currMl;
    ++				matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex3;
    ++				matches[mnum].len = (U32)currMl;
     +				mnum++;
    -+				if (currentMl > ZSTD_OPT_NUM) goto update;
    -+				if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
    ++				if (currMl > ZSTD_OPT_NUM) goto update;
    ++				if (ip+currMl == iLimit) goto update; /* best possible, and avoid read overflow*/
     +			}
     +		}
     +	}
     +
    -+	hashTable[h] = current;   /* Update Hash Table */
    ++	hashTable[h] = curr;   /* Update Hash Table */
     +
     +	while (nbCompares-- && (matchIndex > windowLow)) {
     +		U32* nextPtr = bt + 2*(matchIndex & btMask);
    @@ -11931,7 +11774,7 @@ index 0000000..297a715
     +		if (matchLength > bestLength) {
     +			if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
     +			bestLength = matchLength;
    -+			matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
    ++			matches[mnum].off = ZSTD_REP_MOVE_OPT + curr - matchIndex;
     +			matches[mnum].len = (U32)matchLength;
     +			mnum++;
     +			if (matchLength > ZSTD_OPT_NUM) break;
    @@ -11940,14 +11783,14 @@ index 0000000..297a715
     +		}
     +
     +		if (match[matchLength] < ip[matchLength]) {
    -+			/* match is smaller than current */
    ++			/* match is smaller than curr */
     +			*smallerPtr = matchIndex;             /* update smaller idx */
     +			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
     +			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
     +			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -+			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
    ++			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
     +		} else {
    -+			/* match is larger than current */
    ++			/* match is larger than curr */
     +			*largerPtr = matchIndex;
     +			commonLengthLarger = matchLength;
     +			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    @@ -11958,7 +11801,7 @@ index 0000000..297a715
     +	*smallerPtr = *largerPtr = 0;
     +
     +update:
    -+	zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
    ++	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
     +	return mnum;
     +}
     +
    @@ -12061,7 +11904,7 @@ index 0000000..297a715
     +		litlen = (U32)(ip - anchor);
     +
     +		/* check repCode */
    -+		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    ++		{	U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
     +			for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
    @@ -12146,7 +11989,7 @@ index 0000000..297a715
     +		   }
     +
     +			best_mlen = minMatch;
    -+			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
    ++			{	U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
     +				for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
    @@ -12265,7 +12108,7 @@ index 0000000..297a715
     +	{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
     +
     +	/* Last Literals */
    -+	{   size_t const lastLLSize = iend - anchor;
    ++	{	size_t const lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    @@ -12310,19 +12153,19 @@ index 0000000..297a715
     +	while (ip < ilimit) {
     +		U32 cur, match_num, last_pos, litlen, price;
     +		U32 u, mlen, best_mlen, best_off, litLength;
    -+		U32 current = (U32)(ip-base);
    ++		U32 curr = (U32)(ip-base);
     +		memset(opt, 0, sizeof(ZSTD_optimal_t));
     +		last_pos = 0;
     +		opt[0].litlen = (U32)(ip - anchor);
     +
     +		/* check repCode */
    -+		{   U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
    ++		{	U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
     +			for (i = (ip==anchor); i 0 && repCur <= (S32)current)
    ++				if ( (repCur > 0 && repCur <= (S32)curr)
     +				   && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
     +				   && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
     +					/* repcode detected we should take it */
    @@ -12412,13 +12255,13 @@ index 0000000..297a715
     +			}
     +
     +			best_mlen = minMatch;
    -+			{   U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
    ++			{	U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
     +				for (i = (mlen != 1); i 0 && repCur <= (S32)(current+cur))
    ++					if ( (repCur > 0 && repCur <= (S32)(curr+cur))
     +					  && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
     +					  && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
     +						/* repcode detected */
    @@ -12538,7 +12381,7 @@ index 0000000..297a715
     +	{ int i; for (i=0; irepToConfirm[i] = rep[i]; }
     +
     +	/* Last Literals */
    -+	{   size_t lastLLSize = iend - anchor;
    ++	{	size_t lastLLSize = iend - anchor;
     +		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     +		seqStorePtr->lit += lastLLSize;
     +	}
    
    From 9f95e445ab839b0927ccdfb5518e6143deb89f59 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 17:26:43 -0700
    Subject: [PATCH 066/400] minor comment clarifications
    
    ---
     lib/zstd.h | 23 ++++++++++++-----------
     1 file changed, 12 insertions(+), 11 deletions(-)
    
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 116569b43..e8933f9d7 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -567,14 +567,14 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
     /*===   New experimental advanced parameters API   ===*/
     
     /* notes on API design :
    - *   In below proposal, parameters are pushed one by one into an existing CCtx,
    + *   In this proposal, parameters are pushed one by one into an existing CCtx,
      *   and then applied on all following compression jobs.
      *   When no parameter is ever provided, CCtx is created with compression level 3.
      *
      *   Another approach could be to load parameters into an intermediate _opaque_ object.
      *   The object would then be loaded into CCtx (like ZSTD_compress_advanced())
      *   This approach would be compatible with ZSTD_createCDict_advanced().
    - *   But it's a bit more cumbersome for CCtx, because it requires to manage an additional object.
    + *   But it's more cumbersome for CCtx, as it requires to manage an additional object.
      *
      *   Below proposal push parameters directly into CCtx.
      *   It's a bit more complex for CDict, as advanced version now requires 3 steps.
    @@ -583,13 +583,13 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
      */
     
     /* notes on naming convention :
    - *   Initially, the API favored naming like ZSTD_setCCtxParameter() .
    - *   In this proposal, this is changed into ZSTD_CCtx_setParameter() .
    + *   Initially, the API favored names like ZSTD_setCCtxParameter() .
    + *   In this proposal, convention is changed towards ZSTD_CCtx_setParameter() .
      *   The main idea is that it identifies more clearly the target object type.
      *   It feels clearer when considering other potential variants :
      *   ZSTD_CDict_setParameter() (rather than ZSTD_setCDictParameter())
      *   ZSTD_DCtx_setParameter()  (rather than ZSTD_setDCtxParameter() )
    - *   The first verion looks clearer.
    + *   The left variant looks clearer.
      */
     
     typedef enum {
    @@ -673,7 +673,8 @@ typedef enum {
     
     /*! ZSTD_CCtx_setParameter() :
      *  Set one compression parameter, selected by enum ZSTD_cParameter.
    - *  @result : 0, or an error code (which can be tested with ZSTD_isError()) */
    + *  Note : when `value` is an enum, cast it to unsigned for proper type checking.
    + *  @result : 0, or an error code (which can be tested with ZSTD_isError()). */
     ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
     
     /*! ZSTD_CCtx_setPledgedSrcSize() :
    @@ -719,7 +720,7 @@ ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict
      *  Add a prepared dictionary to cctx, it will used for next compression jobs.
      *  Note that compression parameters will be enforced from within CDict.
      *  Currently, they supercede any compression parameter previously set within CCtx.
    - *  The dictionary will remain valid for all future compression jobs performed using the same cctx.
    + *  The dictionary will remain valid for future compression jobs using same cctx.
      * @result : 0, or an error code (which can be tested with ZSTD_isError()).
      *  Special : adding a NULL CDict means "return to no-dictionary mode".
      *  Note 1 : Currently, only one dictionary can be managed.
    @@ -734,7 +735,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
     
     typedef enum {
         ZSTD_e_continue,  /* continue sending data, encoder transparently decides when to output result, depending on optimal conditions */
    -    ZSTD_e_flush,     /* flush any data provided and buffered so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_flush,     /* flush any data provided, compressed and buffered so far - frame will continue, future data can still reference previous data for better compression */
         ZSTD_e_end        /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
     } ZSTD_EndDirective;
     
    @@ -744,14 +745,15 @@ typedef enum {
      *  - Compression parameters cannot be changed once compression is started.
      *  - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize
      *  - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit.
    - *  - @return provides the amount of data ready to flush and still within internal buffers
    + *  - @return provides the amount of data ready to flush within internal buffers
      *            or an error code, which can be tested using ZSTD_isError().
    - *            if @return != 0, flush is not fully completed, so it must be called again to empty internal buffers.
    + *            if @return != 0, flush is not fully completed, and must be called again to empty internal buffers.
      *  - after a ZSTD_e_end directive, if internal buffer is not fully flushed,
      *            only ZSTD_e_end and ZSTD_e_flush operations are allowed.
      *            It is necessary to fully flush internal buffers
      *            before changing compression parameters or start a new compression job.
      */
    +// Not ready yet !!!
     ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
                                               void* dst, size_t dstCapacity, size_t* dstPos,
                                         const void* src, size_t srcSize, size_t* srcPos,
    @@ -763,7 +765,6 @@ ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
      *  It's allowed to change compression parameters after a reset.
      *  Any internal data not yet flushed is cancelled.
      */
    -// Not ready yet !!!
     ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
     
     
    
    From e12ae023571e4430fde591152130bb47d621aa88 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 16 May 2017 17:32:33 -0700
    Subject: [PATCH 067/400] minor coding style update
    
    reduced some long lines
    ---
     programs/fileio.c | 311 ++++++++++++++++++++++++++++++++--------------
     1 file changed, 219 insertions(+), 92 deletions(-)
    
    diff --git a/programs/fileio.c b/programs/fileio.c
    index ba15555dd..44152b0b1 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -340,25 +340,30 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
     
     #ifdef ZSTD_MULTITHREAD
         ress.cctx = ZSTDMT_createCCtx(g_nbThreads);
    -    if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
    +    if (ress.cctx == NULL)
    +        EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
         if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==FIO_OVERLAP_LOG_NOTSET))
    -        ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 9);   /* use complete window for overlap */
    +        /* use complete window for overlap */
    +        ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 9);
         if (g_overlapLog != FIO_OVERLAP_LOG_NOTSET)
             ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, g_overlapLog);
     #else
         ress.cctx = ZSTD_createCStream();
    -    if (ress.cctx == NULL) EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
    +    if (ress.cctx == NULL)
    +        EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
     #endif
         ress.srcBufferSize = ZSTD_CStreamInSize();
         ress.srcBuffer = malloc(ress.srcBufferSize);
         ress.dstBufferSize = ZSTD_CStreamOutSize();
         ress.dstBuffer = malloc(ress.dstBufferSize);
    -    if (!ress.srcBuffer || !ress.dstBuffer) EXM_THROW(31, "zstd: allocation error : not enough memory");
    +    if (!ress.srcBuffer || !ress.dstBuffer)
    +        EXM_THROW(31, "zstd: allocation error : not enough memory");
     
         /* dictionary */
         {   void* dictBuffer;
             size_t const dictBuffSize = FIO_createDictBuffer(&dictBuffer, dictFileName);   /* works with dictFileName==NULL */
    -        if (dictFileName && (dictBuffer==NULL)) EXM_THROW(32, "zstd: allocation error : can't create dictBuffer");
    +        if (dictFileName && (dictBuffer==NULL))
    +            EXM_THROW(32, "zstd: allocation error : can't create dictBuffer");
             {   ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
                 params.fParams.contentSizeFlag = srcRegFile;
                 params.fParams.checksumFlag = g_checksumFlag;
    @@ -369,7 +374,7 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
                 if (comprParams->searchLog) params.cParams.searchLog = comprParams->searchLog;
                 if (comprParams->searchLength) params.cParams.searchLength = comprParams->searchLength;
                 if (comprParams->targetLength) params.cParams.targetLength = comprParams->targetLength;
    -            if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy)(comprParams->strategy - 1);   /* 0 means : do not change */
    +            if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy) comprParams->strategy;
     #ifdef ZSTD_MULTITHREAD
                 {   size_t const errorCode = ZSTDMT_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize);
                     if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode));
    @@ -398,20 +403,26 @@ static void FIO_freeCResources(cRess_t ress)
     
     
     #ifdef ZSTD_GZCOMPRESS
    -static unsigned long long FIO_compressGzFrame(cRess_t* ress, const char* srcFileName, U64 const srcFileSize, int compressionLevel, U64* readsize)
    +static unsigned long long FIO_compressGzFrame(cRess_t* ress,
    +                    const char* srcFileName, U64 const srcFileSize,
    +                    int compressionLevel, U64* readsize)
     {
         unsigned long long inFileSize = 0, outFileSize = 0;
         z_stream strm;
         int ret;
     
    -    if (compressionLevel > Z_BEST_COMPRESSION) compressionLevel = Z_BEST_COMPRESSION;
    +    if (compressionLevel > Z_BEST_COMPRESSION)
    +        compressionLevel = Z_BEST_COMPRESSION;
     
         strm.zalloc = Z_NULL;
         strm.zfree = Z_NULL;
         strm.opaque = Z_NULL;
     
    -    ret = deflateInit2(&strm, compressionLevel, Z_DEFLATED, 15 /* maxWindowLogSize */ + 16 /* gzip only */, 8, Z_DEFAULT_STRATEGY); /* see http://www.zlib.net/manual.html */
    -    if (ret != Z_OK) EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
    +    ret = deflateInit2(&strm, compressionLevel, Z_DEFLATED,
    +                        15 /* maxWindowLogSize */ + 16 /* gzip only */,
    +                        8, Z_DEFAULT_STRATEGY); /* see http://www.zlib.net/manual.html */
    +    if (ret != Z_OK)
    +        EXM_THROW(71, "zstd: %s: deflateInit2 error %d \n", srcFileName, ret);
     
         strm.next_in = 0;
         strm.avail_in = 0;
    @@ -427,35 +438,45 @@ static unsigned long long FIO_compressGzFrame(cRess_t* ress, const char* srcFile
                 strm.avail_in = (uInt)inSize;
             }
             ret = deflate(&strm, Z_NO_FLUSH);
    -        if (ret != Z_OK) EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, ret);
    +        if (ret != Z_OK)
    +            EXM_THROW(72, "zstd: %s: deflate error %d \n", srcFileName, ret);
             {   size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
                 if (decompBytes) {
    -                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) EXM_THROW(73, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
    +                    EXM_THROW(73, "Write error : cannot write to output file");
                     outFileSize += decompBytes;
                     strm.next_out = (Bytef*)ress->dstBuffer;
                     strm.avail_out = (uInt)ress->dstBufferSize;
                 }
             }
    -        if (!srcFileSize) DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%", (U32)(inFileSize>>20), (double)outFileSize/inFileSize*100)
    -        else DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%", (U32)(inFileSize>>20), (U32)(srcFileSize>>20), (double)outFileSize/inFileSize*100);
    +        if (!srcFileSize)
    +            DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%",
    +                            (U32)(inFileSize>>20),
    +                            (double)outFileSize/inFileSize*100)
    +        else
    +            DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%",
    +                            (U32)(inFileSize>>20), (U32)(srcFileSize>>20),
    +                            (double)outFileSize/inFileSize*100);
         }
     
         while (1) {
             ret = deflate(&strm, Z_FINISH);
             {   size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
                 if (decompBytes) {
    -                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) EXM_THROW(75, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
    +                    EXM_THROW(75, "Write error : cannot write to output file");
                     outFileSize += decompBytes;
                     strm.next_out = (Bytef*)ress->dstBuffer;
                     strm.avail_out = (uInt)ress->dstBufferSize;
    -            }
    -        }
    +        }   }
             if (ret == Z_STREAM_END) break;
    -        if (ret != Z_BUF_ERROR) EXM_THROW(77, "zstd: %s: deflate error %d \n", srcFileName, ret);
    +        if (ret != Z_BUF_ERROR)
    +            EXM_THROW(77, "zstd: %s: deflate error %d \n", srcFileName, ret);
         }
     
         ret = deflateEnd(&strm);
    -    if (ret != Z_OK) EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
    +    if (ret != Z_OK)
    +        EXM_THROW(79, "zstd: %s: deflateEnd error %d \n", srcFileName, ret);
         *readsize = inFileSize;
     
         return outFileSize;
    @@ -464,7 +485,9 @@ static unsigned long long FIO_compressGzFrame(cRess_t* ress, const char* srcFile
     
     
     #ifdef ZSTD_LZMACOMPRESS
    -static unsigned long long FIO_compressLzmaFrame(cRess_t* ress, const char* srcFileName, U64 const srcFileSize, int compressionLevel, U64* readsize, int plain_lzma)
    +static unsigned long long FIO_compressLzmaFrame(cRess_t* ress,
    +                            const char* srcFileName, U64 const srcFileSize,
    +                            int compressionLevel, U64* readsize, int plain_lzma)
     {
         unsigned long long inFileSize = 0, outFileSize = 0;
         lzma_stream strm = LZMA_STREAM_INIT;
    @@ -476,12 +499,15 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress, const char* srcFi
     
         if (plain_lzma) {
             lzma_options_lzma opt_lzma;
    -        if (lzma_lzma_preset(&opt_lzma, compressionLevel)) EXM_THROW(71, "zstd: %s: lzma_lzma_preset error", srcFileName);
    +        if (lzma_lzma_preset(&opt_lzma, compressionLevel))
    +            EXM_THROW(71, "zstd: %s: lzma_lzma_preset error", srcFileName);
             ret = lzma_alone_encoder(&strm, &opt_lzma); /* LZMA */
    -        if (ret != LZMA_OK) EXM_THROW(71, "zstd: %s: lzma_alone_encoder error %d", srcFileName, ret);
    +        if (ret != LZMA_OK)
    +            EXM_THROW(71, "zstd: %s: lzma_alone_encoder error %d", srcFileName, ret);
         } else {
             ret = lzma_easy_encoder(&strm, compressionLevel, LZMA_CHECK_CRC64); /* XZ */
    -        if (ret != LZMA_OK) EXM_THROW(71, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
    +        if (ret != LZMA_OK)
    +            EXM_THROW(71, "zstd: %s: lzma_easy_encoder error %d", srcFileName, ret);
         }
     
         strm.next_in = 0;
    @@ -500,17 +526,24 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress, const char* srcFi
     
             ret = lzma_code(&strm, action);
     
    -        if (ret != LZMA_OK && ret != LZMA_STREAM_END) EXM_THROW(72, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
    +        if (ret != LZMA_OK && ret != LZMA_STREAM_END)
    +            EXM_THROW(72, "zstd: %s: lzma_code encoding error %d", srcFileName, ret);
             {   size_t const compBytes = ress->dstBufferSize - strm.avail_out;
                 if (compBytes) {
    -                if (fwrite(ress->dstBuffer, 1, compBytes, ress->dstFile) != compBytes) EXM_THROW(73, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, compBytes, ress->dstFile) != compBytes)
    +                    EXM_THROW(73, "Write error : cannot write to output file");
                     outFileSize += compBytes;
                     strm.next_out = ress->dstBuffer;
                     strm.avail_out = ress->dstBufferSize;
    -            }
    -        }
    -        if (!srcFileSize) DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%", (U32)(inFileSize>>20), (double)outFileSize/inFileSize*100)
    -        else DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%", (U32)(inFileSize>>20), (U32)(srcFileSize>>20), (double)outFileSize/inFileSize*100);
    +        }   }
    +        if (!srcFileSize)
    +            DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%",
    +                            (U32)(inFileSize>>20),
    +                            (double)outFileSize/inFileSize*100)
    +        else
    +            DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%",
    +                            (U32)(inFileSize>>20), (U32)(srcFileSize>>20),
    +                            (double)outFileSize/inFileSize*100);
             if (ret == LZMA_STREAM_END) break;
         }
     
    @@ -523,7 +556,9 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress, const char* srcFi
     
     #ifdef ZSTD_LZ4COMPRESS
     static int FIO_LZ4_GetBlockSize_FromBlockId (int id) { return (1 << (8 + (2 * id))); }
    -static unsigned long long FIO_compressLz4Frame(cRess_t* ress, const char* srcFileName, U64 const srcFileSize, int compressionLevel, U64* readsize)
    +static unsigned long long FIO_compressLz4Frame(cRess_t* ress,
    +                            const char* srcFileName, U64 const srcFileSize,
    +                            int compressionLevel, U64* readsize)
     {
         unsigned long long inFileSize = 0, outFileSize = 0;
     
    @@ -531,7 +566,8 @@ static unsigned long long FIO_compressLz4Frame(cRess_t* ress, const char* srcFil
         LZ4F_compressionContext_t ctx;
     
         LZ4F_errorCode_t const errorCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
    -    if (LZ4F_isError(errorCode)) EXM_THROW(31, "zstd: failed to create lz4 compression context");
    +    if (LZ4F_isError(errorCode))
    +        EXM_THROW(31, "zstd: failed to create lz4 compression context");
     
         memset(&prefs, 0, sizeof(prefs));
     
    @@ -553,7 +589,9 @@ static unsigned long long FIO_compressLz4Frame(cRess_t* ress, const char* srcFil
             size_t blockSize = FIO_LZ4_GetBlockSize_FromBlockId(LZ4F_max4MB);
             size_t readSize;
             size_t headerSize = LZ4F_compressBegin(ctx, ress->dstBuffer, ress->dstBufferSize, &prefs);
    -        if (LZ4F_isError(headerSize)) EXM_THROW(33, "File header generation failed : %s", LZ4F_getErrorName(headerSize));
    +        if (LZ4F_isError(headerSize))
    +            EXM_THROW(33, "File header generation failed : %s",
    +                            LZ4F_getErrorName(headerSize));
             { size_t const sizeCheck = fwrite(ress->dstBuffer, 1, headerSize, ress->dstFile);
               if (sizeCheck!=headerSize) EXM_THROW(34, "Write error : cannot write header"); }
             outFileSize += headerSize;
    @@ -568,10 +606,18 @@ static unsigned long long FIO_compressLz4Frame(cRess_t* ress, const char* srcFil
     
                 /* Compress Block */
                 outSize = LZ4F_compressUpdate(ctx, ress->dstBuffer, ress->dstBufferSize, ress->srcBuffer, readSize, NULL);
    -            if (LZ4F_isError(outSize)) EXM_THROW(35, "zstd: %s: lz4 compression failed : %s", srcFileName, LZ4F_getErrorName(outSize));
    +            if (LZ4F_isError(outSize))
    +                EXM_THROW(35, "zstd: %s: lz4 compression failed : %s",
    +                            srcFileName, LZ4F_getErrorName(outSize));
                 outFileSize += outSize;
    -            if (!srcFileSize) DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%", (U32)(inFileSize>>20), (double)outFileSize/inFileSize*100)
    -            else DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%", (U32)(inFileSize>>20), (U32)(srcFileSize>>20), (double)outFileSize/inFileSize*100);
    +            if (!srcFileSize)
    +                DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%",
    +                                (U32)(inFileSize>>20),
    +                                (double)outFileSize/inFileSize*100)
    +            else
    +                DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%",
    +                                (U32)(inFileSize>>20), (U32)(srcFileSize>>20),
    +                                (double)outFileSize/inFileSize*100);
     
                 /* Write Block */
                 { size_t const sizeCheck = fwrite(ress->dstBuffer, 1, outSize, ress->dstFile);
    @@ -585,7 +631,9 @@ static unsigned long long FIO_compressLz4Frame(cRess_t* ress, const char* srcFil
     
             /* End of Stream mark */
             headerSize = LZ4F_compressEnd(ctx, ress->dstBuffer, ress->dstBufferSize, NULL);
    -        if (LZ4F_isError(headerSize)) EXM_THROW(38, "zstd: %s: lz4 end of file generation failed : %s", srcFileName, LZ4F_getErrorName(headerSize));
    +        if (LZ4F_isError(headerSize))
    +            EXM_THROW(38, "zstd: %s: lz4 end of file generation failed : %s",
    +                        srcFileName, LZ4F_getErrorName(headerSize));
     
             { size_t const sizeCheck = fwrite(ress->dstBuffer, 1, headerSize, ress->dstFile);
               if (sizeCheck!=headerSize) EXM_THROW(39, "Write error : cannot write end of stream"); }
    @@ -623,7 +671,8 @@ static int FIO_compressFilename_internal(cRess_t ress,
                 compressedfilesize = FIO_compressGzFrame(&ress, srcFileName, fileSize, compressionLevel, &readsize);
     #else
                 (void)compressionLevel;
    -            EXM_THROW(20, "zstd: %s: file cannot be compressed as gzip (zstd compiled without ZSTD_GZCOMPRESS) -- ignored \n", srcFileName);
    +            EXM_THROW(20, "zstd: %s: file cannot be compressed as gzip (zstd compiled without ZSTD_GZCOMPRESS) -- ignored \n",
    +                            srcFileName);
     #endif
                 goto finish;
     
    @@ -633,7 +682,8 @@ static int FIO_compressFilename_internal(cRess_t ress,
                 compressedfilesize = FIO_compressLzmaFrame(&ress, srcFileName, fileSize, compressionLevel, &readsize, g_compressionType==FIO_lzmaCompression);
     #else
                 (void)compressionLevel;
    -            EXM_THROW(20, "zstd: %s: file cannot be compressed as xz/lzma (zstd compiled without ZSTD_LZMACOMPRESS) -- ignored \n", srcFileName);
    +            EXM_THROW(20, "zstd: %s: file cannot be compressed as xz/lzma (zstd compiled without ZSTD_LZMACOMPRESS) -- ignored \n",
    +                            srcFileName);
     #endif
                 goto finish;
     
    @@ -642,7 +692,8 @@ static int FIO_compressFilename_internal(cRess_t ress,
                 compressedfilesize = FIO_compressLz4Frame(&ress, srcFileName, fileSize, compressionLevel, &readsize);
     #else
                 (void)compressionLevel;
    -            EXM_THROW(20, "zstd: %s: file cannot be compressed as lz4 (zstd compiled without ZSTD_LZ4COMPRESS) -- ignored \n", srcFileName);
    +            EXM_THROW(20, "zstd: %s: file cannot be compressed as lz4 (zstd compiled without ZSTD_LZ4COMPRESS) -- ignored \n",
    +                            srcFileName);
     #endif
                 goto finish;
         }
    @@ -653,7 +704,9 @@ static int FIO_compressFilename_internal(cRess_t ress,
     #else
         {   size_t const resetError = ZSTD_resetCStream(ress.cctx, fileSize);
     #endif
    -        if (ZSTD_isError(resetError)) EXM_THROW(21, "Error initializing compression : %s", ZSTD_getErrorName(resetError));
    +        if (ZSTD_isError(resetError))
    +            EXM_THROW(21, "Error initializing compression : %s",
    +                            ZSTD_getErrorName(resetError));
         }
     
         /* Main compression loop */
    @@ -671,20 +724,31 @@ static int FIO_compressFilename_internal(cRess_t ress,
     #else
                     size_t const result = ZSTD_compressStream(ress.cctx, &outBuff, &inBuff);
     #endif
    -                if (ZSTD_isError(result)) EXM_THROW(23, "Compression error : %s ", ZSTD_getErrorName(result));
    +                if (ZSTD_isError(result))
    +                    EXM_THROW(23, "Compression error : %s ", ZSTD_getErrorName(result));
     
                     /* Write compressed stream */
                     if (outBuff.pos) {
                         size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
    -                    if (sizeCheck!=outBuff.pos) EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName);
    +                    if (sizeCheck!=outBuff.pos)
    +                        EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName);
                         compressedfilesize += outBuff.pos;
             }   }   }
             if (g_nbThreads > 1) {
    -            if (!fileSize) DISPLAYUPDATE(2, "\rRead : %u MB", (U32)(readsize>>20))
    -            else DISPLAYUPDATE(2, "\rRead : %u / %u MB", (U32)(readsize>>20), (U32)(fileSize>>20));
    +            if (!fileSize)
    +                DISPLAYUPDATE(2, "\rRead : %u MB", (U32)(readsize>>20))
    +            else
    +                DISPLAYUPDATE(2, "\rRead : %u / %u MB",
    +                                    (U32)(readsize>>20), (U32)(fileSize>>20));
             } else {
    -            if (!fileSize) DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%", (U32)(readsize>>20), (double)compressedfilesize/readsize*100)
    -            else DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%", (U32)(readsize>>20), (U32)(fileSize>>20), (double)compressedfilesize/readsize*100);
    +            if (!fileSize)
    +                DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%%",
    +                                (U32)(readsize>>20),
    +                                (double)compressedfilesize/readsize*100)
    +            else
    +            DISPLAYUPDATE(2, "\rRead : %u / %u MB ==> %.2f%%",
    +                                (U32)(readsize>>20), (U32)(fileSize>>20),
    +                                (double)compressedfilesize/readsize*100);
             }
         }
     
    @@ -722,7 +786,8 @@ finish:
      *            1 : missing or pb opening srcFileName
      */
     static int FIO_compressFilename_srcFile(cRess_t ress,
    -                                        const char* dstFileName, const char* srcFileName, int compressionLevel)
    +                            const char* dstFileName, const char* srcFileName,
    +                            int compressionLevel)
     {
         int result;
     
    @@ -751,7 +816,9 @@ static int FIO_compressFilename_srcFile(cRess_t ress,
      *            1 : pb
      */
     static int FIO_compressFilename_dstFile(cRess_t ress,
    -                                        const char* dstFileName, const char* srcFileName, int compressionLevel)
    +                                        const char* dstFileName,
    +                                        const char* srcFileName,
    +                                        int compressionLevel)
     {
         int result;
         stat_t statbuf;
    @@ -760,12 +827,20 @@ static int FIO_compressFilename_dstFile(cRess_t ress,
         ress.dstFile = FIO_openDstFile(dstFileName);
         if (ress.dstFile==NULL) return 1;  /* could not open dstFileName */
     
    -    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1;
    +    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf))
    +        stat_result = 1;
         result = FIO_compressFilename_srcFile(ress, dstFileName, srcFileName, compressionLevel);
     
    -    if (fclose(ress.dstFile)) { DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); result=1; }  /* error closing dstFile */
    -    if (result!=0) { if (remove(dstFileName)) EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno)); }  /* remove operation artefact */
    -    else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf);
    +    if (fclose(ress.dstFile)) { /* error closing dstFile */
    +        DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno));
    +        result=1;
    +    }
    +    if (result!=0) {  /* remove operation artefact */
    +        if (remove(dstFileName))
    +            EXM_THROW(1, "zstd: %s: %s", dstFileName, strerror(errno));
    +    }
    +    else if (strcmp (dstFileName, stdoutmark) && stat_result)
    +        UTIL_setFileStat(dstFileName, &statbuf);
         return result;
     }
     
    @@ -802,8 +877,10 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
         cRess_t ress = FIO_createCResources(dictFileName, compressionLevel, srcSize, regFile, comprParams);
     
         /* init */
    -    if (dstFileName==NULL) EXM_THROW(27, "FIO_compressMultipleFilenames : allocation error for dstFileName");
    -    if (suffix == NULL) EXM_THROW(28, "FIO_compressMultipleFilenames : dst unknown");  /* should never happen */
    +    if (dstFileName==NULL)
    +        EXM_THROW(27, "FIO_compressMultipleFilenames : allocation error for dstFileName");
    +    if (suffix == NULL)
    +        EXM_THROW(28, "FIO_compressMultipleFilenames : dst unknown");  /* should never happen */
     
         /* loop on each file */
         if (!strcmp(suffix, stdoutmark)) {
    @@ -812,12 +889,19 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
             SET_BINARY_MODE(stdout);
             for (u=0; udstBuffer;
         strm.avail_out = (uInt)ress->dstBufferSize;
    @@ -1078,10 +1174,14 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, FILE* srcFile, co
             }
             ret = inflate(&strm, flush);
             if (ret == Z_BUF_ERROR) EXM_THROW(39, "zstd: %s: premature end", srcFileName);
    -        if (ret != Z_OK && ret != Z_STREAM_END) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; }
    +        if (ret != Z_OK && ret != Z_STREAM_END) {
    +            DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret);
    +            return 0;
    +        }
             {   size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
                 if (decompBytes) {
    -                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) EXM_THROW(31, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
    +                    EXM_THROW(31, "Write error : cannot write to output file");
                     outFileSize += decompBytes;
                     strm.next_out = (Bytef*)ress->dstBuffer;
                     strm.avail_out = (uInt)ress->dstBufferSize;
    @@ -1115,7 +1215,9 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
             ret = lzma_stream_decoder(&strm, UINT64_MAX, 0); /* XZ */
         }
     
    -    if (ret != LZMA_OK) EXM_THROW(71, "zstd: %s: lzma_alone_decoder/lzma_stream_decoder error %d", srcFileName, ret);
    +    if (ret != LZMA_OK)
    +        EXM_THROW(71, "zstd: %s: lzma_alone_decoder/lzma_stream_decoder error %d",
    +                        srcFileName, ret);
     
         strm.next_out = ress->dstBuffer;
         strm.avail_out = ress->dstBufferSize;
    @@ -1131,16 +1233,20 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
             }
             ret = lzma_code(&strm, action);
     
    -        if (ret == LZMA_BUF_ERROR) EXM_THROW(39, "zstd: %s: premature end", srcFileName);
    -        if (ret != LZMA_OK && ret != LZMA_STREAM_END) { DISPLAY("zstd: %s: lzma_code decoding error %d \n", srcFileName, ret); return 0; }
    +        if (ret == LZMA_BUF_ERROR)
    +            EXM_THROW(39, "zstd: %s: premature end", srcFileName);
    +        if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
    +            DISPLAY("zstd: %s: lzma_code decoding error %d \n", srcFileName, ret);
    +            return 0;
    +        }
             {   size_t const decompBytes = ress->dstBufferSize - strm.avail_out;
                 if (decompBytes) {
    -                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) EXM_THROW(31, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
    +                    EXM_THROW(31, "Write error : cannot write to output file");
                     outFileSize += decompBytes;
                     strm.next_out = ress->dstBuffer;
                     strm.avail_out = ress->dstBufferSize;
    -            }
    -        }
    +        }   }
             if (ret == LZMA_STREAM_END) break;
         }
     
    @@ -1152,21 +1258,25 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
     #endif
     
     #ifdef ZSTD_LZ4DECOMPRESS
    -static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, FILE* srcFile, const char* srcFileName)
    +static unsigned long long FIO_decompressLz4Frame(dRess_t* ress,
    +                                    FILE* srcFile, const char* srcFileName)
     {
         unsigned long long filesize = 0;
         LZ4F_errorCode_t nextToLoad;
         LZ4F_decompressionContext_t dCtx;
         LZ4F_errorCode_t const errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
     
    -    if (LZ4F_isError(errorCode)) EXM_THROW(61, "zstd: failed to create lz4 decompression context");
    +    if (LZ4F_isError(errorCode))
    +        EXM_THROW(61, "zstd: failed to create lz4 decompression context");
     
         /* Init feed with magic number (already consumed from FILE* sFile) */
         {   size_t inSize = 4;
             size_t outSize= 0;
             MEM_writeLE32(ress->srcBuffer, LZ4_MAGICNUMBER);
             nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &outSize, ress->srcBuffer, &inSize, NULL);
    -        if (LZ4F_isError(nextToLoad)) EXM_THROW(62, "zstd: %s: lz4 header error : %s", srcFileName, LZ4F_getErrorName(nextToLoad));
    +        if (LZ4F_isError(nextToLoad))
    +            EXM_THROW(62, "zstd: %s: lz4 header error : %s",
    +                            srcFileName, LZ4F_getErrorName(nextToLoad));
         }
     
         /* Main Loop */
    @@ -1185,12 +1295,15 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, FILE* srcFile, c
                 size_t remaining = readSize - pos;
                 decodedBytes = ress->dstBufferSize;
                 nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &decodedBytes, (char*)(ress->srcBuffer)+pos, &remaining, NULL);
    -            if (LZ4F_isError(nextToLoad)) EXM_THROW(66, "zstd: %s: decompression error : %s", srcFileName, LZ4F_getErrorName(nextToLoad));
    +            if (LZ4F_isError(nextToLoad))
    +                EXM_THROW(66, "zstd: %s: decompression error : %s",
    +                                srcFileName, LZ4F_getErrorName(nextToLoad));
                 pos += remaining;
     
                 /* Write Block */
                 if (decodedBytes) {
    -                if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) EXM_THROW(63, "Write error : cannot write to output file");
    +                if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes)
    +                    EXM_THROW(63, "Write error : cannot write to output file");
                     filesize += decodedBytes;
                     DISPLAYUPDATE(2, "\rDecompressed : %u MB  ", (unsigned)(filesize>>20));
                 }
    @@ -1248,7 +1361,11 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch
                 break;   /* no more input */
             }
             readSomething = 1;   /* there is at least >= 4 bytes in srcFile */
    -        if (ress.srcBufferLoaded < toRead) { DISPLAY("zstd: %s: unknown header \n", srcFileName); fclose(srcFile); return 1; }  /* srcFileName is empty */
    +        if (ress.srcBufferLoaded < toRead) {
    +            DISPLAY("zstd: %s: unknown header \n", srcFileName);
    +            fclose(srcFile);
    +            return 1;
    +        }
             if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */
     #ifdef ZSTD_GZDECOMPRESS
                 unsigned long long const result = FIO_decompressGzFrame(&ress, srcFile, srcFileName);
    @@ -1295,8 +1412,7 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch
                         return 1;
                     }
                     filesize += frameSize;
    -            }
    -        }
    +        }   }
         }   /* for each frame */
     
         /* Final Status */
    @@ -1305,7 +1421,10 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch
     
         /* Close file */
         if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName);  /* error should never happen */
    -    if (g_removeSrcFile /* --rm */ && strcmp(srcFileName, stdinmark)) { if (remove(srcFileName)) EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); };
    +    if (g_removeSrcFile /* --rm */ && strcmp(srcFileName, stdinmark)) {
    +        if (remove(srcFileName))
    +            EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno));
    +    }
         return 0;
     }
     
    @@ -1325,16 +1444,19 @@ static int FIO_decompressDstFile(dRess_t ress,
         ress.dstFile = FIO_openDstFile(dstFileName);
         if (ress.dstFile==0) return 1;
     
    -    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf)) stat_result = 1;
    +    if (strcmp (srcFileName, stdinmark) && UTIL_getFileStat(srcFileName, &statbuf))
    +        stat_result = 1;
         result = FIO_decompressSrcFile(ress, dstFileName, srcFileName);
     
    -    if (fclose(ress.dstFile)) EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
    +    if (fclose(ress.dstFile))
    +        EXM_THROW(38, "Write error : cannot properly close %s", dstFileName);
     
         if ( (result != 0)
            && strcmp(dstFileName, nulmark)  /* special case : don't remove() /dev/null (#316) */
            && remove(dstFileName) )
             result=1;   /* don't do anything special if remove() fails */
    -    else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf);
    +    else if (strcmp (dstFileName, stdoutmark) && stat_result)
    +        UTIL_setFileStat(dstFileName, &statbuf);
         return result;
     }
     
    @@ -1361,7 +1483,8 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles
         int missingFiles = 0;
         dRess_t ress = FIO_createDResources(dictFileName);
     
    -    if (suffix==NULL) EXM_THROW(70, "zstd: decompression: unknown dst");   /* should never happen */
    +    if (suffix==NULL)
    +        EXM_THROW(70, "zstd: decompression: unknown dst");   /* should never happen */
     
         if (!strcmp(suffix, stdoutmark) || !strcmp(suffix, nulmark)) {  /* special cases : -c or -t */
             unsigned u;
    @@ -1369,19 +1492,22 @@ int FIO_decompressMultipleFilenames(const char** srcNamesTable, unsigned nbFiles
             if (ress.dstFile == 0) EXM_THROW(71, "cannot open %s", suffix);
             for (u=0; u
    Date: Tue, 16 May 2017 18:10:11 -0700
    Subject: [PATCH 068/400] removed useless variable from CCtx
    
    CStream's pledgedSrcSize is no longer necessary
    srcSize control is realized within bufferless interface.
    ---
     lib/compress/zstd_compress.c |  2 --
     lib/zstd.h                   |  4 ++--
     programs/fileio.c            | 34 ++++++++++++++++++++--------------
     3 files changed, 22 insertions(+), 18 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 565cf04a1..3d1236d05 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -140,7 +140,6 @@ struct ZSTD_CCtx_s {
         size_t outBuffFlushedSize;
         ZSTD_cStreamStage streamStage;
         U32    frameEnded;
    -    U64    pledgedSrcSize;
     };
     
     ZSTD_CCtx* ZSTD_createCCtx(void)
    @@ -3320,7 +3319,6 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters para
         zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
         zcs->streamStage = zcss_load;
         zcs->frameEnded = 0;
    -    zcs->pledgedSrcSize = pledgedSrcSize;
         return 0;   /* ready to go */
     }
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index e8933f9d7..4d14c8026 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -647,7 +647,7 @@ typedef enum {
         /* dictionary parameters */
         ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
                                   * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its user (CCtx or CDict) */
    +                              * But it also requires that dictionary buffer outlives its user (CDict) */
                                  /* Not ready yet ! */
         ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
                                  /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    @@ -717,7 +717,7 @@ ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter pa
     ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
     
     /*! ZSTD_CCtx_refCDict() :
    - *  Add a prepared dictionary to cctx, it will used for next compression jobs.
    + *  Add a prepared dictionary to cctx, to be used for next compression jobs.
      *  Note that compression parameters will be enforced from within CDict.
      *  Currently, they supercede any compression parameter previously set within CCtx.
      *  The dictionary will remain valid for future compression jobs using same cctx.
    diff --git a/programs/fileio.c b/programs/fileio.c
    index 44152b0b1..a36abcaff 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -77,7 +77,7 @@
     #define BLOCKSIZE      (128 KB)
     #define ROLLBUFFERSIZE (BLOCKSIZE*8*64)
     
    -#define FIO_FRAMEHEADERSIZE  5        /* as a define, because needed to allocated table on stack */
    +#define FIO_FRAMEHEADERSIZE  5    /* as a define, because needed to allocated table on stack */
     #define FSE_CHECKSUM_SEED    0
     
     #define CACHELINE 64
    @@ -92,7 +92,7 @@
     ***************************************/
     #define DISPLAY(...)         fprintf(stderr, __VA_ARGS__)
     #define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } }
    -static int g_displayLevel = 2;   /* 0 : no display;   1: errors;   2 : + result + interaction + warnings;   3 : + progression;   4 : + information */
    +static int g_displayLevel = 2;   /* 0 : no display;  1: errors;  2: + result + interaction + warnings;  3: + progression;  4: + information */
     void FIO_setNotificationLevel(unsigned level) { g_displayLevel=level; }
     
     #define DISPLAYUPDATE(l, ...) { if (g_displayLevel>=l) { \
    @@ -102,7 +102,7 @@ void FIO_setNotificationLevel(unsigned level) { g_displayLevel=level; }
     static const clock_t refreshRate = CLOCKS_PER_SEC * 15 / 100;
     static clock_t g_time = 0;
     
    -#undef MIN
    +#undef MIN  /* in case it would be already defined */
     #define MIN(a,b)    ((a) < (b) ? (a) : (b))
     
     
    @@ -226,11 +226,13 @@ static FILE* FIO_openSrcFile(const char* srcFileName)
             SET_BINARY_MODE(stdin);
         } else {
             if (!UTIL_isRegFile(srcFileName)) {
    -            DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n", srcFileName);
    +            DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
    +                            srcFileName);
                 return NULL;
             }
             f = fopen(srcFileName, "rb");
    -        if ( f==NULL ) DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno));
    +        if ( f==NULL )
    +            DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno));
         }
     
         return f;
    @@ -255,26 +257,28 @@ static FILE* FIO_openDstFile(const char* dstFileName)
             if (g_sparseFileSupport == 1) {
                 g_sparseFileSupport = ZSTD_SPARSE_DEFAULT;
             }
    -        if (strcmp (dstFileName, nulmark)) {  /* Check if destination file already exists */
    +        if (strcmp (dstFileName, nulmark)) {
    +            /* Check if destination file already exists */
                 f = fopen( dstFileName, "rb" );
    -            if (f != 0) {  /* dest file exists, prompt for overwrite authorization */
    +            if (f != 0) {  /* dst file exists, prompt for overwrite authorization */
                     fclose(f);
                     if (!g_overwrite) {
                         if (g_displayLevel <= 1) {
                             /* No interaction possible */
    -                        DISPLAY("zstd: %s already exists; not overwritten  \n", dstFileName);
    +                        DISPLAY("zstd: %s already exists; not overwritten  \n",
    +                                dstFileName);
                             return NULL;
                         }
    -                    DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName);
    +                    DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ",
    +                            dstFileName);
                         {   int ch = getchar();
                             if ((ch!='Y') && (ch!='y')) {
                                 DISPLAY("    not overwritten  \n");
                                 return NULL;
                             }
    -                        while ((ch!=EOF) && (ch!='\n')) ch = getchar();  /* flush rest of input line */
    -                    }
    -                }
    -
    +                        /* flush rest of input line */
    +                        while ((ch!=EOF) && (ch!='\n')) ch = getchar();
    +                }   }
                     /* need to unlink */
                     FIO_remove(dstFileName);
             }   }
    @@ -304,7 +308,9 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName)
         fileHandle = fopen(fileName, "rb");
         if (fileHandle==0) EXM_THROW(31, "zstd: %s: %s", fileName, strerror(errno));
         fileSize = UTIL_getFileSize(fileName);
    -    if (fileSize > DICTSIZE_MAX) EXM_THROW(32, "Dictionary file %s is too large (> %u MB)", fileName, DICTSIZE_MAX >> 20);   /* avoid extreme cases */
    +    if (fileSize > DICTSIZE_MAX)
    +        EXM_THROW(32, "Dictionary file %s is too large (> %u MB)",
    +                        fileName, DICTSIZE_MAX >> 20);   /* avoid extreme cases */
         *bufferPtr = malloc((size_t)fileSize);
         if (*bufferPtr==NULL) EXM_THROW(34, "zstd: %s", strerror(errno));
         { size_t const readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle);
    
    From d1a5790f8eaa63db228f9620da4ed68664ef6b44 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 17 May 2017 11:58:53 -0700
    Subject: [PATCH 069/400] [linux-kernel] Dual license with GPLv2
    
    ---
     contrib/linux-kernel/COPYING                  | 339 ++++++++
     contrib/linux-kernel/btrfs.diff               |  22 +-
     contrib/linux-kernel/fs/btrfs/zstd.c          |  18 +
     .../linux-kernel/fs/squashfs/zstd_wrapper.c   |   3 +-
     contrib/linux-kernel/include/linux/xxhash.h   |   6 +
     contrib/linux-kernel/include/linux/zstd.h     |  11 +-
     contrib/linux-kernel/lib/xxhash.c             |   6 +
     contrib/linux-kernel/lib/zstd/bitstream.h     |  74 +-
     contrib/linux-kernel/lib/zstd/compress.c      |  13 +-
     contrib/linux-kernel/lib/zstd/decompress.c    |  13 +-
     .../linux-kernel/lib/zstd/entropy_common.c    |  69 +-
     contrib/linux-kernel/lib/zstd/error_private.h |  11 +-
     contrib/linux-kernel/lib/zstd/fse.h           |  72 +-
     contrib/linux-kernel/lib/zstd/fse_compress.c  |  71 +-
     .../linux-kernel/lib/zstd/fse_decompress.c    |  71 +-
     contrib/linux-kernel/lib/zstd/huf.h           |  72 +-
     contrib/linux-kernel/lib/zstd/huf_compress.c  |  71 +-
     .../linux-kernel/lib/zstd/huf_decompress.c    |  71 +-
     contrib/linux-kernel/lib/zstd/mem.h           |  11 +-
     contrib/linux-kernel/lib/zstd/zstd_common.c   |  11 +-
     contrib/linux-kernel/lib/zstd/zstd_internal.h |  11 +-
     contrib/linux-kernel/lib/zstd/zstd_opt.h      |  11 +-
     contrib/linux-kernel/squashfs.diff            |  13 +-
     contrib/linux-kernel/xxhash.diff              |  20 +-
     contrib/linux-kernel/zstd.diff                | 727 ++++++++++--------
     25 files changed, 1205 insertions(+), 612 deletions(-)
     create mode 100644 contrib/linux-kernel/COPYING
    
    diff --git a/contrib/linux-kernel/COPYING b/contrib/linux-kernel/COPYING
    new file mode 100644
    index 000000000..ecbc05937
    --- /dev/null
    +++ b/contrib/linux-kernel/COPYING
    @@ -0,0 +1,339 @@
    +                    GNU GENERAL PUBLIC LICENSE
    +                       Version 2, June 1991
    +
    + Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
    + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
    + Everyone is permitted to copy and distribute verbatim copies
    + of this license document, but changing it is not allowed.
    +
    +                            Preamble
    +
    +  The licenses for most software are designed to take away your
    +freedom to share and change it.  By contrast, the GNU General Public
    +License is intended to guarantee your freedom to share and change free
    +software--to make sure the software is free for all its users.  This
    +General Public License applies to most of the Free Software
    +Foundation's software and to any other program whose authors commit to
    +using it.  (Some other Free Software Foundation software is covered by
    +the GNU Lesser General Public License instead.)  You can apply it to
    +your programs, too.
    +
    +  When we speak of free software, we are referring to freedom, not
    +price.  Our General Public Licenses are designed to make sure that you
    +have the freedom to distribute copies of free software (and charge for
    +this service if you wish), that you receive source code or can get it
    +if you want it, that you can change the software or use pieces of it
    +in new free programs; and that you know you can do these things.
    +
    +  To protect your rights, we need to make restrictions that forbid
    +anyone to deny you these rights or to ask you to surrender the rights.
    +These restrictions translate to certain responsibilities for you if you
    +distribute copies of the software, or if you modify it.
    +
    +  For example, if you distribute copies of such a program, whether
    +gratis or for a fee, you must give the recipients all the rights that
    +you have.  You must make sure that they, too, receive or can get the
    +source code.  And you must show them these terms so they know their
    +rights.
    +
    +  We protect your rights with two steps: (1) copyright the software, and
    +(2) offer you this license which gives you legal permission to copy,
    +distribute and/or modify the software.
    +
    +  Also, for each author's protection and ours, we want to make certain
    +that everyone understands that there is no warranty for this free
    +software.  If the software is modified by someone else and passed on, we
    +want its recipients to know that what they have is not the original, so
    +that any problems introduced by others will not reflect on the original
    +authors' reputations.
    +
    +  Finally, any free program is threatened constantly by software
    +patents.  We wish to avoid the danger that redistributors of a free
    +program will individually obtain patent licenses, in effect making the
    +program proprietary.  To prevent this, we have made it clear that any
    +patent must be licensed for everyone's free use or not licensed at all.
    +
    +  The precise terms and conditions for copying, distribution and
    +modification follow.
    +
    +                    GNU GENERAL PUBLIC LICENSE
    +   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    +
    +  0. This License applies to any program or other work which contains
    +a notice placed by the copyright holder saying it may be distributed
    +under the terms of this General Public License.  The "Program", below,
    +refers to any such program or work, and a "work based on the Program"
    +means either the Program or any derivative work under copyright law:
    +that is to say, a work containing the Program or a portion of it,
    +either verbatim or with modifications and/or translated into another
    +language.  (Hereinafter, translation is included without limitation in
    +the term "modification".)  Each licensee is addressed as "you".
    +
    +Activities other than copying, distribution and modification are not
    +covered by this License; they are outside its scope.  The act of
    +running the Program is not restricted, and the output from the Program
    +is covered only if its contents constitute a work based on the
    +Program (independent of having been made by running the Program).
    +Whether that is true depends on what the Program does.
    +
    +  1. You may copy and distribute verbatim copies of the Program's
    +source code as you receive it, in any medium, provided that you
    +conspicuously and appropriately publish on each copy an appropriate
    +copyright notice and disclaimer of warranty; keep intact all the
    +notices that refer to this License and to the absence of any warranty;
    +and give any other recipients of the Program a copy of this License
    +along with the Program.
    +
    +You may charge a fee for the physical act of transferring a copy, and
    +you may at your option offer warranty protection in exchange for a fee.
    +
    +  2. You may modify your copy or copies of the Program or any portion
    +of it, thus forming a work based on the Program, and copy and
    +distribute such modifications or work under the terms of Section 1
    +above, provided that you also meet all of these conditions:
    +
    +    a) You must cause the modified files to carry prominent notices
    +    stating that you changed the files and the date of any change.
    +
    +    b) You must cause any work that you distribute or publish, that in
    +    whole or in part contains or is derived from the Program or any
    +    part thereof, to be licensed as a whole at no charge to all third
    +    parties under the terms of this License.
    +
    +    c) If the modified program normally reads commands interactively
    +    when run, you must cause it, when started running for such
    +    interactive use in the most ordinary way, to print or display an
    +    announcement including an appropriate copyright notice and a
    +    notice that there is no warranty (or else, saying that you provide
    +    a warranty) and that users may redistribute the program under
    +    these conditions, and telling the user how to view a copy of this
    +    License.  (Exception: if the Program itself is interactive but
    +    does not normally print such an announcement, your work based on
    +    the Program is not required to print an announcement.)
    +
    +These requirements apply to the modified work as a whole.  If
    +identifiable sections of that work are not derived from the Program,
    +and can be reasonably considered independent and separate works in
    +themselves, then this License, and its terms, do not apply to those
    +sections when you distribute them as separate works.  But when you
    +distribute the same sections as part of a whole which is a work based
    +on the Program, the distribution of the whole must be on the terms of
    +this License, whose permissions for other licensees extend to the
    +entire whole, and thus to each and every part regardless of who wrote it.
    +
    +Thus, it is not the intent of this section to claim rights or contest
    +your rights to work written entirely by you; rather, the intent is to
    +exercise the right to control the distribution of derivative or
    +collective works based on the Program.
    +
    +In addition, mere aggregation of another work not based on the Program
    +with the Program (or with a work based on the Program) on a volume of
    +a storage or distribution medium does not bring the other work under
    +the scope of this License.
    +
    +  3. You may copy and distribute the Program (or a work based on it,
    +under Section 2) in object code or executable form under the terms of
    +Sections 1 and 2 above provided that you also do one of the following:
    +
    +    a) Accompany it with the complete corresponding machine-readable
    +    source code, which must be distributed under the terms of Sections
    +    1 and 2 above on a medium customarily used for software interchange; or,
    +
    +    b) Accompany it with a written offer, valid for at least three
    +    years, to give any third party, for a charge no more than your
    +    cost of physically performing source distribution, a complete
    +    machine-readable copy of the corresponding source code, to be
    +    distributed under the terms of Sections 1 and 2 above on a medium
    +    customarily used for software interchange; or,
    +
    +    c) Accompany it with the information you received as to the offer
    +    to distribute corresponding source code.  (This alternative is
    +    allowed only for noncommercial distribution and only if you
    +    received the program in object code or executable form with such
    +    an offer, in accord with Subsection b above.)
    +
    +The source code for a work means the preferred form of the work for
    +making modifications to it.  For an executable work, complete source
    +code means all the source code for all modules it contains, plus any
    +associated interface definition files, plus the scripts used to
    +control compilation and installation of the executable.  However, as a
    +special exception, the source code distributed need not include
    +anything that is normally distributed (in either source or binary
    +form) with the major components (compiler, kernel, and so on) of the
    +operating system on which the executable runs, unless that component
    +itself accompanies the executable.
    +
    +If distribution of executable or object code is made by offering
    +access to copy from a designated place, then offering equivalent
    +access to copy the source code from the same place counts as
    +distribution of the source code, even though third parties are not
    +compelled to copy the source along with the object code.
    +
    +  4. You may not copy, modify, sublicense, or distribute the Program
    +except as expressly provided under this License.  Any attempt
    +otherwise to copy, modify, sublicense or distribute the Program is
    +void, and will automatically terminate your rights under this License.
    +However, parties who have received copies, or rights, from you under
    +this License will not have their licenses terminated so long as such
    +parties remain in full compliance.
    +
    +  5. You are not required to accept this License, since you have not
    +signed it.  However, nothing else grants you permission to modify or
    +distribute the Program or its derivative works.  These actions are
    +prohibited by law if you do not accept this License.  Therefore, by
    +modifying or distributing the Program (or any work based on the
    +Program), you indicate your acceptance of this License to do so, and
    +all its terms and conditions for copying, distributing or modifying
    +the Program or works based on it.
    +
    +  6. Each time you redistribute the Program (or any work based on the
    +Program), the recipient automatically receives a license from the
    +original licensor to copy, distribute or modify the Program subject to
    +these terms and conditions.  You may not impose any further
    +restrictions on the recipients' exercise of the rights granted herein.
    +You are not responsible for enforcing compliance by third parties to
    +this License.
    +
    +  7. If, as a consequence of a court judgment or allegation of patent
    +infringement or for any other reason (not limited to patent issues),
    +conditions are imposed on you (whether by court order, agreement or
    +otherwise) that contradict the conditions of this License, they do not
    +excuse you from the conditions of this License.  If you cannot
    +distribute so as to satisfy simultaneously your obligations under this
    +License and any other pertinent obligations, then as a consequence you
    +may not distribute the Program at all.  For example, if a patent
    +license would not permit royalty-free redistribution of the Program by
    +all those who receive copies directly or indirectly through you, then
    +the only way you could satisfy both it and this License would be to
    +refrain entirely from distribution of the Program.
    +
    +If any portion of this section is held invalid or unenforceable under
    +any particular circumstance, the balance of the section is intended to
    +apply and the section as a whole is intended to apply in other
    +circumstances.
    +
    +It is not the purpose of this section to induce you to infringe any
    +patents or other property right claims or to contest validity of any
    +such claims; this section has the sole purpose of protecting the
    +integrity of the free software distribution system, which is
    +implemented by public license practices.  Many people have made
    +generous contributions to the wide range of software distributed
    +through that system in reliance on consistent application of that
    +system; it is up to the author/donor to decide if he or she is willing
    +to distribute software through any other system and a licensee cannot
    +impose that choice.
    +
    +This section is intended to make thoroughly clear what is believed to
    +be a consequence of the rest of this License.
    +
    +  8. If the distribution and/or use of the Program is restricted in
    +certain countries either by patents or by copyrighted interfaces, the
    +original copyright holder who places the Program under this License
    +may add an explicit geographical distribution limitation excluding
    +those countries, so that distribution is permitted only in or among
    +countries not thus excluded.  In such case, this License incorporates
    +the limitation as if written in the body of this License.
    +
    +  9. The Free Software Foundation may publish revised and/or new versions
    +of the General Public License from time to time.  Such new versions will
    +be similar in spirit to the present version, but may differ in detail to
    +address new problems or concerns.
    +
    +Each version is given a distinguishing version number.  If the Program
    +specifies a version number of this License which applies to it and "any
    +later version", you have the option of following the terms and conditions
    +either of that version or of any later version published by the Free
    +Software Foundation.  If the Program does not specify a version number of
    +this License, you may choose any version ever published by the Free Software
    +Foundation.
    +
    +  10. If you wish to incorporate parts of the Program into other free
    +programs whose distribution conditions are different, write to the author
    +to ask for permission.  For software which is copyrighted by the Free
    +Software Foundation, write to the Free Software Foundation; we sometimes
    +make exceptions for this.  Our decision will be guided by the two goals
    +of preserving the free status of all derivatives of our free software and
    +of promoting the sharing and reuse of software generally.
    +
    +                            NO WARRANTY
    +
    +  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
    +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
    +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
    +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
    +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
    +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
    +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
    +REPAIR OR CORRECTION.
    +
    +  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
    +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
    +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
    +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
    +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
    +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
    +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
    +POSSIBILITY OF SUCH DAMAGES.
    +
    +                     END OF TERMS AND CONDITIONS
    +
    +            How to Apply These Terms to Your New Programs
    +
    +  If you develop a new program, and you want it to be of the greatest
    +possible use to the public, the best way to achieve this is to make it
    +free software which everyone can redistribute and change under these terms.
    +
    +  To do so, attach the following notices to the program.  It is safest
    +to attach them to the start of each source file to most effectively
    +convey the exclusion of warranty; and each file should have at least
    +the "copyright" line and a pointer to where the full notice is found.
    +
    +    
    +    Copyright (C)   
    +
    +    This program is free software; you can redistribute it and/or modify
    +    it under the terms of the GNU General Public License as published by
    +    the Free Software Foundation; either version 2 of the License, or
    +    (at your option) any later version.
    +
    +    This program is distributed in the hope that it will be useful,
    +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    +    GNU General Public License for more details.
    +
    +    You should have received a copy of the GNU General Public License along
    +    with this program; if not, write to the Free Software Foundation, Inc.,
    +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    +
    +Also add information on how to contact you by electronic and paper mail.
    +
    +If the program is interactive, make it output a short notice like this
    +when it starts in an interactive mode:
    +
    +    Gnomovision version 69, Copyright (C) year name of author
    +    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    +    This is free software, and you are welcome to redistribute it
    +    under certain conditions; type `show c' for details.
    +
    +The hypothetical commands `show w' and `show c' should show the appropriate
    +parts of the General Public License.  Of course, the commands you use may
    +be called something other than `show w' and `show c'; they could even be
    +mouse-clicks or menu items--whatever suits your program.
    +
    +You should also get your employer (if you work as a programmer) or your
    +school, if any, to sign a "copyright disclaimer" for the program, if
    +necessary.  Here is a sample; alter the names:
    +
    +  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
    +  `Gnomovision' (which makes passes at compilers) written by James Hacker.
    +
    +  , 1 April 1989
    +  Ty Coon, President of Vice
    +
    +This General Public License does not permit incorporating your program into
    +proprietary programs.  If your program is a subroutine library, you may
    +consider it more useful to permit linking proprietary applications with the
    +library.  If this is what you want to do, use the GNU Lesser General
    +Public License instead of this License.
    \ No newline at end of file
    diff --git a/contrib/linux-kernel/btrfs.diff b/contrib/linux-kernel/btrfs.diff
    index 92a6e2057..aa3ec1d98 100644
    --- a/contrib/linux-kernel/btrfs.diff
    +++ b/contrib/linux-kernel/btrfs.diff
    @@ -193,10 +193,28 @@ index 1f157fb..b0dec90 100644
      	BTRFS_FEAT_ATTR_PTR(raid56),
     diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
     new file mode 100644
    -index 0000000..010548c
    +index 0000000..45ea326
     --- /dev/null
     +++ b/fs/btrfs/zstd.c
    -@@ -0,0 +1,415 @@
    +@@ -0,0 +1,433 @@
    ++/*
    ++ * Copyright (c) 2016-present, Facebook, Inc.
    ++ * All rights reserved.
    ++ *
    ++ * This program is free software; you can redistribute it and/or
    ++ * modify it under the terms of the GNU General Public
    ++ * License v2 as published by the Free Software Foundation.
    ++ *
    ++ * This program is distributed in the hope that it will be useful,
    ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    ++ * General Public License for more details.
    ++ *
    ++ * You should have received a copy of the GNU General Public
    ++ * License along with this program; if not, write to the
    ++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    ++ * Boston, MA 021110-1307, USA.
    ++ */
     +#include 
     +#include 
     +#include 
    diff --git a/contrib/linux-kernel/fs/btrfs/zstd.c b/contrib/linux-kernel/fs/btrfs/zstd.c
    index 706fa66ef..45ea3263c 100644
    --- a/contrib/linux-kernel/fs/btrfs/zstd.c
    +++ b/contrib/linux-kernel/fs/btrfs/zstd.c
    @@ -1,3 +1,21 @@
    +/*
    + * Copyright (c) 2016-present, Facebook, Inc.
    + * All rights reserved.
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public
    + * License v2 as published by the Free Software Foundation.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    + * General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the
    + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    + * Boston, MA 021110-1307, USA.
    + */
     #include 
     #include 
     #include 
    diff --git a/contrib/linux-kernel/fs/squashfs/zstd_wrapper.c b/contrib/linux-kernel/fs/squashfs/zstd_wrapper.c
    index 7cc93030b..8cb7c76d6 100644
    --- a/contrib/linux-kernel/fs/squashfs/zstd_wrapper.c
    +++ b/contrib/linux-kernel/fs/squashfs/zstd_wrapper.c
    @@ -1,7 +1,8 @@
     /*
      * Squashfs - a compressed read only filesystem for Linux
      *
    - * Copyright (c) 2017 Facebook
    + * Copyright (c) 2016-present, Facebook, Inc.
    + * All rights reserved.
      *
      * This program is free software; you can redistribute it and/or
      * modify it under the terms of the GNU General Public License
    diff --git a/contrib/linux-kernel/include/linux/xxhash.h b/contrib/linux-kernel/include/linux/xxhash.h
    index c77b12b86..9e1f42cb5 100644
    --- a/contrib/linux-kernel/include/linux/xxhash.h
    +++ b/contrib/linux-kernel/include/linux/xxhash.h
    @@ -27,6 +27,12 @@
      * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
      * You can contact the author at:
      * - xxHash homepage: http://cyan4973.github.io/xxHash/
      * - xxHash source repository: https://github.com/Cyan4973/xxHash
    diff --git a/contrib/linux-kernel/include/linux/zstd.h b/contrib/linux-kernel/include/linux/zstd.h
    index ee7bd8207..249575e24 100644
    --- a/contrib/linux-kernel/include/linux/zstd.h
    +++ b/contrib/linux-kernel/include/linux/zstd.h
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     #ifndef ZSTD_H
    diff --git a/contrib/linux-kernel/lib/xxhash.c b/contrib/linux-kernel/lib/xxhash.c
    index f367222c0..dc94904c6 100644
    --- a/contrib/linux-kernel/lib/xxhash.c
    +++ b/contrib/linux-kernel/lib/xxhash.c
    @@ -27,6 +27,12 @@
      * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
      * You can contact the author at:
      * - xxHash homepage: http://cyan4973.github.io/xxHash/
      * - xxHash source repository: https://github.com/Cyan4973/xxHash
    diff --git a/contrib/linux-kernel/lib/zstd/bitstream.h b/contrib/linux-kernel/lib/zstd/bitstream.h
    index 9b5d2bc82..2f6e76c97 100644
    --- a/contrib/linux-kernel/lib/zstd/bitstream.h
    +++ b/contrib/linux-kernel/lib/zstd/bitstream.h
    @@ -1,37 +1,43 @@
    -/* ******************************************************************
    -   bitstream
    -   Part of FSE library
    -   header file (to include)
    -   Copyright (C) 2013-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -   You can contact the author at :
    -   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -****************************************************************** */
    +/*
    + * bitstream
    + * Part of FSE library
    + * header file (to include)
    + * Copyright (C) 2013-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     #ifndef BITSTREAM_H_MODULE
     #define BITSTREAM_H_MODULE
     
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index 4f1e18484..a0789693e 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     
    @@ -3293,5 +3300,5 @@ EXPORT_SYMBOL(ZSTD_compressEnd);
     EXPORT_SYMBOL(ZSTD_getBlockSizeMax);
     EXPORT_SYMBOL(ZSTD_compressBlock);
     
    -MODULE_LICENSE("BSD");
    +MODULE_LICENSE("Dual BSD/GPL");
     MODULE_DESCRIPTION("Zstd Compressor");
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 378d2c521..bd76a75c3 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     
    @@ -2345,5 +2352,5 @@ EXPORT_SYMBOL(ZSTD_nextInputType);
     EXPORT_SYMBOL(ZSTD_decompressBlock);
     EXPORT_SYMBOL(ZSTD_insertBlock);
     
    -MODULE_LICENSE("BSD");
    +MODULE_LICENSE("Dual BSD/GPL");
     MODULE_DESCRIPTION("Zstd Decompressor");
    diff --git a/contrib/linux-kernel/lib/zstd/entropy_common.c b/contrib/linux-kernel/lib/zstd/entropy_common.c
    index 36ad26653..b13fb9980 100644
    --- a/contrib/linux-kernel/lib/zstd/entropy_common.c
    +++ b/contrib/linux-kernel/lib/zstd/entropy_common.c
    @@ -1,36 +1,41 @@
     /*
    -   Common functions of New Generation Entropy library
    -   Copyright (C) 2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -	You can contact the author at :
    -	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -*************************************************************************** */
    + * Common functions of New Generation Entropy library
    + * Copyright (C) 2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     
     /* *************************************
     *  Dependencies
    diff --git a/contrib/linux-kernel/lib/zstd/error_private.h b/contrib/linux-kernel/lib/zstd/error_private.h
    index 8cf148bc4..fd1f4ff1b 100644
    --- a/contrib/linux-kernel/lib/zstd/error_private.h
    +++ b/contrib/linux-kernel/lib/zstd/error_private.h
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     /* Note : this module is expected to remain private, do not expose it */
    diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h
    index 6a7895722..a04215424 100644
    --- a/contrib/linux-kernel/lib/zstd/fse.h
    +++ b/contrib/linux-kernel/lib/zstd/fse.h
    @@ -1,36 +1,42 @@
    -/* ******************************************************************
    -   FSE : Finite State Entropy codec
    -   Public Prototypes declaration
    -   Copyright (C) 2013-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -   You can contact the author at :
    -   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -****************************************************************** */
    +/*
    + * FSE : Finite State Entropy codec
    + * Public Prototypes declaration
    + * Copyright (C) 2013-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     #ifndef FSE_H
     #define FSE_H
     
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index d0b5673f3..d13f00df7 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -1,36 +1,41 @@
    -/* ******************************************************************
    -   FSE : Finite State Entropy encoder
    -   Copyright (C) 2013-2015, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -	You can contact the author at :
    -	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -****************************************************************** */
    +/*
    + * FSE : Finite State Entropy encoder
    + * Copyright (C) 2013-2015, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     
     /* **************************************************************
     *  Compiler specifics
    diff --git a/contrib/linux-kernel/lib/zstd/fse_decompress.c b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    index 6de541131..6d2c36775 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    @@ -1,36 +1,41 @@
    -/* ******************************************************************
    -   FSE : Finite State Entropy decoder
    -   Copyright (C) 2013-2015, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -	You can contact the author at :
    -	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -****************************************************************** */
    +/*
    + * FSE : Finite State Entropy decoder
    + * Copyright (C) 2013-2015, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     
     
     /* **************************************************************
    diff --git a/contrib/linux-kernel/lib/zstd/huf.h b/contrib/linux-kernel/lib/zstd/huf.h
    index f36aded00..b15767599 100644
    --- a/contrib/linux-kernel/lib/zstd/huf.h
    +++ b/contrib/linux-kernel/lib/zstd/huf.h
    @@ -1,36 +1,42 @@
    -/* ******************************************************************
    -   Huffman coder, part of New Generation Entropy library
    -   header file
    -   Copyright (C) 2013-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -   You can contact the author at :
    -   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -****************************************************************** */
    +/*
    + * Huffman coder, part of New Generation Entropy library
    + * header file
    + * Copyright (C) 2013-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     #ifndef HUF_H_298734234
     #define HUF_H_298734234
     
    diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c
    index 41b9ce008..ee03de9a5 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c
    @@ -1,36 +1,41 @@
    -/* ******************************************************************
    -   Huffman encoder, part of New Generation Entropy library
    -   Copyright (C) 2013-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -	You can contact the author at :
    -	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -****************************************************************** */
    +/*
    + * Huffman encoder, part of New Generation Entropy library
    + * Copyright (C) 2013-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     
     
     /* **************************************************************
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index 2d9b33b12..1ed682611 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -1,36 +1,41 @@
    -/* ******************************************************************
    -   Huffman decoder, part of New Generation Entropy library
    -   Copyright (C) 2013-2016, Yann Collet.
    -
    -   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -
    -   Redistribution and use in source and binary forms, with or without
    -   modification, are permitted provided that the following conditions are
    -   met:
    -
    -	   * Redistributions of source code must retain the above copyright
    -   notice, this list of conditions and the following disclaimer.
    -	   * Redistributions in binary form must reproduce the above
    -   copyright notice, this list of conditions and the following disclaimer
    -   in the documentation and/or other materials provided with the
    -   distribution.
    -
    -   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -
    -	You can contact the author at :
    -	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -****************************************************************** */
    +/*
    + * Huffman decoder, part of New Generation Entropy library
    + * Copyright (C) 2013-2016, Yann Collet.
    + *
    + * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions are
    + * met:
    + *
    + *   * Redistributions of source code must retain the above copyright
    + * notice, this list of conditions and the following disclaimer.
    + *   * Redistributions in binary form must reproduce the above
    + * copyright notice, this list of conditions and the following disclaimer
    + * in the documentation and/or other materials provided with the
    + * distribution.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
    + *
    + * You can contact the author at :
    + * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    + */
     
     /* **************************************************************
     *  Compiler specifics
    diff --git a/contrib/linux-kernel/lib/zstd/mem.h b/contrib/linux-kernel/lib/zstd/mem.h
    index 76cae04fa..e656a0e44 100644
    --- a/contrib/linux-kernel/lib/zstd/mem.h
    +++ b/contrib/linux-kernel/lib/zstd/mem.h
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     #ifndef MEM_H_MODULE
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_common.c b/contrib/linux-kernel/lib/zstd/zstd_common.c
    index 106f54055..4ff3cc83b 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_common.c
    +++ b/contrib/linux-kernel/lib/zstd/zstd_common.c
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_internal.h b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    index 5ed54196f..91365eaa8 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_internal.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     #ifndef ZSTD_CCOMMON_H_MODULE
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_opt.h b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    index 9bd5303a6..6855e3c36 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_opt.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    @@ -3,8 +3,15 @@
      * All rights reserved.
      *
      * This source code is licensed under the BSD-style license found in the
    - * LICENSE file in the root directory of this source tree. An additional grant
    - * of patent rights can be found in the PATENTS file in the same directory.
    + * LICENSE file in the root directory of https://github.com/facebook/zstd.
    + * An additional grant of patent rights can be found in the PATENTS file in the
    + * same directory.
    + *
    + * This program is free software; you can redistribute it and/or modify it under
    + * the terms of the GNU General Public License version 2 as published by the
    + * Free Software Foundation. This program is dual-licensed; you may select
    + * either version 2 of the GNU General Public License ("GPL") or BSD license
    + * ("BSD").
      */
     
     
    diff --git a/contrib/linux-kernel/squashfs.diff b/contrib/linux-kernel/squashfs.diff
    index ddf7b3578..b524819d2 100644
    --- a/contrib/linux-kernel/squashfs.diff
    +++ b/contrib/linux-kernel/squashfs.diff
    @@ -1,9 +1,3 @@
    -commit 16bb6b9fd684eadba41a36223d67805d7ea741e7
    -Author: Sean Purcell 
    -Date:   Thu Apr 27 17:17:58 2017 -0700
    -
    -    Add zstd support to squashfs
    -
     diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
     index ffb093e..1adb334 100644
     --- a/fs/squashfs/Kconfig
    @@ -90,14 +84,15 @@ index 506f4ba..24d12fd 100644
      	__le32			s_magic;
     diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c
     new file mode 100644
    -index 0000000..7cc9303
    +index 0000000..8cb7c76
     --- /dev/null
     +++ b/fs/squashfs/zstd_wrapper.c
    -@@ -0,0 +1,149 @@
    +@@ -0,0 +1,150 @@
     +/*
     + * Squashfs - a compressed read only filesystem for Linux
     + *
    -+ * Copyright (c) 2017 Facebook
    ++ * Copyright (c) 2016-present, Facebook, Inc.
    ++ * All rights reserved.
     + *
     + * This program is free software; you can redistribute it and/or
     + * modify it under the terms of the GNU General Public License
    diff --git a/contrib/linux-kernel/xxhash.diff b/contrib/linux-kernel/xxhash.diff
    index 1f1d4899e..2aac5c0c6 100644
    --- a/contrib/linux-kernel/xxhash.diff
    +++ b/contrib/linux-kernel/xxhash.diff
    @@ -1,9 +1,9 @@
     diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h
     new file mode 100644
    -index 0000000..c77b12b
    +index 0000000..9e1f42c
     --- /dev/null
     +++ b/include/linux/xxhash.h
    -@@ -0,0 +1,230 @@
    +@@ -0,0 +1,236 @@
     +/*
     + * xxHash - Extremely Fast Hash algorithm
     + * Copyright (C) 2012-2016, Yann Collet.
    @@ -33,6 +33,12 @@ index 0000000..c77b12b
     + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     + *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
     + * You can contact the author at:
     + * - xxHash homepage: http://cyan4973.github.io/xxHash/
     + * - xxHash source repository: https://github.com/Cyan4973/xxHash
    @@ -262,10 +268,10 @@ index 320ac46..e16f94a 100644
      obj-$(CONFIG_842_COMPRESS) += 842/
     diff --git a/lib/xxhash.c b/lib/xxhash.c
     new file mode 100644
    -index 0000000..f367222
    +index 0000000..dc94904
     --- /dev/null
     +++ b/lib/xxhash.c
    -@@ -0,0 +1,494 @@
    +@@ -0,0 +1,500 @@
     +/*
     + * xxHash - Extremely Fast Hash algorithm
     + * Copyright (C) 2012-2016, Yann Collet.
    @@ -295,6 +301,12 @@ index 0000000..f367222
     + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     + *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
     + * You can contact the author at:
     + * - xxHash homepage: http://cyan4973.github.io/xxHash/
     + * - xxHash source repository: https://github.com/Cyan4973/xxHash
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff
    index 7d7bf5537..0a01f5132 100644
    --- a/contrib/linux-kernel/zstd.diff
    +++ b/contrib/linux-kernel/zstd.diff
    @@ -1,16 +1,23 @@
     diff --git a/include/linux/zstd.h b/include/linux/zstd.h
     new file mode 100644
    -index 0000000..ee7bd82
    +index 0000000..249575e
     --- /dev/null
     +++ b/include/linux/zstd.h
    -@@ -0,0 +1,1150 @@
    +@@ -0,0 +1,1157 @@
     +/*
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +#ifndef ZSTD_H
    @@ -1203,44 +1210,50 @@ index 0000000..aa5eb4d
     +				huf_decompress.o decompress.o
     diff --git a/lib/zstd/bitstream.h b/lib/zstd/bitstream.h
     new file mode 100644
    -index 0000000..9b5d2bc
    +index 0000000..2f6e76c
     --- /dev/null
     +++ b/lib/zstd/bitstream.h
    -@@ -0,0 +1,376 @@
    -+/* ******************************************************************
    -+   bitstream
    -+   Part of FSE library
    -+   header file (to include)
    -+   Copyright (C) 2013-2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+   You can contact the author at :
    -+   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+****************************************************************** */
    +@@ -0,0 +1,382 @@
    ++/*
    ++ * bitstream
    ++ * Part of FSE library
    ++ * header file (to include)
    ++ * Copyright (C) 2013-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +#ifndef BITSTREAM_H_MODULE
     +#define BITSTREAM_H_MODULE
     +
    @@ -1585,17 +1598,24 @@ index 0000000..9b5d2bc
     +#endif /* BITSTREAM_H_MODULE */
     diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
     new file mode 100644
    -index 0000000..4f1e184
    +index 0000000..a078969
     --- /dev/null
     +++ b/lib/zstd/compress.c
    -@@ -0,0 +1,3297 @@
    +@@ -0,0 +1,3304 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +
    @@ -4884,21 +4904,28 @@ index 0000000..4f1e184
     +EXPORT_SYMBOL(ZSTD_getBlockSizeMax);
     +EXPORT_SYMBOL(ZSTD_compressBlock);
     +
    -+MODULE_LICENSE("BSD");
    ++MODULE_LICENSE("Dual BSD/GPL");
     +MODULE_DESCRIPTION("Zstd Compressor");
     diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
     new file mode 100644
    -index 0000000..378d2c5
    +index 0000000..bd76a75
     --- /dev/null
     +++ b/lib/zstd/decompress.c
    -@@ -0,0 +1,2349 @@
    +@@ -0,0 +1,2356 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +
    @@ -7239,47 +7266,52 @@ index 0000000..378d2c5
     +EXPORT_SYMBOL(ZSTD_decompressBlock);
     +EXPORT_SYMBOL(ZSTD_insertBlock);
     +
    -+MODULE_LICENSE("BSD");
    ++MODULE_LICENSE("Dual BSD/GPL");
     +MODULE_DESCRIPTION("Zstd Decompressor");
     diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c
     new file mode 100644
    -index 0000000..36ad266
    +index 0000000..b13fb99
     --- /dev/null
     +++ b/lib/zstd/entropy_common.c
    -@@ -0,0 +1,217 @@
    +@@ -0,0 +1,222 @@
     +/*
    -+   Common functions of New Generation Entropy library
    -+   Copyright (C) 2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+	You can contact the author at :
    -+	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -+*************************************************************************** */
    ++ * Common functions of New Generation Entropy library
    ++ * Copyright (C) 2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +
     +/* *************************************
     +*  Dependencies
    @@ -7466,17 +7498,24 @@ index 0000000..36ad266
     +}
     diff --git a/lib/zstd/error_private.h b/lib/zstd/error_private.h
     new file mode 100644
    -index 0000000..8cf148b
    +index 0000000..fd1f4ff
     --- /dev/null
     +++ b/lib/zstd/error_private.h
    -@@ -0,0 +1,44 @@
    +@@ -0,0 +1,51 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +/* Note : this module is expected to remain private, do not expose it */
    @@ -7516,43 +7555,49 @@ index 0000000..8cf148b
     +#endif /* ERROR_H_MODULE */
     diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h
     new file mode 100644
    -index 0000000..6a78957
    +index 0000000..a042154
     --- /dev/null
     +++ b/lib/zstd/fse.h
    -@@ -0,0 +1,606 @@
    -+/* ******************************************************************
    -+   FSE : Finite State Entropy codec
    -+   Public Prototypes declaration
    -+   Copyright (C) 2013-2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+   You can contact the author at :
    -+   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+****************************************************************** */
    +@@ -0,0 +1,612 @@
    ++/*
    ++ * FSE : Finite State Entropy codec
    ++ * Public Prototypes declaration
    ++ * Copyright (C) 2013-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +#ifndef FSE_H
     +#define FSE_H
     +
    @@ -8128,43 +8173,48 @@ index 0000000..6a78957
     +#endif  /* FSE_H */
     diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c
     new file mode 100644
    -index 0000000..d0b5673
    +index 0000000..d13f00d
     --- /dev/null
     +++ b/lib/zstd/fse_compress.c
    -@@ -0,0 +1,774 @@
    -+/* ******************************************************************
    -+   FSE : Finite State Entropy encoder
    -+   Copyright (C) 2013-2015, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+	You can contact the author at :
    -+	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -+****************************************************************** */
    +@@ -0,0 +1,779 @@
    ++/*
    ++ * FSE : Finite State Entropy encoder
    ++ * Copyright (C) 2013-2015, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +
     +/* **************************************************************
     +*  Compiler specifics
    @@ -8908,43 +8958,48 @@ index 0000000..d0b5673
     +#endif   /* FSE_COMMONDEFS_ONLY */
     diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c
     new file mode 100644
    -index 0000000..6de5411
    +index 0000000..6d2c367
     --- /dev/null
     +++ b/lib/zstd/fse_decompress.c
    -@@ -0,0 +1,292 @@
    -+/* ******************************************************************
    -+   FSE : Finite State Entropy decoder
    -+   Copyright (C) 2013-2015, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+	You can contact the author at :
    -+	- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -+****************************************************************** */
    +@@ -0,0 +1,297 @@
    ++/*
    ++ * FSE : Finite State Entropy decoder
    ++ * Copyright (C) 2013-2015, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +
     +
     +/* **************************************************************
    @@ -9206,43 +9261,49 @@ index 0000000..6de5411
     +#endif   /* FSE_COMMONDEFS_ONLY */
     diff --git a/lib/zstd/huf.h b/lib/zstd/huf.h
     new file mode 100644
    -index 0000000..f36aded
    +index 0000000..b157675
     --- /dev/null
     +++ b/lib/zstd/huf.h
    -@@ -0,0 +1,203 @@
    -+/* ******************************************************************
    -+   Huffman coder, part of New Generation Entropy library
    -+   header file
    -+   Copyright (C) 2013-2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+   You can contact the author at :
    -+   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+****************************************************************** */
    +@@ -0,0 +1,209 @@
    ++/*
    ++ * Huffman coder, part of New Generation Entropy library
    ++ * header file
    ++ * Copyright (C) 2013-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +#ifndef HUF_H_298734234
     +#define HUF_H_298734234
     +
    @@ -9415,43 +9476,48 @@ index 0000000..f36aded
     +#endif   /* HUF_H_298734234 */
     diff --git a/lib/zstd/huf_compress.c b/lib/zstd/huf_compress.c
     new file mode 100644
    -index 0000000..41b9ce0
    +index 0000000..ee03de9
     --- /dev/null
     +++ b/lib/zstd/huf_compress.c
    -@@ -0,0 +1,644 @@
    -+/* ******************************************************************
    -+   Huffman encoder, part of New Generation Entropy library
    -+   Copyright (C) 2013-2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+	You can contact the author at :
    -+	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -+****************************************************************** */
    +@@ -0,0 +1,649 @@
    ++/*
    ++ * Huffman encoder, part of New Generation Entropy library
    ++ * Copyright (C) 2013-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +
     +
     +/* **************************************************************
    @@ -10065,43 +10131,48 @@ index 0000000..41b9ce0
     +}
     diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c
     new file mode 100644
    -index 0000000..2d9b33b
    +index 0000000..1ed6826
     --- /dev/null
     +++ b/lib/zstd/huf_decompress.c
    -@@ -0,0 +1,835 @@
    -+/* ******************************************************************
    -+   Huffman decoder, part of New Generation Entropy library
    -+   Copyright (C) 2013-2016, Yann Collet.
    -+
    -+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    -+
    -+   Redistribution and use in source and binary forms, with or without
    -+   modification, are permitted provided that the following conditions are
    -+   met:
    -+
    -+	   * Redistributions of source code must retain the above copyright
    -+   notice, this list of conditions and the following disclaimer.
    -+	   * Redistributions in binary form must reproduce the above
    -+   copyright notice, this list of conditions and the following disclaimer
    -+   in the documentation and/or other materials provided with the
    -+   distribution.
    -+
    -+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    -+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    -+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    -+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    -+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    -+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    -+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    -+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    -+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    -+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    -+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    -+
    -+	You can contact the author at :
    -+	- FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
    -+	- Public forum : https://groups.google.com/forum/#!forum/lz4c
    -+****************************************************************** */
    +@@ -0,0 +1,840 @@
    ++/*
    ++ * Huffman decoder, part of New Generation Entropy library
    ++ * Copyright (C) 2013-2016, Yann Collet.
    ++ *
    ++ * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
    ++ *
    ++ * Redistribution and use in source and binary forms, with or without
    ++ * modification, are permitted provided that the following conditions are
    ++ * met:
    ++ *
    ++ *   * Redistributions of source code must retain the above copyright
    ++ * notice, this list of conditions and the following disclaimer.
    ++ *   * Redistributions in binary form must reproduce the above
    ++ * copyright notice, this list of conditions and the following disclaimer
    ++ * in the documentation and/or other materials provided with the
    ++ * distribution.
    ++ *
    ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
    ++ *
    ++ * You can contact the author at :
    ++ * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
    ++ */
     +
     +/* **************************************************************
     +*  Compiler specifics
    @@ -10906,17 +10977,24 @@ index 0000000..2d9b33b
     +}
     diff --git a/lib/zstd/mem.h b/lib/zstd/mem.h
     new file mode 100644
    -index 0000000..76cae04
    +index 0000000..e656a0e
     --- /dev/null
     +++ b/lib/zstd/mem.h
    -@@ -0,0 +1,209 @@
    +@@ -0,0 +1,216 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +#ifndef MEM_H_MODULE
    @@ -11121,17 +11199,24 @@ index 0000000..76cae04
     +#endif /* MEM_H_MODULE */
     diff --git a/lib/zstd/zstd_common.c b/lib/zstd/zstd_common.c
     new file mode 100644
    -index 0000000..106f540
    +index 0000000..4ff3cc8
     --- /dev/null
     +++ b/lib/zstd/zstd_common.c
    -@@ -0,0 +1,69 @@
    +@@ -0,0 +1,76 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +
    @@ -11196,17 +11281,24 @@ index 0000000..106f540
     +}
     diff --git a/lib/zstd/zstd_internal.h b/lib/zstd/zstd_internal.h
     new file mode 100644
    -index 0000000..5ed5419
    +index 0000000..91365ea
     --- /dev/null
     +++ b/lib/zstd/zstd_internal.h
    -@@ -0,0 +1,261 @@
    +@@ -0,0 +1,268 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +#ifndef ZSTD_CCOMMON_H_MODULE
    @@ -11463,17 +11555,24 @@ index 0000000..5ed5419
     +#endif   /* ZSTD_CCOMMON_H_MODULE */
     diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h
     new file mode 100644
    -index 0000000..9bd5303
    +index 0000000..6855e3c
     --- /dev/null
     +++ b/lib/zstd/zstd_opt.h
    -@@ -0,0 +1,921 @@
    +@@ -0,0 +1,928 @@
     +/**
     + * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
     + * All rights reserved.
     + *
     + * This source code is licensed under the BSD-style license found in the
    -+ * LICENSE file in the root directory of this source tree. An additional grant
    -+ * of patent rights can be found in the PATENTS file in the same directory.
    ++ * LICENSE file in the root directory of https://github.com/facebook/zstd.
    ++ * An additional grant of patent rights can be found in the PATENTS file in the
    ++ * same directory.
    ++ *
    ++ * This program is free software; you can redistribute it and/or modify it under
    ++ * the terms of the GNU General Public License version 2 as published by the
    ++ * Free Software Foundation. This program is dual-licensed; you may select
    ++ * either version 2 of the GNU General Public License ("GPL") or BSD license
    ++ * ("BSD").
     + */
     +
     +
    
    From 581e5fbe83819f14d18513157868c5612107bec0 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 17 May 2017 12:27:58 -0700
    Subject: [PATCH 070/400] Add clang-format config
    
    ---
     contrib/linux-kernel/lib/zstd/.clang-format | 11 +++++++++++
     1 file changed, 11 insertions(+)
     create mode 100644 contrib/linux-kernel/lib/zstd/.clang-format
    
    diff --git a/contrib/linux-kernel/lib/zstd/.clang-format b/contrib/linux-kernel/lib/zstd/.clang-format
    new file mode 100644
    index 000000000..0c6cf3ba7
    --- /dev/null
    +++ b/contrib/linux-kernel/lib/zstd/.clang-format
    @@ -0,0 +1,11 @@
    +BasedOnStyle: LLVM
    +IndentWidth: 8
    +UseTab: Always
    +BreakBeforeBraces: Linux
    +AllowShortIfStatementsOnASingleLine: false
    +IndentCaseLabels: false
    +
    +ColumnLimit: 160
    +AlignEscapedNewlinesLeft: true
    +ReflowComments: true
    +AllowShortCaseLabelsOnASingleLine: true
    
    From 588579f3a16aaf4b86be28a16d80ef21e127b75b Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 17 May 2017 14:39:57 -0700
    Subject: [PATCH 071/400] [linux-kernel] Rename MEM_* functions to ZSTD_*
    
    ---
     contrib/linux-kernel/kernelize.sh             |  50 +++++-
     contrib/linux-kernel/lib/zstd/bitstream.h     |  70 ++++-----
     contrib/linux-kernel/lib/zstd/compress.c      | 142 +++++++++---------
     contrib/linux-kernel/lib/zstd/decompress.c    |  88 +++++------
     .../linux-kernel/lib/zstd/entropy_common.c    |   8 +-
     contrib/linux-kernel/lib/zstd/fse.h           |  22 +--
     contrib/linux-kernel/lib/zstd/fse_compress.c  |  10 +-
     contrib/linux-kernel/lib/zstd/huf_compress.c  |   6 +-
     .../linux-kernel/lib/zstd/huf_decompress.c    |  26 ++--
     contrib/linux-kernel/lib/zstd/mem.h           | 102 ++++++-------
     contrib/linux-kernel/lib/zstd/zstd_internal.h |   6 +-
     contrib/linux-kernel/lib/zstd/zstd_opt.h      |  14 +-
     12 files changed, 293 insertions(+), 251 deletions(-)
    
    diff --git a/contrib/linux-kernel/kernelize.sh b/contrib/linux-kernel/kernelize.sh
    index ce24f92f6..232fda808 100755
    --- a/contrib/linux-kernel/kernelize.sh
    +++ b/contrib/linux-kernel/kernelize.sh
    @@ -2,6 +2,8 @@
     set -e
     
     # Constants
    +SED_COMMANDS="commands.tmp"
    +CLANG_FORMAT="clang-format-3.9"
     INCLUDE='include/linux/'
     LIB='lib/zstd/'
     SPACES='    '
    @@ -20,6 +22,14 @@ function prompt() {
     done
     }
     
    +function check_not_present() {
    +  grep "$1" $INCLUDE*.h ${LIB}*.{h,c} && exit 1 || true
    +}
    +
    +function check_not_present_in_file() {
    +  grep "$1" "$2" && exit 1 || true
    +}
    +
     echo "Files: " $INCLUDE*.h $LIB*.{h,c}
     
     prompt "Do you wish to replace 4 spaces with a tab?"
    @@ -49,8 +59,44 @@ then
       sed -i '' "s/$TAB{   /$TAB{$TAB/g" $INCLUDE*.h $LIB*.{h,c}
     fi
     
    -prompt "Do you wish to replace 'current' with 'curr'?"
    +rm -f $SED_COMMANDS
    +cat > $SED_COMMANDS <= 1 */
     
     
    @@ -151,7 +151,7 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
     /*-**************************************************************
     *  Internal functions
     ****************************************************************/
    -MEM_STATIC unsigned BIT_highbit32 (register U32 val)
    +ZSTD_STATIC unsigned BIT_highbit32 (register U32 val)
     {
     	return 31 - __builtin_clz(val);
     }
    @@ -167,7 +167,7 @@ static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x
      *  `dstCapacity` must be > sizeof(void*)
      *  @return : 0 if success,
     			  otherwise an error code (can be tested using ERR_isError() ) */
    -MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
    +ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
     {
     	bitC->bitContainer = 0;
     	bitC->bitPos = 0;
    @@ -181,7 +181,7 @@ MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t ds
     /*! BIT_addBits() :
     	can add up to 26 bits into `bitC`.
     	Does not check for register overflow ! */
    -MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    +ZSTD_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
     {
     	bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
     	bitC->bitPos += nbBits;
    @@ -189,7 +189,7 @@ MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
     
     /*! BIT_addBitsFast() :
      *  works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
    -MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    +ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
     {
     	bitC->bitContainer |= value << bitC->bitPos;
     	bitC->bitPos += nbBits;
    @@ -197,10 +197,10 @@ MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBi
     
     /*! BIT_flushBitsFast() :
      *  unsafe version; does not check buffer overflow */
    -MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
    +ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
     {
     	size_t const nbBytes = bitC->bitPos >> 3;
    -	MEM_writeLEST(bitC->ptr, bitC->bitContainer);
    +	ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
     	bitC->ptr += nbBytes;
     	bitC->bitPos &= 7;
     	bitC->bitContainer >>= nbBytes*8;   /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
    @@ -209,10 +209,10 @@ MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
     /*! BIT_flushBits() :
      *  safe version; check for buffer overflow, and prevents it.
      *  note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
    -MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
    +ZSTD_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
     {
     	size_t const nbBytes = bitC->bitPos >> 3;
    -	MEM_writeLEST(bitC->ptr, bitC->bitContainer);
    +	ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
     	bitC->ptr += nbBytes;
     	if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
     	bitC->bitPos &= 7;
    @@ -222,7 +222,7 @@ MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
     /*! BIT_closeCStream() :
      *  @return : size of CStream, in bytes,
     			  or 0 if it could not fit into dstBuffer */
    -MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
    +ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
     {
     	BIT_addBitsFast(bitC, 1, 1);   /* endMark */
     	BIT_flushBits(bitC);
    @@ -242,14 +242,14 @@ MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
     *   `srcSize` must be the *exact* size of the bitStream, in bytes.
     *   @return : size of stream (== srcSize) or an errorCode if a problem is detected
     */
    -MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
    +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
     {
     	if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
     
     	if (srcSize >=  sizeof(bitD->bitContainer)) {  /* normal case */
     		bitD->start = (const char*)srcBuffer;
     		bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
    -		bitD->bitContainer = MEM_readLEST(bitD->ptr);
    +		bitD->bitContainer = ZSTD_readLEST(bitD->ptr);
     		{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
     		  bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */
     		  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
    @@ -276,17 +276,17 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
     	return srcSize;
     }
     
    -MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
    +ZSTD_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
     {
     	return bitContainer >> start;
     }
     
    -MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
    +ZSTD_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
     {
     	return (bitContainer >> start) & BIT_mask[nbBits];
     }
     
    -MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
    +ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
     {
     	return bitContainer & BIT_mask[nbBits];
     }
    @@ -298,7 +298,7 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
      *  On 64-bits, maxNbBits==56.
      *  @return : value extracted
      */
    - MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
    + ZSTD_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
     {
     	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
     	return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
    @@ -306,13 +306,13 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
     
     /*! BIT_lookBitsFast() :
     *   unsafe version; only works only if nbBits >= 1 */
    -MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
     {
     	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
     	return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
     }
     
    -MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
     {
     	bitD->bitsConsumed += nbBits;
     }
    @@ -322,7 +322,7 @@ MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
      *  Pay attention to not read more than nbBits contained into local register.
      *  @return : extracted value.
      */
    -MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
     {
     	size_t const value = BIT_lookBits(bitD, nbBits);
     	BIT_skipBits(bitD, nbBits);
    @@ -331,7 +331,7 @@ MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
     
     /*! BIT_readBitsFast() :
     *   unsafe version; only works only if nbBits >= 1 */
    -MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
     {
     	size_t const value = BIT_lookBitsFast(bitD, nbBits);
     	BIT_skipBits(bitD, nbBits);
    @@ -343,7 +343,7 @@ MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
     *   This function is safe, it guarantees it will not read beyond src buffer.
     *   @return : status of `BIT_DStream_t` internal register.
     			  if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
    -MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
    +ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     {
     	if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
     		return BIT_DStream_overflow;
    @@ -351,7 +351,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     	if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
     		bitD->ptr -= bitD->bitsConsumed >> 3;
     		bitD->bitsConsumed &= 7;
    -		bitD->bitContainer = MEM_readLEST(bitD->ptr);
    +		bitD->bitContainer = ZSTD_readLEST(bitD->ptr);
     		return BIT_DStream_unfinished;
     	}
     	if (bitD->ptr == bitD->start) {
    @@ -366,7 +366,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     		}
     		bitD->ptr -= nbBytes;
     		bitD->bitsConsumed -= nbBytes*8;
    -		bitD->bitContainer = MEM_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD) */
    +		bitD->bitContainer = ZSTD_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD) */
     		return result;
     	}
     }
    @@ -374,7 +374,7 @@ MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     /*! BIT_endOfDStream() :
     *   @return Tells if DStream has exactly reached its end (all bits consumed).
     */
    -MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
    +ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
     {
     	return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
     }
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index a0789693e..daccddf1c 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -411,7 +411,7 @@ size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, siz
     {
     	if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
     	memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
    -	MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
    +	ZSTD_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
     	return ZSTD_blockHeaderSize+srcSize;
     }
     
    @@ -429,11 +429,11 @@ static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void
     			ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
     			break;
     		case 2: /* 2 - 2 - 12 */
    -			MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
    +			ZSTD_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
     			break;
     		default:   /*note : should not be necessary : flSize is within {1,2,3} */
     		case 3: /* 2 - 2 - 20 */
    -			MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
    +			ZSTD_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
     			break;
     	}
     
    @@ -454,11 +454,11 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons
     			ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
     			break;
     		case 2: /* 2 - 2 - 12 */
    -			MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
    +			ZSTD_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
     			break;
     		default:   /*note : should not be necessary : flSize is necessarily within {1,2,3} */
     		case 3: /* 2 - 2 - 20 */
    -			MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
    +			ZSTD_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
     			break;
     	}
     
    @@ -511,18 +511,18 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
     	{
     	case 3: /* 2 - 2 - 10 - 10 */
     		{	U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
    -			MEM_writeLE24(ostart, lhc);
    +			ZSTD_writeLE24(ostart, lhc);
     			break;
     		}
     	case 4: /* 2 - 2 - 14 - 14 */
     		{	U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
    -			MEM_writeLE32(ostart, lhc);
    +			ZSTD_writeLE32(ostart, lhc);
     			break;
     		}
     	default:   /* should not be necessary, lhSize is only {3,4,5} */
     	case 5: /* 2 - 2 - 18 - 18 */
     		{	U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
    -			MEM_writeLE32(ostart, lhc);
    +			ZSTD_writeLE32(ostart, lhc);
     			ostart[4] = (BYTE)(cLitSize >> 10);
     			break;
     		}
    @@ -572,7 +572,7 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
     		mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
     }
     
    -MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
    +ZSTD_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     							  void* dst, size_t dstCapacity,
     							  size_t srcSize)
     {
    @@ -607,7 +607,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     	if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
     	if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
     	else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
    -	else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
    +	else op[0]=0xFF, ZSTD_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
     	if (nbSeq==0) goto _check_compressibility;
     
     	/* seqHead : flags for FSE encoding type */
    @@ -707,9 +707,9 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     		FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
     		FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
     		BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
    -		if (MEM_32bits()) BIT_flushBits(&blockStream);
    +		if (ZSTD_32bits()) BIT_flushBits(&blockStream);
     		BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
    -		if (MEM_32bits()) BIT_flushBits(&blockStream);
    +		if (ZSTD_32bits()) BIT_flushBits(&blockStream);
     		if (longOffsets) {
     			U32 const ofBits = ofCodeTable[nbSeq-1];
     			int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
    @@ -735,14 +735,14 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     																				/* (7)*/  /* (7)*/
     				FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */
     				FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */
    -				if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
    +				if (ZSTD_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
     				FSE_encodeSymbol(&blockStream, &stateLitLength, llCode);        /* 16 */  /* 33 */
    -				if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
    +				if (ZSTD_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
     					BIT_flushBits(&blockStream);                                /* (7)*/
     				BIT_addBits(&blockStream, sequences[n].litLength, llBits);
    -				if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
    +				if (ZSTD_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
     				BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
    -				if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
    +				if (ZSTD_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
     				if (longOffsets) {
     					int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
     					if (extraBits) {
    @@ -786,7 +786,7 @@ _check_compressibility:
     	`offsetCode` : distance to match, or 0 == repCode.
     	`matchCode` : matchLength - MINMATCH
     */
    -MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
    +ZSTD_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
     {
     	/* copy Literals */
     	ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
    @@ -812,14 +812,14 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
     ***************************************/
     static unsigned ZSTD_NbCommonBytes (register size_t val)
     {
    -	if (MEM_isLittleEndian()) {
    -		if (MEM_64bits()) {
    +	if (ZSTD_isLittleEndian()) {
    +		if (ZSTD_64bits()) {
     			return (__builtin_ctzll((U64)val) >> 3);
     		} else { /* 32 bits */
     			return (__builtin_ctz((U32)val) >> 3);
     		}
     	} else {  /* Big Endian CPU */
    -		if (MEM_64bits()) {
    +		if (ZSTD_64bits()) {
     			return (__builtin_clzll(val) >> 3);
     		} else { /* 32 bits */
     			return (__builtin_clz((U32)val) >> 3);
    @@ -833,13 +833,13 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const
     	const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
     
     	while (pIn < pInLoopLimit) {
    -		size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
    +		size_t const diff = ZSTD_readST(pMatch) ^ ZSTD_readST(pIn);
     		if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
     		pIn += ZSTD_NbCommonBytes(diff);
     		return (size_t)(pIn - pStart);
     	}
    -	if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
    -	if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
    +	if (ZSTD_64bits()) if ((pIn<(pInLimit-3)) && (ZSTD_read32(pMatch) == ZSTD_read32(pIn))) { pIn+=4; pMatch+=4; }
    +	if ((pIn<(pInLimit-1)) && (ZSTD_read16(pMatch) == ZSTD_read16(pIn))) { pIn+=2; pMatch+=2; }
     	if ((pIn> (32-h) ; }
    -MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); }   /* only in zstd_opt.h */
    +ZSTD_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(ZSTD_readLE32(ptr), h); }   /* only in zstd_opt.h */
     
     static const U32 prime4bytes = 2654435761U;
     static U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
    -static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
    +static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(ZSTD_read32(ptr), h); }
     
     static const U64 prime5bytes = 889523592379ULL;
     static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
    +static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(ZSTD_readLE64(p), h); }
     
     static const U64 prime6bytes = 227718039650203ULL;
     static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
    +static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(ZSTD_readLE64(p), h); }
     
     static const U64 prime7bytes = 58295818150454627ULL;
     static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
    +static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(ZSTD_readLE64(p), h); }
     
     static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
     static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
    +static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(ZSTD_readLE64(p), h); }
     
     static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
     {
    @@ -953,13 +953,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     		const BYTE* match = base + matchIndex;
     		hashTable[h] = curr;   /* update hash table */
     
    -		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
    +		if ((offset_1 > 0) & (ZSTD_read32(ip+1-offset_1) == ZSTD_read32(ip+1))) {
     			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
     			ip++;
     			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
     		} else {
     			U32 offset;
    -			if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
    +			if ( (matchIndex <= lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip)) ) {
     				ip += ((ip-anchor) >> g_searchStrength) + 1;
     				continue;
     			}
    @@ -983,7 +983,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     			/* check immediate repcode */
     			while ( (ip <= ilimit)
     				 && ( (offset_2>0)
    -				 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    +				 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
     				/* store sequence */
     				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
     				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; }  /* swap offset_2 <=> offset_1 */
    @@ -1060,14 +1060,14 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     		hashTable[h] = curr;   /* update hash table */
     
     		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    -		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    +		   && (ZSTD_read32(repMatch) == ZSTD_read32(ip+1)) ) {
     			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
     			mLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
     			ip++;
     			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
     		} else {
     			if ( (matchIndex < lowestIndex) ||
    -				 (MEM_read32(match) != MEM_read32(ip)) ) {
    +				 (ZSTD_read32(match) != ZSTD_read32(ip)) ) {
     				ip += ((ip-anchor) >> g_searchStrength) + 1;
     				continue;
     			}
    @@ -1096,7 +1096,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     				U32 const repIndex2 = curr2 - offset_2;
     				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    -				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    +				   && (ZSTD_read32(repMatch2) == ZSTD_read32(ip)) ) {
     					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
     					size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    @@ -1201,22 +1201,22 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     		const BYTE* match = base + matchIndexS;
     		hashLong[h2] = hashSmall[h] = curr;   /* update hash tables */
     
    -		if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= curr */
    +		if ((offset_1 > 0) & (ZSTD_read32(ip+1-offset_1) == ZSTD_read32(ip+1))) { /* note : by construction, offset_1 <= curr */
     			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
     			ip++;
     			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
     		} else {
     			U32 offset;
    -			if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
    +			if ( (matchIndexL > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip)) ) {
     				mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
     				offset = (U32)(ip-matchLong);
     				while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
    -			} else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
    +			} else if ( (matchIndexS > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip)) ) {
     				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
     				U32 const matchIndex3 = hashLong[h3];
     				const BYTE* match3 = base + matchIndex3;
     				hashLong[h3] = curr + 1;
    -				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
    +				if ( (matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip+1)) ) {
     					mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
     					ip++;
     					offset = (U32)(ip-match3);
    @@ -1251,7 +1251,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     			/* check immediate repcode */
     			while ( (ip <= ilimit)
     				 && ( (offset_2>0)
    -				 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    +				 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
     				/* store sequence */
     				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
     				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
    @@ -1336,13 +1336,13 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     		hashSmall[hSmall] = hashLong[hLong] = curr;   /* update hash table */
     
     		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    -		   && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
    +		   && (ZSTD_read32(repMatch) == ZSTD_read32(ip+1)) ) {
     			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
     			mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
     			ip++;
     			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
     		} else {
    -			if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
    +			if ((matchLongIndex > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip))) {
     				const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
     				const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
     				U32 offset;
    @@ -1353,14 +1353,14 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     				offset_1 = offset;
     				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
     
    -			} else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
    +			} else if ((matchIndex > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip))) {
     				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
     				U32 const matchIndex3 = hashLong[h3];
     				const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
     				const BYTE* match3 = match3Base + matchIndex3;
     				U32 offset;
     				hashLong[h3] = curr + 1;
    -				if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
    +				if ( (matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip+1)) ) {
     					const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
     					const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
     					mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
    @@ -1399,7 +1399,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     				U32 const repIndex2 = curr2 - offset_2;
     				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
     				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    -				   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
    +				   && (ZSTD_read32(repMatch2) == ZSTD_read32(ip)) ) {
     					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
     					size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
     					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    @@ -1748,7 +1748,7 @@ size_t ZSTD_HcFindBestMatch_generic (
     				currMl = ZSTD_count(ip, match, iLimit);
     		} else {
     			match = dictBase + matchIndex;
    -			if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    +			if (ZSTD_read32(match) == ZSTD_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
     				currMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
     		}
     
    @@ -1837,7 +1837,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     		const BYTE* start=ip+1;
     
     		/* check repCode */
    -		if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
    +		if ((offset_1>0) & (ZSTD_read32(ip+1) == ZSTD_read32(ip+1 - offset_1))) {
     			/* repcode : we take it */
     			matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
     			if (depth==0) goto _storeSequence;
    @@ -1859,7 +1859,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     		if (depth>=1)
     		while (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
    +			if ((offset) && ((offset_1>0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
     				size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
     				int const gain2 = (int)(mlRep * 3);
     				int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
    @@ -1878,7 +1878,7 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     			/* let's find an even better one */
     			if ((depth==2) && (ip0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
    +				if ((offset) && ((offset_1>0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
     					size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
     					int const gain2 = (int)(ml2 * 4);
     					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
    @@ -1913,7 +1913,7 @@ _storeSequence:
     		/* check immediate repcode */
     		while ( (ip <= ilimit)
     			 && ((offset_2>0)
    -			 & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
    +			 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
     			/* store sequence */
     			matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
     			offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
    @@ -2001,7 +2001,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     			const BYTE* const repMatch = repBase + repIndex;
     			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    -			if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
    +			if (ZSTD_read32(ip+1) == ZSTD_read32(repMatch)) {
     				/* repcode detected we should take it */
     				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     				matchLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    @@ -2031,7 +2031,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     				const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     				const BYTE* const repMatch = repBase + repIndex;
     				if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -				if (MEM_read32(ip) == MEM_read32(repMatch)) {
    +				if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
     					/* repcode detected */
     					const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     					size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    @@ -2061,7 +2061,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     					const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     					const BYTE* const repMatch = repBase + repIndex;
     					if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -					if (MEM_read32(ip) == MEM_read32(repMatch)) {
    +					if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
     						/* repcode detected */
     						const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     						size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    @@ -2105,7 +2105,7 @@ _storeSequence:
     			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
     			const BYTE* const repMatch = repBase + repIndex;
     			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -			if (MEM_read32(ip) == MEM_read32(repMatch)) {
    +			if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
     				/* repcode detected we should take it */
     				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     				matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    @@ -2280,12 +2280,12 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     		if (cSize == 0) {  /* block is not compressible */
     			U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
     			if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
    -			MEM_writeLE32(op, cBlockHeader24);   /* no pb, 4th byte will be overwritten */
    +			ZSTD_writeLE32(op, cBlockHeader24);   /* no pb, 4th byte will be overwritten */
     			memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
     			cSize = ZSTD_blockHeaderSize+blockSize;
     		} else {
     			U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
    -			MEM_writeLE24(op, cBlockHeader24);
    +			ZSTD_writeLE24(op, cBlockHeader24);
     			cSize += ZSTD_blockHeaderSize;
     		}
     
    @@ -2316,7 +2316,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
     
     	if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
     
    -	MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
    +	ZSTD_writeLE32(dst, ZSTD_MAGICNUMBER);
     	op[4] = frameHeaderDecriptionByte; pos=5;
     	if (!singleSegment) op[pos++] = windowLogByte;
     	switch(dictIDSizeCode)
    @@ -2324,16 +2324,16 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
     		default:   /* impossible */
     		case 0 : break;
     		case 1 : op[pos] = (BYTE)(dictID); pos++; break;
    -		case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
    -		case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
    +		case 2 : ZSTD_writeLE16(op+pos, (U16)dictID); pos+=2; break;
    +		case 3 : ZSTD_writeLE32(op+pos, dictID); pos+=4; break;
     	}
     	switch(fcsCode)
     	{
     		default:   /* impossible */
     		case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
    -		case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
    -		case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
    -		case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
    +		case 1 : ZSTD_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
    +		case 2 : ZSTD_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
    +		case 3 : ZSTD_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
     	}
     	return pos;
     }
    @@ -2493,7 +2493,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     	BYTE scratchBuffer[1<dictID = cctx->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
    +	cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 :  ZSTD_readLE32(dictPtr);
     	dictPtr += 4;
     
     	{	size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
    @@ -2533,9 +2533,9 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     	}
     
     	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    -	cctx->rep[0] = MEM_readLE32(dictPtr+0);
    -	cctx->rep[1] = MEM_readLE32(dictPtr+4);
    -	cctx->rep[2] = MEM_readLE32(dictPtr+8);
    +	cctx->rep[0] = ZSTD_readLE32(dictPtr+0);
    +	cctx->rep[1] = ZSTD_readLE32(dictPtr+4);
    +	cctx->rep[2] = ZSTD_readLE32(dictPtr+8);
     	dictPtr += 12;
     
     	{	size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
    @@ -2566,7 +2566,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict,
     	if ((dict==NULL) || (dictSize<=8)) return 0;
     
     	/* dict as pure content */
    -	if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
    +	if ((ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
     		return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
     
     	/* dict as zstd dictionary */
    @@ -2634,7 +2634,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
     		/* write one last empty block, make it the "last" block */
     		U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
     		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    -		MEM_writeLE32(op, cBlockHeader24);
    +		ZSTD_writeLE32(op, cBlockHeader24);
     		op += ZSTD_blockHeaderSize;
     		dstCapacity -= ZSTD_blockHeaderSize;
     	}
    @@ -2642,7 +2642,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
     	if (cctx->params.fParams.checksumFlag) {
     		U32 const checksum = (U32) xxh64_digest(&cctx->xxhState);
     		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    -		MEM_writeLE32(op, checksum);
    +		ZSTD_writeLE32(op, checksum);
     		op += 4;
     	}
     
    @@ -2958,7 +2958,7 @@ ZSTD_CStream* ZSTD_initCStream_usingCDict(const ZSTD_CDict* cdict, unsigned long
     
     typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
     
    -MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +ZSTD_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
     	size_t const length = MIN(dstCapacity, srcSize);
     	memcpy(dst, src, length);
    @@ -3242,7 +3242,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
     	if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL;   /* 0 == default; no negative compressionLevel yet */
     	if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
     	cp = ZSTD_defaultCParameters[tableID][compressionLevel];
    -	if (MEM_32bits()) {   /* auto-correction, for 32-bits mode */
    +	if (ZSTD_32bits()) {   /* auto-correction, for 32-bits mode */
     		if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
     		if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
     		if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index bd76a75c3..d3cc2e92d 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -115,7 +115,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
     	dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
     	dctx->litEntropy = dctx->fseEntropy = 0;
     	dctx->dictID = 0;
    -	MEM_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
    +	ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
     	memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue));  /* initial repcodes */
     	dctx->LLTptr = dctx->entropy.LLTable;
     	dctx->MLTptr = dctx->entropy.MLTable;
    @@ -171,7 +171,7 @@ static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
     unsigned ZSTD_isFrame(const void* buffer, size_t size)
     {
     	if (size < 4) return 0;
    -	{	U32 const magic = MEM_readLE32(buffer);
    +	{	U32 const magic = ZSTD_readLE32(buffer);
     		if (magic == ZSTD_MAGICNUMBER) return 1;
     		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
     	}
    @@ -205,11 +205,11 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
     	const BYTE* ip = (const BYTE*)src;
     
     	if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
    -	if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
    -		if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    +	if (ZSTD_readLE32(src) != ZSTD_MAGICNUMBER) {
    +		if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
     			if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
     			memset(fparamsPtr, 0, sizeof(*fparamsPtr));
    -			fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
    +			fparamsPtr->frameContentSize = ZSTD_readLE32((const char *)src + 4);
     			fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
     			return 0;
     		}
    @@ -244,16 +244,16 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
     			default:   /* impossible */
     			case 0 : break;
     			case 1 : dictID = ip[pos]; pos++; break;
    -			case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
    -			case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
    +			case 2 : dictID = ZSTD_readLE16(ip+pos); pos+=2; break;
    +			case 3 : dictID = ZSTD_readLE32(ip+pos); pos+=4; break;
     		}
     		switch(fcsID)
     		{
     			default:   /* impossible */
     			case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
    -			case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
    -			case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
    -			case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
    +			case 1 : frameContentSize = ZSTD_readLE16(ip+pos)+256; break;
    +			case 2 : frameContentSize = ZSTD_readLE32(ip+pos); break;
    +			case 3 : frameContentSize = ZSTD_readLE64(ip+pos); break;
     		}
     		if (!windowSize) windowSize = (U32)frameContentSize;
     		if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
    @@ -296,13 +296,13 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
     	{
     		unsigned long long totalDstSize = 0;
     		while (srcSize >= ZSTD_frameHeaderSize_prefix) {
    -			const U32 magicNumber = MEM_readLE32(src);
    +			const U32 magicNumber = ZSTD_readLE32(src);
     
     			if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
     				size_t skippableSize;
     				if (srcSize < ZSTD_skippableHeaderSize)
     					return ERROR(srcSize_wrong);
    -				skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    +				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) +
     								ZSTD_skippableHeaderSize;
     				if (srcSize < skippableSize) {
     					return ZSTD_CONTENTSIZE_ERROR;
    @@ -366,7 +366,7 @@ typedef struct
     size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
     {
     	if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    -	{	U32 const cBlockHeader = MEM_readLE24(src);
    +	{	U32 const cBlockHeader = ZSTD_readLE24(src);
     		U32 const cSize = cBlockHeader >> 3;
     		bpPtr->lastBlock = cBlockHeader & 1;
     		bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
    @@ -414,7 +414,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     			{	size_t lhSize, litSize, litCSize;
     				U32 singleStream=0;
     				U32 const lhlCode = (istart[0] >> 2) & 3;
    -				U32 const lhc = MEM_readLE32(istart);
    +				U32 const lhc = ZSTD_readLE32(istart);
     				switch(lhlCode)
     				{
     				case 0: case 1: default:   /* note : default is impossible, since lhlCode into [0..3] */
    @@ -468,11 +468,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     					break;
     				case 1:
     					lhSize = 2;
    -					litSize = MEM_readLE16(istart) >> 4;
    +					litSize = ZSTD_readLE16(istart) >> 4;
     					break;
     				case 3:
     					lhSize = 3;
    -					litSize = MEM_readLE24(istart) >> 4;
    +					litSize = ZSTD_readLE24(istart) >> 4;
     					break;
     				}
     
    @@ -501,11 +501,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
     					break;
     				case 1:
     					lhSize = 2;
    -					litSize = MEM_readLE16(istart) >> 4;
    +					litSize = ZSTD_readLE16(istart) >> 4;
     					break;
     				case 3:
     					lhSize = 3;
    -					litSize = MEM_readLE24(istart) >> 4;
    +					litSize = ZSTD_readLE24(istart) >> 4;
     					if (srcSize<4) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
     					break;
     				}
    @@ -752,7 +752,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
     		if (nbSeq > 0x7F) {
     			if (nbSeq == 0xFF) {
     				if (ip+2 > iend) return ERROR(srcSize_wrong);
    -				nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
    +				nbSeq = ZSTD_readLE16(ip) + LONGNBSEQ, ip+=2;
     			} else {
     				if (ip >= iend) return ERROR(srcSize_wrong);
     				nbSeq = ((nbSeq-0x80)<<8) + *ip++;
    @@ -897,7 +897,7 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
     			offset = 0;
     		else {
     			offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    -			if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
    +			if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);
     		}
     
     		if (ofCode <= 1) {
    @@ -920,16 +920,16 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
     	}
     
     	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    -	if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    +	if (ZSTD_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
     
     	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    -	if (MEM_32bits() ||
    +	if (ZSTD_32bits() ||
     	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
     
     	/* ANS state update */
     	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
     	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    -	if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    +	if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
     	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
     
     	return seq;
    @@ -1112,11 +1112,11 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     			if (longOffsets) {
     				int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
     				offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
    -				if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
    +				if (ZSTD_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
     				if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
     			} else {
     				offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    -				if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
    +				if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);
     			}
     		}
     
    @@ -1140,10 +1140,10 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     	}
     
     	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    -	if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    +	if (ZSTD_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
     
     	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    -	if (MEM_32bits() ||
    +	if (ZSTD_32bits() ||
     	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
     
     	{	size_t const pos = seqState->pos + seq.litLength;
    @@ -1155,7 +1155,7 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     	/* ANS state update */
     	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
     	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    -	if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    +	if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
     	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
     
     	return seq;
    @@ -1401,8 +1401,8 @@ size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t len
     size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
     {
     	if (srcSize >= ZSTD_skippableHeaderSize &&
    -			(MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    -		return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4);
    +			(ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    +		return ZSTD_skippableHeaderSize + ZSTD_readLE32((const BYTE*)src + 4);
     	} else {
     		const BYTE* ip = (const BYTE*)src;
     		const BYTE* const ipstart = ip;
    @@ -1507,7 +1507,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     		U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState);
     		U32 checkRead;
     		if (remainingSize<4) return ERROR(checksum_wrong);
    -		checkRead = MEM_readLE32(ip);
    +		checkRead = ZSTD_readLE32(ip);
     		if (checkRead != checkCalc) return ERROR(checksum_wrong);
     		ip += 4;
     		remainingSize -= 4;
    @@ -1543,13 +1543,13 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
     	while (srcSize >= ZSTD_frameHeaderSize_prefix) {
     		U32 magicNumber;
     
    -		magicNumber = MEM_readLE32(src);
    +		magicNumber = ZSTD_readLE32(src);
     		if (magicNumber != ZSTD_MAGICNUMBER) {
     			if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
     				size_t skippableSize;
     				if (srcSize < ZSTD_skippableHeaderSize)
     					return ERROR(srcSize_wrong);
    -				skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    +				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) +
     								ZSTD_skippableHeaderSize;
     				if (srcSize < skippableSize) {
     					return ERROR(srcSize_wrong);
    @@ -1642,7 +1642,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     	{
     	case ZSTDds_getFrameHeaderSize :
     		if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);      /* impossible */
    -		if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */
    +		if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */
     			memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
     			dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix;  /* magic number + skippable frame length */
     			dctx->stage = ZSTDds_decodeSkippableHeader;
    @@ -1729,7 +1729,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     		}
     	case ZSTDds_checkChecksum:
     		{	U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    -			U32 const check32 = MEM_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
    +			U32 const check32 = ZSTD_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
     			if (check32 != h32) return ERROR(checksum_wrong);
     			dctx->expected = 0;
     			dctx->stage = ZSTDds_getFrameHeaderSize;
    @@ -1737,7 +1737,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     		}
     	case ZSTDds_decodeSkippableHeader:
     		{	memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    -			dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
    +			dctx->expected = ZSTD_readLE32(dctx->headerBuffer + 4);
     			dctx->stage = ZSTDds_skipFrame;
     			return 0;
     		}
    @@ -1809,7 +1809,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     	{	int i;
     		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
     		for (i=0; i<3; i++) {
    -			U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
    +			U32 const rep = ZSTD_readLE32(dictPtr); dictPtr += 4;
     			if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted);
     			entropy->rep[i] = rep;
     	}   }
    @@ -1820,11 +1820,11 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const
     static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
     {
     	if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
    -	{	U32 const magic = MEM_readLE32(dict);
    +	{	U32 const magic = ZSTD_readLE32(dict);
     		if (magic != ZSTD_DICT_MAGIC) {
     			return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
     	}   }
    -	dctx->dictID = MEM_readLE32((const char*)dict + 4);
    +	dctx->dictID = ZSTD_readLE32((const char*)dict + 4);
     
     	/* load entropy tables */
     	{	size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    @@ -1904,10 +1904,10 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
     	ddict->dictID = 0;
     	ddict->entropyPresent = 0;
     	if (ddict->dictSize < 8) return 0;
    -	{	U32 const magic = MEM_readLE32(ddict->dictContent);
    +	{	U32 const magic = ZSTD_readLE32(ddict->dictContent);
     		if (magic != ZSTD_DICT_MAGIC) return 0;   /* pure content mode */
     	}
    -	ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
    +	ddict->dictID = ZSTD_readLE32((const char*)ddict->dictContent + 4);
     
     	/* load entropy tables */
     	CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
    @@ -1975,8 +1975,8 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
     unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
     {
     	if (dictSize < 8) return 0;
    -	if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
    -	return MEM_readLE32((const char*)dict + 4);
    +	if (ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
    +	return ZSTD_readLE32((const char*)dict + 4);
     }
     
     /*! ZSTD_getDictID_fromDDict() :
    @@ -2139,7 +2139,7 @@ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
     
     /* *****   Decompression   ***** */
     
    -MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +ZSTD_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
     	size_t const length = MIN(dstCapacity, srcSize);
     	memcpy(dst, src, length);
    diff --git a/contrib/linux-kernel/lib/zstd/entropy_common.c b/contrib/linux-kernel/lib/zstd/entropy_common.c
    index b13fb9980..4e429f23a 100644
    --- a/contrib/linux-kernel/lib/zstd/entropy_common.c
    +++ b/contrib/linux-kernel/lib/zstd/entropy_common.c
    @@ -74,7 +74,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     	int previous0 = 0;
     
     	if (hbSize < 4) return ERROR(srcSize_wrong);
    -	bitStream = MEM_readLE32(ip);
    +	bitStream = ZSTD_readLE32(ip);
     	nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG;   /* extract tableLog */
     	if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
     	bitStream >>= 4;
    @@ -91,7 +91,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     				n0 += 24;
     				if (ip < iend-5) {
     					ip += 2;
    -					bitStream = MEM_readLE32(ip) >> bitCount;
    +					bitStream = ZSTD_readLE32(ip) >> bitCount;
     				} else {
     					bitStream >>= 16;
     					bitCount   += 16;
    @@ -108,7 +108,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     			if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
     				ip += bitCount>>3;
     				bitCount &= 7;
    -				bitStream = MEM_readLE32(ip) >> bitCount;
    +				bitStream = ZSTD_readLE32(ip) >> bitCount;
     			} else {
     				bitStream >>= 2;
     		}   }
    @@ -140,7 +140,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     				bitCount -= (int)(8 * (iend - 4 - ip));
     				ip = iend - 4;
     			}
    -			bitStream = MEM_readLE32(ip) >> (bitCount & 31);
    +			bitStream = ZSTD_readLE32(ip) >> (bitCount & 31);
     	}   }   /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
     	if (remaining != 1) return ERROR(corruption_detected);
     	if (bitCount > 32) return ERROR(corruption_detected);
    diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h
    index a04215424..b59b2c612 100644
    --- a/contrib/linux-kernel/lib/zstd/fse.h
    +++ b/contrib/linux-kernel/lib/zstd/fse.h
    @@ -447,11 +447,11 @@ typedef struct {
     	U32 deltaNbBits;
     } FSE_symbolCompressionTransform; /* total 8 bytes */
     
    -MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
    +ZSTD_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
     {
     	const void* ptr = ct;
     	const U16* u16ptr = (const U16*) ptr;
    -	const U32 tableLog = MEM_read16(ptr);
    +	const U32 tableLog = ZSTD_read16(ptr);
     	statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2;
     	statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
    @@ -462,7 +462,7 @@ MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
     /*! FSE_initCState2() :
     *   Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
     *   uses the smallest state value possible, saving the cost of this symbol */
    -MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
    +ZSTD_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
     {
     	FSE_initCState(statePtr, ct);
     	{	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    @@ -473,7 +473,7 @@ MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U3
     	}
     }
     
    -MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
    +ZSTD_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
     {
     	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
     	const U16* const stateTable = (const U16*)(statePtr->stateTable);
    @@ -482,7 +482,7 @@ MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U3
     	statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
     }
     
    -MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
    +ZSTD_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
     {
     	BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
     	BIT_flushBits(bitC);
    @@ -503,7 +503,7 @@ typedef struct
     	unsigned char  nbBits;
     } FSE_decode_t;   /* size == U32 */
     
    -MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
    +ZSTD_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
     {
     	const void* ptr = dt;
     	const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
    @@ -512,13 +512,13 @@ MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, con
     	DStatePtr->table = dt + 1;
     }
     
    -MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
    +ZSTD_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
     {
     	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
     	return DInfo.symbol;
     }
     
    -MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     {
     	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
    @@ -526,7 +526,7 @@ MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     	DStatePtr->state = DInfo.newState + lowBits;
     }
     
    -MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     {
     	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
    @@ -539,7 +539,7 @@ MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     
     /*! FSE_decodeSymbolFast() :
     	unsafe, only works if no symbol has a probability > 50% */
    -MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     {
     	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
    @@ -550,7 +550,7 @@ MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bit
     	return symbol;
     }
     
    -MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
    +ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
     {
     	return DStatePtr->state == 0;
     }
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index d13f00df7..0a7c01b8f 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -342,24 +342,24 @@ static size_t FSE_count_parallel_wksp(
     	if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
     
     	/* by stripes of 16 bytes */
    -	{	U32 cached = MEM_read32(ip); ip += 4;
    +	{	U32 cached = ZSTD_read32(ip); ip += 4;
     		while (ip < iend-15) {
    -			U32 c = cached; cached = MEM_read32(ip); ip += 4;
    +			U32 c = cached; cached = ZSTD_read32(ip); ip += 4;
     			Counting1[(BYTE) c     ]++;
     			Counting2[(BYTE)(c>>8) ]++;
     			Counting3[(BYTE)(c>>16)]++;
     			Counting4[       c>>24 ]++;
    -			c = cached; cached = MEM_read32(ip); ip += 4;
    +			c = cached; cached = ZSTD_read32(ip); ip += 4;
     			Counting1[(BYTE) c     ]++;
     			Counting2[(BYTE)(c>>8) ]++;
     			Counting3[(BYTE)(c>>16)]++;
     			Counting4[       c>>24 ]++;
    -			c = cached; cached = MEM_read32(ip); ip += 4;
    +			c = cached; cached = ZSTD_read32(ip); ip += 4;
     			Counting1[(BYTE) c     ]++;
     			Counting2[(BYTE)(c>>8) ]++;
     			Counting3[(BYTE)(c>>16)]++;
     			Counting4[       c>>24 ]++;
    -			c = cached; cached = MEM_read32(ip); ip += 4;
    +			c = cached; cached = ZSTD_read32(ip); ip += 4;
     			Counting1[(BYTE) c     ]++;
     			Counting2[(BYTE)(c>>8) ]++;
     			Counting3[(BYTE)(c>>16)]++;
    diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c
    index ee03de9a5..2c1c321e7 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c
    @@ -487,21 +487,21 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
     
     	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
    -		MEM_writeLE16(ostart, (U16)cSize);
    +		ZSTD_writeLE16(ostart, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
     	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
    -		MEM_writeLE16(ostart+2, (U16)cSize);
    +		ZSTD_writeLE16(ostart+2, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
     	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
     		if (cSize==0) return 0;
    -		MEM_writeLE16(ostart+4, (U16)cSize);
    +		ZSTD_writeLE16(ostart+4, (U16)cSize);
     		op += cSize;
     	}
     
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index 1ed682611..81f90ff0f 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -140,11 +140,11 @@ static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, con
     	*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
     
     #define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
    -	if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
    +	if (ZSTD_64bits() || (HUF_TABLELOG_MAX<=12)) \
     		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     
     #define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
    -	if (MEM_64bits()) \
    +	if (ZSTD_64bits()) \
     		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     
     FORCE_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)
    @@ -236,9 +236,9 @@ static size_t HUF_decompress4X2_usingDTable_internal(
     		BIT_DStream_t bitD2;
     		BIT_DStream_t bitD3;
     		BIT_DStream_t bitD4;
    -		size_t const length1 = MEM_readLE16(istart);
    -		size_t const length2 = MEM_readLE16(istart+2);
    -		size_t const length3 = MEM_readLE16(istart+4);
    +		size_t const length1 = ZSTD_readLE16(istart);
    +		size_t const length2 = ZSTD_readLE16(istart+2);
    +		size_t const length3 = ZSTD_readLE16(istart+4);
     		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
     		const BYTE* const istart1 = istart + 6;  /* jumpTable */
     		const BYTE* const istart2 = istart1 + length1;
    @@ -356,7 +356,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
     	/* fill skipped values */
     	if (minWeight>1) {
     		U32 i, skipSize = rankVal[minWeight];
    -		MEM_writeLE16(&(DElt.sequence), baseSeq);
    +		ZSTD_writeLE16(&(DElt.sequence), baseSeq);
     		DElt.nbBits   = (BYTE)(consumed);
     		DElt.length   = 1;
     		for (i = 0; i < skipSize; i++)
    @@ -373,7 +373,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
     			U32 i = start;
     			const U32 end = start + length;
     
    -			MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
    +			ZSTD_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
     			DElt.nbBits = (BYTE)(nbBits + consumed);
     			DElt.length = 2;
     			do { DTable[i++] = DElt; } while (i= 1 */
    @@ -415,7 +415,7 @@ static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
     						   nbBitsBaseline, symbol);
     		} else {
     			HUF_DEltX4 DElt;
    -			MEM_writeLE16(&(DElt.sequence), symbol);
    +			ZSTD_writeLE16(&(DElt.sequence), symbol);
     			DElt.nbBits = (BYTE)(nbBits);
     			DElt.length = 1;
     			{	U32 const end = start + length;
    @@ -534,11 +534,11 @@ static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DE
     	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
     #define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
    -	if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
    +	if (ZSTD_64bits() || (HUF_TABLELOG_MAX<=12)) \
     		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
     #define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
    -	if (MEM_64bits()) \
    +	if (ZSTD_64bits()) \
     		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
     FORCE_INLINE size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)
    @@ -635,9 +635,9 @@ static size_t HUF_decompress4X4_usingDTable_internal(
     		BIT_DStream_t bitD2;
     		BIT_DStream_t bitD3;
     		BIT_DStream_t bitD4;
    -		size_t const length1 = MEM_readLE16(istart);
    -		size_t const length2 = MEM_readLE16(istart+2);
    -		size_t const length3 = MEM_readLE16(istart+4);
    +		size_t const length1 = ZSTD_readLE16(istart);
    +		size_t const length2 = ZSTD_readLE16(istart+2);
    +		size_t const length3 = ZSTD_readLE16(istart+4);
     		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
     		const BYTE* const istart1 = istart + 6;  /* jumpTable */
     		const BYTE* const istart2 = istart1 + length1;
    diff --git a/contrib/linux-kernel/lib/zstd/mem.h b/contrib/linux-kernel/lib/zstd/mem.h
    index e656a0e44..d01b1238a 100644
    --- a/contrib/linux-kernel/lib/zstd/mem.h
    +++ b/contrib/linux-kernel/lib/zstd/mem.h
    @@ -28,11 +28,7 @@
     /*-****************************************
     *  Compiler specifics
     ******************************************/
    -#define MEM_STATIC static __inline __attribute__((unused))
    -
    -/* code only tested on 32 and 64 bits systems */
    -#define MEM_STATIC_ASSERT(c)   { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
    -MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
    +#define ZSTD_STATIC static __inline __attribute__((unused))
     
     
     /*-**************************************************************
    @@ -52,164 +48,164 @@ typedef uintptr_t uPtrDiff;
     /*-**************************************************************
     *  Memory I/O
     *****************************************************************/
    -MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
    -MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
    +ZSTD_STATIC unsigned ZSTD_32bits(void) { return sizeof(size_t)==4; }
    +ZSTD_STATIC unsigned ZSTD_64bits(void) { return sizeof(size_t)==8; }
     
     #if defined(__LITTLE_ENDIAN)
    -#   define MEM_LITTLE_ENDIAN 1
    +#   define ZSTD_LITTLE_ENDIAN 1
     #else
    -#   define MEM_LITTLE_ENDIAN 0
    +#   define ZSTD_LITTLE_ENDIAN 0
     #endif
     
    -MEM_STATIC unsigned MEM_isLittleEndian(void)
    +ZSTD_STATIC unsigned ZSTD_isLittleEndian(void)
     {
    -	return MEM_LITTLE_ENDIAN;
    +	return ZSTD_LITTLE_ENDIAN;
     }
     
    -MEM_STATIC U16 MEM_read16(const void* memPtr)
    +ZSTD_STATIC U16 ZSTD_read16(const void* memPtr)
     {
     	return get_unaligned((const U16*)memPtr);
     }
     
    -MEM_STATIC U32 MEM_read32(const void* memPtr)
    +ZSTD_STATIC U32 ZSTD_read32(const void* memPtr)
     {
     	return get_unaligned((const U32*)memPtr);
     }
     
    -MEM_STATIC U64 MEM_read64(const void* memPtr)
    +ZSTD_STATIC U64 ZSTD_read64(const void* memPtr)
     {
     	return get_unaligned((const U64*)memPtr);
     }
     
    -MEM_STATIC size_t MEM_readST(const void* memPtr)
    +ZSTD_STATIC size_t ZSTD_readST(const void* memPtr)
     {
     	return get_unaligned((const size_t*)memPtr);
     }
     
    -MEM_STATIC void MEM_write16(void* memPtr, U16 value)
    +ZSTD_STATIC void ZSTD_write16(void* memPtr, U16 value)
     {
     	put_unaligned(value, (U16*)memPtr);
     }
     
    -MEM_STATIC void MEM_write32(void* memPtr, U32 value)
    +ZSTD_STATIC void ZSTD_write32(void* memPtr, U32 value)
     {
     	put_unaligned(value, (U32*)memPtr);
     }
     
    -MEM_STATIC void MEM_write64(void* memPtr, U64 value)
    +ZSTD_STATIC void ZSTD_write64(void* memPtr, U64 value)
     {
     	put_unaligned(value, (U64*)memPtr);
     }
     
     /*=== Little endian r/w ===*/
     
    -MEM_STATIC U16 MEM_readLE16(const void* memPtr)
    +ZSTD_STATIC U16 ZSTD_readLE16(const void* memPtr)
     {
     	return get_unaligned_le16(memPtr);
     }
     
    -MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
    +ZSTD_STATIC void ZSTD_writeLE16(void* memPtr, U16 val)
     {
     	put_unaligned_le16(val, memPtr);
     }
     
    -MEM_STATIC U32 MEM_readLE24(const void* memPtr)
    +ZSTD_STATIC U32 ZSTD_readLE24(const void* memPtr)
     {
    -	return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
    +	return ZSTD_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
     }
     
    -MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
    +ZSTD_STATIC void ZSTD_writeLE24(void* memPtr, U32 val)
     {
    -	MEM_writeLE16(memPtr, (U16)val);
    +	ZSTD_writeLE16(memPtr, (U16)val);
     	((BYTE*)memPtr)[2] = (BYTE)(val>>16);
     }
     
    -MEM_STATIC U32 MEM_readLE32(const void* memPtr)
    +ZSTD_STATIC U32 ZSTD_readLE32(const void* memPtr)
     {
     	return get_unaligned_le32(memPtr);
     }
     
    -MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
    +ZSTD_STATIC void ZSTD_writeLE32(void* memPtr, U32 val32)
     {
     	put_unaligned_le32(val32, memPtr);
     }
     
    -MEM_STATIC U64 MEM_readLE64(const void* memPtr)
    +ZSTD_STATIC U64 ZSTD_readLE64(const void* memPtr)
     {
     	return get_unaligned_le64(memPtr);
     }
     
    -MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
    +ZSTD_STATIC void ZSTD_writeLE64(void* memPtr, U64 val64)
     {
     	put_unaligned_le64(val64, memPtr);
     }
     
    -MEM_STATIC size_t MEM_readLEST(const void* memPtr)
    +ZSTD_STATIC size_t ZSTD_readLEST(const void* memPtr)
     {
    -	if (MEM_32bits())
    -		return (size_t)MEM_readLE32(memPtr);
    +	if (ZSTD_32bits())
    +		return (size_t)ZSTD_readLE32(memPtr);
     	else
    -		return (size_t)MEM_readLE64(memPtr);
    +		return (size_t)ZSTD_readLE64(memPtr);
     }
     
    -MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
    +ZSTD_STATIC void ZSTD_writeLEST(void* memPtr, size_t val)
     {
    -	if (MEM_32bits())
    -		MEM_writeLE32(memPtr, (U32)val);
    +	if (ZSTD_32bits())
    +		ZSTD_writeLE32(memPtr, (U32)val);
     	else
    -		MEM_writeLE64(memPtr, (U64)val);
    +		ZSTD_writeLE64(memPtr, (U64)val);
     }
     
     /*=== Big endian r/w ===*/
     
    -MEM_STATIC U32 MEM_readBE32(const void* memPtr)
    +ZSTD_STATIC U32 ZSTD_readBE32(const void* memPtr)
     {
     	return get_unaligned_be32(memPtr);
     }
     
    -MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
    +ZSTD_STATIC void ZSTD_writeBE32(void* memPtr, U32 val32)
     {
     	put_unaligned_be32(val32, memPtr);
     }
     
    -MEM_STATIC U64 MEM_readBE64(const void* memPtr)
    +ZSTD_STATIC U64 ZSTD_readBE64(const void* memPtr)
     {
     	return get_unaligned_be64(memPtr);
     }
     
    -MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
    +ZSTD_STATIC void ZSTD_writeBE64(void* memPtr, U64 val64)
     {
     	put_unaligned_be64(val64, memPtr);
     }
     
    -MEM_STATIC size_t MEM_readBEST(const void* memPtr)
    +ZSTD_STATIC size_t ZSTD_readBEST(const void* memPtr)
     {
    -	if (MEM_32bits())
    -		return (size_t)MEM_readBE32(memPtr);
    +	if (ZSTD_32bits())
    +		return (size_t)ZSTD_readBE32(memPtr);
     	else
    -		return (size_t)MEM_readBE64(memPtr);
    +		return (size_t)ZSTD_readBE64(memPtr);
     }
     
    -MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
    +ZSTD_STATIC void ZSTD_writeBEST(void* memPtr, size_t val)
     {
    -	if (MEM_32bits())
    -		MEM_writeBE32(memPtr, (U32)val);
    +	if (ZSTD_32bits())
    +		ZSTD_writeBE32(memPtr, (U32)val);
     	else
    -		MEM_writeBE64(memPtr, (U64)val);
    +		ZSTD_writeBE64(memPtr, (U64)val);
     }
     
     
     /* function safe only for comparisons */
    -MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
    +ZSTD_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
     {
     	switch (length)
     	{
     	default :
    -	case 4 : return MEM_read32(memPtr);
    -	case 3 : if (MEM_isLittleEndian())
    -				return MEM_read32(memPtr)<<8;
    +	case 4 : return ZSTD_read32(memPtr);
    +	case 3 : if (ZSTD_isLittleEndian())
    +				return ZSTD_read32(memPtr)<<8;
     			 else
    -				return MEM_read32(memPtr)>>8;
    +				return ZSTD_read32(memPtr)>>8;
     	}
     }
     
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_internal.h b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    index 91365eaa8..199513d16 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_internal.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    @@ -131,7 +131,7 @@ static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
     /*! ZSTD_wildcopy() :
     *   custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
     #define WILDCOPY_OVERLENGTH 8
    -MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
    +ZSTD_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
     {
     	const BYTE* ip = (const BYTE*)src;
     	BYTE* op = (BYTE*)dst;
    @@ -141,7 +141,7 @@ MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
     	while (op < oend);
     }
     
    -MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd)   /* should be faster for decoding, but strangely, not verified on all platform */
    +ZSTD_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd)   /* should be faster for decoding, but strangely, not verified on all platform */
     {
     	const BYTE* ip = (const BYTE*)src;
     	BYTE* op = (BYTE*)dst;
    @@ -243,7 +243,7 @@ void ZSTD_stackFree(void* opaque, void* address);
     
     /*======  common function  ======*/
     
    -MEM_STATIC U32 ZSTD_highbit32(U32 val)
    +ZSTD_STATIC U32 ZSTD_highbit32(U32 val)
     {
     	return 31 - __builtin_clz(val);
     }
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_opt.h b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    index 6855e3c36..d1de46b02 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_opt.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_opt.h
    @@ -39,7 +39,7 @@ FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr)
     }
     
     
    -MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t srcSize)
    +ZSTD_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t srcSize)
     {
     	unsigned u;
     
    @@ -165,7 +165,7 @@ FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYT
     }
     
     
    -MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
    +ZSTD_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
     {
     	U32 u;
     
    @@ -274,7 +274,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
     				if (match[bestLength] == ip[bestLength]) currMl = ZSTD_count(ip, match, iLimit);
     			} else {
     				match = dictBase + matchIndex3;
    -				if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
    +				if (ZSTD_readMINMATCH(match, MINMATCH) == ZSTD_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
     					currMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
     			}
     
    @@ -446,7 +446,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
     			for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
    -					&& (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
    +					&& (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) {
     					mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
     					if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
     						best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
    @@ -531,7 +531,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
     				for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
    -					   && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
    +					   && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {
     					   mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
     
     					   if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
    @@ -705,7 +705,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     				const BYTE* const repMatch = repBase + repIndex;
     				if ( (repCur > 0 && repCur <= (S32)curr)
     				   && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    -				   && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    +				   && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
     					/* repcode detected we should take it */
     					const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     					mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    @@ -801,7 +801,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
     					const BYTE* const repMatch = repBase + repIndex;
     					if ( (repCur > 0 && repCur <= (S32)(curr+cur))
     					  && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    -					  && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    +					  && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
     						/* repcode detected */
     						const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
     						mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    
    From 67101c6c777dfd12b81492a410c2349a57876751 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 17 May 2017 14:40:46 -0700
    Subject: [PATCH 072/400] [linux-kernel] clang-format lib/zstd/
    
    ---
     contrib/linux-kernel/lib/zstd/bitstream.h     |  222 +-
     contrib/linux-kernel/lib/zstd/compress.c      | 3299 +++++++++--------
     contrib/linux-kernel/lib/zstd/decompress.c    | 2340 ++++++------
     .../linux-kernel/lib/zstd/entropy_common.c    |  168 +-
     contrib/linux-kernel/lib/zstd/error_private.h |   12 +-
     contrib/linux-kernel/lib/zstd/fse.h           |  206 +-
     contrib/linux-kernel/lib/zstd/fse_compress.c  |  670 ++--
     .../linux-kernel/lib/zstd/fse_decompress.c    |  204 +-
     contrib/linux-kernel/lib/zstd/huf.h           |  124 +-
     contrib/linux-kernel/lib/zstd/huf_compress.c  |  639 ++--
     .../linux-kernel/lib/zstd/huf_decompress.c    |  763 ++--
     contrib/linux-kernel/lib/zstd/mem.h           |  155 +-
     contrib/linux-kernel/lib/zstd/zstd_common.c   |   45 +-
     contrib/linux-kernel/lib/zstd/zstd_internal.h |  253 +-
     contrib/linux-kernel/lib/zstd/zstd_opt.h      |  796 ++--
     15 files changed, 5241 insertions(+), 4655 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/bitstream.h b/contrib/linux-kernel/lib/zstd/bitstream.h
    index cd67d9e64..0fa6db129 100644
    --- a/contrib/linux-kernel/lib/zstd/bitstream.h
    +++ b/contrib/linux-kernel/lib/zstd/bitstream.h
    @@ -50,16 +50,15 @@
     /*-****************************************
     *  Dependencies
     ******************************************/
    -#include "mem.h"            /* unaligned access routines */
    -#include "error_private.h"  /* error codes and messages */
    -
    +#include "error_private.h" /* error codes and messages */
    +#include "mem.h"	   /* unaligned access routines */
     
     /*=========================================
     *  Target specific
     =========================================*/
    -#define STREAM_ACCUMULATOR_MIN_32  25
    -#define STREAM_ACCUMULATOR_MIN_64  57
    -#define STREAM_ACCUMULATOR_MIN    ((U32)(ZSTD_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
    +#define STREAM_ACCUMULATOR_MIN_32 25
    +#define STREAM_ACCUMULATOR_MIN_64 57
    +#define STREAM_ACCUMULATOR_MIN ((U32)(ZSTD_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
     
     /*-******************************************
     *  bitStream encoding API (write forward)
    @@ -68,19 +67,18 @@
     *  A critical property of these streams is that they encode and decode in **reverse** direction.
     *  So the first bit sequence you add will be the last to be read, like a LIFO stack.
     */
    -typedef struct
    -{
    +typedef struct {
     	size_t bitContainer;
    -	int    bitPos;
    -	char*  startPtr;
    -	char*  ptr;
    -	char*  endPtr;
    +	int bitPos;
    +	char *startPtr;
    +	char *ptr;
    +	char *endPtr;
     } BIT_CStream_t;
     
    -ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
    -ZSTD_STATIC void   BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
    -ZSTD_STATIC void   BIT_flushBits(BIT_CStream_t* bitC);
    -ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
    +ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *dstBuffer, size_t dstCapacity);
    +ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits);
    +ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC);
    +ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC);
     
     /* Start with initCStream, providing the size of buffer to write into.
     *  bitStream will never write outside of this buffer.
    @@ -99,29 +97,28 @@ ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
     *  If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
     */
     
    -
     /*-********************************************
     *  bitStream decoding API (read backward)
     **********************************************/
    -typedef struct
    -{
    -	size_t   bitContainer;
    +typedef struct {
    +	size_t bitContainer;
     	unsigned bitsConsumed;
    -	const char* ptr;
    -	const char* start;
    +	const char *ptr;
    +	const char *start;
     } BIT_DStream_t;
     
    -typedef enum { BIT_DStream_unfinished = 0,
    -			   BIT_DStream_endOfBuffer = 1,
    -			   BIT_DStream_completed = 2,
    -			   BIT_DStream_overflow = 3 } BIT_DStream_status;  /* result of BIT_reloadDStream() */
    -			   /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
    -
    -ZSTD_STATIC size_t   BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
    -ZSTD_STATIC size_t   BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
    -ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
    -ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
    +typedef enum {
    +	BIT_DStream_unfinished = 0,
    +	BIT_DStream_endOfBuffer = 1,
    +	BIT_DStream_completed = 2,
    +	BIT_DStream_overflow = 3
    +} BIT_DStream_status; /* result of BIT_reloadDStream() */
    +		      /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
     
    +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize);
    +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, unsigned nbBits);
    +ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD);
    +ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *bitD);
     
     /* Start by invoking BIT_initDStream().
     *  A chunk of the bitStream is then stored into a local register.
    @@ -133,32 +130,27 @@ ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
     *  Checking if DStream has reached its end can be performed with BIT_endOfDStream().
     */
     
    -
     /*-****************************************
     *  unsafe API
     ******************************************/
    -ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
    +ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits);
     /* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
     
    -ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
    +ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC);
     /* unsafe version; does not check buffer overflow */
     
    -ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
    +ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, unsigned nbBits);
     /* faster, but works only if nbBits >= 1 */
     
    -
    -
     /*-**************************************************************
     *  Internal functions
     ****************************************************************/
    -ZSTD_STATIC unsigned BIT_highbit32 (register U32 val)
    -{
    -	return 31 - __builtin_clz(val);
    -}
    +ZSTD_STATIC unsigned BIT_highbit32(register U32 val) { return 31 - __builtin_clz(val); }
     
     /*=====    Local Constants   =====*/
    -static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,  0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF };   /* up to 26 bits */
    -
    +static const unsigned BIT_mask[] = {0,       1,       3,       7,	0xF,      0x1F,     0x3F,     0x7F,      0xFF,
    +				    0x1FF,   0x3FF,   0x7FF,   0xFFF,    0x1FFF,   0x3FFF,   0x7FFF,   0xFFFF,    0x1FFFF,
    +				    0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF}; /* up to 26 bits */
     
     /*-**************************************************************
     *  bitStream encoding
    @@ -167,21 +159,22 @@ static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x
      *  `dstCapacity` must be > sizeof(void*)
      *  @return : 0 if success,
     			  otherwise an error code (can be tested using ERR_isError() ) */
    -ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* startPtr, size_t dstCapacity)
    +ZSTD_STATIC size_t BIT_initCStream(BIT_CStream_t *bitC, void *startPtr, size_t dstCapacity)
     {
     	bitC->bitContainer = 0;
     	bitC->bitPos = 0;
    -	bitC->startPtr = (char*)startPtr;
    +	bitC->startPtr = (char *)startPtr;
     	bitC->ptr = bitC->startPtr;
     	bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->ptr);
    -	if (dstCapacity <= sizeof(bitC->ptr)) return ERROR(dstSize_tooSmall);
    +	if (dstCapacity <= sizeof(bitC->ptr))
    +		return ERROR(dstSize_tooSmall);
     	return 0;
     }
     
     /*! BIT_addBits() :
     	can add up to 26 bits into `bitC`.
     	Does not check for register overflow ! */
    -ZSTD_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    +ZSTD_STATIC void BIT_addBits(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
     {
     	bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
     	bitC->bitPos += nbBits;
    @@ -189,7 +182,7 @@ ZSTD_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
     
     /*! BIT_addBitsFast() :
      *  works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
    -ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits)
    +ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t *bitC, size_t value, unsigned nbBits)
     {
     	bitC->bitContainer |= value << bitC->bitPos;
     	bitC->bitPos += nbBits;
    @@ -197,42 +190,43 @@ ZSTD_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbB
     
     /*! BIT_flushBitsFast() :
      *  unsafe version; does not check buffer overflow */
    -ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
    +ZSTD_STATIC void BIT_flushBitsFast(BIT_CStream_t *bitC)
     {
     	size_t const nbBytes = bitC->bitPos >> 3;
     	ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
     	bitC->ptr += nbBytes;
     	bitC->bitPos &= 7;
    -	bitC->bitContainer >>= nbBytes*8;   /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
    +	bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
     }
     
     /*! BIT_flushBits() :
      *  safe version; check for buffer overflow, and prevents it.
      *  note : does not signal buffer overflow. This will be revealed later on using BIT_closeCStream() */
    -ZSTD_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
    +ZSTD_STATIC void BIT_flushBits(BIT_CStream_t *bitC)
     {
     	size_t const nbBytes = bitC->bitPos >> 3;
     	ZSTD_writeLEST(bitC->ptr, bitC->bitContainer);
     	bitC->ptr += nbBytes;
    -	if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
    +	if (bitC->ptr > bitC->endPtr)
    +		bitC->ptr = bitC->endPtr;
     	bitC->bitPos &= 7;
    -	bitC->bitContainer >>= nbBytes*8;   /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
    +	bitC->bitContainer >>= nbBytes * 8; /* if bitPos >= sizeof(bitContainer)*8 --> undefined behavior */
     }
     
     /*! BIT_closeCStream() :
      *  @return : size of CStream, in bytes,
     			  or 0 if it could not fit into dstBuffer */
    -ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
    +ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t *bitC)
     {
    -	BIT_addBitsFast(bitC, 1, 1);   /* endMark */
    +	BIT_addBitsFast(bitC, 1, 1); /* endMark */
     	BIT_flushBits(bitC);
     
    -	if (bitC->ptr >= bitC->endPtr) return 0; /* doesn't fit within authorized budget : cancel */
    +	if (bitC->ptr >= bitC->endPtr)
    +		return 0; /* doesn't fit within authorized budget : cancel */
     
     	return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
     }
     
    -
     /*-********************************************************
     * bitStream decoding
     **********************************************************/
    @@ -242,54 +236,53 @@ ZSTD_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
     *   `srcSize` must be the *exact* size of the bitStream, in bytes.
     *   @return : size of stream (== srcSize) or an errorCode if a problem is detected
     */
    -ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
    +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize)
     {
    -	if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
    +	if (srcSize < 1) {
    +		memset(bitD, 0, sizeof(*bitD));
    +		return ERROR(srcSize_wrong);
    +	}
     
    -	if (srcSize >=  sizeof(bitD->bitContainer)) {  /* normal case */
    -		bitD->start = (const char*)srcBuffer;
    -		bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
    +	if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
    +		bitD->start = (const char *)srcBuffer;
    +		bitD->ptr = (const char *)srcBuffer + srcSize - sizeof(bitD->bitContainer);
     		bitD->bitContainer = ZSTD_readLEST(bitD->ptr);
    -		{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
    -		  bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */
    -		  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
    -	} else {
    -		bitD->start = (const char*)srcBuffer;
    -		bitD->ptr   = bitD->start;
    -		bitD->bitContainer = *(const BYTE*)(bitD->start);
    -		switch(srcSize)
     		{
    -			case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
    -			case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
    -			case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
    -			case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
    -			case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
    -			case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
    -			default:;
    +			BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1];
    +			bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
    +			if (lastByte == 0)
    +				return ERROR(GENERIC); /* endMark not present */
     		}
    -		{ BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
    -		  bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
    -		  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
    -		bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
    +	} else {
    +		bitD->start = (const char *)srcBuffer;
    +		bitD->ptr = bitD->start;
    +		bitD->bitContainer = *(const BYTE *)(bitD->start);
    +		switch (srcSize) {
    +		case 7: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[6]) << (sizeof(bitD->bitContainer) * 8 - 16);
    +		case 6: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[5]) << (sizeof(bitD->bitContainer) * 8 - 24);
    +		case 5: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[4]) << (sizeof(bitD->bitContainer) * 8 - 32);
    +		case 4: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[3]) << 24;
    +		case 3: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[2]) << 16;
    +		case 2: bitD->bitContainer += (size_t)(((const BYTE *)(srcBuffer))[1]) << 8;
    +		default:;
    +		}
    +		{
    +			BYTE const lastByte = ((const BYTE *)srcBuffer)[srcSize - 1];
    +			bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
    +			if (lastByte == 0)
    +				return ERROR(GENERIC); /* endMark not present */
    +		}
    +		bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize) * 8;
     	}
     
     	return srcSize;
     }
     
    -ZSTD_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
    -{
    -	return bitContainer >> start;
    -}
    +ZSTD_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start) { return bitContainer >> start; }
     
    -ZSTD_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
    -{
    -	return (bitContainer >> start) & BIT_mask[nbBits];
    -}
    +ZSTD_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits) { return (bitContainer >> start) & BIT_mask[nbBits]; }
     
    -ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
    -{
    -	return bitContainer & BIT_mask[nbBits];
    -}
    +ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits) { return bitContainer & BIT_mask[nbBits]; }
     
     /*! BIT_lookBits() :
      *  Provides next n bits from local register.
    @@ -298,31 +291,28 @@ ZSTD_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
      *  On 64-bits, maxNbBits==56.
      *  @return : value extracted
      */
    - ZSTD_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_lookBits(const BIT_DStream_t *bitD, U32 nbBits)
     {
    -	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
    -	return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
    +	U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1;
    +	return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask - nbBits) & bitMask);
     }
     
     /*! BIT_lookBitsFast() :
     *   unsafe version; only works only if nbBits >= 1 */
    -ZSTD_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t *bitD, U32 nbBits)
     {
    -	U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
    -	return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
    +	U32 const bitMask = sizeof(bitD->bitContainer) * 8 - 1;
    +	return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask + 1) - nbBits) & bitMask);
     }
     
    -ZSTD_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
    -{
    -	bitD->bitsConsumed += nbBits;
    -}
    +ZSTD_STATIC void BIT_skipBits(BIT_DStream_t *bitD, U32 nbBits) { bitD->bitsConsumed += nbBits; }
     
     /*! BIT_readBits() :
      *  Read (consume) next n bits from local register and update.
      *  Pay attention to not read more than nbBits contained into local register.
      *  @return : extracted value.
      */
    -ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, U32 nbBits)
     {
     	size_t const value = BIT_lookBits(bitD, nbBits);
     	BIT_skipBits(bitD, nbBits);
    @@ -331,7 +321,7 @@ ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
     
     /*! BIT_readBitsFast() :
     *   unsafe version; only works only if nbBits >= 1 */
    -ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
    +ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t *bitD, U32 nbBits)
     {
     	size_t const value = BIT_lookBitsFast(bitD, nbBits);
     	BIT_skipBits(bitD, nbBits);
    @@ -343,9 +333,9 @@ ZSTD_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
     *   This function is safe, it guarantees it will not read beyond src buffer.
     *   @return : status of `BIT_DStream_t` internal register.
     			  if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
    -ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
    +ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t *bitD)
     {
    -	if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* should not happen => corruption detected */
    +	if (bitD->bitsConsumed > (sizeof(bitD->bitContainer) * 8)) /* should not happen => corruption detected */
     		return BIT_DStream_overflow;
     
     	if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
    @@ -355,18 +345,20 @@ ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     		return BIT_DStream_unfinished;
     	}
     	if (bitD->ptr == bitD->start) {
    -		if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
    +		if (bitD->bitsConsumed < sizeof(bitD->bitContainer) * 8)
    +			return BIT_DStream_endOfBuffer;
     		return BIT_DStream_completed;
     	}
    -	{	U32 nbBytes = bitD->bitsConsumed >> 3;
    +	{
    +		U32 nbBytes = bitD->bitsConsumed >> 3;
     		BIT_DStream_status result = BIT_DStream_unfinished;
     		if (bitD->ptr - nbBytes < bitD->start) {
    -			nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */
    +			nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
     			result = BIT_DStream_endOfBuffer;
     		}
     		bitD->ptr -= nbBytes;
    -		bitD->bitsConsumed -= nbBytes*8;
    -		bitD->bitContainer = ZSTD_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD) */
    +		bitD->bitsConsumed -= nbBytes * 8;
    +		bitD->bitContainer = ZSTD_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */
     		return result;
     	}
     }
    @@ -374,9 +366,9 @@ ZSTD_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
     /*! BIT_endOfDStream() :
     *   @return Tells if DStream has exactly reached its end (all bits consumed).
     */
    -ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
    +ZSTD_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t *DStream)
     {
    -	return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
    +	return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer) * 8));
     }
     
     #endif /* BITSTREAM_H_MODULE */
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index daccddf1c..a7629aed5 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -14,157 +14,159 @@
      * ("BSD").
      */
     
    -
     /*-*************************************
     *  Dependencies
     ***************************************/
    -#include 
    -#include 
    -#include          /* memset */
    -#include "mem.h"
     #include "fse.h"
     #include "huf.h"
    -#include "zstd_internal.h"  /* includes zstd.h */
    +#include "mem.h"
    +#include "zstd_internal.h" /* includes zstd.h */
    +#include 
    +#include 
    +#include  /* memset */
     
     /*-*************************************
     *  Constants
     ***************************************/
    -static const U32 g_searchStrength = 8;   /* control skip over incompressible data */
    +static const U32 g_searchStrength = 8; /* control skip over incompressible data */
     #define HASH_READ_SIZE 8
    -typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
    -
    +typedef enum { ZSTDcs_created = 0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
     
     /*-*************************************
     *  Helper functions
     ***************************************/
    -#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
    +#define ZSTD_STATIC_ASSERT(c)                                   \
    +	{                                                       \
    +		enum { ZSTD_static_assert = 1 / (int)(!!(c)) }; \
    +	}
     size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
     
    -
     /*-*************************************
     *  Sequence storage
     ***************************************/
    -static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
    +static void ZSTD_resetSeqStore(seqStore_t *ssPtr)
     {
     	ssPtr->lit = ssPtr->litStart;
     	ssPtr->sequences = ssPtr->sequencesStart;
     	ssPtr->longLengthID = 0;
     }
     
    -
     /*-*************************************
     *  Context memory management
     ***************************************/
     struct ZSTD_CCtx_s {
    -	const BYTE* nextSrc;    /* next block here to continue on curr prefix */
    -	const BYTE* base;       /* All regular indexes relative to this position */
    -	const BYTE* dictBase;   /* extDict indexes relative to this position */
    -	U32   dictLimit;        /* below that point, need extDict */
    -	U32   lowLimit;         /* below that point, no more data */
    -	U32   nextToUpdate;     /* index from which to continue dictionary update */
    -	U32   nextToUpdate3;    /* index from which to continue dictionary update */
    -	U32   hashLog3;         /* dispatch table : larger == faster, more memory */
    -	U32   loadedDictEnd;    /* index of end of dictionary */
    -	U32   forceWindow;      /* force back-references to respect limit of 1<3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
    +	U32 const hashLog3 = (cParams.searchLength > 3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
     	size_t const h3Size = ((size_t)1) << hashLog3;
     	size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    -	size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<customMem = customMem;
     	return cctx;
     }
     
    -ZSTD_CCtx* ZSTD_initCCtx(void* workspace, size_t workspaceSize)
    +ZSTD_CCtx *ZSTD_initCCtx(void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    -	ZSTD_CCtx* cctx = ZSTD_createCCtx_advanced(stackMem);
    +	ZSTD_CCtx *cctx = ZSTD_createCCtx_advanced(stackMem);
     	if (cctx) {
     		cctx->workSpace = ZSTD_stackAllocAll(cctx->customMem.opaque, &cctx->workSpaceSize);
     	}
     	return cctx;
     }
     
    -size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
    +size_t ZSTD_freeCCtx(ZSTD_CCtx *cctx)
     {
    -	if (cctx==NULL) return 0;   /* support free on NULL */
    +	if (cctx == NULL)
    +		return 0; /* support free on NULL */
     	ZSTD_free(cctx->workSpace, cctx->customMem);
     	ZSTD_free(cctx, cctx->customMem);
    -	return 0;   /* reserved as a potential error code in the future */
    +	return 0; /* reserved as a potential error code in the future */
     }
     
    -const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx)   /* hidden interface */
    -{
    -	return &(ctx->seqStore);
    -}
    -
    -static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx)
    -{
    -	return cctx->params;
    -}
    +const seqStore_t *ZSTD_getSeqStore(const ZSTD_CCtx *ctx) /* hidden interface */ { return &(ctx->seqStore); }
     
    +static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx *cctx) { return cctx->params; }
     
     /** ZSTD_checkParams() :
     	ensure param values remain within authorized range.
     	@return : 0, or an error code if one value is beyond authorized range */
     size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
     {
    -#   define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); }
    +#define CLAMPCHECK(val, min, max)                                       \
    +	{                                                               \
    +		if ((val < min) | (val > max))                          \
    +			return ERROR(compressionParameter_unsupported); \
    +	}
     	CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
     	CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
     	CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
     	CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
     	CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
     	CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
    -	if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
    +	if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2)
    +		return ERROR(compressionParameter_unsupported);
     	return 0;
     }
     
    -
     /** ZSTD_cycleLog() :
      *  condition for correct operation : hashLog > 1 */
     static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
    @@ -181,49 +183,58 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
     	Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
     ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
     {
    -	if (srcSize+dictSize == 0) return cPar;   /* no size information available : no adjustment */
    +	if (srcSize + dictSize == 0)
    +		return cPar; /* no size information available : no adjustment */
     
     	/* resize params, to use less memory when necessary */
    -	{	U32 const minSrcSize = (srcSize==0) ? 500 : 0;
    +	{
    +		U32 const minSrcSize = (srcSize == 0) ? 500 : 0;
     		U64 const rSize = srcSize + dictSize + minSrcSize;
    -		if (rSize < ((U64)1< srcLog) cPar.windowLog = srcLog;
    -	}   }
    -	if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
    -	{	U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
    -		if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
    +			if (cPar.windowLog > srcLog)
    +				cPar.windowLog = srcLog;
    +		}
    +	}
    +	if (cPar.hashLog > cPar.windowLog)
    +		cPar.hashLog = cPar.windowLog;
    +	{
    +		U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
    +		if (cycleLog > cPar.windowLog)
    +			cPar.chainLog -= (cycleLog - cPar.windowLog);
     	}
     
    -	if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* required for frame header */
    +	if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)
    +		cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
     
     	return cPar;
     }
     
    -
     static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
     {
    -	return (param1.cParams.hashLog  == param2.cParams.hashLog)
    -		 & (param1.cParams.chainLog == param2.cParams.chainLog)
    -		 & (param1.cParams.strategy == param2.cParams.strategy)
    -		 & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
    +	return (param1.cParams.hashLog == param2.cParams.hashLog) & (param1.cParams.chainLog == param2.cParams.chainLog) &
    +	       (param1.cParams.strategy == param2.cParams.strategy) & ((param1.cParams.searchLength == 3) == (param2.cParams.searchLength == 3));
     }
     
     /*! ZSTD_continueCCtx() :
     	reuse CCtx without reset (note : requires no dictionary) */
    -static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
    +static size_t ZSTD_continueCCtx(ZSTD_CCtx *cctx, ZSTD_parameters params, U64 frameContentSize)
     {
     	U32 const end = (U32)(cctx->nextSrc - cctx->base);
     	cctx->params = params;
     	cctx->frameContentSize = frameContentSize;
     	cctx->lowLimit = end;
     	cctx->dictLimit = end;
    -	cctx->nextToUpdate = end+1;
    +	cctx->nextToUpdate = end + 1;
     	cctx->stage = ZSTDcs_init;
     	cctx->dictID = 0;
     	cctx->loadedDictEnd = 0;
    -	{ int i; for (i=0; irep[i] = repStartValue[i]; }
    -	cctx->seqStore.litLengthSum = 0;  /* force reset of btopt stats */
    +	{
    +		int i;
    +		for (i = 0; i < ZSTD_REP_NUM; i++)
    +			cctx->rep[i] = repStartValue[i];
    +	}
    +	cctx->seqStore.litLengthSum = 0; /* force reset of btopt stats */
     	xxh64_reset(&cctx->xxhState, 0);
     	return 0;
     }
    @@ -232,9 +243,7 @@ typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_comp
     
     /*! ZSTD_resetCCtx_advanced() :
     	note : `params` must be validated */
    -static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
    -									   ZSTD_parameters params, U64 frameContentSize,
    -									   ZSTD_compResetPolicy_e const crp)
    +static size_t ZSTD_resetCCtx_advanced(ZSTD_CCtx *zc, ZSTD_parameters params, U64 frameContentSize, ZSTD_compResetPolicy_e const crp)
     {
     	if (crp == ZSTDcrp_continue)
     		if (ZSTD_equivalentParams(params, zc->params)) {
    @@ -243,40 +252,45 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
     			return ZSTD_continueCCtx(zc, params, frameContentSize);
     		}
     
    -	{	size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    -		U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
    +	{
    +		size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    +		U32 const divider = (params.cParams.searchLength == 3) ? 3 : 4;
     		size_t const maxNbSeq = blockSize / divider;
    -		size_t const tokenSpace = blockSize + 11*maxNbSeq;
    +		size_t const tokenSpace = blockSize + 11 * maxNbSeq;
     		size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
     		size_t const hSize = ((size_t)1) << params.cParams.hashLog;
    -		U32    const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
    +		U32 const hashLog3 = (params.cParams.searchLength > 3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
     		size_t const h3Size = ((size_t)1) << hashLog3;
     		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    -		void* ptr;
    +		void *ptr;
     
     		/* Check if workSpace is large enough, alloc a new one if needed */
    -		{	size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<workSpaceSize < neededSpace) {
     				ZSTD_free(zc->workSpace, zc->customMem);
     				zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
    -				if (zc->workSpace == NULL) return ERROR(memory_allocation);
    +				if (zc->workSpace == NULL)
    +					return ERROR(memory_allocation);
     				zc->workSpaceSize = neededSpace;
    -		}   }
    +			}
    +		}
     
    -		if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace);   /* reset tables only */
    +		if (crp != ZSTDcrp_noMemset)
    +			memset(zc->workSpace, 0, tableSpace); /* reset tables only */
     		xxh64_reset(&zc->xxhState, 0);
     		zc->hashLog3 = hashLog3;
    -		zc->hashTable = (U32*)(zc->workSpace);
    +		zc->hashTable = (U32 *)(zc->workSpace);
     		zc->chainTable = zc->hashTable + hSize;
     		zc->hashTable3 = zc->chainTable + chainSize;
     		ptr = zc->hashTable3 + h3Size;
    -		zc->hufTable = (HUF_CElt*)ptr;
    +		zc->hufTable = (HUF_CElt *)ptr;
     		zc->flagStaticTables = 0;
     		zc->flagStaticHufTable = HUF_repeat_none;
    -		ptr = ((U32*)ptr) + 256;  /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
    +		ptr = ((U32 *)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
     
     		zc->nextToUpdate = 1;
     		zc->nextSrc = NULL;
    @@ -287,23 +301,27 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
     		zc->params = params;
     		zc->blockSize = blockSize;
     		zc->frameContentSize = frameContentSize;
    -		{ int i; for (i=0; irep[i] = repStartValue[i]; }
    +		{
    +			int i;
    +			for (i = 0; i < ZSTD_REP_NUM; i++)
    +				zc->rep[i] = repStartValue[i];
    +		}
     
     		if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
    -			zc->seqStore.litFreq = (U32*)ptr;
    -			zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
    -			zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
    -			ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
    -			zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
    -			ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
    -			zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
    -			ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
    +			zc->seqStore.litFreq = (U32 *)ptr;
    +			zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1 << Litbits);
    +			zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL + 1);
    +			zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML + 1);
    +			ptr = zc->seqStore.offCodeFreq + (MaxOff + 1);
    +			zc->seqStore.matchTable = (ZSTD_match_t *)ptr;
    +			ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM + 1;
    +			zc->seqStore.priceTable = (ZSTD_optimal_t *)ptr;
    +			ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM + 1;
     			zc->seqStore.litLengthSum = 0;
     		}
    -		zc->seqStore.sequencesStart = (seqDef*)ptr;
    +		zc->seqStore.sequencesStart = (seqDef *)ptr;
     		ptr = zc->seqStore.sequencesStart + maxNbSeq;
    -		zc->seqStore.llCode = (BYTE*) ptr;
    +		zc->seqStore.llCode = (BYTE *)ptr;
     		zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
     		zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
     		zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
    @@ -320,28 +338,32 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
      * ensures next compression will not use repcodes from previous block.
      * Note : only works with regular variant;
      *        do not use with extDict variant ! */
    -void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
    +void ZSTD_invalidateRepCodes(ZSTD_CCtx *cctx)
    +{
     	int i;
    -	for (i=0; irep[i] = 0;
    +	for (i = 0; i < ZSTD_REP_NUM; i++)
    +		cctx->rep[i] = 0;
     }
     
     /*! ZSTD_copyCCtx() :
     *   Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
     *   Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
     *   @return : 0, or an error code */
    -size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
    +size_t ZSTD_copyCCtx(ZSTD_CCtx *dstCCtx, const ZSTD_CCtx *srcCCtx, unsigned long long pledgedSrcSize)
     {
    -	if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
    -
    +	if (srcCCtx->stage != ZSTDcs_init)
    +		return ERROR(stage_wrong);
     
     	memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    -	{	ZSTD_parameters params = srcCCtx->params;
    +	{
    +		ZSTD_parameters params = srcCCtx->params;
     		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
     		ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
     	}
     
     	/* copy tables */
    -	{	size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
    +	{
    +		size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
     		size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
     		size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
     		size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    @@ -350,14 +372,14 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
     
     	/* copy dictionary offsets */
     	dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
    -	dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
    -	dstCCtx->nextSrc      = srcCCtx->nextSrc;
    -	dstCCtx->base         = srcCCtx->base;
    -	dstCCtx->dictBase     = srcCCtx->dictBase;
    -	dstCCtx->dictLimit    = srcCCtx->dictLimit;
    -	dstCCtx->lowLimit     = srcCCtx->lowLimit;
    -	dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
    -	dstCCtx->dictID       = srcCCtx->dictID;
    +	dstCCtx->nextToUpdate3 = srcCCtx->nextToUpdate3;
    +	dstCCtx->nextSrc = srcCCtx->nextSrc;
    +	dstCCtx->base = srcCCtx->base;
    +	dstCCtx->dictBase = srcCCtx->dictBase;
    +	dstCCtx->dictLimit = srcCCtx->dictLimit;
    +	dstCCtx->lowLimit = srcCCtx->lowLimit;
    +	dstCCtx->loadedDictEnd = srcCCtx->loadedDictEnd;
    +	dstCCtx->dictID = srcCCtx->dictID;
     
     	/* copy entropy tables */
     	dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
    @@ -368,259 +390,258 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
     		memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
     	}
     	if (srcCCtx->flagStaticHufTable) {
    -		memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
    +		memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256 * 4);
     	}
     
     	return 0;
     }
     
    -
     /*! ZSTD_reduceTable() :
     *   reduce table indexes by `reducerValue` */
    -static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
    +static void ZSTD_reduceTable(U32 *const table, U32 const size, U32 const reducerValue)
     {
     	U32 u;
    -	for (u=0 ; u < size ; u++) {
    -		if (table[u] < reducerValue) table[u] = 0;
    -		else table[u] -= reducerValue;
    +	for (u = 0; u < size; u++) {
    +		if (table[u] < reducerValue)
    +			table[u] = 0;
    +		else
    +			table[u] -= reducerValue;
     	}
     }
     
     /*! ZSTD_reduceIndex() :
     *   rescale all indexes to avoid future overflow (indexes are U32) */
    -static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
    +static void ZSTD_reduceIndex(ZSTD_CCtx *zc, const U32 reducerValue)
     {
    -	{ U32 const hSize = 1 << zc->params.cParams.hashLog;
    -	  ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
    +	{
    +		U32 const hSize = 1 << zc->params.cParams.hashLog;
    +		ZSTD_reduceTable(zc->hashTable, hSize, reducerValue);
    +	}
     
    -	{ U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
    -	  ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
    +	{
    +		U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
    +		ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue);
    +	}
     
    -	{ U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
    -	  ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
    +	{
    +		U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
    +		ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue);
    +	}
     }
     
    -
     /*-*******************************************************
     *  Block entropic compression
     *********************************************************/
     
     /* See doc/zstd_compression_format.md for detailed format description */
     
    -size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +size_t ZSTD_noCompressBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
    -	if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
    -	memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
    +	if (srcSize + ZSTD_blockHeaderSize > dstCapacity)
    +		return ERROR(dstSize_tooSmall);
    +	memcpy((BYTE *)dst + ZSTD_blockHeaderSize, src, srcSize);
     	ZSTD_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
    -	return ZSTD_blockHeaderSize+srcSize;
    +	return ZSTD_blockHeaderSize + srcSize;
     }
     
    -
    -static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +static size_t ZSTD_noCompressLiterals(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
    -	BYTE* const ostart = (BYTE* const)dst;
    -	U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
    +	BYTE *const ostart = (BYTE * const)dst;
    +	U32 const flSize = 1 + (srcSize > 31) + (srcSize > 4095);
     
    -	if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
    +	if (srcSize + flSize > dstCapacity)
    +		return ERROR(dstSize_tooSmall);
     
    -	switch(flSize)
    -	{
    -		case 1: /* 2 - 1 - 5 */
    -			ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
    -			break;
    -		case 2: /* 2 - 2 - 12 */
    -			ZSTD_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
    -			break;
    -		default:   /*note : should not be necessary : flSize is within {1,2,3} */
    -		case 3: /* 2 - 2 - 20 */
    -			ZSTD_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
    -			break;
    +	switch (flSize) {
    +	case 1: /* 2 - 1 - 5 */ ostart[0] = (BYTE)((U32)set_basic + (srcSize << 3)); break;
    +	case 2: /* 2 - 2 - 12 */ ZSTD_writeLE16(ostart, (U16)((U32)set_basic + (1 << 2) + (srcSize << 4))); break;
    +	default: /*note : should not be necessary : flSize is within {1,2,3} */
    +	case 3: /* 2 - 2 - 20 */ ZSTD_writeLE32(ostart, (U32)((U32)set_basic + (3 << 2) + (srcSize << 4))); break;
     	}
     
     	memcpy(ostart + flSize, src, srcSize);
     	return srcSize + flSize;
     }
     
    -static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +static size_t ZSTD_compressRleLiteralsBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
    -	BYTE* const ostart = (BYTE* const)dst;
    -	U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);
    +	BYTE *const ostart = (BYTE * const)dst;
    +	U32 const flSize = 1 + (srcSize > 31) + (srcSize > 4095);
     
    -	(void)dstCapacity;  /* dstCapacity already guaranteed to be >=4, hence large enough */
    +	(void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
     
    -	switch(flSize)
    -	{
    -		case 1: /* 2 - 1 - 5 */
    -			ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
    -			break;
    -		case 2: /* 2 - 2 - 12 */
    -			ZSTD_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
    -			break;
    -		default:   /*note : should not be necessary : flSize is necessarily within {1,2,3} */
    -		case 3: /* 2 - 2 - 20 */
    -			ZSTD_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
    -			break;
    +	switch (flSize) {
    +	case 1: /* 2 - 1 - 5 */ ostart[0] = (BYTE)((U32)set_rle + (srcSize << 3)); break;
    +	case 2: /* 2 - 2 - 12 */ ZSTD_writeLE16(ostart, (U16)((U32)set_rle + (1 << 2) + (srcSize << 4))); break;
    +	default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
    +	case 3: /* 2 - 2 - 20 */ ZSTD_writeLE32(ostart, (U32)((U32)set_rle + (3 << 2) + (srcSize << 4))); break;
     	}
     
    -	ostart[flSize] = *(const BYTE*)src;
    -	return flSize+1;
    +	ostart[flSize] = *(const BYTE *)src;
    +	return flSize + 1;
     }
     
    -
     static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
     
    -static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
    -									 void* dst, size_t dstCapacity,
    -							   const void* src, size_t srcSize)
    +static size_t ZSTD_compressLiterals(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t const minGain = ZSTD_minGain(srcSize);
     	size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
    -	BYTE*  const ostart = (BYTE*)dst;
    +	BYTE *const ostart = (BYTE *)dst;
     	U32 singleStream = srcSize < 256;
     	symbolEncodingType_e hType = set_compressed;
     	size_t cLitSize;
     
    -
    -	/* small ? don't even attempt compression (speed opt) */
    -#   define LITERAL_NOENTROPY 63
    -	{	size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
    -		if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
    +/* small ? don't even attempt compression (speed opt) */
    +#define LITERAL_NOENTROPY 63
    +	{
    +		size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
    +		if (srcSize <= minLitSize)
    +			return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
     	}
     
    -	if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
    -	{	HUF_repeat repeat = zc->flagStaticHufTable;
    +	if (dstCapacity < lhSize + 1)
    +		return ERROR(dstSize_tooSmall); /* not enough space for compression */
    +	{
    +		HUF_repeat repeat = zc->flagStaticHufTable;
     		int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
    -		if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
    -		cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
    -								: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat);
    -		if (repeat != HUF_repeat_none) { hType = set_repeat; }    /* reused the existing table */
    -		else { zc->flagStaticHufTable = HUF_repeat_check; }       /* now have a table to reuse */
    +		if (repeat == HUF_repeat_valid && lhSize == 3)
    +			singleStream = 1;
    +		cLitSize = singleStream ? HUF_compress1X_repeat(ostart + lhSize, dstCapacity - lhSize, src, srcSize, 255, 11, zc->tmpCounters,
    +								sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
    +					: HUF_compress4X_repeat(ostart + lhSize, dstCapacity - lhSize, src, srcSize, 255, 11, zc->tmpCounters,
    +								sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat);
    +		if (repeat != HUF_repeat_none) {
    +			hType = set_repeat;
    +		} /* reused the existing table */
    +		else {
    +			zc->flagStaticHufTable = HUF_repeat_check;
    +		} /* now have a table to reuse */
     	}
     
    -	if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
    +	if ((cLitSize == 0) | (cLitSize >= srcSize - minGain)) {
     		zc->flagStaticHufTable = HUF_repeat_none;
     		return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
     	}
    -	if (cLitSize==1) {
    +	if (cLitSize == 1) {
     		zc->flagStaticHufTable = HUF_repeat_none;
     		return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
     	}
     
     	/* Build header */
    -	switch(lhSize)
    -	{
    +	switch (lhSize) {
     	case 3: /* 2 - 2 - 10 - 10 */
    -		{	U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
    -			ZSTD_writeLE24(ostart, lhc);
    -			break;
    -		}
    -	case 4: /* 2 - 2 - 14 - 14 */
    -		{	U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
    -			ZSTD_writeLE32(ostart, lhc);
    -			break;
    -		}
    -	default:   /* should not be necessary, lhSize is only {3,4,5} */
    -	case 5: /* 2 - 2 - 18 - 18 */
    -		{	U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
    -			ZSTD_writeLE32(ostart, lhc);
    -			ostart[4] = (BYTE)(cLitSize >> 10);
    -			break;
    -		}
    +	{
    +		U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 14);
    +		ZSTD_writeLE24(ostart, lhc);
    +		break;
     	}
    -	return lhSize+cLitSize;
    +	case 4: /* 2 - 2 - 14 - 14 */
    +	{
    +		U32 const lhc = hType + (2 << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 18);
    +		ZSTD_writeLE32(ostart, lhc);
    +		break;
    +	}
    +	default: /* should not be necessary, lhSize is only {3,4,5} */
    +	case 5:  /* 2 - 2 - 18 - 18 */
    +	{
    +		U32 const lhc = hType + (3 << 2) + ((U32)srcSize << 4) + ((U32)cLitSize << 22);
    +		ZSTD_writeLE32(ostart, lhc);
    +		ostart[4] = (BYTE)(cLitSize >> 10);
    +		break;
    +	}
    +	}
    +	return lhSize + cLitSize;
     }
     
    -static const BYTE LL_Code[64] = {  0,  1,  2,  3,  4,  5,  6,  7,
    -								   8,  9, 10, 11, 12, 13, 14, 15,
    -								  16, 16, 17, 17, 18, 18, 19, 19,
    -								  20, 20, 20, 20, 21, 21, 21, 21,
    -								  22, 22, 22, 22, 22, 22, 22, 22,
    -								  23, 23, 23, 23, 23, 23, 23, 23,
    -								  24, 24, 24, 24, 24, 24, 24, 24,
    -								  24, 24, 24, 24, 24, 24, 24, 24 };
    +static const BYTE LL_Code[64] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 16, 17, 17, 18, 18,
    +				 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23,
    +				 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24};
     
    -static const BYTE ML_Code[128] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    -								  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    -								  32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
    -								  38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
    -								  40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
    -								  41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
    -								  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
    -								  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
    +static const BYTE ML_Code[128] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
    +				  26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38,
    +				  38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
    +				  40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42,
    +				  42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42};
     
    -
    -void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
    +void ZSTD_seqToCodes(const seqStore_t *seqStorePtr)
     {
     	BYTE const LL_deltaCode = 19;
     	BYTE const ML_deltaCode = 36;
    -	const seqDef* const sequences = seqStorePtr->sequencesStart;
    -	BYTE* const llCodeTable = seqStorePtr->llCode;
    -	BYTE* const ofCodeTable = seqStorePtr->ofCode;
    -	BYTE* const mlCodeTable = seqStorePtr->mlCode;
    +	const seqDef *const sequences = seqStorePtr->sequencesStart;
    +	BYTE *const llCodeTable = seqStorePtr->llCode;
    +	BYTE *const ofCodeTable = seqStorePtr->ofCode;
    +	BYTE *const mlCodeTable = seqStorePtr->mlCode;
     	U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
     	U32 u;
    -	for (u=0; u 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
    +		llCodeTable[u] = (llv > 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
     		ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
    -		mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
    +		mlCodeTable[u] = (mlv > 127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
     	}
    -	if (seqStorePtr->longLengthID==1)
    +	if (seqStorePtr->longLengthID == 1)
     		llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
    -	if (seqStorePtr->longLengthID==2)
    +	if (seqStorePtr->longLengthID == 2)
     		mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
     }
     
    -ZSTD_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
    -							  void* dst, size_t dstCapacity,
    -							  size_t srcSize)
    +ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, size_t srcSize)
     {
     	const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
    -	const seqStore_t* seqStorePtr = &(zc->seqStore);
    -	U32 count[MaxSeq+1];
    -	S16 norm[MaxSeq+1];
    -	FSE_CTable* CTable_LitLength = zc->litlengthCTable;
    -	FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
    -	FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
    -	U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */
    -	const seqDef* const sequences = seqStorePtr->sequencesStart;
    -	const BYTE* const ofCodeTable = seqStorePtr->ofCode;
    -	const BYTE* const llCodeTable = seqStorePtr->llCode;
    -	const BYTE* const mlCodeTable = seqStorePtr->mlCode;
    -	BYTE* const ostart = (BYTE*)dst;
    -	BYTE* const oend = ostart + dstCapacity;
    -	BYTE* op = ostart;
    +	const seqStore_t *seqStorePtr = &(zc->seqStore);
    +	U32 count[MaxSeq + 1];
    +	S16 norm[MaxSeq + 1];
    +	FSE_CTable *CTable_LitLength = zc->litlengthCTable;
    +	FSE_CTable *CTable_OffsetBits = zc->offcodeCTable;
    +	FSE_CTable *CTable_MatchLength = zc->matchlengthCTable;
    +	U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
    +	const seqDef *const sequences = seqStorePtr->sequencesStart;
    +	const BYTE *const ofCodeTable = seqStorePtr->ofCode;
    +	const BYTE *const llCodeTable = seqStorePtr->llCode;
    +	const BYTE *const mlCodeTable = seqStorePtr->mlCode;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *const oend = ostart + dstCapacity;
    +	BYTE *op = ostart;
     	size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
    -	BYTE* seqHead;
    -	BYTE scratchBuffer[1<litStart;
    +	{
    +		const BYTE *const literals = seqStorePtr->litStart;
     		size_t const litSize = seqStorePtr->lit - literals;
     		size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
    -		if (ZSTD_isError(cSize)) return cSize;
    +		if (ZSTD_isError(cSize))
    +			return cSize;
     		op += cSize;
     	}
     
     	/* Sequences Header */
    -	if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
    -	if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
    -	else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
    -	else op[0]=0xFF, ZSTD_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
    -	if (nbSeq==0) goto _check_compressibility;
    +	if ((oend - op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */)
    +		return ERROR(dstSize_tooSmall);
    +	if (nbSeq < 0x7F)
    +		*op++ = (BYTE)nbSeq;
    +	else if (nbSeq < LONGNBSEQ)
    +		op[0] = (BYTE)((nbSeq >> 8) + 0x80), op[1] = (BYTE)nbSeq, op += 2;
    +	else
    +		op[0] = 0xFF, ZSTD_writeLE16(op + 1, (U16)(nbSeq - LONGNBSEQ)), op += 3;
    +	if (nbSeq == 0)
    +		goto _check_compressibility;
     
     	/* seqHead : flags for FSE encoding type */
     	seqHead = op++;
     
    -#define MIN_SEQ_FOR_DYNAMIC_FSE   64
    -#define MAX_SEQ_FOR_STATIC_FSE  1000
    +#define MIN_SEQ_FOR_DYNAMIC_FSE 64
    +#define MAX_SEQ_FOR_STATIC_FSE 1000
     
     	/* convert length/distances into codes */
     	ZSTD_seqToCodes(seqStorePtr);
     
     	/* CTable for Literal Lengths */
    -	{	U32 max = MaxLL;
    +	{
    +		U32 max = MaxLL;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = llCodeTable[0];
    @@ -628,23 +649,31 @@ ZSTD_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     			LLtype = set_rle;
     		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
     			LLtype = set_repeat;
    -		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
    +		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog - 1)))) {
     			FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
     			LLtype = set_basic;
     		} else {
     			size_t nbSeq_1 = nbSeq;
     			const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
    -			if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
    +			if (count[llCodeTable[nbSeq - 1]] > 1) {
    +				count[llCodeTable[nbSeq - 1]]--;
    +				nbSeq_1--;
    +			}
     			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    -			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    -			  if (FSE_isError(NCountSize)) return NCountSize;
    -			  op += NCountSize; }
    +			{
    +				size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
    +				if (FSE_isError(NCountSize))
    +					return NCountSize;
    +				op += NCountSize;
    +			}
     			FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
     			LLtype = set_compressed;
    -	}   }
    +		}
    +	}
     
     	/* CTable for Offsets */
    -	{	U32 max = MaxOff;
    +	{
    +		U32 max = MaxOff;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = ofCodeTable[0];
    @@ -652,23 +681,31 @@ ZSTD_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     			Offtype = set_rle;
     		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
     			Offtype = set_repeat;
    -		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
    +		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog - 1)))) {
     			FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
     			Offtype = set_basic;
     		} else {
     			size_t nbSeq_1 = nbSeq;
     			const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
    -			if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
    +			if (count[ofCodeTable[nbSeq - 1]] > 1) {
    +				count[ofCodeTable[nbSeq - 1]]--;
    +				nbSeq_1--;
    +			}
     			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    -			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    -			  if (FSE_isError(NCountSize)) return NCountSize;
    -			  op += NCountSize; }
    +			{
    +				size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
    +				if (FSE_isError(NCountSize))
    +					return NCountSize;
    +				op += NCountSize;
    +			}
     			FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
     			Offtype = set_compressed;
    -	}   }
    +		}
    +	}
     
     	/* CTable for MatchLengths */
    -	{	U32 max = MaxML;
    +	{
    +		U32 max = MaxML;
     		size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
     		if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
     			*op++ = *mlCodeTable;
    @@ -676,107 +713,128 @@ ZSTD_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
     			MLtype = set_rle;
     		} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
     			MLtype = set_repeat;
    -		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
    +		} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog - 1)))) {
     			FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
     			MLtype = set_basic;
     		} else {
     			size_t nbSeq_1 = nbSeq;
     			const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
    -			if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
    +			if (count[mlCodeTable[nbSeq - 1]] > 1) {
    +				count[mlCodeTable[nbSeq - 1]]--;
    +				nbSeq_1--;
    +			}
     			FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
    -			{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
    -			  if (FSE_isError(NCountSize)) return NCountSize;
    -			  op += NCountSize; }
    +			{
    +				size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
    +				if (FSE_isError(NCountSize))
    +					return NCountSize;
    +				op += NCountSize;
    +			}
     			FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
     			MLtype = set_compressed;
    -	}   }
    +		}
    +	}
     
    -	*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
    +	*seqHead = (BYTE)((LLtype << 6) + (Offtype << 4) + (MLtype << 2));
     	zc->flagStaticTables = 0;
     
     	/* Encoding Sequences */
    -	{	BIT_CStream_t blockStream;
    -		FSE_CState_t  stateMatchLength;
    -		FSE_CState_t  stateOffsetBits;
    -		FSE_CState_t  stateLitLength;
    +	{
    +		BIT_CStream_t blockStream;
    +		FSE_CState_t stateMatchLength;
    +		FSE_CState_t stateOffsetBits;
    +		FSE_CState_t stateLitLength;
     
    -		CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
    +		CHECK_E(BIT_initCStream(&blockStream, op, oend - op), dstSize_tooSmall); /* not enough space remaining */
     
     		/* first symbols */
    -		FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
    -		FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);
    -		FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);
    -		BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
    -		if (ZSTD_32bits()) BIT_flushBits(&blockStream);
    -		BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
    -		if (ZSTD_32bits()) BIT_flushBits(&blockStream);
    +		FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq - 1]);
    +		FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq - 1]);
    +		FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq - 1]);
    +		BIT_addBits(&blockStream, sequences[nbSeq - 1].litLength, LL_bits[llCodeTable[nbSeq - 1]]);
    +		if (ZSTD_32bits())
    +			BIT_flushBits(&blockStream);
    +		BIT_addBits(&blockStream, sequences[nbSeq - 1].matchLength, ML_bits[mlCodeTable[nbSeq - 1]]);
    +		if (ZSTD_32bits())
    +			BIT_flushBits(&blockStream);
     		if (longOffsets) {
    -			U32 const ofBits = ofCodeTable[nbSeq-1];
    -			int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
    +			U32 const ofBits = ofCodeTable[nbSeq - 1];
    +			int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN - 1);
     			if (extraBits) {
    -				BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
    +				BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, extraBits);
     				BIT_flushBits(&blockStream);
     			}
    -			BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
    -						ofBits - extraBits);
    +			BIT_addBits(&blockStream, sequences[nbSeq - 1].offset >> extraBits, ofBits - extraBits);
     		} else {
    -			BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
    +			BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, ofCodeTable[nbSeq - 1]);
     		}
     		BIT_flushBits(&blockStream);
     
    -		{	size_t n;
    -			for (n=nbSeq-2 ; n= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
    -					BIT_flushBits(&blockStream);                                /* (7)*/
    +				U32 const llBits = LL_bits[llCode];
    +				U32 const ofBits = ofCode; /* 32b*/ /* 64b*/
    +				U32 const mlBits = ML_bits[mlCode];
    +				/* (7)*/							    /* (7)*/
    +				FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */  /* 15 */
    +				FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
    +				if (ZSTD_32bits())
    +					BIT_flushBits(&blockStream);				  /* (7)*/
    +				FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
    +				if (ZSTD_32bits() || (ofBits + mlBits + llBits >= 64 - 7 - (LLFSELog + MLFSELog + OffFSELog)))
    +					BIT_flushBits(&blockStream); /* (7)*/
     				BIT_addBits(&blockStream, sequences[n].litLength, llBits);
    -				if (ZSTD_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
    +				if (ZSTD_32bits() && ((llBits + mlBits) > 24))
    +					BIT_flushBits(&blockStream);
     				BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
    -				if (ZSTD_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/
    +				if (ZSTD_32bits())
    +					BIT_flushBits(&blockStream); /* (7)*/
     				if (longOffsets) {
    -					int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
    +					int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN - 1);
     					if (extraBits) {
     						BIT_addBits(&blockStream, sequences[n].offset, extraBits);
    -						BIT_flushBits(&blockStream);                            /* (7)*/
    +						BIT_flushBits(&blockStream); /* (7)*/
     					}
    -					BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
    -								ofBits - extraBits);                            /* 31 */
    +					BIT_addBits(&blockStream, sequences[n].offset >> extraBits, ofBits - extraBits); /* 31 */
     				} else {
    -					BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */
    +					BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
     				}
    -				BIT_flushBits(&blockStream);                                    /* (7)*/
    -		}   }
    +				BIT_flushBits(&blockStream); /* (7)*/
    +			}
    +		}
     
     		FSE_flushCState(&blockStream, &stateMatchLength);
     		FSE_flushCState(&blockStream, &stateOffsetBits);
     		FSE_flushCState(&blockStream, &stateLitLength);
     
    -		{	size_t const streamSize = BIT_closeCStream(&blockStream);
    -			if (streamSize==0) return ERROR(dstSize_tooSmall);   /* not enough space */
    +		{
    +			size_t const streamSize = BIT_closeCStream(&blockStream);
    +			if (streamSize == 0)
    +				return ERROR(dstSize_tooSmall); /* not enough space */
     			op += streamSize;
    -	}   }
    +		}
    +	}
     
    -	/* check compressibility */
    -_check_compressibility:
    -	{	size_t const minGain = ZSTD_minGain(srcSize);
    -		size_t const maxCSize = srcSize - minGain;
    -		if ((size_t)(op-ostart) >= maxCSize) {
    -			zc->flagStaticHufTable = HUF_repeat_none;
    -			return 0;
    -	}   }
    +/* check compressibility */
    +_check_compressibility : {
    +	size_t const minGain = ZSTD_minGain(srcSize);
    +	size_t const maxCSize = srcSize - minGain;
    +	if ((size_t)(op - ostart) >= maxCSize) {
    +		zc->flagStaticHufTable = HUF_repeat_none;
    +		return 0;
    +	}
    +}
     
     	/* confirm repcodes */
    -	{ int i; for (i=0; irep[i] = zc->repToConfirm[i]; }
    +	{
    +		int i;
    +		for (i = 0; i < ZSTD_REP_NUM; i++)
    +			zc->rep[i] = zc->repToConfirm[i];
    +	}
     
     	return op - ostart;
     }
    @@ -786,31 +844,36 @@ _check_compressibility:
     	`offsetCode` : distance to match, or 0 == repCode.
     	`matchCode` : matchLength - MINMATCH
     */
    -ZSTD_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
    +ZSTD_STATIC void ZSTD_storeSeq(seqStore_t *seqStorePtr, size_t litLength, const void *literals, U32 offsetCode, size_t matchCode)
     {
     	/* copy Literals */
     	ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
     	seqStorePtr->lit += litLength;
     
     	/* literal Length */
    -	if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
    +	if (litLength > 0xFFFF) {
    +		seqStorePtr->longLengthID = 1;
    +		seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
    +	}
     	seqStorePtr->sequences[0].litLength = (U16)litLength;
     
     	/* match offset */
     	seqStorePtr->sequences[0].offset = offsetCode + 1;
     
     	/* match Length */
    -	if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
    +	if (matchCode > 0xFFFF) {
    +		seqStorePtr->longLengthID = 2;
    +		seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
    +	}
     	seqStorePtr->sequences[0].matchLength = (U16)matchCode;
     
     	seqStorePtr->sequences++;
     }
     
    -
     /*-*************************************
     *  Match length counter
     ***************************************/
    -static unsigned ZSTD_NbCommonBytes (register size_t val)
    +static unsigned ZSTD_NbCommonBytes(register size_t val)
     {
     	if (ZSTD_isLittleEndian()) {
     		if (ZSTD_64bits()) {
    @@ -818,29 +881,41 @@ static unsigned ZSTD_NbCommonBytes (register size_t val)
     		} else { /* 32 bits */
     			return (__builtin_ctz((U32)val) >> 3);
     		}
    -	} else {  /* Big Endian CPU */
    +	} else { /* Big Endian CPU */
     		if (ZSTD_64bits()) {
     			return (__builtin_clzll(val) >> 3);
     		} else { /* 32 bits */
     			return (__builtin_clz((U32)val) >> 3);
    -	}   }
    +		}
    +	}
     }
     
    -
    -static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
    +static size_t ZSTD_count(const BYTE *pIn, const BYTE *pMatch, const BYTE *const pInLimit)
     {
    -	const BYTE* const pStart = pIn;
    -	const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
    +	const BYTE *const pStart = pIn;
    +	const BYTE *const pInLoopLimit = pInLimit - (sizeof(size_t) - 1);
     
     	while (pIn < pInLoopLimit) {
     		size_t const diff = ZSTD_readST(pMatch) ^ ZSTD_readST(pIn);
    -		if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
    +		if (!diff) {
    +			pIn += sizeof(size_t);
    +			pMatch += sizeof(size_t);
    +			continue;
    +		}
     		pIn += ZSTD_NbCommonBytes(diff);
     		return (size_t)(pIn - pStart);
     	}
    -	if (ZSTD_64bits()) if ((pIn<(pInLimit-3)) && (ZSTD_read32(pMatch) == ZSTD_read32(pIn))) { pIn+=4; pMatch+=4; }
    -	if ((pIn<(pInLimit-1)) && (ZSTD_read16(pMatch) == ZSTD_read16(pIn))) { pIn+=2; pMatch+=2; }
    -	if ((pIn> (32-h) ; }
    -ZSTD_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(ZSTD_readLE32(ptr), h); }   /* only in zstd_opt.h */
    +static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32 - 24)) * prime3bytes) >> (32 - h); }
    +ZSTD_STATIC size_t ZSTD_hash3Ptr(const void *ptr, U32 h) { return ZSTD_hash3(ZSTD_readLE32(ptr), h); } /* only in zstd_opt.h */
     
     static const U32 prime4bytes = 2654435761U;
    -static U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
    -static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(ZSTD_read32(ptr), h); }
    +static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32 - h); }
    +static size_t ZSTD_hash4Ptr(const void *ptr, U32 h) { return ZSTD_hash4(ZSTD_read32(ptr), h); }
     
     static const U64 prime5bytes = 889523592379ULL;
    -static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(ZSTD_readLE64(p), h); }
    +static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64 - 40)) * prime5bytes) >> (64 - h)); }
    +static size_t ZSTD_hash5Ptr(const void *p, U32 h) { return ZSTD_hash5(ZSTD_readLE64(p), h); }
     
     static const U64 prime6bytes = 227718039650203ULL;
    -static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(ZSTD_readLE64(p), h); }
    +static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64 - 48)) * prime6bytes) >> (64 - h)); }
    +static size_t ZSTD_hash6Ptr(const void *p, U32 h) { return ZSTD_hash6(ZSTD_readLE64(p), h); }
     
     static const U64 prime7bytes = 58295818150454627ULL;
    -static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(ZSTD_readLE64(p), h); }
    +static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64 - 56)) * prime7bytes) >> (64 - h)); }
    +static size_t ZSTD_hash7Ptr(const void *p, U32 h) { return ZSTD_hash7(ZSTD_readLE64(p), h); }
     
     static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
    -static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
    -static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(ZSTD_readLE64(p), h); }
    +static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u)*prime8bytes) >> (64 - h)); }
    +static size_t ZSTD_hash8Ptr(const void *p, U32 h) { return ZSTD_hash8(ZSTD_readLE64(p), h); }
     
    -static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
    +static size_t ZSTD_hashPtr(const void *p, U32 hBits, U32 mls)
     {
    -	switch(mls)
    -	{
    -	//case 3: return ZSTD_hash3Ptr(p, hBits);
    +	switch (mls) {
    +	// case 3: return ZSTD_hash3Ptr(p, hBits);
     	default:
     	case 4: return ZSTD_hash4Ptr(p, hBits);
     	case 5: return ZSTD_hash5Ptr(p, hBits);
    @@ -898,78 +972,81 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
     	}
     }
     
    -
     /*-*************************************
     *  Fast Scan
     ***************************************/
    -static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
    +static void ZSTD_fillHashTable(ZSTD_CCtx *zc, const void *end, const U32 mls)
     {
    -	U32* const hashTable = zc->hashTable;
    -	U32  const hBits = zc->params.cParams.hashLog;
    -	const BYTE* const base = zc->base;
    -	const BYTE* ip = base + zc->nextToUpdate;
    -	const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    +	U32 *const hashTable = zc->hashTable;
    +	U32 const hBits = zc->params.cParams.hashLog;
    +	const BYTE *const base = zc->base;
    +	const BYTE *ip = base + zc->nextToUpdate;
    +	const BYTE *const iend = ((const BYTE *)end) - HASH_READ_SIZE;
     	const size_t fastHashFillStep = 3;
     
    -	while(ip <= iend) {
    +	while (ip <= iend) {
     		hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
     		ip += fastHashFillStep;
     	}
     }
     
    -
     FORCE_INLINE
    -void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
    -							   const void* src, size_t srcSize,
    -							   const U32 mls)
    +void ZSTD_compressBlock_fast_generic(ZSTD_CCtx *cctx, const void *src, size_t srcSize, const U32 mls)
     {
    -	U32* const hashTable = cctx->hashTable;
    -	U32  const hBits = cctx->params.cParams.hashLog;
    -	seqStore_t* seqStorePtr = &(cctx->seqStore);
    -	const BYTE* const base = cctx->base;
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    -	const U32   lowestIndex = cctx->dictLimit;
    -	const BYTE* const lowest = base + lowestIndex;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - HASH_READ_SIZE;
    -	U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
    +	U32 *const hashTable = cctx->hashTable;
    +	U32 const hBits = cctx->params.cParams.hashLog;
    +	seqStore_t *seqStorePtr = &(cctx->seqStore);
    +	const BYTE *const base = cctx->base;
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
    +	const U32 lowestIndex = cctx->dictLimit;
    +	const BYTE *const lowest = base + lowestIndex;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - HASH_READ_SIZE;
    +	U32 offset_1 = cctx->rep[0], offset_2 = cctx->rep[1];
     	U32 offsetSaved = 0;
     
     	/* init */
    -	ip += (ip==lowest);
    -	{	U32 const maxRep = (U32)(ip-lowest);
    -		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
    -		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
    +	ip += (ip == lowest);
    +	{
    +		U32 const maxRep = (U32)(ip - lowest);
    +		if (offset_2 > maxRep)
    +			offsetSaved = offset_2, offset_2 = 0;
    +		if (offset_1 > maxRep)
    +			offsetSaved = offset_1, offset_1 = 0;
     	}
     
     	/* Main Search Loop */
    -	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
    +	while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
     		size_t mLength;
     		size_t const h = ZSTD_hashPtr(ip, hBits, mls);
    -		U32 const curr = (U32)(ip-base);
    +		U32 const curr = (U32)(ip - base);
     		U32 const matchIndex = hashTable[h];
    -		const BYTE* match = base + matchIndex;
    -		hashTable[h] = curr;   /* update hash table */
    +		const BYTE *match = base + matchIndex;
    +		hashTable[h] = curr; /* update hash table */
     
    -		if ((offset_1 > 0) & (ZSTD_read32(ip+1-offset_1) == ZSTD_read32(ip+1))) {
    -			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    +		if ((offset_1 > 0) & (ZSTD_read32(ip + 1 - offset_1) == ZSTD_read32(ip + 1))) {
    +			mLength = ZSTD_count(ip + 1 + 4, ip + 1 + 4 - offset_1, iend) + 4;
     			ip++;
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH);
     		} else {
     			U32 offset;
    -			if ( (matchIndex <= lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip)) ) {
    -				ip += ((ip-anchor) >> g_searchStrength) + 1;
    +			if ((matchIndex <= lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip))) {
    +				ip += ((ip - anchor) >> g_searchStrength) + 1;
     				continue;
     			}
    -			mLength = ZSTD_count(ip+4, match+4, iend) + 4;
    -			offset = (U32)(ip-match);
    -			while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
    +			mLength = ZSTD_count(ip + 4, match + 4, iend) + 4;
    +			offset = (U32)(ip - match);
    +			while (((ip > anchor) & (match > lowest)) && (ip[-1] == match[-1])) {
    +				ip--;
    +				match--;
    +				mLength++;
    +			} /* catch up */
     			offset_2 = offset_1;
     			offset_1 = offset;
     
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH);
     		}
     
     		/* match found */
    @@ -978,109 +1055,109 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
    -			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
    +			hashTable[ZSTD_hashPtr(base + curr + 2, hBits, mls)] = curr + 2; /* here because curr+2 could be > iend-8 */
    +			hashTable[ZSTD_hashPtr(ip - 2, hBits, mls)] = (U32)(ip - 2 - base);
     			/* check immediate repcode */
    -			while ( (ip <= ilimit)
    -				 && ( (offset_2>0)
    -				 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
    +			while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) {
     				/* store sequence */
    -				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
    -				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; }  /* swap offset_2 <=> offset_1 */
    -				hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
    -				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
    +				size_t const rLength = ZSTD_count(ip + 4, ip + 4 - offset_2, iend) + 4;
    +				{
    +					U32 const tmpOff = offset_2;
    +					offset_2 = offset_1;
    +					offset_1 = tmpOff;
    +				} /* swap offset_2 <=> offset_1 */
    +				hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
    +				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength - MINMATCH);
     				ip += rLength;
     				anchor = ip;
    -				continue;   /* faster when present ... (?) */
    -	}   }   }
    +				continue; /* faster when present ... (?) */
    +			}
    +		}
    +	}
     
     	/* save reps for next block */
     	cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
     	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
    -					   const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_fast(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	const U32 mls = ctx->params.cParams.searchLength;
    -	switch(mls)
    -	{
    +	switch (mls) {
     	default: /* includes case 3 */
    -	case 4 :
    -		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
    -	case 5 :
    -		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
    -	case 6 :
    -		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
    -	case 7 :
    -		ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
    +	case 4: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
    +	case 5: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
    +	case 6: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
    +	case 7: ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
    -								 const void* src, size_t srcSize,
    -								 const U32 mls)
    +static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 mls)
     {
    -	U32* hashTable = ctx->hashTable;
    +	U32 *hashTable = ctx->hashTable;
     	const U32 hBits = ctx->params.cParams.hashLog;
    -	seqStore_t* seqStorePtr = &(ctx->seqStore);
    -	const BYTE* const base = ctx->base;
    -	const BYTE* const dictBase = ctx->dictBase;
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    -	const U32   lowestIndex = ctx->lowLimit;
    -	const BYTE* const dictStart = dictBase + lowestIndex;
    -	const U32   dictLimit = ctx->dictLimit;
    -	const BYTE* const lowPrefixPtr = base + dictLimit;
    -	const BYTE* const dictEnd = dictBase + dictLimit;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - 8;
    -	U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
    +	seqStore_t *seqStorePtr = &(ctx->seqStore);
    +	const BYTE *const base = ctx->base;
    +	const BYTE *const dictBase = ctx->dictBase;
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
    +	const U32 lowestIndex = ctx->lowLimit;
    +	const BYTE *const dictStart = dictBase + lowestIndex;
    +	const U32 dictLimit = ctx->dictLimit;
    +	const BYTE *const lowPrefixPtr = base + dictLimit;
    +	const BYTE *const dictEnd = dictBase + dictLimit;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - 8;
    +	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
     
     	/* Search Loop */
    -	while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
    +	while (ip < ilimit) { /* < instead of <=, because (ip+1) */
     		const size_t h = ZSTD_hashPtr(ip, hBits, mls);
     		const U32 matchIndex = hashTable[h];
    -		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
    -		const BYTE* match = matchBase + matchIndex;
    -		const U32 curr = (U32)(ip-base);
    -		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
    -		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
    -		const BYTE* repMatch = repBase + repIndex;
    +		const BYTE *matchBase = matchIndex < dictLimit ? dictBase : base;
    +		const BYTE *match = matchBase + matchIndex;
    +		const U32 curr = (U32)(ip - base);
    +		const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */
    +		const BYTE *repBase = repIndex < dictLimit ? dictBase : base;
    +		const BYTE *repMatch = repBase + repIndex;
     		size_t mLength;
    -		hashTable[h] = curr;   /* update hash table */
    +		hashTable[h] = curr; /* update hash table */
     
    -		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    -		   && (ZSTD_read32(repMatch) == ZSTD_read32(ip+1)) ) {
    -			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    -			mLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
    +		if ((((U32)((dictLimit - 1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex)) &&
    +		    (ZSTD_read32(repMatch) == ZSTD_read32(ip + 1))) {
    +			const BYTE *repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    +			mLength = ZSTD_count_2segments(ip + 1 + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
     			ip++;
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH);
     		} else {
    -			if ( (matchIndex < lowestIndex) ||
    -				 (ZSTD_read32(match) != ZSTD_read32(ip)) ) {
    -				ip += ((ip-anchor) >> g_searchStrength) + 1;
    +			if ((matchIndex < lowestIndex) || (ZSTD_read32(match) != ZSTD_read32(ip))) {
    +				ip += ((ip - anchor) >> g_searchStrength) + 1;
     				continue;
     			}
    -			{	const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    -				const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
    +			{
    +				const BYTE *matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    +				const BYTE *lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
     				U32 offset;
    -				mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
    -				while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    +				mLength = ZSTD_count_2segments(ip + EQUAL_READ32, match + EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
    +				while (((ip > anchor) & (match > lowMatchPtr)) && (ip[-1] == match[-1])) {
    +					ip--;
    +					match--;
    +					mLength++;
    +				} /* catch up */
     				offset = curr - matchIndex;
     				offset_2 = offset_1;
     				offset_1 = offset;
    -				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    -		}   }
    +				ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH);
    +			}
    +		}
     
     		/* found a match : store it */
     		ip += mLength;
    @@ -1088,153 +1165,164 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashTable[ZSTD_hashPtr(base+curr+2, hBits, mls)] = curr+2;
    -			hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
    +			hashTable[ZSTD_hashPtr(base + curr + 2, hBits, mls)] = curr + 2;
    +			hashTable[ZSTD_hashPtr(ip - 2, hBits, mls)] = (U32)(ip - 2 - base);
     			/* check immediate repcode */
     			while (ip <= ilimit) {
    -				U32 const curr2 = (U32)(ip-base);
    +				U32 const curr2 = (U32)(ip - base);
     				U32 const repIndex2 = curr2 - offset_2;
    -				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    -				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    -				   && (ZSTD_read32(repMatch2) == ZSTD_read32(ip)) ) {
    -					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    -					size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    -					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    -					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    +				const BYTE *repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    +				if ((((U32)((dictLimit - 1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
    +				    && (ZSTD_read32(repMatch2) == ZSTD_read32(ip))) {
    +					const BYTE *const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    +					size_t repLength2 =
    +					    ZSTD_count_2segments(ip + EQUAL_READ32, repMatch2 + EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    +					U32 tmpOffset = offset_2;
    +					offset_2 = offset_1;
    +					offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
    +					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2 - MINMATCH);
     					hashTable[ZSTD_hashPtr(ip, hBits, mls)] = curr2;
     					ip += repLength2;
     					anchor = ip;
     					continue;
     				}
     				break;
    -	}   }   }
    +			}
    +		}
    +	}
     
     	/* save reps for next block */
    -	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    +	ctx->repToConfirm[0] = offset_1;
    +	ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
    -						 const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	U32 const mls = ctx->params.cParams.searchLength;
    -	switch(mls)
    -	{
    +	switch (mls) {
     	default: /* includes case 3 */
    -	case 4 :
    -		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
    -	case 5 :
    -		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
    -	case 6 :
    -		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
    -	case 7 :
    -		ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
    +	case 4: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
    +	case 5: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
    +	case 6: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
    +	case 7: ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
     	}
     }
     
    -
     /*-*************************************
     *  Double Fast
     ***************************************/
    -static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
    +static void ZSTD_fillDoubleHashTable(ZSTD_CCtx *cctx, const void *end, const U32 mls)
     {
    -	U32* const hashLarge = cctx->hashTable;
    -	U32  const hBitsL = cctx->params.cParams.hashLog;
    -	U32* const hashSmall = cctx->chainTable;
    -	U32  const hBitsS = cctx->params.cParams.chainLog;
    -	const BYTE* const base = cctx->base;
    -	const BYTE* ip = base + cctx->nextToUpdate;
    -	const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    +	U32 *const hashLarge = cctx->hashTable;
    +	U32 const hBitsL = cctx->params.cParams.hashLog;
    +	U32 *const hashSmall = cctx->chainTable;
    +	U32 const hBitsS = cctx->params.cParams.chainLog;
    +	const BYTE *const base = cctx->base;
    +	const BYTE *ip = base + cctx->nextToUpdate;
    +	const BYTE *const iend = ((const BYTE *)end) - HASH_READ_SIZE;
     	const size_t fastHashFillStep = 3;
     
    -	while(ip <= iend) {
    +	while (ip <= iend) {
     		hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
     		hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
     		ip += fastHashFillStep;
     	}
     }
     
    -
     FORCE_INLINE
    -void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
    -								 const void* src, size_t srcSize,
    -								 const U32 mls)
    +void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx *cctx, const void *src, size_t srcSize, const U32 mls)
     {
    -	U32* const hashLong = cctx->hashTable;
    +	U32 *const hashLong = cctx->hashTable;
     	const U32 hBitsL = cctx->params.cParams.hashLog;
    -	U32* const hashSmall = cctx->chainTable;
    +	U32 *const hashSmall = cctx->chainTable;
     	const U32 hBitsS = cctx->params.cParams.chainLog;
    -	seqStore_t* seqStorePtr = &(cctx->seqStore);
    -	const BYTE* const base = cctx->base;
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    +	seqStore_t *seqStorePtr = &(cctx->seqStore);
    +	const BYTE *const base = cctx->base;
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
     	const U32 lowestIndex = cctx->dictLimit;
    -	const BYTE* const lowest = base + lowestIndex;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - HASH_READ_SIZE;
    -	U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
    +	const BYTE *const lowest = base + lowestIndex;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - HASH_READ_SIZE;
    +	U32 offset_1 = cctx->rep[0], offset_2 = cctx->rep[1];
     	U32 offsetSaved = 0;
     
     	/* init */
    -	ip += (ip==lowest);
    -	{	U32 const maxRep = (U32)(ip-lowest);
    -		if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
    -		if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
    +	ip += (ip == lowest);
    +	{
    +		U32 const maxRep = (U32)(ip - lowest);
    +		if (offset_2 > maxRep)
    +			offsetSaved = offset_2, offset_2 = 0;
    +		if (offset_1 > maxRep)
    +			offsetSaved = offset_1, offset_1 = 0;
     	}
     
     	/* Main Search Loop */
    -	while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */
    +	while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
     		size_t mLength;
     		size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
     		size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
    -		U32 const curr = (U32)(ip-base);
    +		U32 const curr = (U32)(ip - base);
     		U32 const matchIndexL = hashLong[h2];
     		U32 const matchIndexS = hashSmall[h];
    -		const BYTE* matchLong = base + matchIndexL;
    -		const BYTE* match = base + matchIndexS;
    -		hashLong[h2] = hashSmall[h] = curr;   /* update hash tables */
    +		const BYTE *matchLong = base + matchIndexL;
    +		const BYTE *match = base + matchIndexS;
    +		hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
     
    -		if ((offset_1 > 0) & (ZSTD_read32(ip+1-offset_1) == ZSTD_read32(ip+1))) { /* note : by construction, offset_1 <= curr */
    -			mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
    +		if ((offset_1 > 0) & (ZSTD_read32(ip + 1 - offset_1) == ZSTD_read32(ip + 1))) { /* note : by construction, offset_1 <= curr */
    +			mLength = ZSTD_count(ip + 1 + 4, ip + 1 + 4 - offset_1, iend) + 4;
     			ip++;
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH);
     		} else {
     			U32 offset;
    -			if ( (matchIndexL > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip)) ) {
    -				mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
    -				offset = (U32)(ip-matchLong);
    -				while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
    -			} else if ( (matchIndexS > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip)) ) {
    -				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
    +			if ((matchIndexL > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip))) {
    +				mLength = ZSTD_count(ip + 8, matchLong + 8, iend) + 8;
    +				offset = (U32)(ip - matchLong);
    +				while (((ip > anchor) & (matchLong > lowest)) && (ip[-1] == matchLong[-1])) {
    +					ip--;
    +					matchLong--;
    +					mLength++;
    +				} /* catch up */
    +			} else if ((matchIndexS > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip))) {
    +				size_t const h3 = ZSTD_hashPtr(ip + 1, hBitsL, 8);
     				U32 const matchIndex3 = hashLong[h3];
    -				const BYTE* match3 = base + matchIndex3;
    +				const BYTE *match3 = base + matchIndex3;
     				hashLong[h3] = curr + 1;
    -				if ( (matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip+1)) ) {
    -					mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
    +				if ((matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip + 1))) {
    +					mLength = ZSTD_count(ip + 9, match3 + 8, iend) + 8;
     					ip++;
    -					offset = (U32)(ip-match3);
    -					while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
    +					offset = (U32)(ip - match3);
    +					while (((ip > anchor) & (match3 > lowest)) && (ip[-1] == match3[-1])) {
    +						ip--;
    +						match3--;
    +						mLength++;
    +					} /* catch up */
     				} else {
    -					mLength = ZSTD_count(ip+4, match+4, iend) + 4;
    -					offset = (U32)(ip-match);
    -					while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
    +					mLength = ZSTD_count(ip + 4, match + 4, iend) + 4;
    +					offset = (U32)(ip - match);
    +					while (((ip > anchor) & (match > lowest)) && (ip[-1] == match[-1])) {
    +						ip--;
    +						match--;
    +						mLength++;
    +					} /* catch up */
     				}
     			} else {
    -				ip += ((ip-anchor) >> g_searchStrength) + 1;
    +				ip += ((ip - anchor) >> g_searchStrength) + 1;
     				continue;
     			}
     
     			offset_2 = offset_1;
     			offset_1 = offset;
     
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH);
     		}
     
     		/* match found */
    @@ -1243,145 +1331,153 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] =
    -				hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;  /* here because curr+2 could be > iend-8 */
    -			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
    -				hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
    +			hashLong[ZSTD_hashPtr(base + curr + 2, hBitsL, 8)] = hashSmall[ZSTD_hashPtr(base + curr + 2, hBitsS, mls)] =
    +			    curr + 2; /* here because curr+2 could be > iend-8 */
    +			hashLong[ZSTD_hashPtr(ip - 2, hBitsL, 8)] = hashSmall[ZSTD_hashPtr(ip - 2, hBitsS, mls)] = (U32)(ip - 2 - base);
     
     			/* check immediate repcode */
    -			while ( (ip <= ilimit)
    -				 && ( (offset_2>0)
    -				 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
    +			while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) {
     				/* store sequence */
    -				size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
    -				{ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
    -				hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
    -				hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
    -				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
    +				size_t const rLength = ZSTD_count(ip + 4, ip + 4 - offset_2, iend) + 4;
    +				{
    +					U32 const tmpOff = offset_2;
    +					offset_2 = offset_1;
    +					offset_1 = tmpOff;
    +				} /* swap offset_2 <=> offset_1 */
    +				hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
    +				hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
    +				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength - MINMATCH);
     				ip += rLength;
     				anchor = ip;
    -				continue;   /* faster when present ... (?) */
    -	}   }   }
    +				continue; /* faster when present ... (?) */
    +			}
    +		}
    +	}
     
     	/* save reps for next block */
     	cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
     	cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	const U32 mls = ctx->params.cParams.searchLength;
    -	switch(mls)
    -	{
    +	switch (mls) {
     	default: /* includes case 3 */
    -	case 4 :
    -		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
    -	case 5 :
    -		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
    -	case 6 :
    -		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
    -	case 7 :
    -		ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
    +	case 4: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
    +	case 5: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
    +	case 6: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
    +	case 7: ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
    -								 const void* src, size_t srcSize,
    -								 const U32 mls)
    +static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 mls)
     {
    -	U32* const hashLong = ctx->hashTable;
    -	U32  const hBitsL = ctx->params.cParams.hashLog;
    -	U32* const hashSmall = ctx->chainTable;
    -	U32  const hBitsS = ctx->params.cParams.chainLog;
    -	seqStore_t* seqStorePtr = &(ctx->seqStore);
    -	const BYTE* const base = ctx->base;
    -	const BYTE* const dictBase = ctx->dictBase;
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    -	const U32   lowestIndex = ctx->lowLimit;
    -	const BYTE* const dictStart = dictBase + lowestIndex;
    -	const U32   dictLimit = ctx->dictLimit;
    -	const BYTE* const lowPrefixPtr = base + dictLimit;
    -	const BYTE* const dictEnd = dictBase + dictLimit;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - 8;
    -	U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
    +	U32 *const hashLong = ctx->hashTable;
    +	U32 const hBitsL = ctx->params.cParams.hashLog;
    +	U32 *const hashSmall = ctx->chainTable;
    +	U32 const hBitsS = ctx->params.cParams.chainLog;
    +	seqStore_t *seqStorePtr = &(ctx->seqStore);
    +	const BYTE *const base = ctx->base;
    +	const BYTE *const dictBase = ctx->dictBase;
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
    +	const U32 lowestIndex = ctx->lowLimit;
    +	const BYTE *const dictStart = dictBase + lowestIndex;
    +	const U32 dictLimit = ctx->dictLimit;
    +	const BYTE *const lowPrefixPtr = base + dictLimit;
    +	const BYTE *const dictEnd = dictBase + dictLimit;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - 8;
    +	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
     
     	/* Search Loop */
    -	while (ip < ilimit) {  /* < instead of <=, because (ip+1) */
    +	while (ip < ilimit) { /* < instead of <=, because (ip+1) */
     		const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
     		const U32 matchIndex = hashSmall[hSmall];
    -		const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
    -		const BYTE* match = matchBase + matchIndex;
    +		const BYTE *matchBase = matchIndex < dictLimit ? dictBase : base;
    +		const BYTE *match = matchBase + matchIndex;
     
     		const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
     		const U32 matchLongIndex = hashLong[hLong];
    -		const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
    -		const BYTE* matchLong = matchLongBase + matchLongIndex;
    +		const BYTE *matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
    +		const BYTE *matchLong = matchLongBase + matchLongIndex;
     
    -		const U32 curr = (U32)(ip-base);
    -		const U32 repIndex = curr + 1 - offset_1;   /* offset_1 expected <= curr +1 */
    -		const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
    -		const BYTE* repMatch = repBase + repIndex;
    +		const U32 curr = (U32)(ip - base);
    +		const U32 repIndex = curr + 1 - offset_1; /* offset_1 expected <= curr +1 */
    +		const BYTE *repBase = repIndex < dictLimit ? dictBase : base;
    +		const BYTE *repMatch = repBase + repIndex;
     		size_t mLength;
    -		hashSmall[hSmall] = hashLong[hLong] = curr;   /* update hash table */
    +		hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
     
    -		if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
    -		   && (ZSTD_read32(repMatch) == ZSTD_read32(ip+1)) ) {
    -			const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    -			mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
    +		if ((((U32)((dictLimit - 1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex)) &&
    +		    (ZSTD_read32(repMatch) == ZSTD_read32(ip + 1))) {
    +			const BYTE *repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
    +			mLength = ZSTD_count_2segments(ip + 1 + 4, repMatch + 4, iend, repMatchEnd, lowPrefixPtr) + 4;
     			ip++;
    -			ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
    +			ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, 0, mLength - MINMATCH);
     		} else {
     			if ((matchLongIndex > lowestIndex) && (ZSTD_read64(matchLong) == ZSTD_read64(ip))) {
    -				const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
    -				const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
    +				const BYTE *matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
    +				const BYTE *lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
     				U32 offset;
    -				mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
    +				mLength = ZSTD_count_2segments(ip + 8, matchLong + 8, iend, matchEnd, lowPrefixPtr) + 8;
     				offset = curr - matchLongIndex;
    -				while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */
    +				while (((ip > anchor) & (matchLong > lowMatchPtr)) && (ip[-1] == matchLong[-1])) {
    +					ip--;
    +					matchLong--;
    +					mLength++;
    +				} /* catch up */
     				offset_2 = offset_1;
     				offset_1 = offset;
    -				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    +				ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH);
     
     			} else if ((matchIndex > lowestIndex) && (ZSTD_read32(match) == ZSTD_read32(ip))) {
    -				size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
    +				size_t const h3 = ZSTD_hashPtr(ip + 1, hBitsL, 8);
     				U32 const matchIndex3 = hashLong[h3];
    -				const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
    -				const BYTE* match3 = match3Base + matchIndex3;
    +				const BYTE *const match3Base = matchIndex3 < dictLimit ? dictBase : base;
    +				const BYTE *match3 = match3Base + matchIndex3;
     				U32 offset;
     				hashLong[h3] = curr + 1;
    -				if ( (matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip+1)) ) {
    -					const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
    -					const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
    -					mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
    +				if ((matchIndex3 > lowestIndex) && (ZSTD_read64(match3) == ZSTD_read64(ip + 1))) {
    +					const BYTE *matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
    +					const BYTE *lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
    +					mLength = ZSTD_count_2segments(ip + 9, match3 + 8, iend, matchEnd, lowPrefixPtr) + 8;
     					ip++;
    -					offset = curr+1 - matchIndex3;
    -					while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
    +					offset = curr + 1 - matchIndex3;
    +					while (((ip > anchor) & (match3 > lowMatchPtr)) && (ip[-1] == match3[-1])) {
    +						ip--;
    +						match3--;
    +						mLength++;
    +					} /* catch up */
     				} else {
    -					const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    -					const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
    -					mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
    +					const BYTE *matchEnd = matchIndex < dictLimit ? dictEnd : iend;
    +					const BYTE *lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
    +					mLength = ZSTD_count_2segments(ip + 4, match + 4, iend, matchEnd, lowPrefixPtr) + 4;
     					offset = curr - matchIndex;
    -					while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */
    +					while (((ip > anchor) & (match > lowMatchPtr)) && (ip[-1] == match[-1])) {
    +						ip--;
    +						match--;
    +						mLength++;
    +					} /* catch up */
     				}
     				offset_2 = offset_1;
     				offset_1 = offset;
    -				ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
    +				ZSTD_storeSeq(seqStorePtr, ip - anchor, anchor, offset + ZSTD_REP_MOVE, mLength - MINMATCH);
     
     			} else {
    -				ip += ((ip-anchor) >> g_searchStrength) + 1;
    +				ip += ((ip - anchor) >> g_searchStrength) + 1;
     				continue;
    -		}   }
    +			}
    +		}
     
     		/* found a match : store it */
     		ip += mLength;
    @@ -1389,21 +1485,24 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     
     		if (ip <= ilimit) {
     			/* Fill Table */
    -			hashSmall[ZSTD_hashPtr(base+curr+2, hBitsS, mls)] = curr+2;
    -			hashLong[ZSTD_hashPtr(base+curr+2, hBitsL, 8)] = curr+2;
    -			hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
    -			hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
    +			hashSmall[ZSTD_hashPtr(base + curr + 2, hBitsS, mls)] = curr + 2;
    +			hashLong[ZSTD_hashPtr(base + curr + 2, hBitsL, 8)] = curr + 2;
    +			hashSmall[ZSTD_hashPtr(ip - 2, hBitsS, mls)] = (U32)(ip - 2 - base);
    +			hashLong[ZSTD_hashPtr(ip - 2, hBitsL, 8)] = (U32)(ip - 2 - base);
     			/* check immediate repcode */
     			while (ip <= ilimit) {
    -				U32 const curr2 = (U32)(ip-base);
    +				U32 const curr2 = (U32)(ip - base);
     				U32 const repIndex2 = curr2 - offset_2;
    -				const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    -				if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex))  /* intentional overflow */
    -				   && (ZSTD_read32(repMatch2) == ZSTD_read32(ip)) ) {
    -					const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    -					size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    -					U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
    -					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
    +				const BYTE *repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
    +				if ((((U32)((dictLimit - 1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
    +				    && (ZSTD_read32(repMatch2) == ZSTD_read32(ip))) {
    +					const BYTE *const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
    +					size_t const repLength2 =
    +					    ZSTD_count_2segments(ip + EQUAL_READ32, repMatch2 + EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
    +					U32 tmpOffset = offset_2;
    +					offset_2 = offset_1;
    +					offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
    +					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2 - MINMATCH);
     					hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = curr2;
     					hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = curr2;
     					ip += repLength2;
    @@ -1411,85 +1510,80 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     					continue;
     				}
     				break;
    -	}   }   }
    +			}
    +		}
    +	}
     
     	/* save reps for next block */
    -	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    +	ctx->repToConfirm[0] = offset_1;
    +	ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    -
    -static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
    -						 const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	U32 const mls = ctx->params.cParams.searchLength;
    -	switch(mls)
    -	{
    +	switch (mls) {
     	default: /* includes case 3 */
    -	case 4 :
    -		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
    -	case 5 :
    -		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
    -	case 6 :
    -		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
    -	case 7 :
    -		ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
    +	case 4: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
    +	case 5: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
    +	case 6: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
    +	case 7: ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
     	}
     }
     
    -
     /*-*************************************
     *  Binary Tree search
     ***************************************/
     /** ZSTD_insertBt1() : add one or multiple positions to tree.
     *   ip : assumed <= iend-8 .
     *   @return : nb of positions added */
    -static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
    -						  U32 extDict)
    +static U32 ZSTD_insertBt1(ZSTD_CCtx *zc, const BYTE *const ip, const U32 mls, const BYTE *const iend, U32 nbCompares, U32 extDict)
     {
    -	U32*   const hashTable = zc->hashTable;
    -	U32    const hashLog = zc->params.cParams.hashLog;
    -	size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
    -	U32*   const bt = zc->chainTable;
    -	U32    const btLog  = zc->params.cParams.chainLog - 1;
    -	U32    const btMask = (1 << btLog) - 1;
    +	U32 *const hashTable = zc->hashTable;
    +	U32 const hashLog = zc->params.cParams.hashLog;
    +	size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
    +	U32 *const bt = zc->chainTable;
    +	U32 const btLog = zc->params.cParams.chainLog - 1;
    +	U32 const btMask = (1 << btLog) - 1;
     	U32 matchIndex = hashTable[h];
    -	size_t commonLengthSmaller=0, commonLengthLarger=0;
    -	const BYTE* const base = zc->base;
    -	const BYTE* const dictBase = zc->dictBase;
    +	size_t commonLengthSmaller = 0, commonLengthLarger = 0;
    +	const BYTE *const base = zc->base;
    +	const BYTE *const dictBase = zc->dictBase;
     	const U32 dictLimit = zc->dictLimit;
    -	const BYTE* const dictEnd = dictBase + dictLimit;
    -	const BYTE* const prefixStart = base + dictLimit;
    -	const BYTE* match;
    -	const U32 curr = (U32)(ip-base);
    +	const BYTE *const dictEnd = dictBase + dictLimit;
    +	const BYTE *const prefixStart = base + dictLimit;
    +	const BYTE *match;
    +	const U32 curr = (U32)(ip - base);
     	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
    -	U32* smallerPtr = bt + 2*(curr&btMask);
    -	U32* largerPtr  = smallerPtr + 1;
    -	U32 dummy32;   /* to be nullified at the end */
    +	U32 *smallerPtr = bt + 2 * (curr & btMask);
    +	U32 *largerPtr = smallerPtr + 1;
    +	U32 dummy32; /* to be nullified at the end */
     	U32 const windowLow = zc->lowLimit;
    -	U32 matchEndIdx = curr+8;
    +	U32 matchEndIdx = curr + 8;
     	size_t bestLength = 8;
     
    -	hashTable[h] = curr;   /* Update Hash Table */
    +	hashTable[h] = curr; /* Update Hash Table */
     
     	while (nbCompares-- && (matchIndex > windowLow)) {
    -		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    -		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
    +		U32 *const nextPtr = bt + 2 * (matchIndex & btMask);
    +		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
     
    -		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
    +		if ((!extDict) || (matchIndex + matchLength >= dictLimit)) {
     			match = base + matchIndex;
     			if (match[matchLength] == ip[matchLength])
    -				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
    +				matchLength += ZSTD_count(ip + matchLength + 1, match + matchLength + 1, iend) + 1;
     		} else {
     			match = dictBase + matchIndex;
    -			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
    -			if (matchIndex+matchLength >= dictLimit)
    -				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
    +			matchLength += ZSTD_count_2segments(ip + matchLength, match + matchLength, iend, dictEnd, prefixStart);
    +			if (matchIndex + matchLength >= dictLimit)
    +				match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
     		}
     
     		if (matchLength > bestLength) {
    @@ -1498,212 +1592,205 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
     				matchEndIdx = matchIndex + (U32)matchLength;
     		}
     
    -		if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
    -			break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
    +		if (ip + matchLength == iend) /* equal : no way to know if inf or sup */
    +			break;		      /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
     
    -		if (match[matchLength] < ip[matchLength]) {  /* necessarily within correct buffer */
    +		if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */
     			/* match is smaller than curr */
    -			*smallerPtr = matchIndex;             /* update smaller idx */
    -			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
    -			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
    +			*smallerPtr = matchIndex;	  /* update smaller idx */
    +			commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
    +			if (matchIndex <= btLow) {
    +				smallerPtr = &dummy32;
    +				break;
    +			}			  /* beyond tree size, stop the search */
    +			smallerPtr = nextPtr + 1; /* new "smaller" => larger of match */
    +			matchIndex = nextPtr[1];  /* new matchIndex larger than previous (closer to curr) */
     		} else {
     			/* match is larger than curr */
     			*largerPtr = matchIndex;
     			commonLengthLarger = matchLength;
    -			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    +			if (matchIndex <= btLow) {
    +				largerPtr = &dummy32;
    +				break;
    +			} /* beyond tree size, stop the search */
     			largerPtr = nextPtr;
     			matchIndex = nextPtr[0];
    -	}   }
    +		}
    +	}
     
     	*smallerPtr = *largerPtr = 0;
    -	if (bestLength > 384) return MIN(192, (U32)(bestLength - 384));   /* speed optimization */
    -	if (matchEndIdx > curr + 8) return matchEndIdx - curr - 8;
    +	if (bestLength > 384)
    +		return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
    +	if (matchEndIdx > curr + 8)
    +		return matchEndIdx - curr - 8;
     	return 1;
     }
     
    -
    -static size_t ZSTD_insertBtAndFindBestMatch (
    -						ZSTD_CCtx* zc,
    -						const BYTE* const ip, const BYTE* const iend,
    -						size_t* offsetPtr,
    -						U32 nbCompares, const U32 mls,
    -						U32 extDict)
    +static size_t ZSTD_insertBtAndFindBestMatch(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, size_t *offsetPtr, U32 nbCompares, const U32 mls,
    +					    U32 extDict)
     {
    -	U32*   const hashTable = zc->hashTable;
    -	U32    const hashLog = zc->params.cParams.hashLog;
    -	size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
    -	U32*   const bt = zc->chainTable;
    -	U32    const btLog  = zc->params.cParams.chainLog - 1;
    -	U32    const btMask = (1 << btLog) - 1;
    -	U32 matchIndex  = hashTable[h];
    -	size_t commonLengthSmaller=0, commonLengthLarger=0;
    -	const BYTE* const base = zc->base;
    -	const BYTE* const dictBase = zc->dictBase;
    +	U32 *const hashTable = zc->hashTable;
    +	U32 const hashLog = zc->params.cParams.hashLog;
    +	size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
    +	U32 *const bt = zc->chainTable;
    +	U32 const btLog = zc->params.cParams.chainLog - 1;
    +	U32 const btMask = (1 << btLog) - 1;
    +	U32 matchIndex = hashTable[h];
    +	size_t commonLengthSmaller = 0, commonLengthLarger = 0;
    +	const BYTE *const base = zc->base;
    +	const BYTE *const dictBase = zc->dictBase;
     	const U32 dictLimit = zc->dictLimit;
    -	const BYTE* const dictEnd = dictBase + dictLimit;
    -	const BYTE* const prefixStart = base + dictLimit;
    -	const U32 curr = (U32)(ip-base);
    +	const BYTE *const dictEnd = dictBase + dictLimit;
    +	const BYTE *const prefixStart = base + dictLimit;
    +	const U32 curr = (U32)(ip - base);
     	const U32 btLow = btMask >= curr ? 0 : curr - btMask;
     	const U32 windowLow = zc->lowLimit;
    -	U32* smallerPtr = bt + 2*(curr&btMask);
    -	U32* largerPtr  = bt + 2*(curr&btMask) + 1;
    -	U32 matchEndIdx = curr+8;
    -	U32 dummy32;   /* to be nullified at the end */
    +	U32 *smallerPtr = bt + 2 * (curr & btMask);
    +	U32 *largerPtr = bt + 2 * (curr & btMask) + 1;
    +	U32 matchEndIdx = curr + 8;
    +	U32 dummy32; /* to be nullified at the end */
     	size_t bestLength = 0;
     
    -	hashTable[h] = curr;   /* Update Hash Table */
    +	hashTable[h] = curr; /* Update Hash Table */
     
     	while (nbCompares-- && (matchIndex > windowLow)) {
    -		U32* const nextPtr = bt + 2*(matchIndex & btMask);
    -		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
    -		const BYTE* match;
    +		U32 *const nextPtr = bt + 2 * (matchIndex & btMask);
    +		size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
    +		const BYTE *match;
     
    -		if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
    +		if ((!extDict) || (matchIndex + matchLength >= dictLimit)) {
     			match = base + matchIndex;
     			if (match[matchLength] == ip[matchLength])
    -				matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
    +				matchLength += ZSTD_count(ip + matchLength + 1, match + matchLength + 1, iend) + 1;
     		} else {
     			match = dictBase + matchIndex;
    -			matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
    -			if (matchIndex+matchLength >= dictLimit)
    -				match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
    +			matchLength += ZSTD_count_2segments(ip + matchLength, match + matchLength, iend, dictEnd, prefixStart);
    +			if (matchIndex + matchLength >= dictLimit)
    +				match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
     		}
     
     		if (matchLength > bestLength) {
     			if (matchLength > matchEndIdx - matchIndex)
     				matchEndIdx = matchIndex + (U32)matchLength;
    -			if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
    +			if ((4 * (int)(matchLength - bestLength)) > (int)(ZSTD_highbit32(curr - matchIndex + 1) - ZSTD_highbit32((U32)offsetPtr[0] + 1)))
     				bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
    -			if (ip+matchLength == iend)   /* equal : no way to know if inf or sup */
    -				break;   /* drop, to guarantee consistency (miss a little bit of compression) */
    +			if (ip + matchLength == iend) /* equal : no way to know if inf or sup */
    +				break;		      /* drop, to guarantee consistency (miss a little bit of compression) */
     		}
     
     		if (match[matchLength] < ip[matchLength]) {
     			/* match is smaller than curr */
    -			*smallerPtr = matchIndex;             /* update smaller idx */
    -			commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
    -			if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    -			smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
    -			matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to curr) */
    +			*smallerPtr = matchIndex;	  /* update smaller idx */
    +			commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
    +			if (matchIndex <= btLow) {
    +				smallerPtr = &dummy32;
    +				break;
    +			}			  /* beyond tree size, stop the search */
    +			smallerPtr = nextPtr + 1; /* new "smaller" => larger of match */
    +			matchIndex = nextPtr[1];  /* new matchIndex larger than previous (closer to curr) */
     		} else {
     			/* match is larger than curr */
     			*largerPtr = matchIndex;
     			commonLengthLarger = matchLength;
    -			if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
    +			if (matchIndex <= btLow) {
    +				largerPtr = &dummy32;
    +				break;
    +			} /* beyond tree size, stop the search */
     			largerPtr = nextPtr;
     			matchIndex = nextPtr[0];
    -	}   }
    +		}
    +	}
     
     	*smallerPtr = *largerPtr = 0;
     
    -	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr+1;
    +	zc->nextToUpdate = (matchEndIdx > curr + 8) ? matchEndIdx - 8 : curr + 1;
     	return bestLength;
     }
     
    -
    -static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
    +static void ZSTD_updateTree(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, const U32 nbCompares, const U32 mls)
     {
    -	const BYTE* const base = zc->base;
    +	const BYTE *const base = zc->base;
     	const U32 target = (U32)(ip - base);
     	U32 idx = zc->nextToUpdate;
     
    -	while(idx < target)
    -		idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
    +	while (idx < target)
    +		idx += ZSTD_insertBt1(zc, base + idx, mls, iend, nbCompares, 0);
     }
     
     /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
    -static size_t ZSTD_BtFindBestMatch (
    -						ZSTD_CCtx* zc,
    -						const BYTE* const ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 mls)
    +static size_t ZSTD_BtFindBestMatch(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls)
     {
    -	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    +	if (ip < zc->base + zc->nextToUpdate)
    +		return 0; /* skipped area */
     	ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
     	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
     }
     
    -
    -static size_t ZSTD_BtFindBestMatch_selectMLS (
    -						ZSTD_CCtx* zc,   /* Index table will be updated */
    -						const BYTE* ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 matchLengthSearch)
    +static size_t ZSTD_BtFindBestMatch_selectMLS(ZSTD_CCtx *zc, /* Index table will be updated */
    +					     const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 matchLengthSearch)
     {
    -	switch(matchLengthSearch)
    -	{
    -	default : /* includes case 3 */
    -	case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    -	case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    -	case 7 :
    -	case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
    +	switch (matchLengthSearch) {
    +	default: /* includes case 3 */
    +	case 4: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    +	case 5: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    +	case 7:
    +	case 6: return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
     	}
     }
     
    -
    -static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
    +static void ZSTD_updateTree_extDict(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iend, const U32 nbCompares, const U32 mls)
     {
    -	const BYTE* const base = zc->base;
    +	const BYTE *const base = zc->base;
     	const U32 target = (U32)(ip - base);
     	U32 idx = zc->nextToUpdate;
     
    -	while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
    +	while (idx < target)
    +		idx += ZSTD_insertBt1(zc, base + idx, mls, iend, nbCompares, 1);
     }
     
    -
     /** Tree updater, providing best match */
    -static size_t ZSTD_BtFindBestMatch_extDict (
    -						ZSTD_CCtx* zc,
    -						const BYTE* const ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 mls)
    +static size_t ZSTD_BtFindBestMatch_extDict(ZSTD_CCtx *zc, const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts,
    +					   const U32 mls)
     {
    -	if (ip < zc->base + zc->nextToUpdate) return 0;   /* skipped area */
    +	if (ip < zc->base + zc->nextToUpdate)
    +		return 0; /* skipped area */
     	ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
     	return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
     }
     
    -
    -static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
    -						ZSTD_CCtx* zc,   /* Index table will be updated */
    -						const BYTE* ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 matchLengthSearch)
    +static size_t ZSTD_BtFindBestMatch_selectMLS_extDict(ZSTD_CCtx *zc, /* Index table will be updated */
    +						     const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts,
    +						     const U32 matchLengthSearch)
     {
    -	switch(matchLengthSearch)
    -	{
    -	default : /* includes case 3 */
    -	case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    -	case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    -	case 7 :
    -	case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
    +	switch (matchLengthSearch) {
    +	default: /* includes case 3 */
    +	case 4: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
    +	case 5: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
    +	case 7:
    +	case 6: return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
     	}
     }
     
    -
    -
     /* *********************************
     *  Hash Chain
     ***********************************/
    -#define NEXT_IN_CHAIN(d, mask)   chainTable[(d) & mask]
    +#define NEXT_IN_CHAIN(d, mask) chainTable[(d)&mask]
     
     /* Update chains up to ip (excluded)
        Assumption : always within prefix (i.e. not within extDict) */
     FORCE_INLINE
    -U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
    +U32 ZSTD_insertAndFindFirstIndex(ZSTD_CCtx *zc, const BYTE *ip, U32 mls)
     {
    -	U32* const hashTable  = zc->hashTable;
    +	U32 *const hashTable = zc->hashTable;
     	const U32 hashLog = zc->params.cParams.hashLog;
    -	U32* const chainTable = zc->chainTable;
    +	U32 *const chainTable = zc->chainTable;
     	const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
    -	const BYTE* const base = zc->base;
    +	const BYTE *const base = zc->base;
     	const U32 target = (U32)(ip - base);
     	U32 idx = zc->nextToUpdate;
     
    -	while(idx < target) { /* catch up */
    -		size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
    +	while (idx < target) { /* catch up */
    +		size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls);
     		NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
     		hashTable[h] = idx;
     		idx++;
    @@ -1713,274 +1800,260 @@ U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
     	return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
     }
     
    -
    -
     FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
    -size_t ZSTD_HcFindBestMatch_generic (
    -						ZSTD_CCtx* zc,   /* Index table will be updated */
    -						const BYTE* const ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 mls, const U32 extDict)
    +    size_t
    +    ZSTD_HcFindBestMatch_generic(ZSTD_CCtx *zc, /* Index table will be updated */
    +				 const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls, const U32 extDict)
     {
    -	U32* const chainTable = zc->chainTable;
    +	U32 *const chainTable = zc->chainTable;
     	const U32 chainSize = (1 << zc->params.cParams.chainLog);
    -	const U32 chainMask = chainSize-1;
    -	const BYTE* const base = zc->base;
    -	const BYTE* const dictBase = zc->dictBase;
    +	const U32 chainMask = chainSize - 1;
    +	const BYTE *const base = zc->base;
    +	const BYTE *const dictBase = zc->dictBase;
     	const U32 dictLimit = zc->dictLimit;
    -	const BYTE* const prefixStart = base + dictLimit;
    -	const BYTE* const dictEnd = dictBase + dictLimit;
    +	const BYTE *const prefixStart = base + dictLimit;
    +	const BYTE *const dictEnd = dictBase + dictLimit;
     	const U32 lowLimit = zc->lowLimit;
    -	const U32 curr = (U32)(ip-base);
    +	const U32 curr = (U32)(ip - base);
     	const U32 minChain = curr > chainSize ? curr - chainSize : 0;
    -	int nbAttempts=maxNbAttempts;
    -	size_t ml=EQUAL_READ32-1;
    +	int nbAttempts = maxNbAttempts;
    +	size_t ml = EQUAL_READ32 - 1;
     
     	/* HC4 match finder */
    -	U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
    +	U32 matchIndex = ZSTD_insertAndFindFirstIndex(zc, ip, mls);
     
    -	for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
    -		const BYTE* match;
    -		size_t currMl=0;
    +	for (; (matchIndex > lowLimit) & (nbAttempts > 0); nbAttempts--) {
    +		const BYTE *match;
    +		size_t currMl = 0;
     		if ((!extDict) || matchIndex >= dictLimit) {
     			match = base + matchIndex;
    -			if (match[ml] == ip[ml])   /* potentially better */
    +			if (match[ml] == ip[ml]) /* potentially better */
     				currMl = ZSTD_count(ip, match, iLimit);
     		} else {
     			match = dictBase + matchIndex;
    -			if (ZSTD_read32(match) == ZSTD_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    -				currMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
    +			if (ZSTD_read32(match) == ZSTD_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
    +				currMl = ZSTD_count_2segments(ip + EQUAL_READ32, match + EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
     		}
     
     		/* save best solution */
    -		if (currMl > ml) { ml = currMl; *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE; if (ip+currMl == iLimit) break; /* best possible, and avoid read overflow*/ }
    +		if (currMl > ml) {
    +			ml = currMl;
    +			*offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
    +			if (ip + currMl == iLimit)
    +				break; /* best possible, and avoid read overflow*/
    +		}
     
    -		if (matchIndex <= minChain) break;
    +		if (matchIndex <= minChain)
    +			break;
     		matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
     	}
     
     	return ml;
     }
     
    -
    -FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
    -						ZSTD_CCtx* zc,
    -						const BYTE* ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 matchLengthSearch)
    +FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS(ZSTD_CCtx *zc, const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts,
    +						   const U32 matchLengthSearch)
     {
    -	switch(matchLengthSearch)
    -	{
    -	default : /* includes case 3 */
    -	case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
    -	case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
    -	case 7 :
    -	case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
    +	switch (matchLengthSearch) {
    +	default: /* includes case 3 */
    +	case 4: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
    +	case 5: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
    +	case 7:
    +	case 6: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
     	}
     }
     
    -
    -FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
    -						ZSTD_CCtx* zc,
    -						const BYTE* ip, const BYTE* const iLimit,
    -						size_t* offsetPtr,
    -						const U32 maxNbAttempts, const U32 matchLengthSearch)
    +FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS(ZSTD_CCtx *zc, const BYTE *ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts,
    +							   const U32 matchLengthSearch)
     {
    -	switch(matchLengthSearch)
    -	{
    -	default : /* includes case 3 */
    -	case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
    -	case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
    -	case 7 :
    -	case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
    +	switch (matchLengthSearch) {
    +	default: /* includes case 3 */
    +	case 4: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
    +	case 5: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
    +	case 7:
    +	case 6: return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
     	}
     }
     
    -
     /* *******************************
     *  Common parser - lazy strategy
     *********************************/
     FORCE_INLINE
    -void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
    -									 const void* src, size_t srcSize,
    -									 const U32 searchMethod, const U32 depth)
    +void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 searchMethod, const U32 depth)
     {
    -	seqStore_t* seqStorePtr = &(ctx->seqStore);
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - 8;
    -	const BYTE* const base = ctx->base + ctx->dictLimit;
    +	seqStore_t *seqStorePtr = &(ctx->seqStore);
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - 8;
    +	const BYTE *const base = ctx->base + ctx->dictLimit;
     
     	U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
     	U32 const mls = ctx->params.cParams.searchLength;
     
    -	typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
    -						size_t* offsetPtr,
    -						U32 maxNbAttempts, U32 matchLengthSearch);
    +	typedef size_t (*searchMax_f)(ZSTD_CCtx * zc, const BYTE *ip, const BYTE *iLimit, size_t *offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch);
     	searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
    -	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset=0;
    +	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset = 0;
     
     	/* init */
    -	ip += (ip==base);
    +	ip += (ip == base);
     	ctx->nextToUpdate3 = ctx->nextToUpdate;
    -	{	U32 const maxRep = (U32)(ip-base);
    -		if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
    -		if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
    +	{
    +		U32 const maxRep = (U32)(ip - base);
    +		if (offset_2 > maxRep)
    +			savedOffset = offset_2, offset_2 = 0;
    +		if (offset_1 > maxRep)
    +			savedOffset = offset_1, offset_1 = 0;
     	}
     
     	/* Match Loop */
     	while (ip < ilimit) {
    -		size_t matchLength=0;
    -		size_t offset=0;
    -		const BYTE* start=ip+1;
    +		size_t matchLength = 0;
    +		size_t offset = 0;
    +		const BYTE *start = ip + 1;
     
     		/* check repCode */
    -		if ((offset_1>0) & (ZSTD_read32(ip+1) == ZSTD_read32(ip+1 - offset_1))) {
    +		if ((offset_1 > 0) & (ZSTD_read32(ip + 1) == ZSTD_read32(ip + 1 - offset_1))) {
     			/* repcode : we take it */
    -			matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    -			if (depth==0) goto _storeSequence;
    +			matchLength = ZSTD_count(ip + 1 + EQUAL_READ32, ip + 1 + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32;
    +			if (depth == 0)
    +				goto _storeSequence;
     		}
     
     		/* first search (depth 0) */
    -		{	size_t offsetFound = 99999999;
    +		{
    +			size_t offsetFound = 99999999;
     			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
     			if (ml2 > matchLength)
    -				matchLength = ml2, start = ip, offset=offsetFound;
    +				matchLength = ml2, start = ip, offset = offsetFound;
     		}
     
     		if (matchLength < EQUAL_READ32) {
    -			ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
    +			ip += ((ip - anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
     			continue;
     		}
     
     		/* let's try to find a better solution */
    -		if (depth>=1)
    -		while (ip0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
    -				size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    -				int const gain2 = (int)(mlRep * 3);
    -				int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
    -				if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
    -					matchLength = mlRep, offset = 0, start = ip;
    -			}
    -			{	size_t offset2=99999999;
    -				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    -				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    -				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    -				if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    -					matchLength = ml2, offset = offset2, start = ip;
    -					continue;   /* search a better one */
    -			}   }
    -
    -			/* let's find an even better one */
    -			if ((depth==2) && (ip0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
    -					size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
    -					int const gain2 = (int)(ml2 * 4);
    -					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
    -					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
    -						matchLength = ml2, offset = 0, start = ip;
    +		if (depth >= 1)
    +			while (ip < ilimit) {
    +				ip++;
    +				if ((offset) && ((offset_1 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
    +					size_t const mlRep = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32;
    +					int const gain2 = (int)(mlRep * 3);
    +					int const gain1 = (int)(matchLength * 3 - ZSTD_highbit32((U32)offset + 1) + 1);
    +					if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
    +						matchLength = mlRep, offset = 0, start = ip;
     				}
    -				{	size_t offset2=99999999;
    +				{
    +					size_t offset2 = 99999999;
     					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    -					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    -					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    +					int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */
    +					int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 4);
     					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
     						matchLength = ml2, offset = offset2, start = ip;
    -						continue;
    -			}   }   }
    -			break;  /* nothing found : store previous solution */
    -		}
    +						continue; /* search a better one */
    +					}
    +				}
    +
    +				/* let's find an even better one */
    +				if ((depth == 2) && (ip < ilimit)) {
    +					ip++;
    +					if ((offset) && ((offset_1 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_1)))) {
    +						size_t const ml2 = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_1, iend) + EQUAL_READ32;
    +						int const gain2 = (int)(ml2 * 4);
    +						int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 1);
    +						if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
    +							matchLength = ml2, offset = 0, start = ip;
    +					}
    +					{
    +						size_t offset2 = 99999999;
    +						size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    +						int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */
    +						int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 7);
    +						if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    +							matchLength = ml2, offset = offset2, start = ip;
    +							continue;
    +						}
    +					}
    +				}
    +				break; /* nothing found : store previous solution */
    +			}
     
     		/* catch up */
     		if (offset) {
    -			while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE]))   /* only search for offset within prefix */
    -				{ start--; matchLength++; }
    -			offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
    +			while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) &&
    +			       (start[-1] == start[-1 - offset + ZSTD_REP_MOVE])) /* only search for offset within prefix */
    +			{
    +				start--;
    +				matchLength++;
    +			}
    +			offset_2 = offset_1;
    +			offset_1 = (U32)(offset - ZSTD_REP_MOVE);
     		}
     
    -		/* store sequence */
    -_storeSequence:
    -		{	size_t const litLength = start - anchor;
    -			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
    -			anchor = ip = start + matchLength;
    -		}
    +	/* store sequence */
    +	_storeSequence : {
    +		size_t const litLength = start - anchor;
    +		ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH);
    +		anchor = ip = start + matchLength;
    +	}
     
     		/* check immediate repcode */
    -		while ( (ip <= ilimit)
    -			 && ((offset_2>0)
    -			 & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)) )) {
    +		while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) {
     			/* store sequence */
    -			matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
    -			offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
    -			ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
    +			matchLength = ZSTD_count(ip + EQUAL_READ32, ip + EQUAL_READ32 - offset_2, iend) + EQUAL_READ32;
    +			offset = offset_2;
    +			offset_2 = offset_1;
    +			offset_1 = (U32)offset; /* swap repcodes */
    +			ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength - MINMATCH);
     			ip += matchLength;
     			anchor = ip;
    -			continue;   /* faster when present ... (?) */
    -	}   }
    +			continue; /* faster when present ... (?) */
    +		}
    +	}
     
     	/* Save reps for next block */
     	ctx->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
     	ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    +static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2); }
     
    -static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    -{
    -	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
    -}
    +static void ZSTD_compressBlock_lazy2(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2); }
     
    -static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    -{
    -	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
    -}
    -
    -static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    -{
    -	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
    -}
    -
    -static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    -{
    -	ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
    -}
    +static void ZSTD_compressBlock_lazy(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1); }
     
    +static void ZSTD_compressBlock_greedy(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0); }
     
     FORCE_INLINE
    -void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
    -									 const void* src, size_t srcSize,
    -									 const U32 searchMethod, const U32 depth)
    +void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx *ctx, const void *src, size_t srcSize, const U32 searchMethod, const U32 depth)
     {
    -	seqStore_t* seqStorePtr = &(ctx->seqStore);
    -	const BYTE* const istart = (const BYTE*)src;
    -	const BYTE* ip = istart;
    -	const BYTE* anchor = istart;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* const ilimit = iend - 8;
    -	const BYTE* const base = ctx->base;
    +	seqStore_t *seqStorePtr = &(ctx->seqStore);
    +	const BYTE *const istart = (const BYTE *)src;
    +	const BYTE *ip = istart;
    +	const BYTE *anchor = istart;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *const ilimit = iend - 8;
    +	const BYTE *const base = ctx->base;
     	const U32 dictLimit = ctx->dictLimit;
     	const U32 lowestIndex = ctx->lowLimit;
    -	const BYTE* const prefixStart = base + dictLimit;
    -	const BYTE* const dictBase = ctx->dictBase;
    -	const BYTE* const dictEnd  = dictBase + dictLimit;
    -	const BYTE* const dictStart  = dictBase + ctx->lowLimit;
    +	const BYTE *const prefixStart = base + dictLimit;
    +	const BYTE *const dictBase = ctx->dictBase;
    +	const BYTE *const dictEnd = dictBase + dictLimit;
    +	const BYTE *const dictStart = dictBase + ctx->lowLimit;
     
     	const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
     	const U32 mls = ctx->params.cParams.searchLength;
     
    -	typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
    -						size_t* offsetPtr,
    -						U32 maxNbAttempts, U32 matchLengthSearch);
    +	typedef size_t (*searchMax_f)(ZSTD_CCtx * zc, const BYTE *ip, const BYTE *iLimit, size_t *offsetPtr, U32 maxNbAttempts, U32 matchLengthSearch);
     	searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
     
     	U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
    @@ -1991,237 +2064,266 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     
     	/* Match Loop */
     	while (ip < ilimit) {
    -		size_t matchLength=0;
    -		size_t offset=0;
    -		const BYTE* start=ip+1;
    -		U32 curr = (U32)(ip-base);
    +		size_t matchLength = 0;
    +		size_t offset = 0;
    +		const BYTE *start = ip + 1;
    +		U32 curr = (U32)(ip - base);
     
     		/* check repCode */
    -		{	const U32 repIndex = (U32)(curr+1 - offset_1);
    -			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
    -			const BYTE* const repMatch = repBase + repIndex;
    -			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */
    -			if (ZSTD_read32(ip+1) == ZSTD_read32(repMatch)) {
    -				/* repcode detected we should take it */
    -				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    -				matchLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    -				if (depth==0) goto _storeSequence;
    -		}   }
    -
    -		/* first search (depth 0) */
    -		{	size_t offsetFound = 99999999;
    -			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
    -			if (ml2 > matchLength)
    -				matchLength = ml2, start = ip, offset=offsetFound;
    +		{
    +			const U32 repIndex = (U32)(curr + 1 - offset_1);
    +			const BYTE *const repBase = repIndex < dictLimit ? dictBase : base;
    +			const BYTE *const repMatch = repBase + repIndex;
    +			if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
    +				if (ZSTD_read32(ip + 1) == ZSTD_read32(repMatch)) {
    +					/* repcode detected we should take it */
    +					const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend;
    +					matchLength =
    +					    ZSTD_count_2segments(ip + 1 + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    +					if (depth == 0)
    +						goto _storeSequence;
    +				}
     		}
     
    -		 if (matchLength < EQUAL_READ32) {
    -			ip += ((ip-anchor) >> g_searchStrength) + 1;   /* jump faster over incompressible sections */
    +		/* first search (depth 0) */
    +		{
    +			size_t offsetFound = 99999999;
    +			size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
    +			if (ml2 > matchLength)
    +				matchLength = ml2, start = ip, offset = offsetFound;
    +		}
    +
    +		if (matchLength < EQUAL_READ32) {
    +			ip += ((ip - anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
     			continue;
     		}
     
     		/* let's try to find a better solution */
    -		if (depth>=1)
    -		while (ip= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -				if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    -					/* repcode detected */
    -					const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    -					size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    -					int const gain2 = (int)(repLength * 3);
    -					int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
    -					if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    -						matchLength = repLength, offset = 0, start = ip;
    -			}   }
    -
    -			/* search match, depth 1 */
    -			{	size_t offset2=99999999;
    -				size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    -				int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    -				int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
    -				if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    -					matchLength = ml2, offset = offset2, start = ip;
    -					continue;   /* search a better one */
    -			}   }
    -
    -			/* let's find an even better one */
    -			if ((depth==2) && (ip= 1)
    +			while (ip < ilimit) {
    +				ip++;
     				curr++;
     				/* check repCode */
     				if (offset) {
     					const U32 repIndex = (U32)(curr - offset_1);
    -					const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
    -					const BYTE* const repMatch = repBase + repIndex;
    -					if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -					if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    -						/* repcode detected */
    -						const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    -						size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    -						int gain2 = (int)(repLength * 4);
    -						int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
    -						if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    -							matchLength = repLength, offset = 0, start = ip;
    -				}   }
    +					const BYTE *const repBase = repIndex < dictLimit ? dictBase : base;
    +					const BYTE *const repMatch = repBase + repIndex;
    +					if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
    +						if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    +							/* repcode detected */
    +							const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend;
    +							size_t const repLength =
    +							    ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) +
    +							    EQUAL_READ32;
    +							int const gain2 = (int)(repLength * 3);
    +							int const gain1 = (int)(matchLength * 3 - ZSTD_highbit32((U32)offset + 1) + 1);
    +							if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    +								matchLength = repLength, offset = 0, start = ip;
    +						}
    +				}
     
    -				/* search match, depth 2 */
    -				{	size_t offset2=99999999;
    +				/* search match, depth 1 */
    +				{
    +					size_t offset2 = 99999999;
     					size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    -					int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */
    -					int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
    +					int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */
    +					int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 4);
     					if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
     						matchLength = ml2, offset = offset2, start = ip;
    -						continue;
    -			}   }   }
    -			break;  /* nothing found : store previous solution */
    -		}
    +						continue; /* search a better one */
    +					}
    +				}
    +
    +				/* let's find an even better one */
    +				if ((depth == 2) && (ip < ilimit)) {
    +					ip++;
    +					curr++;
    +					/* check repCode */
    +					if (offset) {
    +						const U32 repIndex = (U32)(curr - offset_1);
    +						const BYTE *const repBase = repIndex < dictLimit ? dictBase : base;
    +						const BYTE *const repMatch = repBase + repIndex;
    +						if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
    +							if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    +								/* repcode detected */
    +								const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend;
    +								size_t repLength = ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend,
    +													repEnd, prefixStart) +
    +										   EQUAL_READ32;
    +								int gain2 = (int)(repLength * 4);
    +								int gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 1);
    +								if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
    +									matchLength = repLength, offset = 0, start = ip;
    +							}
    +					}
    +
    +					/* search match, depth 2 */
    +					{
    +						size_t offset2 = 99999999;
    +						size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
    +						int const gain2 = (int)(ml2 * 4 - ZSTD_highbit32((U32)offset2 + 1)); /* raw approx */
    +						int const gain1 = (int)(matchLength * 4 - ZSTD_highbit32((U32)offset + 1) + 7);
    +						if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
    +							matchLength = ml2, offset = offset2, start = ip;
    +							continue;
    +						}
    +					}
    +				}
    +				break; /* nothing found : store previous solution */
    +			}
     
     		/* catch up */
     		if (offset) {
    -			U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
    -			const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
    -			const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
    -			while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; }  /* catch up */
    -			offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
    +			U32 const matchIndex = (U32)((start - base) - (offset - ZSTD_REP_MOVE));
    +			const BYTE *match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
    +			const BYTE *const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
    +			while ((start > anchor) && (match > mStart) && (start[-1] == match[-1])) {
    +				start--;
    +				match--;
    +				matchLength++;
    +			} /* catch up */
    +			offset_2 = offset_1;
    +			offset_1 = (U32)(offset - ZSTD_REP_MOVE);
     		}
     
    -		/* store sequence */
    -_storeSequence:
    -		{	size_t const litLength = start - anchor;
    -			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
    -			anchor = ip = start + matchLength;
    -		}
    +	/* store sequence */
    +	_storeSequence : {
    +		size_t const litLength = start - anchor;
    +		ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH);
    +		anchor = ip = start + matchLength;
    +	}
     
     		/* check immediate repcode */
     		while (ip <= ilimit) {
    -			const U32 repIndex = (U32)((ip-base) - offset_2);
    -			const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
    -			const BYTE* const repMatch = repBase + repIndex;
    -			if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */
    -			if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    -				/* repcode detected we should take it */
    -				const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
    -				matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    -				offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset;   /* swap offset history */
    -				ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
    -				ip += matchLength;
    -				anchor = ip;
    -				continue;   /* faster when present ... (?) */
    -			}
    +			const U32 repIndex = (U32)((ip - base) - offset_2);
    +			const BYTE *const repBase = repIndex < dictLimit ? dictBase : base;
    +			const BYTE *const repMatch = repBase + repIndex;
    +			if (((U32)((dictLimit - 1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
    +				if (ZSTD_read32(ip) == ZSTD_read32(repMatch)) {
    +					/* repcode detected we should take it */
    +					const BYTE *const repEnd = repIndex < dictLimit ? dictEnd : iend;
    +					matchLength =
    +					    ZSTD_count_2segments(ip + EQUAL_READ32, repMatch + EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
    +					offset = offset_2;
    +					offset_2 = offset_1;
    +					offset_1 = (U32)offset; /* swap offset history */
    +					ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength - MINMATCH);
    +					ip += matchLength;
    +					anchor = ip;
    +					continue; /* faster when present ... (?) */
    +				}
     			break;
    -	}   }
    +		}
    +	}
     
     	/* Save reps for next block */
    -	ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
    +	ctx->repToConfirm[0] = offset_1;
    +	ctx->repToConfirm[1] = offset_2;
     
     	/* Last Literals */
    -	{	size_t const lastLLSize = iend - anchor;
    +	{
    +		size_t const lastLLSize = iend - anchor;
     		memcpy(seqStorePtr->lit, anchor, lastLLSize);
     		seqStorePtr->lit += lastLLSize;
     	}
     }
     
    +void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize) { ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0); }
     
    -void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    -{
    -	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
    -}
    -
    -static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
     }
     
    -static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
     }
     
    -static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     	ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
     }
     
    -
     /* The optimal parser */
     #include "zstd_opt.h"
     
    -static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_btopt(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     #ifdef ZSTD_OPT_H_91842398743
     	ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
     #else
    -	(void)ctx; (void)src; (void)srcSize;
    +	(void)ctx;
    +	(void)src;
    +	(void)srcSize;
     	return;
     #endif
     }
     
    -static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_btopt2(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     #ifdef ZSTD_OPT_H_91842398743
     	ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
     #else
    -	(void)ctx; (void)src; (void)srcSize;
    +	(void)ctx;
    +	(void)src;
    +	(void)srcSize;
     	return;
     #endif
     }
     
    -static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     #ifdef ZSTD_OPT_H_91842398743
     	ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
     #else
    -	(void)ctx; (void)src; (void)srcSize;
    +	(void)ctx;
    +	(void)src;
    +	(void)srcSize;
     	return;
     #endif
     }
     
    -static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
    +static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx *ctx, const void *src, size_t srcSize)
     {
     #ifdef ZSTD_OPT_H_91842398743
     	ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
     #else
    -	(void)ctx; (void)src; (void)srcSize;
    +	(void)ctx;
    +	(void)src;
    +	(void)srcSize;
     	return;
     #endif
     }
     
    -
    -typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
    +typedef void (*ZSTD_blockCompressor)(ZSTD_CCtx *ctx, const void *src, size_t srcSize);
     
     static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
     {
     	static const ZSTD_blockCompressor blockCompressor[2][8] = {
    -		{ ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
    -		{ ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
    -	};
    +	    {ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2,
    +	     ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2},
    +	    {ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,
    +	     ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict}};
     
     	return blockCompressor[extDict][(U32)strat];
     }
     
    -
    -static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +static size_t ZSTD_compressBlock_internal(ZSTD_CCtx *zc, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
    -	const BYTE* const base = zc->base;
    -	const BYTE* const istart = (const BYTE*)src;
    -	const U32 curr = (U32)(istart-base);
    -	if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0;   /* don't even attempt compression below a certain srcSize */
    +	const BYTE *const base = zc->base;
    +	const BYTE *const istart = (const BYTE *)src;
    +	const U32 curr = (U32)(istart - base);
    +	if (srcSize < MIN_CBLOCK_SIZE + ZSTD_blockHeaderSize + 1)
    +		return 0; /* don't even attempt compression below a certain srcSize */
     	ZSTD_resetSeqStore(&(zc->seqStore));
     	if (curr > zc->nextToUpdate + 384)
    -		zc->nextToUpdate = curr - MIN(192, (U32)(curr - zc->nextToUpdate - 384));   /* update tree not updated after finding very long rep matches */
    +		zc->nextToUpdate = curr - MIN(192, (U32)(curr - zc->nextToUpdate - 384)); /* update tree not updated after finding very long rep matches */
     	blockCompressor(zc, src, srcSize);
     	return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
     }
     
    -
     /*! ZSTD_compress_generic() :
     *   Compress a chunk of data into one or multiple blocks.
     *   All blocks will be terminated, all input will be consumed.
    @@ -2229,16 +2331,13 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCa
     *   Frame is supposed already started (header already produced)
     *   @return : compressed size, or an error code
     */
    -static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    -									 void* dst, size_t dstCapacity,
    -							   const void* src, size_t srcSize,
    -									 U32 lastFrameChunk)
    +static size_t ZSTD_compress_generic(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 lastFrameChunk)
     {
     	size_t blockSize = cctx->blockSize;
     	size_t remaining = srcSize;
    -	const BYTE* ip = (const BYTE*)src;
    -	BYTE* const ostart = (BYTE*)dst;
    -	BYTE* op = ostart;
    +	const BYTE *ip = (const BYTE *)src;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *op = ostart;
     	U32 const maxDist = 1 << cctx->params.cParams.windowLog;
     
     	if (cctx->params.fParams.checksumFlag && srcSize)
    @@ -2248,11 +2347,13 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     		U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
     		size_t cSize;
     
    -		if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall);   /* not enough space to store compressed block */
    -		if (remaining < blockSize) blockSize = remaining;
    +		if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
    +			return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
    +		if (remaining < blockSize)
    +			blockSize = remaining;
     
     		/* preemptive overflow correction */
    -		if (cctx->lowLimit > (3U<<29)) {
    +		if (cctx->lowLimit > (3U << 29)) {
     			U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
     			U32 const curr = (U32)(ip - cctx->base);
     			U32 const newCurr = (curr & cycleMask) + (1 << cctx->params.cParams.windowLog);
    @@ -2263,28 +2364,34 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     			cctx->dictBase += correction;
     			cctx->lowLimit -= correction;
     			cctx->dictLimit -= correction;
    -			if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
    -			else cctx->nextToUpdate -= correction;
    +			if (cctx->nextToUpdate < correction)
    +				cctx->nextToUpdate = 0;
    +			else
    +				cctx->nextToUpdate -= correction;
     		}
     
    -		if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
    +		if ((U32)(ip + blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
     			/* enforce maxDist */
    -			U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
    -			if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
    -			if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
    +			U32 const newLowLimit = (U32)(ip + blockSize - cctx->base) - maxDist;
    +			if (cctx->lowLimit < newLowLimit)
    +				cctx->lowLimit = newLowLimit;
    +			if (cctx->dictLimit < cctx->lowLimit)
    +				cctx->dictLimit = cctx->lowLimit;
     		}
     
    -		cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
    -		if (ZSTD_isError(cSize)) return cSize;
    +		cSize = ZSTD_compressBlock_internal(cctx, op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize, ip, blockSize);
    +		if (ZSTD_isError(cSize))
    +			return cSize;
     
    -		if (cSize == 0) {  /* block is not compressible */
    -			U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
    -			if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
    -			ZSTD_writeLE32(op, cBlockHeader24);   /* no pb, 4th byte will be overwritten */
    +		if (cSize == 0) { /* block is not compressible */
    +			U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw) << 1) + (U32)(blockSize << 3);
    +			if (blockSize + ZSTD_blockHeaderSize > dstCapacity)
    +				return ERROR(dstSize_tooSmall);
    +			ZSTD_writeLE32(op, cBlockHeader24); /* no pb, 4th byte will be overwritten */
     			memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
    -			cSize = ZSTD_blockHeaderSize+blockSize;
    +			cSize = ZSTD_blockHeaderSize + blockSize;
     		} else {
    -			U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
    +			U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed) << 1) + (U32)(cSize << 3);
     			ZSTD_writeLE24(op, cBlockHeader24);
     			cSize += ZSTD_blockHeaderSize;
     		}
    @@ -2295,65 +2402,85 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     		op += cSize;
     	}
     
    -	if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
    -	return op-ostart;
    +	if (lastFrameChunk && (op > ostart))
    +		cctx->stage = ZSTDcs_ending;
    +	return op - ostart;
     }
     
    -
    -static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
    -									ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
    -{   BYTE* const op = (BYTE*)dst;
    -	U32   const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536);   /* 0-3 */
    -	U32   const checksumFlag = params.fParams.checksumFlag>0;
    -	U32   const windowSize = 1U << params.cParams.windowLog;
    -	U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
    -	BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
    -	U32   const fcsCode = params.fParams.contentSizeFlag ?
    -					 (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) :   /* 0-3 */
    -					  0;
    -	BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
    +static size_t ZSTD_writeFrameHeader(void *dst, size_t dstCapacity, ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
    +{
    +	BYTE *const op = (BYTE *)dst;
    +	U32 const dictIDSizeCode = (dictID > 0) + (dictID >= 256) + (dictID >= 65536); /* 0-3 */
    +	U32 const checksumFlag = params.fParams.checksumFlag > 0;
    +	U32 const windowSize = 1U << params.cParams.windowLog;
    +	U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
    +	BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
    +	U32 const fcsCode = params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU)
    +							   : /* 0-3 */
    +				0;
    +	BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag << 2) + (singleSegment << 5) + (fcsCode << 6));
     	size_t pos;
     
    -	if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
    +	if (dstCapacity < ZSTD_frameHeaderSize_max)
    +		return ERROR(dstSize_tooSmall);
     
     	ZSTD_writeLE32(dst, ZSTD_MAGICNUMBER);
    -	op[4] = frameHeaderDecriptionByte; pos=5;
    -	if (!singleSegment) op[pos++] = windowLogByte;
    -	switch(dictIDSizeCode)
    -	{
    -		default:   /* impossible */
    -		case 0 : break;
    -		case 1 : op[pos] = (BYTE)(dictID); pos++; break;
    -		case 2 : ZSTD_writeLE16(op+pos, (U16)dictID); pos+=2; break;
    -		case 3 : ZSTD_writeLE32(op+pos, dictID); pos+=4; break;
    +	op[4] = frameHeaderDecriptionByte;
    +	pos = 5;
    +	if (!singleSegment)
    +		op[pos++] = windowLogByte;
    +	switch (dictIDSizeCode) {
    +	default: /* impossible */
    +	case 0: break;
    +	case 1:
    +		op[pos] = (BYTE)(dictID);
    +		pos++;
    +		break;
    +	case 2:
    +		ZSTD_writeLE16(op + pos, (U16)dictID);
    +		pos += 2;
    +		break;
    +	case 3:
    +		ZSTD_writeLE32(op + pos, dictID);
    +		pos += 4;
    +		break;
     	}
    -	switch(fcsCode)
    -	{
    -		default:   /* impossible */
    -		case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
    -		case 1 : ZSTD_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
    -		case 2 : ZSTD_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
    -		case 3 : ZSTD_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
    +	switch (fcsCode) {
    +	default: /* impossible */
    +	case 0:
    +		if (singleSegment)
    +			op[pos++] = (BYTE)(pledgedSrcSize);
    +		break;
    +	case 1:
    +		ZSTD_writeLE16(op + pos, (U16)(pledgedSrcSize - 256));
    +		pos += 2;
    +		break;
    +	case 2:
    +		ZSTD_writeLE32(op + pos, (U32)(pledgedSrcSize));
    +		pos += 4;
    +		break;
    +	case 3:
    +		ZSTD_writeLE64(op + pos, (U64)(pledgedSrcSize));
    +		pos += 8;
    +		break;
     	}
     	return pos;
     }
     
    -
    -static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
    -							  void* dst, size_t dstCapacity,
    -						const void* src, size_t srcSize,
    -							   U32 frame, U32 lastFrameChunk)
    +static size_t ZSTD_compressContinue_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, U32 frame, U32 lastFrameChunk)
     {
    -	const BYTE* const ip = (const BYTE*) src;
    +	const BYTE *const ip = (const BYTE *)src;
     	size_t fhSize = 0;
     
    -	if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
    +	if (cctx->stage == ZSTDcs_created)
    +		return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
     
    -	if (frame && (cctx->stage==ZSTDcs_init)) {
    +	if (frame && (cctx->stage == ZSTDcs_init)) {
     		fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
    -		if (ZSTD_isError(fhSize)) return fhSize;
    +		if (ZSTD_isError(fhSize))
    +			return fhSize;
     		dstCapacity -= fhSize;
    -		dst = (char*)dst + fhSize;
    +		dst = (char *)dst + fhSize;
     		cctx->stage = ZSTDcs_ongoing;
     	}
     
    @@ -2366,11 +2493,12 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
     		cctx->dictBase = cctx->base;
     		cctx->base -= delta;
     		cctx->nextToUpdate = cctx->dictLimit;
    -		if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit;   /* too small extDict */
    +		if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE)
    +			cctx->lowLimit = cctx->dictLimit; /* too small extDict */
     	}
     
     	/* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
    -	if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
    +	if ((ip + srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
     		ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
     		U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
     		cctx->lowLimit = lowLimitMax;
    @@ -2379,43 +2507,37 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
     	cctx->nextSrc = ip + srcSize;
     
     	if (srcSize) {
    -		size_t const cSize = frame ?
    -							 ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
    -							 ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
    -		if (ZSTD_isError(cSize)) return cSize;
    +		size_t const cSize = frame ? ZSTD_compress_generic(cctx, dst, dstCapacity, src, srcSize, lastFrameChunk)
    +					   : ZSTD_compressBlock_internal(cctx, dst, dstCapacity, src, srcSize);
    +		if (ZSTD_isError(cSize))
    +			return cSize;
     		return cSize + fhSize;
     	} else
     		return fhSize;
     }
     
    -
    -size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
    -							  void* dst, size_t dstCapacity,
    -						const void* src, size_t srcSize)
    +size_t ZSTD_compressContinue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 0);
     }
     
    +size_t ZSTD_getBlockSizeMax(ZSTD_CCtx *cctx) { return MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog); }
     
    -size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
    -{
    -	return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
    -}
    -
    -size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +size_t ZSTD_compressBlock(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
    -	if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
    +	if (srcSize > blockSizeMax)
    +		return ERROR(srcSize_wrong);
     	return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
     }
     
     /*! ZSTD_loadDictionaryContent() :
      *  @return : 0, or an error code
      */
    -static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
    +static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx *zc, const void *src, size_t srcSize)
     {
    -	const BYTE* const ip = (const BYTE*) src;
    -	const BYTE* const iend = ip + srcSize;
    +	const BYTE *const ip = (const BYTE *)src;
    +	const BYTE *const iend = ip + srcSize;
     
     	/* input becomes curr prefix */
     	zc->lowLimit = zc->dictLimit;
    @@ -2426,55 +2548,52 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
     	zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base);
     
     	zc->nextSrc = iend;
    -	if (srcSize <= HASH_READ_SIZE) return 0;
    +	if (srcSize <= HASH_READ_SIZE)
    +		return 0;
     
    -	switch(zc->params.cParams.strategy)
    -	{
    -	case ZSTD_fast:
    -		ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
    -		break;
    +	switch (zc->params.cParams.strategy) {
    +	case ZSTD_fast: ZSTD_fillHashTable(zc, iend, zc->params.cParams.searchLength); break;
     
    -	case ZSTD_dfast:
    -		ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
    -		break;
    +	case ZSTD_dfast: ZSTD_fillDoubleHashTable(zc, iend, zc->params.cParams.searchLength); break;
     
     	case ZSTD_greedy:
     	case ZSTD_lazy:
     	case ZSTD_lazy2:
     		if (srcSize >= HASH_READ_SIZE)
    -			ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
    +			ZSTD_insertAndFindFirstIndex(zc, iend - HASH_READ_SIZE, zc->params.cParams.searchLength);
     		break;
     
     	case ZSTD_btlazy2:
     	case ZSTD_btopt:
     	case ZSTD_btopt2:
     		if (srcSize >= HASH_READ_SIZE)
    -			ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
    +			ZSTD_updateTree(zc, iend - HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
     		break;
     
     	default:
    -		return ERROR(GENERIC);   /* strategy doesn't exist; impossible */
    +		return ERROR(GENERIC); /* strategy doesn't exist; impossible */
     	}
     
     	zc->nextToUpdate = (U32)(iend - zc->base);
     	return 0;
     }
     
    -
     /* Dictionaries that assign zero probability to symbols that show up causes problems
        when FSE encoding.  Refuse dictionaries that assign zero probability to symbols
        that we may encounter during compression.
        NOTE: This behavior is not standard and could be improved in the future. */
    -static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
    +static size_t ZSTD_checkDictNCount(short *normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue)
    +{
     	U32 s;
    -	if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
    +	if (dictMaxSymbolValue < maxSymbolValue)
    +		return ERROR(dictionary_corrupted);
     	for (s = 0; s <= maxSymbolValue; ++s) {
    -		if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
    +		if (normalizedCounter[s] == 0)
    +			return ERROR(dictionary_corrupted);
     	}
     	return 0;
     }
     
    -
     /* Dictionary format :
      * See :
      * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
    @@ -2484,74 +2603,95 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
      *  assumptions : magic number supposed already checked
      *                dictSize supposed > 8
      */
    -static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    +static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t dictSize)
     {
    -	const BYTE* dictPtr = (const BYTE*)dict;
    -	const BYTE* const dictEnd = dictPtr + dictSize;
    -	short offcodeNCount[MaxOff+1];
    +	const BYTE *dictPtr = (const BYTE *)dict;
    +	const BYTE *const dictEnd = dictPtr + dictSize;
    +	short offcodeNCount[MaxOff + 1];
     	unsigned offcodeMaxValue = MaxOff;
    -	BYTE scratchBuffer[1<dictID = cctx->params.fParams.noDictIDFlag ? 0 :  ZSTD_readLE32(dictPtr);
    +	dictPtr += 4; /* skip magic number */
    +	cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : ZSTD_readLE32(dictPtr);
     	dictPtr += 4;
     
    -	{	size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd-dictPtr);
    -		if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
    +	{
    +		size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr);
    +		if (HUF_isError(hufHeaderSize))
    +			return ERROR(dictionary_corrupted);
     		dictPtr += hufHeaderSize;
     	}
     
    -	{	unsigned offcodeLog;
    -		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    +	{
    +		unsigned offcodeLog;
    +		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(offcodeHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (offcodeLog > OffFSELog)
    +			return ERROR(dictionary_corrupted);
     		/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
    -		CHECK_E (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    +		CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)),
    +			dictionary_corrupted);
     		dictPtr += offcodeHeaderSize;
     	}
     
    -	{	short matchlengthNCount[MaxML+1];
    +	{
    +		short matchlengthNCount[MaxML + 1];
     		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
    -		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
    +		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(matchlengthHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (matchlengthLog > MLFSELog)
    +			return ERROR(dictionary_corrupted);
     		/* Every match length code must have non-zero probability */
    -		CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
    -		CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    +		CHECK_F(ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
    +		CHECK_E(
    +		    FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)),
    +		    dictionary_corrupted);
     		dictPtr += matchlengthHeaderSize;
     	}
     
    -	{	short litlengthNCount[MaxLL+1];
    +	{
    +		short litlengthNCount[MaxLL + 1];
     		unsigned litlengthMaxValue = MaxLL, litlengthLog;
    -		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
    +		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(litlengthHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (litlengthLog > LLFSELog)
    +			return ERROR(dictionary_corrupted);
     		/* Every literal length code must have non-zero probability */
    -		CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
    -		CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
    +		CHECK_F(ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
    +		CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)),
    +			dictionary_corrupted);
     		dictPtr += litlengthHeaderSize;
     	}
     
    -	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    -	cctx->rep[0] = ZSTD_readLE32(dictPtr+0);
    -	cctx->rep[1] = ZSTD_readLE32(dictPtr+4);
    -	cctx->rep[2] = ZSTD_readLE32(dictPtr+8);
    +	if (dictPtr + 12 > dictEnd)
    +		return ERROR(dictionary_corrupted);
    +	cctx->rep[0] = ZSTD_readLE32(dictPtr + 0);
    +	cctx->rep[1] = ZSTD_readLE32(dictPtr + 4);
    +	cctx->rep[2] = ZSTD_readLE32(dictPtr + 8);
     	dictPtr += 12;
     
    -	{	size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
    +	{
    +		size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
     		U32 offcodeMax = MaxOff;
     		if (dictContentSize <= ((U32)-1) - 128 KB) {
     			U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
    -			offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
    +			offcodeMax = ZSTD_highbit32(maxOffset);		     /* Calculate minimum offset code required to represent maxOffset */
     		}
     		/* All offset values <= dictContentSize + 128 KB must be representable */
    -		CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
    +		CHECK_F(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
     		/* All repCodes must be <= dictContentSize and != 0*/
    -		{	U32 u;
    -			for (u=0; u<3; u++) {
    -				if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
    -				if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
    -		}   }
    +		{
    +			U32 u;
    +			for (u = 0; u < 3; u++) {
    +				if (cctx->rep[u] == 0)
    +					return ERROR(dictionary_corrupted);
    +				if (cctx->rep[u] > dictContentSize)
    +					return ERROR(dictionary_corrupted);
    +			}
    +		}
     
     		cctx->flagStaticTables = 1;
     		cctx->flagStaticHufTable = HUF_repeat_valid;
    @@ -2561,9 +2701,10 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     
     /** ZSTD_compress_insertDictionary() :
     *   @return : 0, or an error code */
    -static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    +static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx *cctx, const void *dict, size_t dictSize)
     {
    -	if ((dict==NULL) || (dictSize<=8)) return 0;
    +	if ((dict == NULL) || (dictSize <= 8))
    +		return 0;
     
     	/* dict as pure content */
     	if ((ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
    @@ -2575,56 +2716,47 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict,
     
     /*! ZSTD_compressBegin_internal() :
     *   @return : 0, or an error code */
    -static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
    -							 const void* dict, size_t dictSize,
    -								   ZSTD_parameters params, U64 pledgedSrcSize)
    +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_parameters params, U64 pledgedSrcSize)
     {
     	ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
     	CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
     	return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
     }
     
    -
     /*! ZSTD_compressBegin_advanced() :
     *   @return : 0, or an error code */
    -size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
    -							 const void* dict, size_t dictSize,
    -								   ZSTD_parameters params, unsigned long long pledgedSrcSize)
    +size_t ZSTD_compressBegin_advanced(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
     	/* compression parameters verification and optimization */
     	CHECK_F(ZSTD_checkCParams(params.cParams));
     	return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
     }
     
    -
    -size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
    +size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx *cctx, const void *dict, size_t dictSize, int compressionLevel)
     {
     	ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
     	return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
     }
     
    -
    -size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
    -{
    -	return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);
    -}
    -
    +size_t ZSTD_compressBegin(ZSTD_CCtx *cctx, int compressionLevel) { return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel); }
     
     /*! ZSTD_writeEpilogue() :
     *   Ends a frame.
     *   @return : nb of bytes written into dst (or an error code) */
    -static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
    +static size_t ZSTD_writeEpilogue(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity)
     {
    -	BYTE* const ostart = (BYTE*)dst;
    -	BYTE* op = ostart;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *op = ostart;
     	size_t fhSize = 0;
     
    -	if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong);  /* init missing */
    +	if (cctx->stage == ZSTDcs_created)
    +		return ERROR(stage_wrong); /* init missing */
     
     	/* special case : empty frame */
     	if (cctx->stage == ZSTDcs_init) {
     		fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
    -		if (ZSTD_isError(fhSize)) return fhSize;
    +		if (ZSTD_isError(fhSize))
    +			return fhSize;
     		dstCapacity -= fhSize;
     		op += fhSize;
     		cctx->stage = ZSTDcs_ongoing;
    @@ -2632,81 +2764,75 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
     
     	if (cctx->stage != ZSTDcs_ending) {
     		/* write one last empty block, make it the "last" block */
    -		U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
    -		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    +		U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw) << 1) + 0;
    +		if (dstCapacity < 4)
    +			return ERROR(dstSize_tooSmall);
     		ZSTD_writeLE32(op, cBlockHeader24);
     		op += ZSTD_blockHeaderSize;
     		dstCapacity -= ZSTD_blockHeaderSize;
     	}
     
     	if (cctx->params.fParams.checksumFlag) {
    -		U32 const checksum = (U32) xxh64_digest(&cctx->xxhState);
    -		if (dstCapacity<4) return ERROR(dstSize_tooSmall);
    +		U32 const checksum = (U32)xxh64_digest(&cctx->xxhState);
    +		if (dstCapacity < 4)
    +			return ERROR(dstSize_tooSmall);
     		ZSTD_writeLE32(op, checksum);
     		op += 4;
     	}
     
    -	cctx->stage = ZSTDcs_created;  /* return to "created but no init" status */
    -	return op-ostart;
    +	cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
    +	return op - ostart;
     }
     
    -
    -size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
    -						 void* dst, size_t dstCapacity,
    -				   const void* src, size_t srcSize)
    +size_t ZSTD_compressEnd(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t endResult;
     	size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 1);
    -	if (ZSTD_isError(cSize)) return cSize;
    -	endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
    -	if (ZSTD_isError(endResult)) return endResult;
    +	if (ZSTD_isError(cSize))
    +		return cSize;
    +	endResult = ZSTD_writeEpilogue(cctx, (char *)dst + cSize, dstCapacity - cSize);
    +	if (ZSTD_isError(endResult))
    +		return endResult;
     	return cSize + endResult;
     }
     
    -
    -static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
    -							   void* dst, size_t dstCapacity,
    -						 const void* src, size_t srcSize,
    -						 const void* dict,size_t dictSize,
    -							   ZSTD_parameters params)
    +static size_t ZSTD_compress_internal(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize,
    +				     ZSTD_parameters params)
     {
     	CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
    -	return ZSTD_compressEnd(cctx, dst,  dstCapacity, src, srcSize);
    +	return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
     }
     
    -size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, ZSTD_parameters params)
    +size_t ZSTD_compress_usingDict(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize,
    +			       ZSTD_parameters params)
     {
     	return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
     }
     
    -
    -size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, ZSTD_parameters params)
    +size_t ZSTD_compressCCtx(ZSTD_CCtx *ctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, ZSTD_parameters params)
     {
     	return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, NULL, 0, params);
     }
     
    -
     /* =====  Dictionary API  ===== */
     
     struct ZSTD_CDict_s {
    -	void* dictBuffer;
    -	const void* dictContent;
    +	void *dictBuffer;
    +	const void *dictContent;
     	size_t dictContentSize;
    -	ZSTD_CCtx* refContext;
    -};  /* typedef'd tp ZSTD_CDict within "zstd.h" */
    +	ZSTD_CCtx *refContext;
    +}; /* typedef'd tp ZSTD_CDict within "zstd.h" */
     
    -size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams)
    +size_t ZSTD_CDictWorkspaceBound(ZSTD_compressionParameters cParams) { return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CDict)); }
    +
    +static ZSTD_CDict *ZSTD_createCDict_advanced(const void *dictBuffer, size_t dictSize, unsigned byReference, ZSTD_parameters params, ZSTD_customMem customMem)
     {
    -	return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CDict));
    -}
    +	if (!customMem.customAlloc || !customMem.customFree)
    +		return NULL;
     
    -static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
    -											 ZSTD_parameters params, ZSTD_customMem customMem)
    -{
    -	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    -
    -	{	ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    -		ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
    +	{
    +		ZSTD_CDict *const cdict = (ZSTD_CDict *)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    +		ZSTD_CCtx *const cctx = ZSTD_createCCtx_advanced(customMem);
     
     		if (!cdict || !cctx) {
     			ZSTD_free(cdict, customMem);
    @@ -2718,20 +2844,26 @@ static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dict
     			cdict->dictBuffer = NULL;
     			cdict->dictContent = dictBuffer;
     		} else {
    -			void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    -			if (!internalBuffer) { ZSTD_free(cctx, customMem); ZSTD_free(cdict, customMem); return NULL; }
    +			void *const internalBuffer = ZSTD_malloc(dictSize, customMem);
    +			if (!internalBuffer) {
    +				ZSTD_free(cctx, customMem);
    +				ZSTD_free(cdict, customMem);
    +				return NULL;
    +			}
     			memcpy(internalBuffer, dictBuffer, dictSize);
     			cdict->dictBuffer = internalBuffer;
     			cdict->dictContent = internalBuffer;
     		}
     
    -		{	size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
    +		{
    +			size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
     			if (ZSTD_isError(errorCode)) {
     				ZSTD_free(cdict->dictBuffer, customMem);
     				ZSTD_free(cdict, customMem);
     				ZSTD_freeCCtx(cctx);
     				return NULL;
    -		}   }
    +			}
    +		}
     
     		cdict->refContext = cctx;
     		cdict->dictContentSize = dictSize;
    @@ -2739,16 +2871,18 @@ static ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dict
     	}
     }
     
    -ZSTD_CDict* ZSTD_initCDict(const void* dict, size_t dictSize, ZSTD_parameters params, void* workspace, size_t workspaceSize)
    +ZSTD_CDict *ZSTD_initCDict(const void *dict, size_t dictSize, ZSTD_parameters params, void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
     	return ZSTD_createCDict_advanced(dict, dictSize, 1, params, stackMem);
     }
     
    -size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
    +size_t ZSTD_freeCDict(ZSTD_CDict *cdict)
     {
    -	if (cdict==NULL) return 0;   /* support free on NULL */
    -	{	ZSTD_customMem const cMem = cdict->refContext->customMem;
    +	if (cdict == NULL)
    +		return 0; /* support free on NULL */
    +	{
    +		ZSTD_customMem const cMem = cdict->refContext->customMem;
     		ZSTD_freeCCtx(cdict->refContext);
     		ZSTD_free(cdict->dictBuffer, cMem);
     		ZSTD_free(cdict, cMem);
    @@ -2756,13 +2890,12 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
     	}
     }
     
    -static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
    -	return ZSTD_getParamsFromCCtx(cdict->refContext);
    -}
    +static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict *cdict) { return ZSTD_getParamsFromCCtx(cdict->refContext); }
     
    -size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize)
    +size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx *cctx, const ZSTD_CDict *cdict, unsigned long long pledgedSrcSize)
     {
    -	if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
    +	if (cdict->dictContentSize)
    +		CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
     	else {
     		ZSTD_parameters params = cdict->refContext->params;
     		params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    @@ -2775,14 +2908,11 @@ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, u
     *   Compression using a digested Dictionary.
     *   Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
     *   Note that compression level is decided during dictionary creation */
    -size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
    -								void* dst, size_t dstCapacity,
    -								const void* src, size_t srcSize,
    -								const ZSTD_CDict* cdict)
    +size_t ZSTD_compress_usingCDict(ZSTD_CCtx *cctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_CDict *cdict)
     {
     	CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
     
    -	if (cdict->refContext->params.fParams.contentSizeFlag==1) {
    +	if (cdict->refContext->params.fParams.contentSizeFlag == 1) {
     		cctx->params.fParams.contentSizeFlag = 1;
     		cctx->frameContentSize = srcSize;
     	} else {
    @@ -2792,8 +2922,6 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
     	return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
     }
     
    -
    -
     /* ******************************************************************
     *  Streaming
     ********************************************************************/
    @@ -2801,27 +2929,27 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
     typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
     
     struct ZSTD_CStream_s {
    -	ZSTD_CCtx* cctx;
    -	ZSTD_CDict* cdictLocal;
    -	const ZSTD_CDict* cdict;
    -	char*  inBuff;
    +	ZSTD_CCtx *cctx;
    +	ZSTD_CDict *cdictLocal;
    +	const ZSTD_CDict *cdict;
    +	char *inBuff;
     	size_t inBuffSize;
     	size_t inToCompress;
     	size_t inBuffPos;
     	size_t inBuffTarget;
     	size_t blockSize;
    -	char*  outBuff;
    +	char *outBuff;
     	size_t outBuffSize;
     	size_t outBuffContentSize;
     	size_t outBuffFlushedSize;
     	ZSTD_cStreamStage stage;
    -	U32    checksum;
    -	U32    frameEnded;
    -	U64    pledgedSrcSize;
    -	U64    inputProcessed;
    +	U32 checksum;
    +	U32 frameEnded;
    +	U64 pledgedSrcSize;
    +	U64 inputProcessed;
     	ZSTD_parameters params;
     	ZSTD_customMem customMem;
    -};   /* typedef'd to ZSTD_CStream within "zstd.h" */
    +}; /* typedef'd to ZSTD_CStream within "zstd.h" */
     
     size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams)
     {
    @@ -2832,25 +2960,32 @@ size_t ZSTD_CStreamWorkspaceBound(ZSTD_compressionParameters cParams)
     	return ZSTD_CCtxWorkspaceBound(cParams) + ZSTD_ALIGN(sizeof(ZSTD_CStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize);
     }
     
    -ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
    +ZSTD_CStream *ZSTD_createCStream_advanced(ZSTD_customMem customMem)
     {
    -	ZSTD_CStream* zcs;
    +	ZSTD_CStream *zcs;
     
    -	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +	if (!customMem.customAlloc || !customMem.customFree)
    +		return NULL;
     
    -	zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
    -	if (zcs==NULL) return NULL;
    +	zcs = (ZSTD_CStream *)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
    +	if (zcs == NULL)
    +		return NULL;
     	memset(zcs, 0, sizeof(ZSTD_CStream));
     	memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
     	zcs->cctx = ZSTD_createCCtx_advanced(customMem);
    -	if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
    +	if (zcs->cctx == NULL) {
    +		ZSTD_freeCStream(zcs);
    +		return NULL;
    +	}
     	return zcs;
     }
     
    -size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
    +size_t ZSTD_freeCStream(ZSTD_CStream *zcs)
     {
    -	if (zcs==NULL) return 0;   /* support free on NULL */
    -	{	ZSTD_customMem const cMem = zcs->customMem;
    +	if (zcs == NULL)
    +		return 0; /* support free on NULL */
    +	{
    +		ZSTD_customMem const cMem = zcs->customMem;
     		ZSTD_freeCCtx(zcs->cctx);
     		zcs->cctx = NULL;
     		ZSTD_freeCDict(zcs->cdictLocal);
    @@ -2864,18 +2999,20 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
     	}
     }
     
    -
     /*======   Initialization   ======*/
     
    -size_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    -size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
    +size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    +size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */; }
     
    -static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    +static size_t ZSTD_resetCStream_internal(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize)
     {
    -	if (zcs->inBuffSize==0) return ERROR(stage_wrong);   /* zcs has not been init at least once => can't reset */
    +	if (zcs->inBuffSize == 0)
    +		return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */
     
    -	if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
    -	else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
    +	if (zcs->cdict)
    +		CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
    +	else
    +		CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
     
     	zcs->inToCompress = 0;
     	zcs->inBuffPos = 0;
    @@ -2885,10 +3022,10 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long p
     	zcs->frameEnded = 0;
     	zcs->pledgedSrcSize = pledgedSrcSize;
     	zcs->inputProcessed = 0;
    -	return 0;   /* ready to go */
    +	return 0; /* ready to go */
     }
     
    -size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    +size_t ZSTD_resetCStream(ZSTD_CStream *zcs, unsigned long long pledgedSrcSize)
     {
     
     	zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    @@ -2896,33 +3033,36 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
     	return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
     }
     
    -static size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
    -								 const void* dict, size_t dictSize,
    -								 ZSTD_parameters params, unsigned long long pledgedSrcSize)
    +static size_t ZSTD_initCStream_advanced(ZSTD_CStream *zcs, const void *dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
     	/* allocate buffers */
    -	{	size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
    +	{
    +		size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
     		if (zcs->inBuffSize < neededInBuffSize) {
     			zcs->inBuffSize = neededInBuffSize;
     			ZSTD_free(zcs->inBuff, zcs->customMem);
    -			zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
    -			if (zcs->inBuff == NULL) return ERROR(memory_allocation);
    +			zcs->inBuff = (char *)ZSTD_malloc(neededInBuffSize, zcs->customMem);
    +			if (zcs->inBuff == NULL)
    +				return ERROR(memory_allocation);
     		}
     		zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
     	}
    -	if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
    -		zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
    +	if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize) + 1) {
    +		zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize) + 1;
     		ZSTD_free(zcs->outBuff, zcs->customMem);
    -		zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
    -		if (zcs->outBuff == NULL) return ERROR(memory_allocation);
    +		zcs->outBuff = (char *)ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
    +		if (zcs->outBuff == NULL)
    +			return ERROR(memory_allocation);
     	}
     
     	if (dict && dictSize >= 8) {
     		ZSTD_freeCDict(zcs->cdictLocal);
     		zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0, params, zcs->customMem);
    -		if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    +		if (zcs->cdictLocal == NULL)
    +			return ERROR(memory_allocation);
     		zcs->cdict = zcs->cdictLocal;
    -	} else zcs->cdict = NULL;
    +	} else
    +		zcs->cdict = NULL;
     
     	zcs->checksum = params.fParams.checksumFlag > 0;
     	zcs->params = params;
    @@ -2930,21 +3070,23 @@ static size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
     	return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
     }
     
    -ZSTD_CStream* ZSTD_initCStream(ZSTD_parameters params, unsigned long long pledgedSrcSize, void* workspace, size_t workspaceSize)
    +ZSTD_CStream *ZSTD_initCStream(ZSTD_parameters params, unsigned long long pledgedSrcSize, void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    -	ZSTD_CStream* const zcs = ZSTD_createCStream_advanced(stackMem);
    +	ZSTD_CStream *const zcs = ZSTD_createCStream_advanced(stackMem);
     	if (zcs) {
     		size_t const code = ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
    -		if (ZSTD_isError(code)) { return NULL; }
    +		if (ZSTD_isError(code)) {
    +			return NULL;
    +		}
     	}
     	return zcs;
     }
     
    -ZSTD_CStream* ZSTD_initCStream_usingCDict(const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, void* workspace, size_t workspaceSize)
    +ZSTD_CStream *ZSTD_initCStream_usingCDict(const ZSTD_CDict *cdict, unsigned long long pledgedSrcSize, void *workspace, size_t workspaceSize)
     {
     	ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
    -	ZSTD_CStream* const zcs = ZSTD_initCStream(params, pledgedSrcSize, workspace, workspaceSize);
    +	ZSTD_CStream *const zcs = ZSTD_initCStream(params, pledgedSrcSize, workspace, workspaceSize);
     	if (zcs) {
     		zcs->cdict = cdict;
     		if (ZSTD_isError(ZSTD_resetCStream_internal(zcs, pledgedSrcSize))) {
    @@ -2958,140 +3100,149 @@ ZSTD_CStream* ZSTD_initCStream_usingCDict(const ZSTD_CDict* cdict, unsigned long
     
     typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
     
    -ZSTD_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t const length = MIN(dstCapacity, srcSize);
     	memcpy(dst, src, length);
     	return length;
     }
     
    -static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
    -							  void* dst, size_t* dstCapacityPtr,
    -						const void* src, size_t* srcSizePtr,
    -							  ZSTD_flush_e const flush)
    +static size_t ZSTD_compressStream_generic(ZSTD_CStream *zcs, void *dst, size_t *dstCapacityPtr, const void *src, size_t *srcSizePtr, ZSTD_flush_e const flush)
     {
     	U32 someMoreWork = 1;
    -	const char* const istart = (const char*)src;
    -	const char* const iend = istart + *srcSizePtr;
    -	const char* ip = istart;
    -	char* const ostart = (char*)dst;
    -	char* const oend = ostart + *dstCapacityPtr;
    -	char* op = ostart;
    +	const char *const istart = (const char *)src;
    +	const char *const iend = istart + *srcSizePtr;
    +	const char *ip = istart;
    +	char *const ostart = (char *)dst;
    +	char *const oend = ostart + *dstCapacityPtr;
    +	char *op = ostart;
     
     	while (someMoreWork) {
    -		switch(zcs->stage)
    -		{
    -		case zcss_init: return ERROR(init_missing);   /* call ZBUFF_compressInit() first ! */
    +		switch (zcs->stage) {
    +		case zcss_init:
    +			return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
     
     		case zcss_load:
     			/* complete inBuffer */
    -			{	size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    -				size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
    +			{
    +				size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    +				size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend - ip);
     				zcs->inBuffPos += loaded;
     				ip += loaded;
    -				if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
    -					someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
    -			}   }
    +				if ((zcs->inBuffPos == zcs->inToCompress) || (!flush && (toLoad != loaded))) {
    +					someMoreWork = 0;
    +					break; /* not enough input to get a full block : stop there, wait for more */
    +				}
    +			}
     			/* compress curr block (note : this stage cannot be stopped in the middle) */
    -			{	void* cDst;
    +			{
    +				void *cDst;
     				size_t cSize;
     				size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
    -				size_t oSize = oend-op;
    +				size_t oSize = oend - op;
     				if (oSize >= ZSTD_compressBound(iSize))
    -					cDst = op;   /* compress directly into output buffer (avoid flush stage) */
    +					cDst = op; /* compress directly into output buffer (avoid flush stage) */
     				else
     					cDst = zcs->outBuff, oSize = zcs->outBuffSize;
    -				cSize = (flush == zsf_end) ?
    -						ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
    -						ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
    -				if (ZSTD_isError(cSize)) return cSize;
    -				if (flush == zsf_end) zcs->frameEnded = 1;
    +				cSize = (flush == zsf_end) ? ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize)
    +							   : ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
    +				if (ZSTD_isError(cSize))
    +					return cSize;
    +				if (flush == zsf_end)
    +					zcs->frameEnded = 1;
     				/* prepare next block */
     				zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
     				if (zcs->inBuffTarget > zcs->inBuffSize)
    -					zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;   /* note : inBuffSize >= blockSize */
    +					zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffSize >= blockSize */
     				zcs->inToCompress = zcs->inBuffPos;
    -				if (cDst == op) { op += cSize; break; }   /* no need to flush */
    +				if (cDst == op) {
    +					op += cSize;
    +					break;
    +				} /* no need to flush */
     				zcs->outBuffContentSize = cSize;
     				zcs->outBuffFlushedSize = 0;
    -				zcs->stage = zcss_flush;   /* pass-through to flush stage */
    +				zcs->stage = zcss_flush; /* pass-through to flush stage */
     			}
     
    -		case zcss_flush:
    -			{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    -				size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    -				op += flushed;
    -				zcs->outBuffFlushedSize += flushed;
    -				if (toFlush!=flushed) { someMoreWork = 0; break; }  /* dst too small to store flushed data : stop there */
    -				zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
    -				zcs->stage = zcss_load;
    +		case zcss_flush: {
    +			size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    +			size_t const flushed = ZSTD_limitCopy(op, oend - op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    +			op += flushed;
    +			zcs->outBuffFlushedSize += flushed;
    +			if (toFlush != flushed) {
    +				someMoreWork = 0;
     				break;
    -			}
    +			} /* dst too small to store flushed data : stop there */
    +			zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
    +			zcs->stage = zcss_load;
    +			break;
    +		}
     
     		case zcss_final:
    -			someMoreWork = 0;   /* do nothing */
    +			someMoreWork = 0; /* do nothing */
     			break;
     
     		default:
    -			return ERROR(GENERIC);   /* impossible */
    +			return ERROR(GENERIC); /* impossible */
     		}
     	}
     
     	*srcSizePtr = ip - istart;
     	*dstCapacityPtr = op - ostart;
     	zcs->inputProcessed += *srcSizePtr;
    -	if (zcs->frameEnded) return 0;
    -	{	size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
    -		if (hintInSize==0) hintInSize = zcs->blockSize;
    +	if (zcs->frameEnded)
    +		return 0;
    +	{
    +		size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
    +		if (hintInSize == 0)
    +			hintInSize = zcs->blockSize;
     		return hintInSize;
     	}
     }
     
    -size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
    +size_t ZSTD_compressStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
     {
     	size_t sizeRead = input->size - input->pos;
     	size_t sizeWritten = output->size - output->pos;
    -	size_t const result = ZSTD_compressStream_generic(zcs,
    -													  (char*)(output->dst) + output->pos, &sizeWritten,
    -													  (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
    +	size_t const result =
    +	    ZSTD_compressStream_generic(zcs, (char *)(output->dst) + output->pos, &sizeWritten, (const char *)(input->src) + input->pos, &sizeRead, zsf_gather);
     	input->pos += sizeRead;
     	output->pos += sizeWritten;
     	return result;
     }
     
    -
     /*======   Finalize   ======*/
     
     /*! ZSTD_flushStream() :
     *   @return : amount of data remaining to flush */
    -size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
    +size_t ZSTD_flushStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)
     {
     	size_t srcSize = 0;
     	size_t sizeWritten = output->size - output->pos;
    -	size_t const result = ZSTD_compressStream_generic(zcs,
    -													 (char*)(output->dst) + output->pos, &sizeWritten,
    -													 &srcSize, &srcSize, /* use a valid src address instead of NULL */
    -													  zsf_flush);
    +	size_t const result = ZSTD_compressStream_generic(zcs, (char *)(output->dst) + output->pos, &sizeWritten, &srcSize,
    +							  &srcSize, /* use a valid src address instead of NULL */
    +							  zsf_flush);
     	output->pos += sizeWritten;
    -	if (ZSTD_isError(result)) return result;
    -	return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
    +	if (ZSTD_isError(result))
    +		return result;
    +	return zcs->outBuffContentSize - zcs->outBuffFlushedSize; /* remaining to flush */
     }
     
    -
    -size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
    +size_t ZSTD_endStream(ZSTD_CStream *zcs, ZSTD_outBuffer *output)
     {
    -	BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
    -	BYTE* const oend = (BYTE*)(output->dst) + output->size;
    -	BYTE* op = ostart;
    +	BYTE *const ostart = (BYTE *)(output->dst) + output->pos;
    +	BYTE *const oend = (BYTE *)(output->dst) + output->size;
    +	BYTE *op = ostart;
     
     	if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize))
    -		return ERROR(srcSize_wrong);   /* pledgedSrcSize not respected */
    +		return ERROR(srcSize_wrong); /* pledgedSrcSize not respected */
     
     	if (zcs->stage != zcss_final) {
     		/* flush whatever remains */
     		size_t srcSize = 0;
     		size_t sizeWritten = output->size - output->pos;
    -		size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end);  /* use a valid src address instead of NULL */
    +		size_t const notEnded =
    +		    ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end); /* use a valid src address instead of NULL */
     		size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     		op += sizeWritten;
     		if (remainingToFlush) {
    @@ -3100,134 +3251,138 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     		}
     		/* create epilogue */
     		zcs->stage = zcss_final;
    -		zcs->outBuffContentSize = !notEnded ? 0 :
    -			ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0);  /* write epilogue, including final empty block, into outBuff */
    +		zcs->outBuffContentSize = !notEnded ? 0 : ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL,
    +									   0); /* write epilogue, including final empty block, into outBuff */
     	}
     
     	/* flush epilogue */
    -	{	size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    -		size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    +	{
    +		size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    +		size_t const flushed = ZSTD_limitCopy(op, oend - op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
     		op += flushed;
     		zcs->outBuffFlushedSize += flushed;
    -		output->pos += op-ostart;
    -		if (toFlush==flushed) zcs->stage = zcss_init;  /* end reached */
    +		output->pos += op - ostart;
    +		if (toFlush == flushed)
    +			zcs->stage = zcss_init; /* end reached */
     		return toFlush - flushed;
     	}
     }
     
    -
    -
     /*-=====  Pre-defined compression levels  =====-*/
     
     #define ZSTD_DEFAULT_CLEVEL 1
    -#define ZSTD_MAX_CLEVEL     22
    +#define ZSTD_MAX_CLEVEL 22
     int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
     
    -static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
    -{   /* "default" */
    +static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL + 1] = {
    +    {
    +	/* "default" */
     	/* W,  C,  H,  S,  L, TL, strat */
    -	{ 18, 12, 12,  1,  7, 16, ZSTD_fast    },  /* level  0 - never used */
    -	{ 19, 13, 14,  1,  7, 16, ZSTD_fast    },  /* level  1 */
    -	{ 19, 15, 16,  1,  6, 16, ZSTD_fast    },  /* level  2 */
    -	{ 20, 16, 17,  1,  5, 16, ZSTD_dfast   },  /* level  3.*/
    -	{ 20, 18, 18,  1,  5, 16, ZSTD_dfast   },  /* level  4.*/
    -	{ 20, 15, 18,  3,  5, 16, ZSTD_greedy  },  /* level  5 */
    -	{ 21, 16, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
    -	{ 21, 17, 20,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
    -	{ 21, 18, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
    -	{ 21, 20, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
    -	{ 21, 19, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
    -	{ 22, 20, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
    -	{ 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
    -	{ 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 13 */
    -	{ 22, 21, 22,  6,  5, 16, ZSTD_lazy2   },  /* level 14 */
    -	{ 22, 21, 21,  5,  5, 16, ZSTD_btlazy2 },  /* level 15 */
    -	{ 23, 22, 22,  5,  5, 16, ZSTD_btlazy2 },  /* level 16 */
    -	{ 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
    -	{ 23, 23, 22,  6,  5, 32, ZSTD_btopt   },  /* level 18 */
    -	{ 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
    -	{ 25, 25, 23,  7,  3, 64, ZSTD_btopt2  },  /* level 20 */
    -	{ 26, 26, 23,  7,  3,256, ZSTD_btopt2  },  /* level 21 */
    -	{ 27, 27, 25,  9,  3,512, ZSTD_btopt2  },  /* level 22 */
    -},
    -{   /* for srcSize <= 256 KB */
    +	{18, 12, 12, 1, 7, 16, ZSTD_fast},    /* level  0 - never used */
    +	{19, 13, 14, 1, 7, 16, ZSTD_fast},    /* level  1 */
    +	{19, 15, 16, 1, 6, 16, ZSTD_fast},    /* level  2 */
    +	{20, 16, 17, 1, 5, 16, ZSTD_dfast},   /* level  3.*/
    +	{20, 18, 18, 1, 5, 16, ZSTD_dfast},   /* level  4.*/
    +	{20, 15, 18, 3, 5, 16, ZSTD_greedy},  /* level  5 */
    +	{21, 16, 19, 2, 5, 16, ZSTD_lazy},    /* level  6 */
    +	{21, 17, 20, 3, 5, 16, ZSTD_lazy},    /* level  7 */
    +	{21, 18, 20, 3, 5, 16, ZSTD_lazy2},   /* level  8 */
    +	{21, 20, 20, 3, 5, 16, ZSTD_lazy2},   /* level  9 */
    +	{21, 19, 21, 4, 5, 16, ZSTD_lazy2},   /* level 10 */
    +	{22, 20, 22, 4, 5, 16, ZSTD_lazy2},   /* level 11 */
    +	{22, 20, 22, 5, 5, 16, ZSTD_lazy2},   /* level 12 */
    +	{22, 21, 22, 5, 5, 16, ZSTD_lazy2},   /* level 13 */
    +	{22, 21, 22, 6, 5, 16, ZSTD_lazy2},   /* level 14 */
    +	{22, 21, 21, 5, 5, 16, ZSTD_btlazy2}, /* level 15 */
    +	{23, 22, 22, 5, 5, 16, ZSTD_btlazy2}, /* level 16 */
    +	{23, 21, 22, 4, 5, 24, ZSTD_btopt},   /* level 17 */
    +	{23, 23, 22, 6, 5, 32, ZSTD_btopt},   /* level 18 */
    +	{23, 23, 22, 6, 3, 48, ZSTD_btopt},   /* level 19 */
    +	{25, 25, 23, 7, 3, 64, ZSTD_btopt2},  /* level 20 */
    +	{26, 26, 23, 7, 3, 256, ZSTD_btopt2}, /* level 21 */
    +	{27, 27, 25, 9, 3, 512, ZSTD_btopt2}, /* level 22 */
    +    },
    +    {
    +	/* for srcSize <= 256 KB */
     	/* W,  C,  H,  S,  L,  T, strat */
    -	{  0,  0,  0,  0,  0,  0, ZSTD_fast    },  /* level  0 - not used */
    -	{ 18, 13, 14,  1,  6,  8, ZSTD_fast    },  /* level  1 */
    -	{ 18, 14, 13,  1,  5,  8, ZSTD_dfast   },  /* level  2 */
    -	{ 18, 16, 15,  1,  5,  8, ZSTD_dfast   },  /* level  3 */
    -	{ 18, 15, 17,  1,  5,  8, ZSTD_greedy  },  /* level  4.*/
    -	{ 18, 16, 17,  4,  5,  8, ZSTD_greedy  },  /* level  5.*/
    -	{ 18, 16, 17,  3,  5,  8, ZSTD_lazy    },  /* level  6.*/
    -	{ 18, 17, 17,  4,  4,  8, ZSTD_lazy    },  /* level  7 */
    -	{ 18, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
    -	{ 18, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
    -	{ 18, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
    -	{ 18, 18, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 11.*/
    -	{ 18, 18, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 12.*/
    -	{ 18, 19, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13 */
    -	{ 18, 18, 18,  4,  4, 16, ZSTD_btopt   },  /* level 14.*/
    -	{ 18, 18, 18,  4,  3, 16, ZSTD_btopt   },  /* level 15.*/
    -	{ 18, 19, 18,  6,  3, 32, ZSTD_btopt   },  /* level 16.*/
    -	{ 18, 19, 18,  8,  3, 64, ZSTD_btopt   },  /* level 17.*/
    -	{ 18, 19, 18,  9,  3,128, ZSTD_btopt   },  /* level 18.*/
    -	{ 18, 19, 18, 10,  3,256, ZSTD_btopt   },  /* level 19.*/
    -	{ 18, 19, 18, 11,  3,512, ZSTD_btopt2  },  /* level 20.*/
    -	{ 18, 19, 18, 12,  3,512, ZSTD_btopt2  },  /* level 21.*/
    -	{ 18, 19, 18, 13,  3,512, ZSTD_btopt2  },  /* level 22.*/
    -},
    -{   /* for srcSize <= 128 KB */
    +	{0, 0, 0, 0, 0, 0, ZSTD_fast},	 /* level  0 - not used */
    +	{18, 13, 14, 1, 6, 8, ZSTD_fast},      /* level  1 */
    +	{18, 14, 13, 1, 5, 8, ZSTD_dfast},     /* level  2 */
    +	{18, 16, 15, 1, 5, 8, ZSTD_dfast},     /* level  3 */
    +	{18, 15, 17, 1, 5, 8, ZSTD_greedy},    /* level  4.*/
    +	{18, 16, 17, 4, 5, 8, ZSTD_greedy},    /* level  5.*/
    +	{18, 16, 17, 3, 5, 8, ZSTD_lazy},      /* level  6.*/
    +	{18, 17, 17, 4, 4, 8, ZSTD_lazy},      /* level  7 */
    +	{18, 17, 17, 4, 4, 8, ZSTD_lazy2},     /* level  8 */
    +	{18, 17, 17, 5, 4, 8, ZSTD_lazy2},     /* level  9 */
    +	{18, 17, 17, 6, 4, 8, ZSTD_lazy2},     /* level 10 */
    +	{18, 18, 17, 6, 4, 8, ZSTD_lazy2},     /* level 11.*/
    +	{18, 18, 17, 7, 4, 8, ZSTD_lazy2},     /* level 12.*/
    +	{18, 19, 17, 6, 4, 8, ZSTD_btlazy2},   /* level 13 */
    +	{18, 18, 18, 4, 4, 16, ZSTD_btopt},    /* level 14.*/
    +	{18, 18, 18, 4, 3, 16, ZSTD_btopt},    /* level 15.*/
    +	{18, 19, 18, 6, 3, 32, ZSTD_btopt},    /* level 16.*/
    +	{18, 19, 18, 8, 3, 64, ZSTD_btopt},    /* level 17.*/
    +	{18, 19, 18, 9, 3, 128, ZSTD_btopt},   /* level 18.*/
    +	{18, 19, 18, 10, 3, 256, ZSTD_btopt},  /* level 19.*/
    +	{18, 19, 18, 11, 3, 512, ZSTD_btopt2}, /* level 20.*/
    +	{18, 19, 18, 12, 3, 512, ZSTD_btopt2}, /* level 21.*/
    +	{18, 19, 18, 13, 3, 512, ZSTD_btopt2}, /* level 22.*/
    +    },
    +    {
    +	/* for srcSize <= 128 KB */
     	/* W,  C,  H,  S,  L,  T, strat */
    -	{ 17, 12, 12,  1,  7,  8, ZSTD_fast    },  /* level  0 - not used */
    -	{ 17, 12, 13,  1,  6,  8, ZSTD_fast    },  /* level  1 */
    -	{ 17, 13, 16,  1,  5,  8, ZSTD_fast    },  /* level  2 */
    -	{ 17, 16, 16,  2,  5,  8, ZSTD_dfast   },  /* level  3 */
    -	{ 17, 13, 15,  3,  4,  8, ZSTD_greedy  },  /* level  4 */
    -	{ 17, 15, 17,  4,  4,  8, ZSTD_greedy  },  /* level  5 */
    -	{ 17, 16, 17,  3,  4,  8, ZSTD_lazy    },  /* level  6 */
    -	{ 17, 15, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  7 */
    -	{ 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */
    -	{ 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */
    -	{ 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */
    -	{ 17, 17, 17,  7,  4,  8, ZSTD_lazy2   },  /* level 11 */
    -	{ 17, 17, 17,  8,  4,  8, ZSTD_lazy2   },  /* level 12 */
    -	{ 17, 18, 17,  6,  4,  8, ZSTD_btlazy2 },  /* level 13.*/
    -	{ 17, 17, 17,  7,  3,  8, ZSTD_btopt   },  /* level 14.*/
    -	{ 17, 17, 17,  7,  3, 16, ZSTD_btopt   },  /* level 15.*/
    -	{ 17, 18, 17,  7,  3, 32, ZSTD_btopt   },  /* level 16.*/
    -	{ 17, 18, 17,  7,  3, 64, ZSTD_btopt   },  /* level 17.*/
    -	{ 17, 18, 17,  7,  3,256, ZSTD_btopt   },  /* level 18.*/
    -	{ 17, 18, 17,  8,  3,256, ZSTD_btopt   },  /* level 19.*/
    -	{ 17, 18, 17,  9,  3,256, ZSTD_btopt2  },  /* level 20.*/
    -	{ 17, 18, 17, 10,  3,256, ZSTD_btopt2  },  /* level 21.*/
    -	{ 17, 18, 17, 11,  3,512, ZSTD_btopt2  },  /* level 22.*/
    -},
    -{   /* for srcSize <= 16 KB */
    +	{17, 12, 12, 1, 7, 8, ZSTD_fast},      /* level  0 - not used */
    +	{17, 12, 13, 1, 6, 8, ZSTD_fast},      /* level  1 */
    +	{17, 13, 16, 1, 5, 8, ZSTD_fast},      /* level  2 */
    +	{17, 16, 16, 2, 5, 8, ZSTD_dfast},     /* level  3 */
    +	{17, 13, 15, 3, 4, 8, ZSTD_greedy},    /* level  4 */
    +	{17, 15, 17, 4, 4, 8, ZSTD_greedy},    /* level  5 */
    +	{17, 16, 17, 3, 4, 8, ZSTD_lazy},      /* level  6 */
    +	{17, 15, 17, 4, 4, 8, ZSTD_lazy2},     /* level  7 */
    +	{17, 17, 17, 4, 4, 8, ZSTD_lazy2},     /* level  8 */
    +	{17, 17, 17, 5, 4, 8, ZSTD_lazy2},     /* level  9 */
    +	{17, 17, 17, 6, 4, 8, ZSTD_lazy2},     /* level 10 */
    +	{17, 17, 17, 7, 4, 8, ZSTD_lazy2},     /* level 11 */
    +	{17, 17, 17, 8, 4, 8, ZSTD_lazy2},     /* level 12 */
    +	{17, 18, 17, 6, 4, 8, ZSTD_btlazy2},   /* level 13.*/
    +	{17, 17, 17, 7, 3, 8, ZSTD_btopt},     /* level 14.*/
    +	{17, 17, 17, 7, 3, 16, ZSTD_btopt},    /* level 15.*/
    +	{17, 18, 17, 7, 3, 32, ZSTD_btopt},    /* level 16.*/
    +	{17, 18, 17, 7, 3, 64, ZSTD_btopt},    /* level 17.*/
    +	{17, 18, 17, 7, 3, 256, ZSTD_btopt},   /* level 18.*/
    +	{17, 18, 17, 8, 3, 256, ZSTD_btopt},   /* level 19.*/
    +	{17, 18, 17, 9, 3, 256, ZSTD_btopt2},  /* level 20.*/
    +	{17, 18, 17, 10, 3, 256, ZSTD_btopt2}, /* level 21.*/
    +	{17, 18, 17, 11, 3, 512, ZSTD_btopt2}, /* level 22.*/
    +    },
    +    {
    +	/* for srcSize <= 16 KB */
     	/* W,  C,  H,  S,  L,  T, strat */
    -	{ 14, 12, 12,  1,  7,  6, ZSTD_fast    },  /* level  0 - not used */
    -	{ 14, 14, 14,  1,  6,  6, ZSTD_fast    },  /* level  1 */
    -	{ 14, 14, 14,  1,  4,  6, ZSTD_fast    },  /* level  2 */
    -	{ 14, 14, 14,  1,  4,  6, ZSTD_dfast   },  /* level  3.*/
    -	{ 14, 14, 14,  4,  4,  6, ZSTD_greedy  },  /* level  4.*/
    -	{ 14, 14, 14,  3,  4,  6, ZSTD_lazy    },  /* level  5.*/
    -	{ 14, 14, 14,  4,  4,  6, ZSTD_lazy2   },  /* level  6 */
    -	{ 14, 14, 14,  5,  4,  6, ZSTD_lazy2   },  /* level  7 */
    -	{ 14, 14, 14,  6,  4,  6, ZSTD_lazy2   },  /* level  8.*/
    -	{ 14, 15, 14,  6,  4,  6, ZSTD_btlazy2 },  /* level  9.*/
    -	{ 14, 15, 14,  3,  3,  6, ZSTD_btopt   },  /* level 10.*/
    -	{ 14, 15, 14,  6,  3,  8, ZSTD_btopt   },  /* level 11.*/
    -	{ 14, 15, 14,  6,  3, 16, ZSTD_btopt   },  /* level 12.*/
    -	{ 14, 15, 14,  6,  3, 24, ZSTD_btopt   },  /* level 13.*/
    -	{ 14, 15, 15,  6,  3, 48, ZSTD_btopt   },  /* level 14.*/
    -	{ 14, 15, 15,  6,  3, 64, ZSTD_btopt   },  /* level 15.*/
    -	{ 14, 15, 15,  6,  3, 96, ZSTD_btopt   },  /* level 16.*/
    -	{ 14, 15, 15,  6,  3,128, ZSTD_btopt   },  /* level 17.*/
    -	{ 14, 15, 15,  6,  3,256, ZSTD_btopt   },  /* level 18.*/
    -	{ 14, 15, 15,  7,  3,256, ZSTD_btopt   },  /* level 19.*/
    -	{ 14, 15, 15,  8,  3,256, ZSTD_btopt2  },  /* level 20.*/
    -	{ 14, 15, 15,  9,  3,256, ZSTD_btopt2  },  /* level 21.*/
    -	{ 14, 15, 15, 10,  3,256, ZSTD_btopt2  },  /* level 22.*/
    -},
    +	{14, 12, 12, 1, 7, 6, ZSTD_fast},      /* level  0 - not used */
    +	{14, 14, 14, 1, 6, 6, ZSTD_fast},      /* level  1 */
    +	{14, 14, 14, 1, 4, 6, ZSTD_fast},      /* level  2 */
    +	{14, 14, 14, 1, 4, 6, ZSTD_dfast},     /* level  3.*/
    +	{14, 14, 14, 4, 4, 6, ZSTD_greedy},    /* level  4.*/
    +	{14, 14, 14, 3, 4, 6, ZSTD_lazy},      /* level  5.*/
    +	{14, 14, 14, 4, 4, 6, ZSTD_lazy2},     /* level  6 */
    +	{14, 14, 14, 5, 4, 6, ZSTD_lazy2},     /* level  7 */
    +	{14, 14, 14, 6, 4, 6, ZSTD_lazy2},     /* level  8.*/
    +	{14, 15, 14, 6, 4, 6, ZSTD_btlazy2},   /* level  9.*/
    +	{14, 15, 14, 3, 3, 6, ZSTD_btopt},     /* level 10.*/
    +	{14, 15, 14, 6, 3, 8, ZSTD_btopt},     /* level 11.*/
    +	{14, 15, 14, 6, 3, 16, ZSTD_btopt},    /* level 12.*/
    +	{14, 15, 14, 6, 3, 24, ZSTD_btopt},    /* level 13.*/
    +	{14, 15, 15, 6, 3, 48, ZSTD_btopt},    /* level 14.*/
    +	{14, 15, 15, 6, 3, 64, ZSTD_btopt},    /* level 15.*/
    +	{14, 15, 15, 6, 3, 96, ZSTD_btopt},    /* level 16.*/
    +	{14, 15, 15, 6, 3, 128, ZSTD_btopt},   /* level 17.*/
    +	{14, 15, 15, 6, 3, 256, ZSTD_btopt},   /* level 18.*/
    +	{14, 15, 15, 7, 3, 256, ZSTD_btopt},   /* level 19.*/
    +	{14, 15, 15, 8, 3, 256, ZSTD_btopt2},  /* level 20.*/
    +	{14, 15, 15, 9, 3, 256, ZSTD_btopt2},  /* level 21.*/
    +	{14, 15, 15, 10, 3, 256, ZSTD_btopt2}, /* level 22.*/
    +    },
     };
     
     /*! ZSTD_getCParams() :
    @@ -3237,15 +3392,20 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
     {
     	ZSTD_compressionParameters cp;
     	size_t const addedSize = srcSize ? 0 : 500;
    -	U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
    -	U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
    -	if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL;   /* 0 == default; no negative compressionLevel yet */
    -	if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
    +	U64 const rSize = srcSize + dictSize ? srcSize + dictSize + addedSize : (U64)-1;
    +	U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
    +	if (compressionLevel <= 0)
    +		compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */
    +	if (compressionLevel > ZSTD_MAX_CLEVEL)
    +		compressionLevel = ZSTD_MAX_CLEVEL;
     	cp = ZSTD_defaultCParameters[tableID][compressionLevel];
    -	if (ZSTD_32bits()) {   /* auto-correction, for 32-bits mode */
    -		if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
    -		if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
    -		if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
    +	if (ZSTD_32bits()) { /* auto-correction, for 32-bits mode */
    +		if (cp.windowLog > ZSTD_WINDOWLOG_MAX)
    +			cp.windowLog = ZSTD_WINDOWLOG_MAX;
    +		if (cp.chainLog > ZSTD_CHAINLOG_MAX)
    +			cp.chainLog = ZSTD_CHAINLOG_MAX;
    +		if (cp.hashLog > ZSTD_HASHLOG_MAX)
    +			cp.hashLog = ZSTD_HASHLOG_MAX;
     	}
     	cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
     	return cp;
    @@ -3254,7 +3414,8 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
     /*! ZSTD_getParams() :
     *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
     *   All fields of `ZSTD_frameParameters` are set to default (0) */
    -ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
    +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
    +{
     	ZSTD_parameters params;
     	ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
     	memset(¶ms, 0, sizeof(params));
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index d3cc2e92d..2926b36fc 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -14,7 +14,6 @@
      * ("BSD").
      */
     
    -
     /* ***************************************************************
     *  Tuning parameters
     *****************************************************************/
    @@ -24,87 +23,86 @@
     *  Frames requiring more memory will be rejected.
     */
     #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
    -#  define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1)   /* defined within zstd.h */
    +#define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
     #endif
     
    -
     /*-*******************************************************
     *  Dependencies
     *********************************************************/
    -#include 
    -#include 
    -#include       /* memcpy, memmove, memset */
    -#include "mem.h"         /* low level memory routines */
     #include "fse.h"
     #include "huf.h"
    +#include "mem.h" /* low level memory routines */
     #include "zstd_internal.h"
    +#include 
    +#include 
    +#include  /* memcpy, memmove, memset */
     
    -#define ZSTD_PREFETCH(ptr)   __builtin_prefetch(ptr, 0, 0)
    +#define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
     
     /*-*************************************
     *  Macros
     ***************************************/
    -#define ZSTD_isError ERR_isError   /* for inlining */
    -#define FSE_isError  ERR_isError
    -#define HUF_isError  ERR_isError
    -
    +#define ZSTD_isError ERR_isError /* for inlining */
    +#define FSE_isError ERR_isError
    +#define HUF_isError ERR_isError
     
     /*_*******************************************************
     *  Memory operations
     **********************************************************/
    -static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
    -
    +static void ZSTD_copy4(void *dst, const void *src) { memcpy(dst, src, 4); }
     
     /*-*************************************************************
     *   Context management
     ***************************************************************/
    -typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
    -			   ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
    -			   ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
    -			   ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
    +typedef enum {
    +	ZSTDds_getFrameHeaderSize,
    +	ZSTDds_decodeFrameHeader,
    +	ZSTDds_decodeBlockHeader,
    +	ZSTDds_decompressBlock,
    +	ZSTDds_decompressLastBlock,
    +	ZSTDds_checkChecksum,
    +	ZSTDds_decodeSkippableHeader,
    +	ZSTDds_skipFrame
    +} ZSTD_dStage;
     
     typedef struct {
     	FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
     	FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
     	FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
    -	HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)];  /* can accommodate HUF_decompress4X */
    +	HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
     	U32 rep[ZSTD_REP_NUM];
     } ZSTD_entropyTables_t;
     
    -struct ZSTD_DCtx_s
    -{
    -	const FSE_DTable* LLTptr;
    -	const FSE_DTable* MLTptr;
    -	const FSE_DTable* OFTptr;
    -	const HUF_DTable* HUFptr;
    +struct ZSTD_DCtx_s {
    +	const FSE_DTable *LLTptr;
    +	const FSE_DTable *MLTptr;
    +	const FSE_DTable *OFTptr;
    +	const HUF_DTable *HUFptr;
     	ZSTD_entropyTables_t entropy;
    -	const void* previousDstEnd;   /* detect continuity */
    -	const void* base;             /* start of curr segment */
    -	const void* vBase;            /* virtual start of previous segment if it was just before curr one */
    -	const void* dictEnd;          /* end of previous segment */
    +	const void *previousDstEnd; /* detect continuity */
    +	const void *base;	   /* start of curr segment */
    +	const void *vBase;	  /* virtual start of previous segment if it was just before curr one */
    +	const void *dictEnd;	/* end of previous segment */
     	size_t expected;
     	ZSTD_frameParams fParams;
    -	blockType_e bType;   /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
    +	blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
     	ZSTD_dStage stage;
     	U32 litEntropy;
     	U32 fseEntropy;
     	struct xxh64_state xxhState;
     	size_t headerSize;
     	U32 dictID;
    -	const BYTE* litPtr;
    +	const BYTE *litPtr;
     	ZSTD_customMem customMem;
     	size_t litSize;
     	size_t rleSize;
     	BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
     	BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
    -};  /* typedef'd to ZSTD_DCtx within "zstd.h" */
    +}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
     
    -size_t ZSTD_DCtxWorkspaceBound(void)
    -{
    -	return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx));
    -}
    +size_t ZSTD_DCtxWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx)); }
     
    -size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
    +size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx)
     {
     	dctx->expected = ZSTD_frameHeaderSize_prefix;
     	dctx->stage = ZSTDds_getFrameHeaderSize;
    @@ -112,11 +110,11 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
     	dctx->base = NULL;
     	dctx->vBase = NULL;
     	dctx->dictEnd = NULL;
    -	dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    +	dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
     	dctx->litEntropy = dctx->fseEntropy = 0;
     	dctx->dictID = 0;
     	ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
    -	memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue));  /* initial repcodes */
    +	memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
     	dctx->LLTptr = dctx->entropy.LLTable;
     	dctx->MLTptr = dctx->entropy.MLTable;
     	dctx->OFTptr = dctx->entropy.OFTable;
    @@ -124,40 +122,42 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
     	return 0;
     }
     
    -ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
    +ZSTD_DCtx *ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
     {
    -	ZSTD_DCtx* dctx;
    +	ZSTD_DCtx *dctx;
     
    -	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +	if (!customMem.customAlloc || !customMem.customFree)
    +		return NULL;
     
    -	dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
    -	if (!dctx) return NULL;
    +	dctx = (ZSTD_DCtx *)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
    +	if (!dctx)
    +		return NULL;
     	memcpy(&dctx->customMem, &customMem, sizeof(customMem));
     	ZSTD_decompressBegin(dctx);
     	return dctx;
     }
     
    -ZSTD_DCtx* ZSTD_initDCtx(void* workspace, size_t workspaceSize)
    +ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
     	return ZSTD_createDCtx_advanced(stackMem);
     }
     
    -size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
    +size_t ZSTD_freeDCtx(ZSTD_DCtx *dctx)
     {
    -	if (dctx==NULL) return 0;   /* support free on NULL */
    +	if (dctx == NULL)
    +		return 0; /* support free on NULL */
     	ZSTD_free(dctx, dctx->customMem);
    -	return 0;   /* reserved as a potential error code in the future */
    +	return 0; /* reserved as a potential error code in the future */
     }
     
    -void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    +void ZSTD_copyDCtx(ZSTD_DCtx *dstDCtx, const ZSTD_DCtx *srcDCtx)
     {
    -	size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
    -	memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
    +	size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
    +	memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
     }
     
    -static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
    -
    +static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict);
     
     /*-*************************************************************
     *   Decompression section
    @@ -168,46 +168,51 @@ static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
      *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
      *  Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
      *  Note 3 : Skippable Frame Identifiers are considered valid. */
    -unsigned ZSTD_isFrame(const void* buffer, size_t size)
    +unsigned ZSTD_isFrame(const void *buffer, size_t size)
     {
    -	if (size < 4) return 0;
    -	{	U32 const magic = ZSTD_readLE32(buffer);
    -		if (magic == ZSTD_MAGICNUMBER) return 1;
    -		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
    +	if (size < 4)
    +		return 0;
    +	{
    +		U32 const magic = ZSTD_readLE32(buffer);
    +		if (magic == ZSTD_MAGICNUMBER)
    +			return 1;
    +		if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START)
    +			return 1;
     	}
     	return 0;
     }
     
    -
     /** ZSTD_frameHeaderSize() :
     *   srcSize must be >= ZSTD_frameHeaderSize_prefix.
     *   @return : size of the Frame Header */
    -static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
    +static size_t ZSTD_frameHeaderSize(const void *src, size_t srcSize)
     {
    -	if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
    -	{	BYTE const fhd = ((const BYTE*)src)[4];
    -		U32 const dictID= fhd & 3;
    +	if (srcSize < ZSTD_frameHeaderSize_prefix)
    +		return ERROR(srcSize_wrong);
    +	{
    +		BYTE const fhd = ((const BYTE *)src)[4];
    +		U32 const dictID = fhd & 3;
     		U32 const singleSegment = (fhd >> 5) & 1;
     		U32 const fcsId = fhd >> 6;
    -		return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
    -				+ (singleSegment && !fcsId);
    +		return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + (singleSegment && !fcsId);
     	}
     }
     
    -
     /** ZSTD_getFrameParams() :
     *   decode Frame Header, or require larger `srcSize`.
     *   @return : 0, `fparamsPtr` is correctly filled,
     *            >0, `srcSize` is too small, result is expected `srcSize`,
     *             or an error code, which can be tested using ZSTD_isError() */
    -size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
    +size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src, size_t srcSize)
     {
    -	const BYTE* ip = (const BYTE*)src;
    +	const BYTE *ip = (const BYTE *)src;
     
    -	if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
    +	if (srcSize < ZSTD_frameHeaderSize_prefix)
    +		return ZSTD_frameHeaderSize_prefix;
     	if (ZSTD_readLE32(src) != ZSTD_MAGICNUMBER) {
     		if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    -			if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
    +			if (srcSize < ZSTD_skippableHeaderSize)
    +				return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
     			memset(fparamsPtr, 0, sizeof(*fparamsPtr));
     			fparamsPtr->frameContentSize = ZSTD_readLE32((const char *)src + 4);
     			fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
    @@ -217,46 +222,64 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
     	}
     
     	/* ensure there is enough `srcSize` to fully read/decode frame header */
    -	{ size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
    -	  if (srcSize < fhsize) return fhsize; }
    +	{
    +		size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
    +		if (srcSize < fhsize)
    +			return fhsize;
    +	}
     
    -	{	BYTE const fhdByte = ip[4];
    +	{
    +		BYTE const fhdByte = ip[4];
     		size_t pos = 5;
    -		U32 const dictIDSizeCode = fhdByte&3;
    -		U32 const checksumFlag = (fhdByte>>2)&1;
    -		U32 const singleSegment = (fhdByte>>5)&1;
    -		U32 const fcsID = fhdByte>>6;
    +		U32 const dictIDSizeCode = fhdByte & 3;
    +		U32 const checksumFlag = (fhdByte >> 2) & 1;
    +		U32 const singleSegment = (fhdByte >> 5) & 1;
    +		U32 const fcsID = fhdByte >> 6;
     		U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
     		U32 windowSize = 0;
     		U32 dictID = 0;
     		U64 frameContentSize = 0;
    -		if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported);   /* reserved bits, which must be zero */
    +		if ((fhdByte & 0x08) != 0)
    +			return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
     		if (!singleSegment) {
     			BYTE const wlByte = ip[pos++];
     			U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
    -			if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge);  /* avoids issue with 1 << windowLog */
    +			if (windowLog > ZSTD_WINDOWLOG_MAX)
    +				return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */
     			windowSize = (1U << windowLog);
    -			windowSize += (windowSize >> 3) * (wlByte&7);
    +			windowSize += (windowSize >> 3) * (wlByte & 7);
     		}
     
    -		switch(dictIDSizeCode)
    -		{
    -			default:   /* impossible */
    -			case 0 : break;
    -			case 1 : dictID = ip[pos]; pos++; break;
    -			case 2 : dictID = ZSTD_readLE16(ip+pos); pos+=2; break;
    -			case 3 : dictID = ZSTD_readLE32(ip+pos); pos+=4; break;
    +		switch (dictIDSizeCode) {
    +		default: /* impossible */
    +		case 0: break;
    +		case 1:
    +			dictID = ip[pos];
    +			pos++;
    +			break;
    +		case 2:
    +			dictID = ZSTD_readLE16(ip + pos);
    +			pos += 2;
    +			break;
    +		case 3:
    +			dictID = ZSTD_readLE32(ip + pos);
    +			pos += 4;
    +			break;
     		}
    -		switch(fcsID)
    -		{
    -			default:   /* impossible */
    -			case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
    -			case 1 : frameContentSize = ZSTD_readLE16(ip+pos)+256; break;
    -			case 2 : frameContentSize = ZSTD_readLE32(ip+pos); break;
    -			case 3 : frameContentSize = ZSTD_readLE64(ip+pos); break;
    +		switch (fcsID) {
    +		default: /* impossible */
    +		case 0:
    +			if (singleSegment)
    +				frameContentSize = ip[pos];
    +			break;
    +		case 1: frameContentSize = ZSTD_readLE16(ip + pos) + 256; break;
    +		case 2: frameContentSize = ZSTD_readLE32(ip + pos); break;
    +		case 3: frameContentSize = ZSTD_readLE64(ip + pos); break;
     		}
    -		if (!windowSize) windowSize = (U32)frameContentSize;
    -		if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
    +		if (!windowSize)
    +			windowSize = (U32)frameContentSize;
    +		if (windowSize > windowSizeMax)
    +			return ERROR(frameParameter_windowTooLarge);
     		fparamsPtr->frameContentSize = frameContentSize;
     		fparamsPtr->windowSize = windowSize;
     		fparamsPtr->dictID = dictID;
    @@ -274,7 +297,8 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
     {
     	{
     		ZSTD_frameParams fParams;
    -		if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0) return ZSTD_CONTENTSIZE_ERROR;
    +		if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0)
    +			return ZSTD_CONTENTSIZE_ERROR;
     		if (fParams.windowSize == 0) {
     			/* Either skippable or empty frame, size == 0 either way */
     			return 0;
    @@ -291,7 +315,7 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
      *  `srcSize` must be the exact length of some number of ZSTD compressed and/or
      *      skippable frames
      *  @return : decompressed size of the frames contained */
    -unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
    +unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize)
     {
     	{
     		unsigned long long totalDstSize = 0;
    @@ -302,8 +326,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
     				size_t skippableSize;
     				if (srcSize < ZSTD_skippableHeaderSize)
     					return ERROR(srcSize_wrong);
    -				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) +
    -								ZSTD_skippableHeaderSize;
    +				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize;
     				if (srcSize < skippableSize) {
     					return ZSTD_CONTENTSIZE_ERROR;
     				}
    @@ -315,10 +338,12 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
     
     			{
     				unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
    -				if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
    +				if (ret >= ZSTD_CONTENTSIZE_ERROR)
    +					return ret;
     
     				/* check for overflow */
    -				if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
    +				if (totalDstSize + ret < totalDstSize)
    +					return ZSTD_CONTENTSIZE_ERROR;
     				totalDstSize += ret;
     			}
     			{
    @@ -343,19 +368,21 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
     /** ZSTD_decodeFrameHeader() :
     *   `headerSize` must be the size provided by ZSTD_frameHeaderSize().
     *   @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
    -static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
    +static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx *dctx, const void *src, size_t headerSize)
     {
     	size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
    -	if (ZSTD_isError(result)) return result;  /* invalid header */
    -	if (result>0) return ERROR(srcSize_wrong);   /* headerSize too small */
    -	if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
    -	if (dctx->fParams.checksumFlag) xxh64_reset(&dctx->xxhState, 0);
    +	if (ZSTD_isError(result))
    +		return result; /* invalid header */
    +	if (result > 0)
    +		return ERROR(srcSize_wrong); /* headerSize too small */
    +	if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
    +		return ERROR(dictionary_wrong);
    +	if (dctx->fParams.checksumFlag)
    +		xxh64_reset(&dctx->xxhState, 0);
     	return 0;
     }
     
    -
    -typedef struct
    -{
    +typedef struct {
     	blockType_e blockType;
     	U32 lastBlock;
     	U32 origSize;
    @@ -363,441 +390,468 @@ typedef struct
     
     /*! ZSTD_getcBlockSize() :
     *   Provides the size of compressed block from block header `src` */
    -size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
    +size_t ZSTD_getcBlockSize(const void *src, size_t srcSize, blockProperties_t *bpPtr)
     {
    -	if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    -	{	U32 const cBlockHeader = ZSTD_readLE24(src);
    +	if (srcSize < ZSTD_blockHeaderSize)
    +		return ERROR(srcSize_wrong);
    +	{
    +		U32 const cBlockHeader = ZSTD_readLE24(src);
     		U32 const cSize = cBlockHeader >> 3;
     		bpPtr->lastBlock = cBlockHeader & 1;
     		bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
    -		bpPtr->origSize = cSize;   /* only useful for RLE */
    -		if (bpPtr->blockType == bt_rle) return 1;
    -		if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
    +		bpPtr->origSize = cSize; /* only useful for RLE */
    +		if (bpPtr->blockType == bt_rle)
    +			return 1;
    +		if (bpPtr->blockType == bt_reserved)
    +			return ERROR(corruption_detected);
     		return cSize;
     	}
     }
     
    -
    -static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +static size_t ZSTD_copyRawBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
    -	if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
    +	if (srcSize > dstCapacity)
    +		return ERROR(dstSize_tooSmall);
     	memcpy(dst, src, srcSize);
     	return srcSize;
     }
     
    -
    -static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
    +static size_t ZSTD_setRleBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize, size_t regenSize)
     {
    -	if (srcSize != 1) return ERROR(srcSize_wrong);
    -	if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
    -	memset(dst, *(const BYTE*)src, regenSize);
    +	if (srcSize != 1)
    +		return ERROR(srcSize_wrong);
    +	if (regenSize > dstCapacity)
    +		return ERROR(dstSize_tooSmall);
    +	memset(dst, *(const BYTE *)src, regenSize);
     	return regenSize;
     }
     
     /*! ZSTD_decodeLiteralsBlock() :
     	@return : nb of bytes read from src (< srcSize ) */
    -size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
    -						  const void* src, size_t srcSize)   /* note : srcSize < BLOCKSIZE */
    +size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
     {
    -	if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
    +	if (srcSize < MIN_CBLOCK_SIZE)
    +		return ERROR(corruption_detected);
     
    -	{	const BYTE* const istart = (const BYTE*) src;
    +	{
    +		const BYTE *const istart = (const BYTE *)src;
     		symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
     
    -		switch(litEncType)
    -		{
    +		switch (litEncType) {
     		case set_repeat:
    -			if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
    -			/* fall-through */
    +			if (dctx->litEntropy == 0)
    +				return ERROR(dictionary_corrupted);
    +		/* fall-through */
     		case set_compressed:
    -			if (srcSize < 5) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
    -			{	size_t lhSize, litSize, litCSize;
    -				U32 singleStream=0;
    +			if (srcSize < 5)
    +				return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
    +			{
    +				size_t lhSize, litSize, litCSize;
    +				U32 singleStream = 0;
     				U32 const lhlCode = (istart[0] >> 2) & 3;
     				U32 const lhc = ZSTD_readLE32(istart);
    -				switch(lhlCode)
    -				{
    -				case 0: case 1: default:   /* note : default is impossible, since lhlCode into [0..3] */
    +				switch (lhlCode) {
    +				case 0:
    +				case 1:
    +				default: /* note : default is impossible, since lhlCode into [0..3] */
     					/* 2 - 2 - 10 - 10 */
     					singleStream = !lhlCode;
     					lhSize = 3;
    -					litSize  = (lhc >> 4) & 0x3FF;
    +					litSize = (lhc >> 4) & 0x3FF;
     					litCSize = (lhc >> 14) & 0x3FF;
     					break;
     				case 2:
     					/* 2 - 2 - 14 - 14 */
     					lhSize = 4;
    -					litSize  = (lhc >> 4) & 0x3FFF;
    +					litSize = (lhc >> 4) & 0x3FFF;
     					litCSize = lhc >> 18;
     					break;
     				case 3:
     					/* 2 - 2 - 18 - 18 */
     					lhSize = 5;
    -					litSize  = (lhc >> 4) & 0x3FFFF;
    +					litSize = (lhc >> 4) & 0x3FFFF;
     					litCSize = (lhc >> 22) + (istart[4] << 10);
     					break;
     				}
    -				if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    -				if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
    +				if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX)
    +					return ERROR(corruption_detected);
    +				if (litCSize + lhSize > srcSize)
    +					return ERROR(corruption_detected);
     
    -				if (HUF_isError((litEncType==set_repeat) ?
    -									( singleStream ?
    -										HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
    -										HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
    -									( singleStream ?
    -										HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
    -										HUF_decompress4X_hufOnly (dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
    +				if (HUF_isError(
    +					(litEncType == set_repeat)
    +					    ? (singleStream ? HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr)
    +							    : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr))
    +					    : (singleStream
    +						   ? HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize)
    +						   : HUF_decompress4X_hufOnly(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize))))
     					return ERROR(corruption_detected);
     
     				dctx->litPtr = dctx->litBuffer;
     				dctx->litSize = litSize;
     				dctx->litEntropy = 1;
    -				if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
    +				if (litEncType == set_compressed)
    +					dctx->HUFptr = dctx->entropy.hufTable;
     				memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
     				return litCSize + lhSize;
     			}
     
    -		case set_basic:
    -			{	size_t litSize, lhSize;
    -				U32 const lhlCode = ((istart[0]) >> 2) & 3;
    -				switch(lhlCode)
    -				{
    -				case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
    -					lhSize = 1;
    -					litSize = istart[0] >> 3;
    -					break;
    -				case 1:
    -					lhSize = 2;
    -					litSize = ZSTD_readLE16(istart) >> 4;
    -					break;
    -				case 3:
    -					lhSize = 3;
    -					litSize = ZSTD_readLE24(istart) >> 4;
    -					break;
    -				}
    -
    -				if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */
    -					if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
    -					memcpy(dctx->litBuffer, istart+lhSize, litSize);
    -					dctx->litPtr = dctx->litBuffer;
    -					dctx->litSize = litSize;
    -					memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
    -					return lhSize+litSize;
    -				}
    -				/* direct reference into compressed stream */
    -				dctx->litPtr = istart+lhSize;
    -				dctx->litSize = litSize;
    -				return lhSize+litSize;
    +		case set_basic: {
    +			size_t litSize, lhSize;
    +			U32 const lhlCode = ((istart[0]) >> 2) & 3;
    +			switch (lhlCode) {
    +			case 0:
    +			case 2:
    +			default: /* note : default is impossible, since lhlCode into [0..3] */
    +				lhSize = 1;
    +				litSize = istart[0] >> 3;
    +				break;
    +			case 1:
    +				lhSize = 2;
    +				litSize = ZSTD_readLE16(istart) >> 4;
    +				break;
    +			case 3:
    +				lhSize = 3;
    +				litSize = ZSTD_readLE24(istart) >> 4;
    +				break;
     			}
     
    -		case set_rle:
    -			{	U32 const lhlCode = ((istart[0]) >> 2) & 3;
    -				size_t litSize, lhSize;
    -				switch(lhlCode)
    -				{
    -				case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
    -					lhSize = 1;
    -					litSize = istart[0] >> 3;
    -					break;
    -				case 1:
    -					lhSize = 2;
    -					litSize = ZSTD_readLE16(istart) >> 4;
    -					break;
    -				case 3:
    -					lhSize = 3;
    -					litSize = ZSTD_readLE24(istart) >> 4;
    -					if (srcSize<4) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
    -					break;
    -				}
    -				if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    -				memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
    +			if (lhSize + litSize + WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
    +				if (litSize + lhSize > srcSize)
    +					return ERROR(corruption_detected);
    +				memcpy(dctx->litBuffer, istart + lhSize, litSize);
     				dctx->litPtr = dctx->litBuffer;
     				dctx->litSize = litSize;
    -				return lhSize+1;
    +				memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
    +				return lhSize + litSize;
     			}
    +			/* direct reference into compressed stream */
    +			dctx->litPtr = istart + lhSize;
    +			dctx->litSize = litSize;
    +			return lhSize + litSize;
    +		}
    +
    +		case set_rle: {
    +			U32 const lhlCode = ((istart[0]) >> 2) & 3;
    +			size_t litSize, lhSize;
    +			switch (lhlCode) {
    +			case 0:
    +			case 2:
    +			default: /* note : default is impossible, since lhlCode into [0..3] */
    +				lhSize = 1;
    +				litSize = istart[0] >> 3;
    +				break;
    +			case 1:
    +				lhSize = 2;
    +				litSize = ZSTD_readLE16(istart) >> 4;
    +				break;
    +			case 3:
    +				lhSize = 3;
    +				litSize = ZSTD_readLE24(istart) >> 4;
    +				if (srcSize < 4)
    +					return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
    +				break;
    +			}
    +			if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX)
    +				return ERROR(corruption_detected);
    +			memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
    +			dctx->litPtr = dctx->litBuffer;
    +			dctx->litSize = litSize;
    +			return lhSize + 1;
    +		}
     		default:
    -			return ERROR(corruption_detected);   /* impossible */
    +			return ERROR(corruption_detected); /* impossible */
     		}
     	}
     }
     
    -
     typedef union {
     	FSE_decode_t realData;
     	U32 alignedBy4;
     } FSE_decode_t4;
     
    -static const FSE_decode_t4 LL_defaultDTable[(1< max) return ERROR(corruption_detected);
    -		FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
    +	const void *const tmpPtr = defaultTable; /* bypass strict aliasing */
    +	switch (type) {
    +	case set_rle:
    +		if (!srcSize)
    +			return ERROR(srcSize_wrong);
    +		if ((*(const BYTE *)src) > max)
    +			return ERROR(corruption_detected);
    +		FSE_buildDTable_rle(DTableSpace, *(const BYTE *)src);
     		*DTablePtr = DTableSpace;
     		return 1;
    -	case set_basic :
    -		*DTablePtr = (const FSE_DTable*)tmpPtr;
    -		return 0;
    +	case set_basic: *DTablePtr = (const FSE_DTable *)tmpPtr; return 0;
     	case set_repeat:
    -		if (!flagRepeatTable) return ERROR(corruption_detected);
    +		if (!flagRepeatTable)
    +			return ERROR(corruption_detected);
     		return 0;
    -	default :   /* impossible */
    -	case set_compressed :
    -		{	U32 tableLog;
    -			S16 norm[MaxSeq+1];
    -			size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
    -			if (FSE_isError(headerSize)) return ERROR(corruption_detected);
    -			if (tableLog > maxLog) return ERROR(corruption_detected);
    -			FSE_buildDTable(DTableSpace, norm, max, tableLog);
    -			*DTablePtr = DTableSpace;
    -			return headerSize;
    -	}   }
    +	default: /* impossible */
    +	case set_compressed: {
    +		U32 tableLog;
    +		S16 norm[MaxSeq + 1];
    +		size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
    +		if (FSE_isError(headerSize))
    +			return ERROR(corruption_detected);
    +		if (tableLog > maxLog)
    +			return ERROR(corruption_detected);
    +		FSE_buildDTable(DTableSpace, norm, max, tableLog);
    +		*DTablePtr = DTableSpace;
    +		return headerSize;
    +	}
    +	}
     }
     
    -size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
    -							 const void* src, size_t srcSize)
    +size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, size_t srcSize)
     {
    -	const BYTE* const istart = (const BYTE* const)src;
    -	const BYTE* const iend = istart + srcSize;
    -	const BYTE* ip = istart;
    +	const BYTE *const istart = (const BYTE *const)src;
    +	const BYTE *const iend = istart + srcSize;
    +	const BYTE *ip = istart;
     
     	/* check */
    -	if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
    +	if (srcSize < MIN_SEQUENCES_SIZE)
    +		return ERROR(srcSize_wrong);
     
     	/* SeqHead */
    -	{	int nbSeq = *ip++;
    -		if (!nbSeq) { *nbSeqPtr=0; return 1; }
    +	{
    +		int nbSeq = *ip++;
    +		if (!nbSeq) {
    +			*nbSeqPtr = 0;
    +			return 1;
    +		}
     		if (nbSeq > 0x7F) {
     			if (nbSeq == 0xFF) {
    -				if (ip+2 > iend) return ERROR(srcSize_wrong);
    -				nbSeq = ZSTD_readLE16(ip) + LONGNBSEQ, ip+=2;
    +				if (ip + 2 > iend)
    +					return ERROR(srcSize_wrong);
    +				nbSeq = ZSTD_readLE16(ip) + LONGNBSEQ, ip += 2;
     			} else {
    -				if (ip >= iend) return ERROR(srcSize_wrong);
    -				nbSeq = ((nbSeq-0x80)<<8) + *ip++;
    +				if (ip >= iend)
    +					return ERROR(srcSize_wrong);
    +				nbSeq = ((nbSeq - 0x80) << 8) + *ip++;
     			}
     		}
     		*nbSeqPtr = nbSeq;
     	}
     
     	/* FSE table descriptors */
    -	if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
    -	{	symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
    +	if (ip + 4 > iend)
    +		return ERROR(srcSize_wrong); /* minimum possible size */
    +	{
    +		symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
     		symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
     		symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
     		ip++;
     
     		/* Build DTables */
    -		{	size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
    -													  LLtype, MaxLL, LLFSELog,
    -													  ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
    -			if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
    +		{
    +			size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, LLtype, MaxLL, LLFSELog, ip, iend - ip,
    +								  LL_defaultDTable, dctx->fseEntropy);
    +			if (ZSTD_isError(llhSize))
    +				return ERROR(corruption_detected);
     			ip += llhSize;
     		}
    -		{	size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
    -													  OFtype, MaxOff, OffFSELog,
    -													  ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
    -			if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
    +		{
    +			size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, OFtype, MaxOff, OffFSELog, ip, iend - ip,
    +								  OF_defaultDTable, dctx->fseEntropy);
    +			if (ZSTD_isError(ofhSize))
    +				return ERROR(corruption_detected);
     			ip += ofhSize;
     		}
    -		{	size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
    -													  MLtype, MaxML, MLFSELog,
    -													  ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
    -			if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
    +		{
    +			size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, MLtype, MaxML, MLFSELog, ip, iend - ip,
    +								  ML_defaultDTable, dctx->fseEntropy);
    +			if (ZSTD_isError(mlhSize))
    +				return ERROR(corruption_detected);
     			ip += mlhSize;
     		}
     	}
     
    -	return ip-istart;
    +	return ip - istart;
     }
     
    -
     typedef struct {
     	size_t litLength;
     	size_t matchLength;
     	size_t offset;
    -	const BYTE* match;
    +	const BYTE *match;
     } seq_t;
     
     typedef struct {
    @@ -806,29 +860,29 @@ typedef struct {
     	FSE_DState_t stateOffb;
     	FSE_DState_t stateML;
     	size_t prevOffset[ZSTD_REP_NUM];
    -	const BYTE* base;
    +	const BYTE *base;
     	size_t pos;
     	uPtrDiff gotoDict;
     } seqState_t;
     
    -
     FORCE_NOINLINE
    -size_t ZSTD_execSequenceLast7(BYTE* op,
    -							  BYTE* const oend, seq_t sequence,
    -							  const BYTE** litPtr, const BYTE* const litLimit,
    -							  const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    +size_t ZSTD_execSequenceLast7(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
    +			      const BYTE *const vBase, const BYTE *const dictEnd)
     {
    -	BYTE* const oLitEnd = op + sequence.litLength;
    +	BYTE *const oLitEnd = op + sequence.litLength;
     	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    -	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    -	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    -	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    -	const BYTE* match = oLitEnd - sequence.offset;
    +	BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
    +	BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
    +	const BYTE *const iLitEnd = *litPtr + sequence.litLength;
    +	const BYTE *match = oLitEnd - sequence.offset;
     
     	/* check */
    -	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    -	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    -	if (oLitEnd <= oend_w) return ERROR(GENERIC);   /* Precondition */
    +	if (oMatchEnd > oend)
    +		return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    +	if (iLitEnd > litLimit)
    +		return ERROR(corruption_detected); /* over-read beyond lit buffer */
    +	if (oLitEnd <= oend_w)
    +		return ERROR(GENERIC); /* Precondition */
     
     	/* copy literals */
     	if (op < oend_w) {
    @@ -836,76 +890,75 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
     		*litPtr += oend_w - op;
     		op = oend_w;
     	}
    -	while (op < oLitEnd) *op++ = *(*litPtr)++;
    +	while (op < oLitEnd)
    +		*op++ = *(*litPtr)++;
     
     	/* copy Match */
     	if (sequence.offset > (size_t)(oLitEnd - base)) {
     		/* offset beyond prefix */
    -		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    -		match = dictEnd - (base-match);
    +		if (sequence.offset > (size_t)(oLitEnd - vBase))
    +			return ERROR(corruption_detected);
    +		match = dictEnd - (base - match);
     		if (match + sequence.matchLength <= dictEnd) {
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{	size_t const length1 = dictEnd - match;
    +		{
    +			size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
     			match = base;
    -	}   }
    -	while (op < oMatchEnd) *op++ = *match++;
    +		}
    +	}
    +	while (op < oMatchEnd)
    +		*op++ = *match++;
     	return sequenceLength;
     }
     
    -
    -
    -
    -static seq_t ZSTD_decodeSequence(seqState_t* seqState)
    +static seq_t ZSTD_decodeSequence(seqState_t *seqState)
     {
     	seq_t seq;
     
     	U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
     	U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
    -	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb);   /* <= maxOff, by table construction */
    +	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
     
     	U32 const llBits = LL_bits[llCode];
     	U32 const mlBits = ML_bits[mlCode];
     	U32 const ofBits = ofCode;
    -	U32 const totalBits = llBits+mlBits+ofBits;
    +	U32 const totalBits = llBits + mlBits + ofBits;
     
    -	static const U32 LL_base[MaxLL+1] = {
    -							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,   10,    11,    12,    13,    14,     15,
    -							16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
    -							0x2000, 0x4000, 0x8000, 0x10000 };
    +	static const U32 LL_base[MaxLL + 1] = {0,  1,  2,  3,  4,  5,  6,  7,  8,    9,     10,    11,    12,    13,     14,     15,     16,     18,
    +					       20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
     
    -	static const U32 ML_base[MaxML+1] = {
    -							 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,   14,    15,    16,    17,    18,
    -							19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,   30,    31,    32,    33,    34,
    -							35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
    -							0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
    +	static const U32 ML_base[MaxML + 1] = {3,  4,  5,  6,  7,  8,  9,  10,   11,    12,    13,    14,    15,     16,     17,     18,     19,     20,
    +					       21, 22, 23, 24, 25, 26, 27, 28,   29,    30,    31,    32,    33,     34,     35,     37,     39,     41,
    +					       43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
     
    -	static const U32 OF_base[MaxOff+1] = {
    -							 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
    -							 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
    -							 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
    -							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
    +	static const U32 OF_base[MaxOff + 1] = {0,       1,	1,	5,	0xD,      0x1D,      0x3D,      0x7D,      0xFD,     0x1FD,
    +						0x3FD,   0x7FD,    0xFFD,    0x1FFD,   0x3FFD,   0x7FFD,    0xFFFD,    0x1FFFD,   0x3FFFD,  0x7FFFD,
    +						0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
     
     	/* sequence */
    -	{	size_t offset;
    +	{
    +		size_t offset;
     		if (!ofCode)
     			offset = 0;
     		else {
    -			offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    -			if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);
    +			offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    +			if (ZSTD_32bits())
    +				BIT_reloadDStream(&seqState->DStream);
     		}
     
     		if (ofCode <= 1) {
    -			offset += (llCode==0);
    +			offset += (llCode == 0);
     			if (offset) {
    -				size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    -				temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */
    -				if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
    +				size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    +				temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
    +				if (offset != 1)
    +					seqState->prevOffset[2] = seqState->prevOffset[1];
     				seqState->prevOffset[1] = seqState->prevOffset[0];
     				seqState->prevOffset[0] = offset = temp;
     			} else {
    @@ -919,123 +972,130 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
     		seq.offset = offset;
     	}
     
    -	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    -	if (ZSTD_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    +	seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <=  16 bits */
    +	if (ZSTD_32bits() && (mlBits + llBits > 24))
    +		BIT_reloadDStream(&seqState->DStream);
     
    -	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    -	if (ZSTD_32bits() ||
    -	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
    +	seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <=  16 bits */
    +	if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog)))
    +		BIT_reloadDStream(&seqState->DStream);
     
     	/* ANS state update */
    -	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
    -	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    -	if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    -	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
    +	FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <=  9 bits */
    +	FSE_updateState(&seqState->stateML, &seqState->DStream); /* <=  9 bits */
    +	if (ZSTD_32bits())
    +		BIT_reloadDStream(&seqState->DStream);		   /* <= 18 bits */
    +	FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <=  8 bits */
     
     	return seq;
     }
     
    -
     FORCE_INLINE
    -size_t ZSTD_execSequence(BYTE* op,
    -						 BYTE* const oend, seq_t sequence,
    -						 const BYTE** litPtr, const BYTE* const litLimit,
    -						 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    +size_t ZSTD_execSequence(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
    +			 const BYTE *const vBase, const BYTE *const dictEnd)
     {
    -	BYTE* const oLitEnd = op + sequence.litLength;
    +	BYTE *const oLitEnd = op + sequence.litLength;
     	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    -	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    -	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    -	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    -	const BYTE* match = oLitEnd - sequence.offset;
    +	BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
    +	BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
    +	const BYTE *const iLitEnd = *litPtr + sequence.litLength;
    +	const BYTE *match = oLitEnd - sequence.offset;
     
     	/* check */
    -	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    -	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    -	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    +	if (oMatchEnd > oend)
    +		return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    +	if (iLitEnd > litLimit)
    +		return ERROR(corruption_detected); /* over-read beyond lit buffer */
    +	if (oLitEnd > oend_w)
    +		return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
     
     	/* copy Literals */
     	ZSTD_copy8(op, *litPtr);
     	if (sequence.litLength > 8)
    -		ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8);   /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
    +		ZSTD_wildcopy(op + 8, (*litPtr) + 8,
    +			      sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
     	op = oLitEnd;
    -	*litPtr = iLitEnd;   /* update for next sequence */
    +	*litPtr = iLitEnd; /* update for next sequence */
     
     	/* copy Match */
     	if (sequence.offset > (size_t)(oLitEnd - base)) {
     		/* offset beyond prefix */
    -		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    +		if (sequence.offset > (size_t)(oLitEnd - vBase))
    +			return ERROR(corruption_detected);
     		match = dictEnd + (match - base);
     		if (match + sequence.matchLength <= dictEnd) {
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{	size_t const length1 = dictEnd - match;
    +		{
    +			size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
     			match = base;
     			if (op > oend_w || sequence.matchLength < MINMATCH) {
    -			  U32 i;
    -			  for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
    -			  return sequenceLength;
    +				U32 i;
    +				for (i = 0; i < sequence.matchLength; ++i)
    +					op[i] = match[i];
    +				return sequenceLength;
     			}
    -	}   }
    +		}
    +	}
     	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
     
     	/* match within prefix */
     	if (sequence.offset < 8) {
     		/* close range match, overlap */
    -		static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */
    -		static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */
    +		static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4};   /* added */
    +		static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
     		int const sub2 = dec64table[sequence.offset];
     		op[0] = match[0];
     		op[1] = match[1];
     		op[2] = match[2];
     		op[3] = match[3];
     		match += dec32table[sequence.offset];
    -		ZSTD_copy4(op+4, match);
    +		ZSTD_copy4(op + 4, match);
     		match -= sub2;
     	} else {
     		ZSTD_copy8(op, match);
     	}
    -	op += 8; match += 8;
    +	op += 8;
    +	match += 8;
     
    -	if (oMatchEnd > oend-(16-MINMATCH)) {
    +	if (oMatchEnd > oend - (16 - MINMATCH)) {
     		if (op < oend_w) {
     			ZSTD_wildcopy(op, match, oend_w - op);
     			match += oend_w - op;
     			op = oend_w;
     		}
    -		while (op < oMatchEnd) *op++ = *match++;
    +		while (op < oMatchEnd)
    +			*op++ = *match++;
     	} else {
    -		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8);   /* works even if matchLength < 8 */
    +		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */
     	}
     	return sequenceLength;
     }
     
    -
    -static size_t ZSTD_decompressSequences(
    -							   ZSTD_DCtx* dctx,
    -							   void* dst, size_t maxDstSize,
    -						 const void* seqStart, size_t seqSize)
    +static size_t ZSTD_decompressSequences(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize)
     {
    -	const BYTE* ip = (const BYTE*)seqStart;
    -	const BYTE* const iend = ip + seqSize;
    -	BYTE* const ostart = (BYTE* const)dst;
    -	BYTE* const oend = ostart + maxDstSize;
    -	BYTE* op = ostart;
    -	const BYTE* litPtr = dctx->litPtr;
    -	const BYTE* const litEnd = litPtr + dctx->litSize;
    -	const BYTE* const base = (const BYTE*) (dctx->base);
    -	const BYTE* const vBase = (const BYTE*) (dctx->vBase);
    -	const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
    +	const BYTE *ip = (const BYTE *)seqStart;
    +	const BYTE *const iend = ip + seqSize;
    +	BYTE *const ostart = (BYTE * const)dst;
    +	BYTE *const oend = ostart + maxDstSize;
    +	BYTE *op = ostart;
    +	const BYTE *litPtr = dctx->litPtr;
    +	const BYTE *const litEnd = litPtr + dctx->litSize;
    +	const BYTE *const base = (const BYTE *)(dctx->base);
    +	const BYTE *const vBase = (const BYTE *)(dctx->vBase);
    +	const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd);
     	int nbSeq;
     
     	/* Build Decoding Tables */
    -	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    -		if (ZSTD_isError(seqHSize)) return seqHSize;
    +	{
    +		size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    +		if (ZSTD_isError(seqHSize))
    +			return seqHSize;
     		ip += seqHSize;
     	}
     
    @@ -1043,89 +1103,101 @@ static size_t ZSTD_decompressSequences(
     	if (nbSeq) {
     		seqState_t seqState;
     		dctx->fseEntropy = 1;
    -		{ U32 i; for (i=0; ientropy.rep[i]; }
    -		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
    +		{
    +			U32 i;
    +			for (i = 0; i < ZSTD_REP_NUM; i++)
    +				seqState.prevOffset[i] = dctx->entropy.rep[i];
    +		}
    +		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected);
     		FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
     		FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
     		FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
     
    -		for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
    +		for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq;) {
     			nbSeq--;
    -			{	seq_t const sequence = ZSTD_decodeSequence(&seqState);
    +			{
    +				seq_t const sequence = ZSTD_decodeSequence(&seqState);
     				size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
    -				if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
    +				if (ZSTD_isError(oneSeqSize))
    +					return oneSeqSize;
     				op += oneSeqSize;
    -		}   }
    +			}
    +		}
     
     		/* check if reached exact end */
    -		if (nbSeq) return ERROR(corruption_detected);
    +		if (nbSeq)
    +			return ERROR(corruption_detected);
     		/* save reps for next block */
    -		{ U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); }
    +		{
    +			U32 i;
    +			for (i = 0; i < ZSTD_REP_NUM; i++)
    +				dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]);
    +		}
     	}
     
     	/* last literal segment */
    -	{	size_t const lastLLSize = litEnd - litPtr;
    -		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
    +	{
    +		size_t const lastLLSize = litEnd - litPtr;
    +		if (lastLLSize > (size_t)(oend - op))
    +			return ERROR(dstSize_tooSmall);
     		memcpy(op, litPtr, lastLLSize);
     		op += lastLLSize;
     	}
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -
    -FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int const longOffsets)
    +FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t *seqState, int const longOffsets)
     {
     	seq_t seq;
     
     	U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
     	U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
    -	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb);   /* <= maxOff, by table construction */
    +	U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
     
     	U32 const llBits = LL_bits[llCode];
     	U32 const mlBits = ML_bits[mlCode];
     	U32 const ofBits = ofCode;
    -	U32 const totalBits = llBits+mlBits+ofBits;
    +	U32 const totalBits = llBits + mlBits + ofBits;
     
    -	static const U32 LL_base[MaxLL+1] = {
    -							 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,   10,    11,    12,    13,    14,     15,
    -							16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
    -							0x2000, 0x4000, 0x8000, 0x10000 };
    +	static const U32 LL_base[MaxLL + 1] = {0,  1,  2,  3,  4,  5,  6,  7,  8,    9,     10,    11,    12,    13,     14,     15,     16,     18,
    +					       20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
     
    -	static const U32 ML_base[MaxML+1] = {
    -							 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,   14,    15,    16,    17,    18,
    -							19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,   30,    31,    32,    33,    34,
    -							35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
    -							0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
    +	static const U32 ML_base[MaxML + 1] = {3,  4,  5,  6,  7,  8,  9,  10,   11,    12,    13,    14,    15,     16,     17,     18,     19,     20,
    +					       21, 22, 23, 24, 25, 26, 27, 28,   29,    30,    31,    32,    33,     34,     35,     37,     39,     41,
    +					       43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
     
    -	static const U32 OF_base[MaxOff+1] = {
    -							 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
    -							 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
    -							 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
    -							 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
    +	static const U32 OF_base[MaxOff + 1] = {0,       1,	1,	5,	0xD,      0x1D,      0x3D,      0x7D,      0xFD,     0x1FD,
    +						0x3FD,   0x7FD,    0xFFD,    0x1FFD,   0x3FFD,   0x7FFD,    0xFFFD,    0x1FFFD,   0x3FFFD,  0x7FFFD,
    +						0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
     
     	/* sequence */
    -	{	size_t offset;
    +	{
    +		size_t offset;
     		if (!ofCode)
     			offset = 0;
     		else {
     			if (longOffsets) {
     				int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
     				offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
    -				if (ZSTD_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
    -				if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
    +				if (ZSTD_32bits() || extraBits)
    +					BIT_reloadDStream(&seqState->DStream);
    +				if (extraBits)
    +					offset += BIT_readBitsFast(&seqState->DStream, extraBits);
     			} else {
    -				offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    -				if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);
    +				offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */
    +				if (ZSTD_32bits())
    +					BIT_reloadDStream(&seqState->DStream);
     			}
     		}
     
     		if (ofCode <= 1) {
    -			offset += (llCode==0);
    +			offset += (llCode == 0);
     			if (offset) {
    -				size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    -				temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */
    -				if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
    +				size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
    +				temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
    +				if (offset != 1)
    +					seqState->prevOffset[2] = seqState->prevOffset[1];
     				seqState->prevOffset[1] = seqState->prevOffset[0];
     				seqState->prevOffset[0] = offset = temp;
     			} else {
    @@ -1139,29 +1211,34 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
     		seq.offset = offset;
     	}
     
    -	seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    -	if (ZSTD_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
    +	seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <=  16 bits */
    +	if (ZSTD_32bits() && (mlBits + llBits > 24))
    +		BIT_reloadDStream(&seqState->DStream);
     
    -	seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    -	if (ZSTD_32bits() ||
    -	   (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
    +	seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <=  16 bits */
    +	if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog)))
    +		BIT_reloadDStream(&seqState->DStream);
     
    -	{	size_t const pos = seqState->pos + seq.litLength;
    -		seq.match = seqState->base + pos - seq.offset;    /* single memory segment */
    -		if (seq.offset > pos) seq.match += seqState->gotoDict;   /* separate memory segment */
    +	{
    +		size_t const pos = seqState->pos + seq.litLength;
    +		seq.match = seqState->base + pos - seq.offset; /* single memory segment */
    +		if (seq.offset > pos)
    +			seq.match += seqState->gotoDict; /* separate memory segment */
     		seqState->pos = pos + seq.matchLength;
     	}
     
     	/* ANS state update */
    -	FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
    -	FSE_updateState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */
    -	if (ZSTD_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
    -	FSE_updateState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */
    +	FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <=  9 bits */
    +	FSE_updateState(&seqState->stateML, &seqState->DStream); /* <=  9 bits */
    +	if (ZSTD_32bits())
    +		BIT_reloadDStream(&seqState->DStream);		   /* <= 18 bits */
    +	FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <=  8 bits */
     
     	return seq;
     }
     
    -static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
    +static seq_t ZSTD_decodeSequenceLong(seqState_t *seqState, unsigned const windowSize)
    +{
     	if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
     		return ZSTD_decodeSequenceLong_generic(seqState, 1);
     	} else {
    @@ -1170,225 +1247,243 @@ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const window
     }
     
     FORCE_INLINE
    -size_t ZSTD_execSequenceLong(BYTE* op,
    -								BYTE* const oend, seq_t sequence,
    -								const BYTE** litPtr, const BYTE* const litLimit,
    -								const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
    +size_t ZSTD_execSequenceLong(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
    +			     const BYTE *const vBase, const BYTE *const dictEnd)
     {
    -	BYTE* const oLitEnd = op + sequence.litLength;
    +	BYTE *const oLitEnd = op + sequence.litLength;
     	size_t const sequenceLength = sequence.litLength + sequence.matchLength;
    -	BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */
    -	BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
    -	const BYTE* const iLitEnd = *litPtr + sequence.litLength;
    -	const BYTE* match = sequence.match;
    +	BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
    +	BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
    +	const BYTE *const iLitEnd = *litPtr + sequence.litLength;
    +	const BYTE *match = sequence.match;
     
     	/* check */
    -	if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    -	if (iLitEnd > litLimit) return ERROR(corruption_detected);   /* over-read beyond lit buffer */
    -	if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
    +	if (oMatchEnd > oend)
    +		return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
    +	if (iLitEnd > litLimit)
    +		return ERROR(corruption_detected); /* over-read beyond lit buffer */
    +	if (oLitEnd > oend_w)
    +		return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
     
     	/* copy Literals */
     	ZSTD_copy8(op, *litPtr);
     	if (sequence.litLength > 8)
    -		ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8);   /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
    +		ZSTD_wildcopy(op + 8, (*litPtr) + 8,
    +			      sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
     	op = oLitEnd;
    -	*litPtr = iLitEnd;   /* update for next sequence */
    +	*litPtr = iLitEnd; /* update for next sequence */
     
     	/* copy Match */
     	if (sequence.offset > (size_t)(oLitEnd - base)) {
     		/* offset beyond prefix */
    -		if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    +		if (sequence.offset > (size_t)(oLitEnd - vBase))
    +			return ERROR(corruption_detected);
     		if (match + sequence.matchLength <= dictEnd) {
     			memmove(oLitEnd, match, sequence.matchLength);
     			return sequenceLength;
     		}
     		/* span extDict & currPrefixSegment */
    -		{	size_t const length1 = dictEnd - match;
    +		{
    +			size_t const length1 = dictEnd - match;
     			memmove(oLitEnd, match, length1);
     			op = oLitEnd + length1;
     			sequence.matchLength -= length1;
     			match = base;
     			if (op > oend_w || sequence.matchLength < MINMATCH) {
    -			  U32 i;
    -			  for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
    -			  return sequenceLength;
    +				U32 i;
    +				for (i = 0; i < sequence.matchLength; ++i)
    +					op[i] = match[i];
    +				return sequenceLength;
     			}
    -	}   }
    +		}
    +	}
     	/* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
     
     	/* match within prefix */
     	if (sequence.offset < 8) {
     		/* close range match, overlap */
    -		static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */
    -		static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */
    +		static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4};   /* added */
    +		static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
     		int const sub2 = dec64table[sequence.offset];
     		op[0] = match[0];
     		op[1] = match[1];
     		op[2] = match[2];
     		op[3] = match[3];
     		match += dec32table[sequence.offset];
    -		ZSTD_copy4(op+4, match);
    +		ZSTD_copy4(op + 4, match);
     		match -= sub2;
     	} else {
     		ZSTD_copy8(op, match);
     	}
    -	op += 8; match += 8;
    +	op += 8;
    +	match += 8;
     
    -	if (oMatchEnd > oend-(16-MINMATCH)) {
    +	if (oMatchEnd > oend - (16 - MINMATCH)) {
     		if (op < oend_w) {
     			ZSTD_wildcopy(op, match, oend_w - op);
     			match += oend_w - op;
     			op = oend_w;
     		}
    -		while (op < oMatchEnd) *op++ = *match++;
    +		while (op < oMatchEnd)
    +			*op++ = *match++;
     	} else {
    -		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8);   /* works even if matchLength < 8 */
    +		ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */
     	}
     	return sequenceLength;
     }
     
    -static size_t ZSTD_decompressSequencesLong(
    -							   ZSTD_DCtx* dctx,
    -							   void* dst, size_t maxDstSize,
    -						 const void* seqStart, size_t seqSize)
    +static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize)
     {
    -	const BYTE* ip = (const BYTE*)seqStart;
    -	const BYTE* const iend = ip + seqSize;
    -	BYTE* const ostart = (BYTE* const)dst;
    -	BYTE* const oend = ostart + maxDstSize;
    -	BYTE* op = ostart;
    -	const BYTE* litPtr = dctx->litPtr;
    -	const BYTE* const litEnd = litPtr + dctx->litSize;
    -	const BYTE* const base = (const BYTE*) (dctx->base);
    -	const BYTE* const vBase = (const BYTE*) (dctx->vBase);
    -	const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
    +	const BYTE *ip = (const BYTE *)seqStart;
    +	const BYTE *const iend = ip + seqSize;
    +	BYTE *const ostart = (BYTE * const)dst;
    +	BYTE *const oend = ostart + maxDstSize;
    +	BYTE *op = ostart;
    +	const BYTE *litPtr = dctx->litPtr;
    +	const BYTE *const litEnd = litPtr + dctx->litSize;
    +	const BYTE *const base = (const BYTE *)(dctx->base);
    +	const BYTE *const vBase = (const BYTE *)(dctx->vBase);
    +	const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd);
     	unsigned const windowSize = dctx->fParams.windowSize;
     	int nbSeq;
     
     	/* Build Decoding Tables */
    -	{	size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    -		if (ZSTD_isError(seqHSize)) return seqHSize;
    +	{
    +		size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    +		if (ZSTD_isError(seqHSize))
    +			return seqHSize;
     		ip += seqHSize;
     	}
     
     	/* Regen sequences */
     	if (nbSeq) {
     #define STORED_SEQS 4
    -#define STOSEQ_MASK (STORED_SEQS-1)
    +#define STOSEQ_MASK (STORED_SEQS - 1)
     #define ADVANCED_SEQS 4
     		seq_t sequences[STORED_SEQS];
     		int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
     		seqState_t seqState;
     		int seqNb;
     		dctx->fseEntropy = 1;
    -		{ U32 i; for (i=0; ientropy.rep[i]; }
    +		{
    +			U32 i;
    +			for (i = 0; i < ZSTD_REP_NUM; i++)
    +				seqState.prevOffset[i] = dctx->entropy.rep[i];
    +		}
     		seqState.base = base;
    -		seqState.pos = (size_t)(op-base);
    +		seqState.pos = (size_t)(op - base);
     		seqState.gotoDict = (uPtrDiff)dictEnd - (uPtrDiff)base; /* cast to avoid undefined behaviour */
    -		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
    +		CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected);
     		FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
     		FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
     		FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
     
     		/* prepare in advance */
    -		for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNbentropy.rep[i] = (U32)(seqState.prevOffset[i]); }
    +		{
    +			U32 i;
    +			for (i = 0; i < ZSTD_REP_NUM; i++)
    +				dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]);
    +		}
     	}
     
     	/* last literal segment */
    -	{	size_t const lastLLSize = litEnd - litPtr;
    -		if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
    +	{
    +		size_t const lastLLSize = litEnd - litPtr;
    +		if (lastLLSize > (size_t)(oend - op))
    +			return ERROR(dstSize_tooSmall);
     		memcpy(op, litPtr, lastLLSize);
     		op += lastLLSize;
     	}
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    +static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
    +{ /* blockType == blockCompressed */
    +	const BYTE *ip = (const BYTE *)src;
     
    -static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
    -							void* dst, size_t dstCapacity,
    -					  const void* src, size_t srcSize)
    -{   /* blockType == blockCompressed */
    -	const BYTE* ip = (const BYTE*)src;
    -
    -	if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
    +	if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX)
    +		return ERROR(srcSize_wrong);
     
     	/* Decode literals section */
    -	{	size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    -		if (ZSTD_isError(litCSize)) return litCSize;
    +	{
    +		size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    +		if (ZSTD_isError(litCSize))
    +			return litCSize;
     		ip += litCSize;
     		srcSize -= litCSize;
     	}
    -	if (sizeof(size_t) > 4)  /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
    -							 /* likely because of register pressure */
    -							 /* if that's the correct cause, then 32-bits ARM should be affected differently */
    -							 /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
    -		if (dctx->fParams.windowSize > (1<<23))
    +	if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
    +				/* likely because of register pressure */
    +				/* if that's the correct cause, then 32-bits ARM should be affected differently */
    +				/* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
    +		if (dctx->fParams.windowSize > (1 << 23))
     			return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
     	return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
     }
     
    -
    -static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
    +static void ZSTD_checkContinuity(ZSTD_DCtx *dctx, const void *dst)
     {
    -	if (dst != dctx->previousDstEnd) {   /* not contiguous */
    +	if (dst != dctx->previousDstEnd) { /* not contiguous */
     		dctx->dictEnd = dctx->previousDstEnd;
    -		dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
    +		dctx->vBase = (const char *)dst - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base));
     		dctx->base = dst;
     		dctx->previousDstEnd = dst;
     	}
     }
     
    -size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
    -							void* dst, size_t dstCapacity,
    -					  const void* src, size_t srcSize)
    +size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t dSize;
     	ZSTD_checkContinuity(dctx, dst);
     	dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
    -	dctx->previousDstEnd = (char*)dst + dSize;
    +	dctx->previousDstEnd = (char *)dst + dSize;
     	return dSize;
     }
     
    -
     /** ZSTD_insertBlock() :
     	insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
    -size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
    +size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, size_t blockSize)
     {
     	ZSTD_checkContinuity(dctx, blockStart);
    -	dctx->previousDstEnd = (const char*)blockStart + blockSize;
    +	dctx->previousDstEnd = (const char *)blockStart + blockSize;
     	return blockSize;
     }
     
    -
    -size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
    +size_t ZSTD_generateNxBytes(void *dst, size_t dstCapacity, BYTE byte, size_t length)
     {
    -	if (length > dstCapacity) return ERROR(dstSize_tooSmall);
    +	if (length > dstCapacity)
    +		return ERROR(dstSize_tooSmall);
     	memset(dst, byte, length);
     	return length;
     }
    @@ -1400,22 +1495,25 @@ size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t len
      *  @return : the compressed size of the frame starting at `src` */
     size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
     {
    -	if (srcSize >= ZSTD_skippableHeaderSize &&
    -			(ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    -		return ZSTD_skippableHeaderSize + ZSTD_readLE32((const BYTE*)src + 4);
    +	if (srcSize >= ZSTD_skippableHeaderSize && (ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    +		return ZSTD_skippableHeaderSize + ZSTD_readLE32((const BYTE *)src + 4);
     	} else {
    -		const BYTE* ip = (const BYTE*)src;
    -		const BYTE* const ipstart = ip;
    +		const BYTE *ip = (const BYTE *)src;
    +		const BYTE *const ipstart = ip;
     		size_t remainingSize = srcSize;
     		ZSTD_frameParams fParams;
     
     		size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize);
    -		if (ZSTD_isError(headerSize)) return headerSize;
    +		if (ZSTD_isError(headerSize))
    +			return headerSize;
     
     		/* Frame Header */
    -		{	size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    -			if (ZSTD_isError(ret)) return ret;
    -			if (ret > 0) return ERROR(srcSize_wrong);
    +		{
    +			size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
    +			if (ZSTD_isError(ret))
    +				return ret;
    +			if (ret > 0)
    +				return ERROR(srcSize_wrong);
     		}
     
     		ip += headerSize;
    @@ -1425,18 +1523,22 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
     		while (1) {
     			blockProperties_t blockProperties;
     			size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
    -			if (ZSTD_isError(cBlockSize)) return cBlockSize;
    +			if (ZSTD_isError(cBlockSize))
    +				return cBlockSize;
     
    -			if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) return ERROR(srcSize_wrong);
    +			if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
    +				return ERROR(srcSize_wrong);
     
     			ip += ZSTD_blockHeaderSize + cBlockSize;
     			remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
     
    -			if (blockProperties.lastBlock) break;
    +			if (blockProperties.lastBlock)
    +				break;
     		}
     
    -		if (fParams.checksumFlag) {   /* Frame content checksum */
    -			if (remainingSize < 4) return ERROR(srcSize_wrong);
    +		if (fParams.checksumFlag) { /* Frame content checksum */
    +			if (remainingSize < 4)
    +				return ERROR(srcSize_wrong);
     			ip += 4;
     			remainingSize -= 4;
     		}
    @@ -1447,25 +1549,28 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
     
     /*! ZSTD_decompressFrame() :
     *   @dctx must be properly initialized */
    -static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
    -								 void* dst, size_t dstCapacity,
    -								 const void** srcPtr, size_t *srcSizePtr)
    +static size_t ZSTD_decompressFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void **srcPtr, size_t *srcSizePtr)
     {
    -	const BYTE* ip = (const BYTE*)(*srcPtr);
    -	BYTE* const ostart = (BYTE* const)dst;
    -	BYTE* const oend = ostart + dstCapacity;
    -	BYTE* op = ostart;
    +	const BYTE *ip = (const BYTE *)(*srcPtr);
    +	BYTE *const ostart = (BYTE * const)dst;
    +	BYTE *const oend = ostart + dstCapacity;
    +	BYTE *op = ostart;
     	size_t remainingSize = *srcSizePtr;
     
     	/* check */
    -	if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    +	if (remainingSize < ZSTD_frameHeaderSize_min + ZSTD_blockHeaderSize)
    +		return ERROR(srcSize_wrong);
     
     	/* Frame Header */
    -	{	size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
    -		if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
    -		if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
    +	{
    +		size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
    +		if (ZSTD_isError(frameHeaderSize))
    +			return frameHeaderSize;
    +		if (remainingSize < frameHeaderSize + ZSTD_blockHeaderSize)
    +			return ERROR(srcSize_wrong);
     		CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
    -		ip += frameHeaderSize; remainingSize -= frameHeaderSize;
    +		ip += frameHeaderSize;
    +		remainingSize -= frameHeaderSize;
     	}
     
     	/* Loop on each block */
    @@ -1473,42 +1578,41 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     		size_t decodedSize;
     		blockProperties_t blockProperties;
     		size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
    -		if (ZSTD_isError(cBlockSize)) return cBlockSize;
    +		if (ZSTD_isError(cBlockSize))
    +			return cBlockSize;
     
     		ip += ZSTD_blockHeaderSize;
     		remainingSize -= ZSTD_blockHeaderSize;
    -		if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
    +		if (cBlockSize > remainingSize)
    +			return ERROR(srcSize_wrong);
     
    -		switch(blockProperties.blockType)
    -		{
    -		case bt_compressed:
    -			decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
    -			break;
    -		case bt_raw :
    -			decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
    -			break;
    -		case bt_rle :
    -			decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
    -			break;
    -		case bt_reserved :
    -		default:
    -			return ERROR(corruption_detected);
    +		switch (blockProperties.blockType) {
    +		case bt_compressed: decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend - op, ip, cBlockSize); break;
    +		case bt_raw: decodedSize = ZSTD_copyRawBlock(op, oend - op, ip, cBlockSize); break;
    +		case bt_rle: decodedSize = ZSTD_generateNxBytes(op, oend - op, *ip, blockProperties.origSize); break;
    +		case bt_reserved:
    +		default: return ERROR(corruption_detected);
     		}
     
    -		if (ZSTD_isError(decodedSize)) return decodedSize;
    -		if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, op, decodedSize);
    +		if (ZSTD_isError(decodedSize))
    +			return decodedSize;
    +		if (dctx->fParams.checksumFlag)
    +			xxh64_update(&dctx->xxhState, op, decodedSize);
     		op += decodedSize;
     		ip += cBlockSize;
     		remainingSize -= cBlockSize;
    -		if (blockProperties.lastBlock) break;
    +		if (blockProperties.lastBlock)
    +			break;
     	}
     
    -	if (dctx->fParams.checksumFlag) {   /* Frame content checksum verification */
    +	if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
     		U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState);
     		U32 checkRead;
    -		if (remainingSize<4) return ERROR(checksum_wrong);
    +		if (remainingSize < 4)
    +			return ERROR(checksum_wrong);
     		checkRead = ZSTD_readLE32(ip);
    -		if (checkRead != checkCalc) return ERROR(checksum_wrong);
    +		if (checkRead != checkCalc)
    +			return ERROR(checksum_wrong);
     		ip += 4;
     		remainingSize -= 4;
     	}
    @@ -1516,19 +1620,16 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
     	/* Allow caller to get size read */
     	*srcPtr = ip;
     	*srcSizePtr = remainingSize;
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict);
    -static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict);
    +static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict);
    +static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict);
     
    -static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
    -										void* dst, size_t dstCapacity,
    -								  const void* src, size_t srcSize,
    -								  const void *dict, size_t dictSize,
    -								  const ZSTD_DDict* ddict)
    +static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize,
    +					const ZSTD_DDict *ddict)
     {
    -	void* const dststart = dst;
    +	void *const dststart = dst;
     
     	if (ddict) {
     		if (dict) {
    @@ -1549,8 +1650,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
     				size_t skippableSize;
     				if (srcSize < ZSTD_skippableHeaderSize)
     					return ERROR(srcSize_wrong);
    -				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) +
    -								ZSTD_skippableHeaderSize;
    +				skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize;
     				if (srcSize < skippableSize) {
     					return ERROR(srcSize_wrong);
     				}
    @@ -1573,90 +1673,87 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
     		}
     		ZSTD_checkContinuity(dctx, dst);
     
    -		{	const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
    -													&src, &srcSize);
    -			if (ZSTD_isError(res)) return res;
    +		{
    +			const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, &src, &srcSize);
    +			if (ZSTD_isError(res))
    +				return res;
     			/* don't need to bounds check this, ZSTD_decompressFrame will have
     			 * already */
    -			dst = (BYTE*)dst + res;
    +			dst = (BYTE *)dst + res;
     			dstCapacity -= res;
     		}
     	}
     
    -	if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */
    +	if (srcSize)
    +		return ERROR(srcSize_wrong); /* input not entirely consumed */
     
    -	return (BYTE*)dst - (BYTE*)dststart;
    +	return (BYTE *)dst - (BYTE *)dststart;
     }
     
    -size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void *dict, size_t dictSize)
    +size_t ZSTD_decompress_usingDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize)
     {
     	return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
     }
     
    -
    -size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +size_t ZSTD_decompressDCtx(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
     }
     
    -
     /*-**************************************
     *   Advanced Streaming Decompression API
     *   Bufferless and synchronous
     ****************************************/
    -size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
    +size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx) { return dctx->expected; }
     
    -ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
    -	switch(dctx->stage)
    -	{
    -	default:   /* should not happen */
    +ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx)
    +{
    +	switch (dctx->stage) {
    +	default: /* should not happen */
     	case ZSTDds_getFrameHeaderSize:
    -	case ZSTDds_decodeFrameHeader:
    -		return ZSTDnit_frameHeader;
    -	case ZSTDds_decodeBlockHeader:
    -		return ZSTDnit_blockHeader;
    -	case ZSTDds_decompressBlock:
    -		return ZSTDnit_block;
    -	case ZSTDds_decompressLastBlock:
    -		return ZSTDnit_lastBlock;
    -	case ZSTDds_checkChecksum:
    -		return ZSTDnit_checksum;
    +	case ZSTDds_decodeFrameHeader: return ZSTDnit_frameHeader;
    +	case ZSTDds_decodeBlockHeader: return ZSTDnit_blockHeader;
    +	case ZSTDds_decompressBlock: return ZSTDnit_block;
    +	case ZSTDds_decompressLastBlock: return ZSTDnit_lastBlock;
    +	case ZSTDds_checkChecksum: return ZSTDnit_checksum;
     	case ZSTDds_decodeSkippableHeader:
    -	case ZSTDds_skipFrame:
    -		return ZSTDnit_skippableFrame;
    +	case ZSTDds_skipFrame: return ZSTDnit_skippableFrame;
     	}
     }
     
    -int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }   /* for zbuff */
    +int ZSTD_isSkipFrame(ZSTD_DCtx *dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
     
     /** ZSTD_decompressContinue() :
     *   @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
     *             or an error code, which can be tested using ZSTD_isError() */
    -size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	/* Sanity check */
    -	if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
    -	if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
    +	if (srcSize != dctx->expected)
    +		return ERROR(srcSize_wrong);
    +	if (dstCapacity)
    +		ZSTD_checkContinuity(dctx, dst);
     
    -	switch (dctx->stage)
    -	{
    -	case ZSTDds_getFrameHeaderSize :
    -		if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);      /* impossible */
    -		if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */
    +	switch (dctx->stage) {
    +	case ZSTDds_getFrameHeaderSize:
    +		if (srcSize != ZSTD_frameHeaderSize_prefix)
    +			return ERROR(srcSize_wrong);					/* impossible */
    +		if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
     			memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
    -			dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix;  /* magic number + skippable frame length */
    +			dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
     			dctx->stage = ZSTDds_decodeSkippableHeader;
     			return 0;
     		}
     		dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
    -		if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
    +		if (ZSTD_isError(dctx->headerSize))
    +			return dctx->headerSize;
     		memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
     		if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
     			dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
     			dctx->stage = ZSTDds_decodeFrameHeader;
     			return 0;
     		}
    -		dctx->expected = 0;   /* not necessary to copy more */
    +		dctx->expected = 0; /* not necessary to copy more */
     
     	case ZSTDds_decodeFrameHeader:
     		memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    @@ -1665,171 +1762,187 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
     		dctx->stage = ZSTDds_decodeBlockHeader;
     		return 0;
     
    -	case ZSTDds_decodeBlockHeader:
    -		{	blockProperties_t bp;
    -			size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
    -			if (ZSTD_isError(cBlockSize)) return cBlockSize;
    -			dctx->expected = cBlockSize;
    -			dctx->bType = bp.blockType;
    -			dctx->rleSize = bp.origSize;
    -			if (cBlockSize) {
    -				dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
    -				return 0;
    -			}
    -			/* empty block */
    -			if (bp.lastBlock) {
    -				if (dctx->fParams.checksumFlag) {
    -					dctx->expected = 4;
    -					dctx->stage = ZSTDds_checkChecksum;
    -				} else {
    -					dctx->expected = 0; /* end of frame */
    -					dctx->stage = ZSTDds_getFrameHeaderSize;
    -				}
    -			} else {
    -				dctx->expected = 3;  /* go directly to next header */
    -				dctx->stage = ZSTDds_decodeBlockHeader;
    -			}
    +	case ZSTDds_decodeBlockHeader: {
    +		blockProperties_t bp;
    +		size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
    +		if (ZSTD_isError(cBlockSize))
    +			return cBlockSize;
    +		dctx->expected = cBlockSize;
    +		dctx->bType = bp.blockType;
    +		dctx->rleSize = bp.origSize;
    +		if (cBlockSize) {
    +			dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
     			return 0;
     		}
    +		/* empty block */
    +		if (bp.lastBlock) {
    +			if (dctx->fParams.checksumFlag) {
    +				dctx->expected = 4;
    +				dctx->stage = ZSTDds_checkChecksum;
    +			} else {
    +				dctx->expected = 0; /* end of frame */
    +				dctx->stage = ZSTDds_getFrameHeaderSize;
    +			}
    +		} else {
    +			dctx->expected = 3; /* go directly to next header */
    +			dctx->stage = ZSTDds_decodeBlockHeader;
    +		}
    +		return 0;
    +	}
     	case ZSTDds_decompressLastBlock:
    -	case ZSTDds_decompressBlock:
    -		{	size_t rSize;
    -			switch(dctx->bType)
    -			{
    -			case bt_compressed:
    -				rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
    -				break;
    -			case bt_raw :
    -				rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
    -				break;
    -			case bt_rle :
    -				rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
    -				break;
    -			case bt_reserved :   /* should never happen */
    -			default:
    -				return ERROR(corruption_detected);
    -			}
    -			if (ZSTD_isError(rSize)) return rSize;
    -			if (dctx->fParams.checksumFlag) xxh64_update(&dctx->xxhState, dst, rSize);
    -
    -			if (dctx->stage == ZSTDds_decompressLastBlock) {   /* end of frame */
    -				if (dctx->fParams.checksumFlag) {  /* another round for frame checksum */
    -					dctx->expected = 4;
    -					dctx->stage = ZSTDds_checkChecksum;
    -				} else {
    -					dctx->expected = 0;   /* ends here */
    -					dctx->stage = ZSTDds_getFrameHeaderSize;
    -				}
    -			} else {
    -				dctx->stage = ZSTDds_decodeBlockHeader;
    -				dctx->expected = ZSTD_blockHeaderSize;
    -				dctx->previousDstEnd = (char*)dst + rSize;
    -			}
    +	case ZSTDds_decompressBlock: {
    +		size_t rSize;
    +		switch (dctx->bType) {
    +		case bt_compressed: rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize); break;
    +		case bt_raw: rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); break;
    +		case bt_rle: rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize); break;
    +		case bt_reserved: /* should never happen */
    +		default: return ERROR(corruption_detected);
    +		}
    +		if (ZSTD_isError(rSize))
     			return rSize;
    +		if (dctx->fParams.checksumFlag)
    +			xxh64_update(&dctx->xxhState, dst, rSize);
    +
    +		if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
    +			if (dctx->fParams.checksumFlag) {	/* another round for frame checksum */
    +				dctx->expected = 4;
    +				dctx->stage = ZSTDds_checkChecksum;
    +			} else {
    +				dctx->expected = 0; /* ends here */
    +				dctx->stage = ZSTDds_getFrameHeaderSize;
    +			}
    +		} else {
    +			dctx->stage = ZSTDds_decodeBlockHeader;
    +			dctx->expected = ZSTD_blockHeaderSize;
    +			dctx->previousDstEnd = (char *)dst + rSize;
     		}
    -	case ZSTDds_checkChecksum:
    -		{	U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    -			U32 const check32 = ZSTD_readLE32(src);   /* srcSize == 4, guaranteed by dctx->expected */
    -			if (check32 != h32) return ERROR(checksum_wrong);
    -			dctx->expected = 0;
    -			dctx->stage = ZSTDds_getFrameHeaderSize;
    -			return 0;
    -		}
    -	case ZSTDds_decodeSkippableHeader:
    -		{	memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    -			dctx->expected = ZSTD_readLE32(dctx->headerBuffer + 4);
    -			dctx->stage = ZSTDds_skipFrame;
    -			return 0;
    -		}
    -	case ZSTDds_skipFrame:
    -		{	dctx->expected = 0;
    -			dctx->stage = ZSTDds_getFrameHeaderSize;
    -			return 0;
    -		}
    +		return rSize;
    +	}
    +	case ZSTDds_checkChecksum: {
    +		U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
    +		U32 const check32 = ZSTD_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
    +		if (check32 != h32)
    +			return ERROR(checksum_wrong);
    +		dctx->expected = 0;
    +		dctx->stage = ZSTDds_getFrameHeaderSize;
    +		return 0;
    +	}
    +	case ZSTDds_decodeSkippableHeader: {
    +		memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
    +		dctx->expected = ZSTD_readLE32(dctx->headerBuffer + 4);
    +		dctx->stage = ZSTDds_skipFrame;
    +		return 0;
    +	}
    +	case ZSTDds_skipFrame: {
    +		dctx->expected = 0;
    +		dctx->stage = ZSTDds_getFrameHeaderSize;
    +		return 0;
    +	}
     	default:
    -		return ERROR(GENERIC);   /* impossible */
    +		return ERROR(GENERIC); /* impossible */
     	}
     }
     
    -
    -static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    +static size_t ZSTD_refDictContent(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
     {
     	dctx->dictEnd = dctx->previousDstEnd;
    -	dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
    +	dctx->vBase = (const char *)dict - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base));
     	dctx->base = dict;
    -	dctx->previousDstEnd = (const char*)dict + dictSize;
    +	dctx->previousDstEnd = (const char *)dict + dictSize;
     	return 0;
     }
     
     /* ZSTD_loadEntropy() :
      * dict : must point at beginning of a valid zstd dictionary
      * @return : size of entropy tables read */
    -static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const dict, size_t const dictSize)
    +static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const dict, size_t const dictSize)
     {
    -	const BYTE* dictPtr = (const BYTE*)dict;
    -	const BYTE* const dictEnd = dictPtr + dictSize;
    +	const BYTE *dictPtr = (const BYTE *)dict;
    +	const BYTE *const dictEnd = dictPtr + dictSize;
     
    -	if (dictSize <= 8) return ERROR(dictionary_corrupted);
    -	dictPtr += 8;   /* skip header = magic + dictID */
    +	if (dictSize <= 8)
    +		return ERROR(dictionary_corrupted);
    +	dictPtr += 8; /* skip header = magic + dictID */
     
    -
    -	{	size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
    -		if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
    +	{
    +		size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd - dictPtr);
    +		if (HUF_isError(hSize))
    +			return ERROR(dictionary_corrupted);
     		dictPtr += hSize;
     	}
     
    -	{	short offcodeNCount[MaxOff+1];
    +	{
    +		short offcodeNCount[MaxOff + 1];
     		U32 offcodeMaxValue = MaxOff, offcodeLog;
    -		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
    +		size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(offcodeHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (offcodeLog > OffFSELog)
    +			return ERROR(dictionary_corrupted);
     		CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
     		dictPtr += offcodeHeaderSize;
     	}
     
    -	{	short matchlengthNCount[MaxML+1];
    +	{
    +		short matchlengthNCount[MaxML + 1];
     		unsigned matchlengthMaxValue = MaxML, matchlengthLog;
    -		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
    +		size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(matchlengthHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (matchlengthLog > MLFSELog)
    +			return ERROR(dictionary_corrupted);
     		CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
     		dictPtr += matchlengthHeaderSize;
     	}
     
    -	{	short litlengthNCount[MaxLL+1];
    +	{
    +		short litlengthNCount[MaxLL + 1];
     		unsigned litlengthMaxValue = MaxLL, litlengthLog;
    -		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
    -		if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
    -		if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
    +		size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd - dictPtr);
    +		if (FSE_isError(litlengthHeaderSize))
    +			return ERROR(dictionary_corrupted);
    +		if (litlengthLog > LLFSELog)
    +			return ERROR(dictionary_corrupted);
     		CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
     		dictPtr += litlengthHeaderSize;
     	}
     
    -	if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
    -	{	int i;
    -		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
    -		for (i=0; i<3; i++) {
    -			U32 const rep = ZSTD_readLE32(dictPtr); dictPtr += 4;
    -			if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted);
    +	if (dictPtr + 12 > dictEnd)
    +		return ERROR(dictionary_corrupted);
    +	{
    +		int i;
    +		size_t const dictContentSize = (size_t)(dictEnd - (dictPtr + 12));
    +		for (i = 0; i < 3; i++) {
    +			U32 const rep = ZSTD_readLE32(dictPtr);
    +			dictPtr += 4;
    +			if (rep == 0 || rep >= dictContentSize)
    +				return ERROR(dictionary_corrupted);
     			entropy->rep[i] = rep;
    -	}   }
    +		}
    +	}
     
    -	return dictPtr - (const BYTE*)dict;
    +	return dictPtr - (const BYTE *)dict;
     }
     
    -static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    +static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
     {
    -	if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
    -	{	U32 const magic = ZSTD_readLE32(dict);
    +	if (dictSize < 8)
    +		return ZSTD_refDictContent(dctx, dict, dictSize);
    +	{
    +		U32 const magic = ZSTD_readLE32(dict);
     		if (magic != ZSTD_DICT_MAGIC) {
    -			return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
    -	}   }
    -	dctx->dictID = ZSTD_readLE32((const char*)dict + 4);
    +			return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
    +		}
    +	}
    +	dctx->dictID = ZSTD_readLE32((const char *)dict + 4);
     
     	/* load entropy tables */
    -	{	size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    -		if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
    -		dict = (const char*)dict + eSize;
    +	{
    +		size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
    +		if (ZSTD_isError(eSize))
    +			return ERROR(dictionary_corrupted);
    +		dict = (const char *)dict + eSize;
     		dictSize -= eSize;
     	}
     	dctx->litEntropy = dctx->fseEntropy = 1;
    @@ -1838,49 +1951,40 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
     	return ZSTD_refDictContent(dctx, dict, dictSize);
     }
     
    -size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
    +size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
     {
     	CHECK_F(ZSTD_decompressBegin(dctx));
    -	if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
    +	if (dict && dictSize)
    +		CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
     	return 0;
     }
     
    -
     /* ======   ZSTD_DDict   ====== */
     
     struct ZSTD_DDict_s {
    -	void* dictBuffer;
    -	const void* dictContent;
    +	void *dictBuffer;
    +	const void *dictContent;
     	size_t dictSize;
     	ZSTD_entropyTables_t entropy;
     	U32 dictID;
     	U32 entropyPresent;
     	ZSTD_customMem cMem;
    -};  /* typedef'd to ZSTD_DDict within "zstd.h" */
    +}; /* typedef'd to ZSTD_DDict within "zstd.h" */
     
    -size_t ZSTD_DDictWorkspaceBound(void)
    -{
    -	return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DDict));
    -}
    +size_t ZSTD_DDictWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DDict)); }
     
    -static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict)
    -{
    -	return ddict->dictContent;
    -}
    +static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict) { return ddict->dictContent; }
     
    -static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict)
    -{
    -	return ddict->dictSize;
    -}
    +static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict) { return ddict->dictSize; }
     
    -static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
    +static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict)
     {
    -	ZSTD_decompressBegin(dstDCtx);  /* init */
    -	if (ddict) {   /* support refDDict on NULL */
    +	ZSTD_decompressBegin(dstDCtx); /* init */
    +	if (ddict) {		       /* support refDDict on NULL */
     		dstDCtx->dictID = ddict->dictID;
     		dstDCtx->base = ddict->dictContent;
     		dstDCtx->vBase = ddict->dictContent;
    -		dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
    +		dstDCtx->dictEnd = (const BYTE *)ddict->dictContent + ddict->dictSize;
     		dstDCtx->previousDstEnd = dstDCtx->dictEnd;
     		if (ddict->entropyPresent) {
     			dstDCtx->litEntropy = 1;
    @@ -1899,49 +2003,59 @@ static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
     	}
     }
     
    -static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
    +static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict *ddict)
     {
     	ddict->dictID = 0;
     	ddict->entropyPresent = 0;
    -	if (ddict->dictSize < 8) return 0;
    -	{	U32 const magic = ZSTD_readLE32(ddict->dictContent);
    -		if (magic != ZSTD_DICT_MAGIC) return 0;   /* pure content mode */
    +	if (ddict->dictSize < 8)
    +		return 0;
    +	{
    +		U32 const magic = ZSTD_readLE32(ddict->dictContent);
    +		if (magic != ZSTD_DICT_MAGIC)
    +			return 0; /* pure content mode */
     	}
    -	ddict->dictID = ZSTD_readLE32((const char*)ddict->dictContent + 4);
    +	ddict->dictID = ZSTD_readLE32((const char *)ddict->dictContent + 4);
     
     	/* load entropy tables */
    -	CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
    +	CHECK_E(ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted);
     	ddict->entropyPresent = 1;
     	return 0;
     }
     
    -
    -static ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
    +static ZSTD_DDict *ZSTD_createDDict_advanced(const void *dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
     {
    -	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +	if (!customMem.customAlloc || !customMem.customFree)
    +		return NULL;
     
    -	{	ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
    -		if (!ddict) return NULL;
    +	{
    +		ZSTD_DDict *const ddict = (ZSTD_DDict *)ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
    +		if (!ddict)
    +			return NULL;
     		ddict->cMem = customMem;
     
     		if ((byReference) || (!dict) || (!dictSize)) {
     			ddict->dictBuffer = NULL;
     			ddict->dictContent = dict;
     		} else {
    -			void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    -			if (!internalBuffer) { ZSTD_freeDDict(ddict); return NULL; }
    +			void *const internalBuffer = ZSTD_malloc(dictSize, customMem);
    +			if (!internalBuffer) {
    +				ZSTD_freeDDict(ddict);
    +				return NULL;
    +			}
     			memcpy(internalBuffer, dict, dictSize);
     			ddict->dictBuffer = internalBuffer;
     			ddict->dictContent = internalBuffer;
     		}
     		ddict->dictSize = dictSize;
    -		ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    +		ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
     		/* parse dictionary content */
    -		{	size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
    +		{
    +			size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
     			if (ZSTD_isError(errorCode)) {
     				ZSTD_freeDDict(ddict);
     				return NULL;
    -		}   }
    +			}
    +		}
     
     		return ddict;
     	}
    @@ -1951,17 +2065,18 @@ static ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
     *   Create a digested dictionary, to start decompression without startup delay.
     *   `dict` content is copied inside DDict.
     *   Consequently, `dict` can be released after `ZSTD_DDict` creation */
    -ZSTD_DDict* ZSTD_initDDict(const void* dict, size_t dictSize, void* workspace, size_t workspaceSize)
    +ZSTD_DDict *ZSTD_initDDict(const void *dict, size_t dictSize, void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
     	return ZSTD_createDDict_advanced(dict, dictSize, 1, stackMem);
     }
     
    -
    -size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
    +size_t ZSTD_freeDDict(ZSTD_DDict *ddict)
     {
    -	if (ddict==NULL) return 0;   /* support free on NULL */
    -	{	ZSTD_customMem const cMem = ddict->cMem;
    +	if (ddict == NULL)
    +		return 0; /* support free on NULL */
    +	{
    +		ZSTD_customMem const cMem = ddict->cMem;
     		ZSTD_free(ddict->dictBuffer, cMem);
     		ZSTD_free(ddict, cMem);
     		return 0;
    @@ -1972,20 +2087,23 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
      *  Provides the dictID stored within dictionary.
      *  if @return == 0, the dictionary is not conformant with Zstandard specification.
      *  It can still be loaded, but as a content-only dictionary. */
    -unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
    +unsigned ZSTD_getDictID_fromDict(const void *dict, size_t dictSize)
     {
    -	if (dictSize < 8) return 0;
    -	if (ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
    -	return ZSTD_readLE32((const char*)dict + 4);
    +	if (dictSize < 8)
    +		return 0;
    +	if (ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC)
    +		return 0;
    +	return ZSTD_readLE32((const char *)dict + 4);
     }
     
     /*! ZSTD_getDictID_fromDDict() :
      *  Provides the dictID of the dictionary loaded into `ddict`.
      *  If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
      *  Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
    -unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
    +unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict)
     {
    -	if (ddict==NULL) return 0;
    +	if (ddict == NULL)
    +		return 0;
     	return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
     }
     
    @@ -1999,91 +2117,92 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
      *  - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
      *  - This is not a Zstandard frame.
      *  When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
    -unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
    +unsigned ZSTD_getDictID_fromFrame(const void *src, size_t srcSize)
     {
    -	ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
    +	ZSTD_frameParams zfp = {0, 0, 0, 0};
     	size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
    -	if (ZSTD_isError(hError)) return 0;
    +	if (ZSTD_isError(hError))
    +		return 0;
     	return zfp.dictID;
     }
     
    -
     /*! ZSTD_decompress_usingDDict() :
     *   Decompression using a pre-digested Dictionary
     *   Use dictionary without significant overhead. */
    -size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
    -								  void* dst, size_t dstCapacity,
    -							const void* src, size_t srcSize,
    -							const ZSTD_DDict* ddict)
    +size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_DDict *ddict)
     {
     	/* pass content and size in case legacy frames are encountered */
    -	return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
    -									 NULL, 0,
    -									 ddict);
    +	return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, NULL, 0, ddict);
     }
     
    -
     /*=====================================
     *   Streaming decompression
     *====================================*/
     
    -typedef enum { zdss_init, zdss_loadHeader,
    -			   zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
    +typedef enum { zdss_init, zdss_loadHeader, zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
     
     /* *** Resource management *** */
     struct ZSTD_DStream_s {
    -	ZSTD_DCtx* dctx;
    -	ZSTD_DDict* ddictLocal;
    -	const ZSTD_DDict* ddict;
    +	ZSTD_DCtx *dctx;
    +	ZSTD_DDict *ddictLocal;
    +	const ZSTD_DDict *ddict;
     	ZSTD_frameParams fParams;
     	ZSTD_dStreamStage stage;
    -	char*  inBuff;
    +	char *inBuff;
     	size_t inBuffSize;
     	size_t inPos;
     	size_t maxWindowSize;
    -	char*  outBuff;
    +	char *outBuff;
     	size_t outBuffSize;
     	size_t outStart;
     	size_t outEnd;
     	size_t blockSize;
    -	BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];   /* tmp buffer to store frame header */
    +	BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
     	size_t lhSize;
     	ZSTD_customMem customMem;
    -	void* legacyContext;
    +	void *legacyContext;
     	U32 previousLegacyVersion;
     	U32 legacyVersion;
     	U32 hostageByte;
    -};   /* typedef'd to ZSTD_DStream within "zstd.h" */
    +}; /* typedef'd to ZSTD_DStream within "zstd.h" */
     
    -size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize) {
    +size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize)
    +{
     	size_t const blockSize = MIN(maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
     	size_t const inBuffSize = blockSize;
     	size_t const outBuffSize = maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
     	return ZSTD_DCtxWorkspaceBound() + ZSTD_ALIGN(sizeof(ZSTD_DStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize);
     }
     
    -static ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
    +static ZSTD_DStream *ZSTD_createDStream_advanced(ZSTD_customMem customMem)
     {
    -	ZSTD_DStream* zds;
    +	ZSTD_DStream *zds;
     
    -	if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +	if (!customMem.customAlloc || !customMem.customFree)
    +		return NULL;
     
    -	zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
    -	if (zds==NULL) return NULL;
    +	zds = (ZSTD_DStream *)ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
    +	if (zds == NULL)
    +		return NULL;
     	memset(zds, 0, sizeof(ZSTD_DStream));
     	memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
     	zds->dctx = ZSTD_createDCtx_advanced(customMem);
    -	if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
    +	if (zds->dctx == NULL) {
    +		ZSTD_freeDStream(zds);
    +		return NULL;
    +	}
     	zds->stage = zdss_init;
     	zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
     	return zds;
     }
     
    -ZSTD_DStream* ZSTD_initDStream(size_t maxWindowSize, void* workspace, size_t workspaceSize)
    +ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, size_t workspaceSize)
     {
     	ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
    -	ZSTD_DStream* zds = ZSTD_createDStream_advanced(stackMem);
    -	if (!zds) { return NULL; }
    +	ZSTD_DStream *zds = ZSTD_createDStream_advanced(stackMem);
    +	if (!zds) {
    +		return NULL;
    +	}
     
     	zds->maxWindowSize = maxWindowSize;
     	zds->stage = zdss_loadHeader;
    @@ -2096,19 +2215,21 @@ ZSTD_DStream* ZSTD_initDStream(size_t maxWindowSize, void* workspace, size_t wor
     	return zds;
     }
     
    -ZSTD_DStream* ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict* ddict, void* workspace, size_t workspaceSize)
    +ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize)
     {
    -	ZSTD_DStream* zds = ZSTD_initDStream(maxWindowSize, workspace, workspaceSize);
    +	ZSTD_DStream *zds = ZSTD_initDStream(maxWindowSize, workspace, workspaceSize);
     	if (zds) {
     		zds->ddict = ddict;
     	}
     	return zds;
     }
     
    -size_t ZSTD_freeDStream(ZSTD_DStream* zds)
    +size_t ZSTD_freeDStream(ZSTD_DStream *zds)
     {
    -	if (zds==NULL) return 0;   /* support free on null */
    -	{	ZSTD_customMem const cMem = zds->customMem;
    +	if (zds == NULL)
    +		return 0; /* support free on null */
    +	{
    +		ZSTD_customMem const cMem = zds->customMem;
     		ZSTD_freeDCtx(zds->dctx);
     		zds->dctx = NULL;
     		ZSTD_freeDDict(zds->ddictLocal);
    @@ -2122,13 +2243,12 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
     	}
     }
     
    -
     /* *** Initialization *** */
     
    -size_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
    +size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
     size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
     
    -size_t ZSTD_resetDStream(ZSTD_DStream* zds)
    +size_t ZSTD_resetDStream(ZSTD_DStream *zds)
     {
     	zds->stage = zdss_loadHeader;
     	zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
    @@ -2139,178 +2259,210 @@ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
     
     /* *****   Decompression   ***** */
     
    -ZSTD_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
     {
     	size_t const length = MIN(dstCapacity, srcSize);
     	memcpy(dst, src, length);
     	return length;
     }
     
    -
    -size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
    +size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
     {
    -	const char* const istart = (const char*)(input->src) + input->pos;
    -	const char* const iend = (const char*)(input->src) + input->size;
    -	const char* ip = istart;
    -	char* const ostart = (char*)(output->dst) + output->pos;
    -	char* const oend = (char*)(output->dst) + output->size;
    -	char* op = ostart;
    +	const char *const istart = (const char *)(input->src) + input->pos;
    +	const char *const iend = (const char *)(input->src) + input->size;
    +	const char *ip = istart;
    +	char *const ostart = (char *)(output->dst) + output->pos;
    +	char *const oend = (char *)(output->dst) + output->size;
    +	char *op = ostart;
     	U32 someMoreWork = 1;
     
     	while (someMoreWork) {
    -		switch(zds->stage)
    -		{
    -		case zdss_init :
    -			ZSTD_resetDStream(zds);   /* transparent reset on starting decoding a new frame */
    -			/* fall-through */
    +		switch (zds->stage) {
    +		case zdss_init:
    +			ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
    +						/* fall-through */
     
    -		case zdss_loadHeader :
    -			{	size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    -				if (ZSTD_isError(hSize))
    +		case zdss_loadHeader: {
    +			size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
    +			if (ZSTD_isError(hSize))
     				return hSize;
    -				if (hSize != 0) {   /* need more input */
    -					size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */
    -					if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */
    -						memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
    -						zds->lhSize += iend-ip;
    -						input->pos = input->size;
    -						return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize;   /* remaining header bytes + next block header */
    -					}
    -					memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
    -					break;
    -			}   }
    +			if (hSize != 0) {				   /* need more input */
    +				size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
    +				if (toLoad > (size_t)(iend - ip)) {	/* not enough input to load full header */
    +					memcpy(zds->headerBuffer + zds->lhSize, ip, iend - ip);
    +					zds->lhSize += iend - ip;
    +					input->pos = input->size;
    +					return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) +
    +					       ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
    +				}
    +				memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad);
    +				zds->lhSize = hSize;
    +				ip += toLoad;
    +				break;
    +			}
    +		}
     
     			/* check for single-pass mode opportunity */
     			if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    -				&& (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
    -				size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
    -				if (cSize <= (size_t)(iend-istart)) {
    -					size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
    -					if (ZSTD_isError(decompressedSize)) return decompressedSize;
    +			    && (U64)(size_t)(oend - op) >= zds->fParams.frameContentSize) {
    +				size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend - istart);
    +				if (cSize <= (size_t)(iend - istart)) {
    +					size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend - op, istart, cSize, zds->ddict);
    +					if (ZSTD_isError(decompressedSize))
    +						return decompressedSize;
     					ip = istart + cSize;
     					op += decompressedSize;
     					zds->dctx->expected = 0;
     					zds->stage = zdss_init;
     					someMoreWork = 0;
     					break;
    -			}   }
    +				}
    +			}
     
     			/* Consume header */
     			ZSTD_refDDict(zds->dctx, zds->ddict);
    -			{	size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    +			{
    +				size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
     				CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    -				{	size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -					CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
    -			}   }
    +				{
    +					size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +					CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer + h1Size, h2Size));
    +				}
    +			}
     
     			zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
    -			if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
    +			if (zds->fParams.windowSize > zds->maxWindowSize)
    +				return ERROR(frameParameter_windowTooLarge);
     
     			/* Adapt buffer sizes to frame header instructions */
    -			{	size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +			{
    +				size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
     				size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
     				zds->blockSize = blockSize;
     				if (zds->inBuffSize < blockSize) {
     					ZSTD_free(zds->inBuff, zds->customMem);
     					zds->inBuffSize = blockSize;
    -					zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    -					if (zds->inBuff == NULL) return ERROR(memory_allocation);
    +					zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem);
    +					if (zds->inBuff == NULL)
    +						return ERROR(memory_allocation);
     				}
     				if (zds->outBuffSize < neededOutSize) {
     					ZSTD_free(zds->outBuff, zds->customMem);
     					zds->outBuffSize = neededOutSize;
    -					zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
    -					if (zds->outBuff == NULL) return ERROR(memory_allocation);
    -			}   }
    -			zds->stage = zdss_read;
    -			/* pass-through */
    -
    -		case zdss_read:
    -			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -				if (neededInSize==0) {  /* end of frame */
    -					zds->stage = zdss_init;
    -					someMoreWork = 0;
    -					break;
    +					zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem);
    +					if (zds->outBuff == NULL)
    +						return ERROR(memory_allocation);
     				}
    -				if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
    -					const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    -					size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    -						zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
    -						ip, neededInSize);
    -					if (ZSTD_isError(decodedSize)) return decodedSize;
    -					ip += neededInSize;
    -					if (!decodedSize && !isSkipFrame) break;   /* this was just a header */
    -					zds->outEnd = zds->outStart + decodedSize;
    -					zds->stage = zdss_flush;
    -					break;
    -				}
    -				if (ip==iend) { someMoreWork = 0; break; }   /* no more input */
    -				zds->stage = zdss_load;
    -				/* pass-through */
     			}
    +			zds->stage = zdss_read;
    +		/* pass-through */
     
    -		case zdss_load:
    -			{	size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -				size_t const toLoad = neededInSize - zds->inPos;   /* should always be <= remaining space within inBuff */
    -				size_t loadedSize;
    -				if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected);   /* should never happen */
    -				loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
    -				ip += loadedSize;
    -				zds->inPos += loadedSize;
    -				if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */
    -
    -				/* decode loaded input */
    -				{  const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    -				   size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    -						zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
    -						zds->inBuff, neededInSize);
    -					if (ZSTD_isError(decodedSize)) return decodedSize;
    -					zds->inPos = 0;   /* input is consumed */
    -					if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; }   /* this was just a header */
    -					zds->outEnd = zds->outStart +  decodedSize;
    -					zds->stage = zdss_flush;
    -					/* pass-through */
    -			}   }
    -
    -		case zdss_flush:
    -			{	size_t const toFlushSize = zds->outEnd - zds->outStart;
    -				size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
    -				op += flushedSize;
    -				zds->outStart += flushedSize;
    -				if (flushedSize == toFlushSize) {  /* flush completed */
    -					zds->stage = zdss_read;
    -					if (zds->outStart + zds->blockSize > zds->outBuffSize)
    -						zds->outStart = zds->outEnd = 0;
    -					break;
    -				}
    -				/* cannot complete flush */
    +		case zdss_read: {
    +			size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +			if (neededInSize == 0) { /* end of frame */
    +				zds->stage = zdss_init;
     				someMoreWork = 0;
     				break;
     			}
    -		default: return ERROR(GENERIC);   /* impossible */
    -	}   }
    +			if ((size_t)(iend - ip) >= neededInSize) { /* decode directly from src */
    +				const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    +				size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart,
    +										   (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), ip, neededInSize);
    +				if (ZSTD_isError(decodedSize))
    +					return decodedSize;
    +				ip += neededInSize;
    +				if (!decodedSize && !isSkipFrame)
    +					break; /* this was just a header */
    +				zds->outEnd = zds->outStart + decodedSize;
    +				zds->stage = zdss_flush;
    +				break;
    +			}
    +			if (ip == iend) {
    +				someMoreWork = 0;
    +				break;
    +			} /* no more input */
    +			zds->stage = zdss_load;
    +			/* pass-through */
    +		}
    +
    +		case zdss_load: {
    +			size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +			size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
    +			size_t loadedSize;
    +			if (toLoad > zds->inBuffSize - zds->inPos)
    +				return ERROR(corruption_detected); /* should never happen */
    +			loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend - ip);
    +			ip += loadedSize;
    +			zds->inPos += loadedSize;
    +			if (loadedSize < toLoad) {
    +				someMoreWork = 0;
    +				break;
    +			} /* not enough input, wait for more */
    +
    +			/* decode loaded input */
    +			{
    +				const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    +				size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
    +										   zds->inBuff, neededInSize);
    +				if (ZSTD_isError(decodedSize))
    +					return decodedSize;
    +				zds->inPos = 0; /* input is consumed */
    +				if (!decodedSize && !isSkipFrame) {
    +					zds->stage = zdss_read;
    +					break;
    +				} /* this was just a header */
    +				zds->outEnd = zds->outStart + decodedSize;
    +				zds->stage = zdss_flush;
    +				/* pass-through */
    +			}
    +		}
    +
    +		case zdss_flush: {
    +			size_t const toFlushSize = zds->outEnd - zds->outStart;
    +			size_t const flushedSize = ZSTD_limitCopy(op, oend - op, zds->outBuff + zds->outStart, toFlushSize);
    +			op += flushedSize;
    +			zds->outStart += flushedSize;
    +			if (flushedSize == toFlushSize) { /* flush completed */
    +				zds->stage = zdss_read;
    +				if (zds->outStart + zds->blockSize > zds->outBuffSize)
    +					zds->outStart = zds->outEnd = 0;
    +				break;
    +			}
    +			/* cannot complete flush */
    +			someMoreWork = 0;
    +			break;
    +		}
    +		default:
    +			return ERROR(GENERIC); /* impossible */
    +		}
    +	}
     
     	/* result */
    -	input->pos += (size_t)(ip-istart);
    -	output->pos += (size_t)(op-ostart);
    -	{	size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -		if (!nextSrcSizeHint) {   /* frame fully decoded */
    -			if (zds->outEnd == zds->outStart) {  /* output fully flushed */
    +	input->pos += (size_t)(ip - istart);
    +	output->pos += (size_t)(op - ostart);
    +	{
    +		size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +		if (!nextSrcSizeHint) {			    /* frame fully decoded */
    +			if (zds->outEnd == zds->outStart) { /* output fully flushed */
     				if (zds->hostageByte) {
    -					if (input->pos >= input->size) { zds->stage = zdss_read; return 1; }  /* can't release hostage (not present) */
    -					input->pos++;  /* release hostage */
    +					if (input->pos >= input->size) {
    +						zds->stage = zdss_read;
    +						return 1;
    +					}	     /* can't release hostage (not present) */
    +					input->pos++; /* release hostage */
     				}
     				return 0;
     			}
     			if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
    -				input->pos--;   /* note : pos > 0, otherwise, impossible to finish reading last block */
    -				zds->hostageByte=1;
    +				input->pos--;    /* note : pos > 0, otherwise, impossible to finish reading last block */
    +				zds->hostageByte = 1;
     			}
     			return 1;
     		}
    -		nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block);   /* preload header of next block */
    -		if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC);   /* should never happen */
    -		nextSrcSizeHint -= zds->inPos;   /* already loaded*/
    +		nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
    +		if (zds->inPos > nextSrcSizeHint)
    +			return ERROR(GENERIC); /* should never happen */
    +		nextSrcSizeHint -= zds->inPos; /* already loaded*/
     		return nextSrcSizeHint;
     	}
     }
    diff --git a/contrib/linux-kernel/lib/zstd/entropy_common.c b/contrib/linux-kernel/lib/zstd/entropy_common.c
    index 4e429f23a..b354fc2cd 100644
    --- a/contrib/linux-kernel/lib/zstd/entropy_common.c
    +++ b/contrib/linux-kernel/lib/zstd/entropy_common.c
    @@ -40,31 +40,27 @@
     /* *************************************
     *  Dependencies
     ***************************************/
    -#include "mem.h"
    -#include "error_private.h"       /* ERR_*, ERROR */
    +#include "error_private.h" /* ERR_*, ERROR */
     #include "fse.h"
     #include "huf.h"
    -
    +#include "mem.h"
     
     /*===   Version   ===*/
     unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
     
    -
     /*===   Error Management   ===*/
     unsigned FSE_isError(size_t code) { return ERR_isError(code); }
     
     unsigned HUF_isError(size_t code) { return ERR_isError(code); }
     
    -
     /*-**************************************************************
     *  FSE NCount encoding-decoding
     ****************************************************************/
    -size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
    -				 const void* headerBuffer, size_t hbSize)
    +size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSVPtr, unsigned *tableLogPtr, const void *headerBuffer, size_t hbSize)
     {
    -	const BYTE* const istart = (const BYTE*) headerBuffer;
    -	const BYTE* const iend = istart + hbSize;
    -	const BYTE* ip = istart;
    +	const BYTE *const istart = (const BYTE *)headerBuffer;
    +	const BYTE *const iend = istart + hbSize;
    +	const BYTE *ip = istart;
     	int nbBits;
     	int remaining;
     	int threshold;
    @@ -73,29 +69,32 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     	unsigned charnum = 0;
     	int previous0 = 0;
     
    -	if (hbSize < 4) return ERROR(srcSize_wrong);
    +	if (hbSize < 4)
    +		return ERROR(srcSize_wrong);
     	bitStream = ZSTD_readLE32(ip);
    -	nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG;   /* extract tableLog */
    -	if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
    +	nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
    +	if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX)
    +		return ERROR(tableLog_tooLarge);
     	bitStream >>= 4;
     	bitCount = 4;
     	*tableLogPtr = nbBits;
    -	remaining = (1<1) & (charnum<=*maxSVPtr)) {
    +	while ((remaining > 1) & (charnum <= *maxSVPtr)) {
     		if (previous0) {
     			unsigned n0 = charnum;
     			while ((bitStream & 0xFFFF) == 0xFFFF) {
     				n0 += 24;
    -				if (ip < iend-5) {
    +				if (ip < iend - 5) {
     					ip += 2;
     					bitStream = ZSTD_readLE32(ip) >> bitCount;
     				} else {
     					bitStream >>= 16;
    -					bitCount   += 16;
    -			}   }
    +					bitCount += 16;
    +				}
    +			}
     			while ((bitStream & 3) == 3) {
     				n0 += 3;
     				bitStream >>= 2;
    @@ -103,29 +102,34 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     			}
     			n0 += bitStream & 3;
     			bitCount += 2;
    -			if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
    -			while (charnum < n0) normalizedCounter[charnum++] = 0;
    -			if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
    -				ip += bitCount>>3;
    +			if (n0 > *maxSVPtr)
    +				return ERROR(maxSymbolValue_tooSmall);
    +			while (charnum < n0)
    +				normalizedCounter[charnum++] = 0;
    +			if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) {
    +				ip += bitCount >> 3;
     				bitCount &= 7;
     				bitStream = ZSTD_readLE32(ip) >> bitCount;
     			} else {
     				bitStream >>= 2;
    -		}   }
    -		{	int const max = (2*threshold-1) - remaining;
    +			}
    +		}
    +		{
    +			int const max = (2 * threshold - 1) - remaining;
     			int count;
     
    -			if ((bitStream & (threshold-1)) < (U32)max) {
    -				count = bitStream & (threshold-1);
    -				bitCount += nbBits-1;
    +			if ((bitStream & (threshold - 1)) < (U32)max) {
    +				count = bitStream & (threshold - 1);
    +				bitCount += nbBits - 1;
     			} else {
    -				count = bitStream & (2*threshold-1);
    -				if (count >= threshold) count -= max;
    +				count = bitStream & (2 * threshold - 1);
    +				if (count >= threshold)
    +					count -= max;
     				bitCount += nbBits;
     			}
     
    -			count--;   /* extra accuracy */
    -			remaining -= count < 0 ? -count : count;   /* -1 means +1 */
    +			count--;				 /* extra accuracy */
    +			remaining -= count < 0 ? -count : count; /* -1 means +1 */
     			normalizedCounter[charnum++] = (short)count;
     			previous0 = !count;
     			while (remaining < threshold) {
    @@ -133,24 +137,26 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     				threshold >>= 1;
     			}
     
    -			if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
    -				ip += bitCount>>3;
    +			if ((ip <= iend - 7) || (ip + (bitCount >> 3) <= iend - 4)) {
    +				ip += bitCount >> 3;
     				bitCount &= 7;
     			} else {
     				bitCount -= (int)(8 * (iend - 4 - ip));
     				ip = iend - 4;
     			}
     			bitStream = ZSTD_readLE32(ip) >> (bitCount & 31);
    -	}   }   /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
    -	if (remaining != 1) return ERROR(corruption_detected);
    -	if (bitCount > 32) return ERROR(corruption_detected);
    -	*maxSVPtr = charnum-1;
    +		}
    +	} /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
    +	if (remaining != 1)
    +		return ERROR(corruption_detected);
    +	if (bitCount > 32)
    +		return ERROR(corruption_detected);
    +	*maxSVPtr = charnum - 1;
     
    -	ip += (bitCount+7)>>3;
    -	return ip-istart;
    +	ip += (bitCount + 7) >> 3;
    +	return ip - istart;
     }
     
    -
     /*! HUF_readStats() :
     	Read compact Huffman tree, saved by HUF_writeCTable().
     	`huffWeight` is destination buffer.
    @@ -158,65 +164,81 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     	@return : size read from `src` , or an error Code .
     	Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
     */
    -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
    -					 U32* nbSymbolsPtr, U32* tableLogPtr,
    -					 const void* src, size_t srcSize)
    +size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize)
     {
     	U32 weightTotal;
    -	const BYTE* ip = (const BYTE*) src;
    +	const BYTE *ip = (const BYTE *)src;
     	size_t iSize;
     	size_t oSize;
     
    -	if (!srcSize) return ERROR(srcSize_wrong);
    +	if (!srcSize)
    +		return ERROR(srcSize_wrong);
     	iSize = ip[0];
    -	/* memset(huffWeight, 0, hwSize);   *//* is not necessary, even though some analyzer complain ... */
    +	/* memset(huffWeight, 0, hwSize);   */ /* is not necessary, even though some analyzer complain ... */
     
    -	if (iSize >= 128) {  /* special header */
    +	if (iSize >= 128) { /* special header */
     		oSize = iSize - 127;
    -		iSize = ((oSize+1)/2);
    -		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
    -		if (oSize >= hwSize) return ERROR(corruption_detected);
    +		iSize = ((oSize + 1) / 2);
    +		if (iSize + 1 > srcSize)
    +			return ERROR(srcSize_wrong);
    +		if (oSize >= hwSize)
    +			return ERROR(corruption_detected);
     		ip += 1;
    -		{	U32 n;
    -			for (n=0; n> 4;
    -				huffWeight[n+1] = ip[n/2] & 15;
    -	}   }   }
    -	else  {   /* header compressed with FSE (normal case) */
    -		FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)];  /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
    -		if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
    -		oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6);   /* max (hwSize-1) values decoded, as last one is implied */
    -		if (FSE_isError(oSize)) return oSize;
    +		{
    +			U32 n;
    +			for (n = 0; n < oSize; n += 2) {
    +				huffWeight[n] = ip[n / 2] >> 4;
    +				huffWeight[n + 1] = ip[n / 2] & 15;
    +			}
    +		}
    +	} else {						 /* header compressed with FSE (normal case) */
    +		FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
    +		if (iSize + 1 > srcSize)
    +			return ERROR(srcSize_wrong);
    +		oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */
    +		if (FSE_isError(oSize))
    +			return oSize;
     	}
     
     	/* collect weight stats */
     	memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
     	weightTotal = 0;
    -	{	U32 n; for (n=0; n= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
    +	{
    +		U32 n;
    +		for (n = 0; n < oSize; n++) {
    +			if (huffWeight[n] >= HUF_TABLELOG_MAX)
    +				return ERROR(corruption_detected);
     			rankStats[huffWeight[n]]++;
     			weightTotal += (1 << huffWeight[n]) >> 1;
    -	}   }
    -	if (weightTotal == 0) return ERROR(corruption_detected);
    +		}
    +	}
    +	if (weightTotal == 0)
    +		return ERROR(corruption_detected);
     
     	/* get last non-null symbol weight (implied, total must be 2^n) */
    -	{	U32 const tableLog = BIT_highbit32(weightTotal) + 1;
    -		if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
    +	{
    +		U32 const tableLog = BIT_highbit32(weightTotal) + 1;
    +		if (tableLog > HUF_TABLELOG_MAX)
    +			return ERROR(corruption_detected);
     		*tableLogPtr = tableLog;
     		/* determine last weight */
    -		{	U32 const total = 1 << tableLog;
    +		{
    +			U32 const total = 1 << tableLog;
     			U32 const rest = total - weightTotal;
     			U32 const verif = 1 << BIT_highbit32(rest);
     			U32 const lastWeight = BIT_highbit32(rest) + 1;
    -			if (verif != rest) return ERROR(corruption_detected);    /* last value must be a clean power of 2 */
    +			if (verif != rest)
    +				return ERROR(corruption_detected); /* last value must be a clean power of 2 */
     			huffWeight[oSize] = (BYTE)lastWeight;
     			rankStats[lastWeight]++;
    -	}   }
    +		}
    +	}
     
     	/* check tree construction validity */
    -	if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected);   /* by construction : at least 2 elts of rank 1, must be even */
    +	if ((rankStats[1] < 2) || (rankStats[1] & 1))
    +		return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
     
     	/* results */
    -	*nbSymbolsPtr = (U32)(oSize+1);
    -	return iSize+1;
    +	*nbSymbolsPtr = (U32)(oSize + 1);
    +	return iSize + 1;
     }
    diff --git a/contrib/linux-kernel/lib/zstd/error_private.h b/contrib/linux-kernel/lib/zstd/error_private.h
    index fd1f4ff1b..1a60b31f7 100644
    --- a/contrib/linux-kernel/lib/zstd/error_private.h
    +++ b/contrib/linux-kernel/lib/zstd/error_private.h
    @@ -22,23 +22,20 @@
     /* ****************************************
     *  Dependencies
     ******************************************/
    -#include         /* size_t */
    +#include  /* size_t */
     #include   /* enum list */
     
    -
     /* ****************************************
     *  Compiler-specific
     ******************************************/
     #define ERR_STATIC static __attribute__((unused))
     
    -
     /*-****************************************
     *  Customization (error_public.h)
     ******************************************/
     typedef ZSTD_ErrorCode ERR_enum;
     #define PREFIX(name) ZSTD_error_##name
     
    -
     /*-****************************************
     *  Error codes handling
     ******************************************/
    @@ -46,6 +43,11 @@ typedef ZSTD_ErrorCode ERR_enum;
     
     ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
     
    -ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
    +ERR_STATIC ERR_enum ERR_getErrorCode(size_t code)
    +{
    +	if (!ERR_isError(code))
    +		return (ERR_enum)0;
    +	return (ERR_enum)(0 - code);
    +}
     
     #endif /* ERROR_H_MODULE */
    diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h
    index b59b2c612..9749755c3 100644
    --- a/contrib/linux-kernel/lib/zstd/fse.h
    +++ b/contrib/linux-kernel/lib/zstd/fse.h
    @@ -40,12 +40,10 @@
     #ifndef FSE_H
     #define FSE_H
     
    -
     /*-*****************************************
     *  Dependencies
     ******************************************/
    -#include     /* size_t, ptrdiff_t */
    -
    +#include  /* size_t, ptrdiff_t */
     
     /*-*****************************************
     *  FSE_PUBLIC_API : control library symbols visibility
    @@ -53,26 +51,25 @@
     #define FSE_PUBLIC_API
     
     /*------   Version   ------*/
    -#define FSE_VERSION_MAJOR    0
    -#define FSE_VERSION_MINOR    9
    -#define FSE_VERSION_RELEASE  0
    +#define FSE_VERSION_MAJOR 0
    +#define FSE_VERSION_MINOR 9
    +#define FSE_VERSION_RELEASE 0
     
     #define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
     #define FSE_QUOTE(str) #str
     #define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
     #define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
     
    -#define FSE_VERSION_NUMBER  (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
    -FSE_PUBLIC_API unsigned FSE_versionNumber(void);   /**< library version number; to be used when checking dll version */
    +#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR * 100 * 100 + FSE_VERSION_MINOR * 100 + FSE_VERSION_RELEASE)
    +FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */
     
     /*-*****************************************
     *  Tool functions
     ******************************************/
    -FSE_PUBLIC_API size_t FSE_compressBound(size_t size);       /* maximum compressed size */
    +FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */
     
     /* Error Management */
    -FSE_PUBLIC_API unsigned    FSE_isError(size_t code);        /* tells if a return value is an error code */
    -
    +FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
     
     /*-*****************************************
     *  FSE detailed API
    @@ -107,7 +104,7 @@ FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize
     	'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
     	@return : tableLog,
     			  or an errorCode, which can be tested using FSE_isError() */
    -FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
    +FSE_PUBLIC_API size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t srcSize, unsigned maxSymbolValue);
     
     /*! FSE_NCountWriteBound():
     	Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
    @@ -118,19 +115,18 @@ FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tab
     	Compactly save 'normalizedCounter' into 'buffer'.
     	@return : size of the compressed table,
     			  or an errorCode, which can be tested using FSE_isError(). */
    -FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
    -
    +FSE_PUBLIC_API size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
     
     /*! Constructor and Destructor of FSE_CTable.
     	Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
    -typedef unsigned FSE_CTable;   /* don't allocate that. It's only meant to be more restrictive than void* */
    +typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
     
     /*! FSE_compress_usingCTable():
     	Compress `src` using `ct` into `dst` which must be already allocated.
     	@return : size of compressed data (<= `dstCapacity`),
     			  or 0 if compressed data could not fit into `dst`,
     			  or an errorCode, which can be tested using FSE_isError() */
    -FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
    +FSE_PUBLIC_API size_t FSE_compress_usingCTable(void *dst, size_t dstCapacity, const void *src, size_t srcSize, const FSE_CTable *ct);
     
     /*!
     Tutorial :
    @@ -175,7 +171,6 @@ If it returns '0', compressed data could not fit into 'dst'.
     If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
     */
     
    -
     /* *** DECOMPRESSION *** */
     
     /*! FSE_readNCount():
    @@ -183,23 +178,23 @@ If there is an error, the function will return an ErrorCode (which can be tested
     	@return : size read from 'rBuffer',
     			  or an errorCode, which can be tested using FSE_isError().
     			  maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
    -FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
    +FSE_PUBLIC_API size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSymbolValuePtr, unsigned *tableLogPtr, const void *rBuffer, size_t rBuffSize);
     
     /*! Constructor and Destructor of FSE_DTable.
     	Note that its size depends on 'tableLog' */
    -typedef unsigned FSE_DTable;   /* don't allocate that. It's just a way to be more restrictive than void* */
    +typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
     
     /*! FSE_buildDTable():
     	Builds 'dt', which must be already allocated, using FSE_createDTable().
     	return : 0, or an errorCode, which can be tested using FSE_isError() */
    -FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
    +FSE_PUBLIC_API size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
     
     /*! FSE_decompress_usingDTable():
     	Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
     	into `dst` which must be already allocated.
     	@return : size of regenerated data (necessarily <= `dstCapacity`),
     			  or an errorCode, which can be tested using FSE_isError() */
    -FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
    +FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt);
     
     /*!
     Tutorial :
    @@ -229,23 +224,20 @@ FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<
     If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)
     */
     
    -
     /* *** Dependency *** */
     #include "bitstream.h"
     
    -
     /* *****************************************
     *  Static allocation
     *******************************************/
     /* FSE buffer bounds */
     #define FSE_NCOUNTBOUND 512
    -#define FSE_BLOCKBOUND(size) (size + (size>>7))
    -#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size))   /* Macro version, useful for static allocation */
    +#define FSE_BLOCKBOUND(size) (size + (size >> 7))
    +#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
     
     /* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
    -#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue)   (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
    -#define FSE_DTABLE_SIZE_U32(maxTableLog)                   (1 + (1<= `1024` unsigned
      */
    -size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    -				 const void* source, size_t sourceSize, unsigned* workSpace);
    +size_t FSE_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace);
     
     /* FSE_countFast_wksp() :
      * Same as FSE_countFast(), but using an externally provided scratch buffer.
      * `workSpace` must be a table of minimum `1024` unsigned
      */
    -size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* workSpace);
    +size_t FSE_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize, unsigned *workSpace);
     
     /*! FSE_count_simple
      * Same as FSE_countFast(), but does not use any additional memory (not even on stack).
      * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`).
     */
    -size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
    -
    -
    +size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize);
     
     unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
     /**< same as FSE_optimalTableLog(), which used `minus==2` */
    @@ -278,31 +267,32 @@ unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsi
      * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
      * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
      */
    -#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue)   ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
    -size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
    +#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) \
    +	(FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024))
    +size_t FSE_compress_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace,
    +			 size_t wkspSize);
     
    -size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
    +size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits);
     /**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */
     
    -size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
    +size_t FSE_buildCTable_rle(FSE_CTable *ct, unsigned char symbolValue);
     /**< build a fake FSE_CTable, designed to compress always the same symbolValue */
     
     /* FSE_buildCTable_wksp() :
      * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
      * `wkspSize` must be >= `(1<= 1 (otherwise, result will be corrupted) */
     
    -
     /* *****************************************
     *  Implementation of inlined functions
     *******************************************/
    @@ -447,88 +433,86 @@ typedef struct {
     	U32 deltaNbBits;
     } FSE_symbolCompressionTransform; /* total 8 bytes */
     
    -ZSTD_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
    +ZSTD_STATIC void FSE_initCState(FSE_CState_t *statePtr, const FSE_CTable *ct)
     {
    -	const void* ptr = ct;
    -	const U16* u16ptr = (const U16*) ptr;
    +	const void *ptr = ct;
    +	const U16 *u16ptr = (const U16 *)ptr;
     	const U32 tableLog = ZSTD_read16(ptr);
    -	statePtr->value = (ptrdiff_t)1<stateTable = u16ptr+2;
    -	statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
    +	statePtr->value = (ptrdiff_t)1 << tableLog;
    +	statePtr->stateTable = u16ptr + 2;
    +	statePtr->symbolTT = ((const U32 *)ct + 1 + (tableLog ? (1 << (tableLog - 1)) : 1));
     	statePtr->stateLog = tableLog;
     }
     
    -
     /*! FSE_initCState2() :
     *   Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
     *   uses the smallest state value possible, saving the cost of this symbol */
    -ZSTD_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
    +ZSTD_STATIC void FSE_initCState2(FSE_CState_t *statePtr, const FSE_CTable *ct, U32 symbol)
     {
     	FSE_initCState(statePtr, ct);
    -	{	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    -		const U16* stateTable = (const U16*)(statePtr->stateTable);
    -		U32 nbBitsOut  = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
    +	{
    +		const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform *)(statePtr->symbolTT))[symbol];
    +		const U16 *stateTable = (const U16 *)(statePtr->stateTable);
    +		U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1 << 15)) >> 16);
     		statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
     		statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
     	}
     }
     
    -ZSTD_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
    +ZSTD_STATIC void FSE_encodeSymbol(BIT_CStream_t *bitC, FSE_CState_t *statePtr, U32 symbol)
     {
    -	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
    -	const U16* const stateTable = (const U16*)(statePtr->stateTable);
    -	U32 nbBitsOut  = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
    +	const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform *)(statePtr->symbolTT))[symbol];
    +	const U16 *const stateTable = (const U16 *)(statePtr->stateTable);
    +	U32 nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
     	BIT_addBits(bitC, statePtr->value, nbBitsOut);
    -	statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
    +	statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
     }
     
    -ZSTD_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
    +ZSTD_STATIC void FSE_flushCState(BIT_CStream_t *bitC, const FSE_CState_t *statePtr)
     {
     	BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
     	BIT_flushBits(bitC);
     }
     
    -
     /* ======    Decompression    ====== */
     
     typedef struct {
     	U16 tableLog;
     	U16 fastMode;
    -} FSE_DTableHeader;   /* sizeof U32 */
    +} FSE_DTableHeader; /* sizeof U32 */
     
    -typedef struct
    -{
    +typedef struct {
     	unsigned short newState;
    -	unsigned char  symbol;
    -	unsigned char  nbBits;
    -} FSE_decode_t;   /* size == U32 */
    +	unsigned char symbol;
    +	unsigned char nbBits;
    +} FSE_decode_t; /* size == U32 */
     
    -ZSTD_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
    +ZSTD_STATIC void FSE_initDState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD, const FSE_DTable *dt)
     {
    -	const void* ptr = dt;
    -	const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
    +	const void *ptr = dt;
    +	const FSE_DTableHeader *const DTableH = (const FSE_DTableHeader *)ptr;
     	DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
     	BIT_reloadDStream(bitD);
     	DStatePtr->table = dt + 1;
     }
     
    -ZSTD_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
    +ZSTD_STATIC BYTE FSE_peekSymbol(const FSE_DState_t *DStatePtr)
     {
    -	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    +	FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state];
     	return DInfo.symbol;
     }
     
    -ZSTD_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC void FSE_updateState(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
     {
    -	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    +	FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
     	size_t const lowBits = BIT_readBits(bitD, nbBits);
     	DStatePtr->state = DInfo.newState + lowBits;
     }
     
    -ZSTD_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC BYTE FSE_decodeSymbol(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
     {
    -	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    +	FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
     	BYTE const symbol = DInfo.symbol;
     	size_t const lowBits = BIT_readBits(bitD, nbBits);
    @@ -539,9 +523,9 @@ ZSTD_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
     
     /*! FSE_decodeSymbolFast() :
     	unsafe, only works if no symbol has a probability > 50% */
    -ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
    +ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t *DStatePtr, BIT_DStream_t *bitD)
     {
    -	FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
    +	FSE_decode_t const DInfo = ((const FSE_decode_t *)(DStatePtr->table))[DStatePtr->state];
     	U32 const nbBits = DInfo.nbBits;
     	BYTE const symbol = DInfo.symbol;
     	size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
    @@ -550,12 +534,7 @@ ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bi
     	return symbol;
     }
     
    -ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
    -{
    -	return DStatePtr->state == 0;
    -}
    -
    -
    +ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr) { return DStatePtr->state == 0; }
     
     #ifndef FSE_COMMONDEFS_ONLY
     
    @@ -568,17 +547,17 @@ ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
     *  Reduced memory usage can improve speed, due to cache effect
     *  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
     #ifndef FSE_MAX_MEMORY_USAGE
    -#  define FSE_MAX_MEMORY_USAGE 14
    +#define FSE_MAX_MEMORY_USAGE 14
     #endif
     #ifndef FSE_DEFAULT_MEMORY_USAGE
    -#  define FSE_DEFAULT_MEMORY_USAGE 13
    +#define FSE_DEFAULT_MEMORY_USAGE 13
     #endif
     
     /*!FSE_MAX_SYMBOL_VALUE :
     *  Maximum symbol value authorized.
     *  Required for proper stack allocation */
     #ifndef FSE_MAX_SYMBOL_VALUE
    -#  define FSE_MAX_SYMBOL_VALUE 255
    +#define FSE_MAX_SYMBOL_VALUE 255
     #endif
     
     /* **************************************************************
    @@ -588,25 +567,22 @@ ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
     #define FSE_FUNCTION_EXTENSION
     #define FSE_DECODE_TYPE FSE_decode_t
     
    -
    -#endif   /* !FSE_COMMONDEFS_ONLY */
    -
    +#endif /* !FSE_COMMONDEFS_ONLY */
     
     /* ***************************************************************
     *  Constants
     *****************************************************************/
    -#define FSE_MAX_TABLELOG  (FSE_MAX_MEMORY_USAGE-2)
    -#define FSE_MAX_TABLESIZE (1U< FSE_TABLELOG_ABSOLUTE_MAX
    -#  error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
    +#error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
     #endif
     
    -#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
    +#define FSE_TABLESTEP(tableSize) ((tableSize >> 1) + (tableSize >> 3) + 3)
     
    -
    -#endif  /* FSE_H */
    +#endif /* FSE_H */
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index 0a7c01b8f..6bb810ff8 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -42,21 +42,21 @@
     ****************************************************************/
     #define FORCE_INLINE static __always_inline
     
    -
     /* **************************************************************
     *  Includes
     ****************************************************************/
    -#include 
    -#include      /* memcpy, memset */
     #include "bitstream.h"
     #include "fse.h"
    -
    +#include 
    +#include  /* memcpy, memset */
     
     /* **************************************************************
     *  Error Management
     ****************************************************************/
    -#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    -
    +#define FSE_STATIC_ASSERT(c)                                   \
    +	{                                                      \
    +		enum { FSE_static_assert = 1 / (int)(!!(c)) }; \
    +	} /* use only *after* variable declarations */
     
     /* **************************************************************
     *  Templates
    @@ -69,17 +69,16 @@
     
     /* safety checks */
     #ifndef FSE_FUNCTION_EXTENSION
    -#  error "FSE_FUNCTION_EXTENSION must be defined"
    +#error "FSE_FUNCTION_EXTENSION must be defined"
     #endif
     #ifndef FSE_FUNCTION_TYPE
    -#  error "FSE_FUNCTION_TYPE must be defined"
    +#error "FSE_FUNCTION_TYPE must be defined"
     #endif
     
     /* Function names */
    -#define FSE_CAT(X,Y) X##Y
    -#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    -#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
    -
    +#define FSE_CAT(X, Y) X##Y
    +#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y)
    +#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y)
     
     /* Function templates */
     
    @@ -88,88 +87,99 @@
      * wkspSize should be sized to handle worst case situation, which is `1<>1 : 1) ;
    -	FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
    +	void *const ptr = ct;
    +	U16 *const tableU16 = ((U16 *)ptr) + 2;
    +	void *const FSCT = ((U32 *)ptr) + 1 /* header */ + (tableLog ? tableSize >> 1 : 1);
    +	FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT);
     	U32 const step = FSE_TABLESTEP(tableSize);
    -	U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
    +	U32 cumul[FSE_MAX_SYMBOL_VALUE + 2];
     
    -	FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
    -	U32 highThreshold = tableSize-1;
    +	FSE_FUNCTION_TYPE *const tableSymbol = (FSE_FUNCTION_TYPE *)workSpace;
    +	U32 highThreshold = tableSize - 1;
     
     	/* CTable header */
    -	if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
    -	tableU16[-2] = (U16) tableLog;
    -	tableU16[-1] = (U16) maxSymbolValue;
    +	if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize)
    +		return ERROR(tableLog_tooLarge);
    +	tableU16[-2] = (U16)tableLog;
    +	tableU16[-1] = (U16)maxSymbolValue;
     
     	/* For explanations on how to distribute symbol values over the table :
     	*  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
     
     	/* symbol start positions */
    -	{	U32 u;
    +	{
    +		U32 u;
     		cumul[0] = 0;
    -		for (u=1; u<=maxSymbolValue+1; u++) {
    -			if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */
    -				cumul[u] = cumul[u-1] + 1;
    -				tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
    +		for (u = 1; u <= maxSymbolValue + 1; u++) {
    +			if (normalizedCounter[u - 1] == -1) { /* Low proba symbol */
    +				cumul[u] = cumul[u - 1] + 1;
    +				tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u - 1);
     			} else {
    -				cumul[u] = cumul[u-1] + normalizedCounter[u-1];
    -		}   }
    -		cumul[maxSymbolValue+1] = tableSize+1;
    +				cumul[u] = cumul[u - 1] + normalizedCounter[u - 1];
    +			}
    +		}
    +		cumul[maxSymbolValue + 1] = tableSize + 1;
     	}
     
     	/* Spread symbols */
    -	{	U32 position = 0;
    +	{
    +		U32 position = 0;
     		U32 symbol;
    -		for (symbol=0; symbol<=maxSymbolValue; symbol++) {
    +		for (symbol = 0; symbol <= maxSymbolValue; symbol++) {
     			int nbOccurences;
    -			for (nbOccurences=0; nbOccurences highThreshold) position = (position + step) & tableMask;   /* Low proba area */
    -		}   }
    +				while (position > highThreshold)
    +					position = (position + step) & tableMask; /* Low proba area */
    +			}
    +		}
     
    -		if (position!=0) return ERROR(GENERIC);   /* Must have gone through all positions */
    +		if (position != 0)
    +			return ERROR(GENERIC); /* Must have gone through all positions */
     	}
     
     	/* Build table */
    -	{	U32 u; for (u=0; u> 3) + 3;
    -	return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
    +	size_t const maxHeaderSize = (((maxSymbolValue + 1) * tableLog) >> 3) + 3;
    +	return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
     }
     
    -static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
    -									   const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
    -									   unsigned writeIsSafe)
    +static size_t FSE_writeNCount_generic(void *header, size_t headerBufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
    +				      unsigned writeIsSafe)
     {
    -	BYTE* const ostart = (BYTE*) header;
    -	BYTE* out = ostart;
    -	BYTE* const oend = ostart + headerBufferSize;
    +	BYTE *const ostart = (BYTE *)header;
    +	BYTE *out = ostart;
    +	BYTE *const oend = ostart + headerBufferSize;
     	int nbBits;
     	const int tableSize = 1 << tableLog;
     	int remaining;
    @@ -198,81 +207,94 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
     	int previous0 = 0;
     
     	bitStream = 0;
    -	bitCount  = 0;
    +	bitCount = 0;
     	/* Table Size */
    -	bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
    -	bitCount  += 4;
    +	bitStream += (tableLog - FSE_MIN_TABLELOG) << bitCount;
    +	bitCount += 4;
     
     	/* Init */
    -	remaining = tableSize+1;   /* +1 for extra accuracy */
    +	remaining = tableSize + 1; /* +1 for extra accuracy */
     	threshold = tableSize;
    -	nbBits = tableLog+1;
    +	nbBits = tableLog + 1;
     
    -	while (remaining>1) {  /* stops at 1 */
    +	while (remaining > 1) { /* stops at 1 */
     		if (previous0) {
     			unsigned start = charnum;
    -			while (!normalizedCounter[charnum]) charnum++;
    -			while (charnum >= start+24) {
    -				start+=24;
    +			while (!normalizedCounter[charnum])
    +				charnum++;
    +			while (charnum >= start + 24) {
    +				start += 24;
     				bitStream += 0xFFFFU << bitCount;
    -				if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    -				out[0] = (BYTE) bitStream;
    -				out[1] = (BYTE)(bitStream>>8);
    -				out+=2;
    -				bitStream>>=16;
    +				if ((!writeIsSafe) && (out > oend - 2))
    +					return ERROR(dstSize_tooSmall); /* Buffer overflow */
    +				out[0] = (BYTE)bitStream;
    +				out[1] = (BYTE)(bitStream >> 8);
    +				out += 2;
    +				bitStream >>= 16;
     			}
    -			while (charnum >= start+3) {
    -				start+=3;
    +			while (charnum >= start + 3) {
    +				start += 3;
     				bitStream += 3 << bitCount;
     				bitCount += 2;
     			}
    -			bitStream += (charnum-start) << bitCount;
    +			bitStream += (charnum - start) << bitCount;
     			bitCount += 2;
    -			if (bitCount>16) {
    -				if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    +			if (bitCount > 16) {
    +				if ((!writeIsSafe) && (out > oend - 2))
    +					return ERROR(dstSize_tooSmall); /* Buffer overflow */
     				out[0] = (BYTE)bitStream;
    -				out[1] = (BYTE)(bitStream>>8);
    +				out[1] = (BYTE)(bitStream >> 8);
     				out += 2;
     				bitStream >>= 16;
     				bitCount -= 16;
    -		}   }
    -		{	int count = normalizedCounter[charnum++];
    -			int const max = (2*threshold-1)-remaining;
    -			remaining -= count < 0 ? -count : count;
    -			count++;   /* +1 for extra accuracy */
    -			if (count>=threshold) count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
    -			bitStream += count << bitCount;
    -			bitCount  += nbBits;
    -			bitCount  -= (count>=1;
    +			}
     		}
    -		if (bitCount>16) {
    -			if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    +		{
    +			int count = normalizedCounter[charnum++];
    +			int const max = (2 * threshold - 1) - remaining;
    +			remaining -= count < 0 ? -count : count;
    +			count++; /* +1 for extra accuracy */
    +			if (count >= threshold)
    +				count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
    +			bitStream += count << bitCount;
    +			bitCount += nbBits;
    +			bitCount -= (count < max);
    +			previous0 = (count == 1);
    +			if (remaining < 1)
    +				return ERROR(GENERIC);
    +			while (remaining < threshold)
    +				nbBits--, threshold >>= 1;
    +		}
    +		if (bitCount > 16) {
    +			if ((!writeIsSafe) && (out > oend - 2))
    +				return ERROR(dstSize_tooSmall); /* Buffer overflow */
     			out[0] = (BYTE)bitStream;
    -			out[1] = (BYTE)(bitStream>>8);
    +			out[1] = (BYTE)(bitStream >> 8);
     			out += 2;
     			bitStream >>= 16;
     			bitCount -= 16;
    -	}   }
    +		}
    +	}
     
     	/* flush remaining bitStream */
    -	if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
    +	if ((!writeIsSafe) && (out > oend - 2))
    +		return ERROR(dstSize_tooSmall); /* Buffer overflow */
     	out[0] = (BYTE)bitStream;
    -	out[1] = (BYTE)(bitStream>>8);
    -	out+= (bitCount+7) /8;
    +	out[1] = (BYTE)(bitStream >> 8);
    +	out += (bitCount + 7) / 8;
     
    -	if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
    +	if (charnum > maxSymbolValue + 1)
    +		return ERROR(GENERIC);
     
    -	return (out-ostart);
    +	return (out - ostart);
     }
     
    -
    -size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
    +size_t FSE_writeNCount(void *buffer, size_t bufferSize, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
     {
    -	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported */
    -	if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
    +	if (tableLog > FSE_MAX_TABLELOG)
    +		return ERROR(tableLog_tooLarge); /* Unsupported */
    +	if (tableLog < FSE_MIN_TABLELOG)
    +		return ERROR(GENERIC); /* Unsupported */
     
     	if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
     		return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
    @@ -280,8 +302,6 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalized
     	return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
     }
     
    -
    -
     /*-**************************************************************
     *  Counting histogram
     ****************************************************************/
    @@ -292,46 +312,52 @@ size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalized
     	For this reason, prefer using a table `count` with 256 elements.
     	@return : count of most numerous element
     */
    -size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
    -						const void* src, size_t srcSize)
    +size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void *src, size_t srcSize)
     {
    -	const BYTE* ip = (const BYTE*)src;
    -	const BYTE* const end = ip + srcSize;
    +	const BYTE *ip = (const BYTE *)src;
    +	const BYTE *const end = ip + srcSize;
     	unsigned maxSymbolValue = *maxSymbolValuePtr;
    -	unsigned max=0;
    +	unsigned max = 0;
     
    -	memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
    -	if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
    +	memset(count, 0, (maxSymbolValue + 1) * sizeof(*count));
    +	if (srcSize == 0) {
    +		*maxSymbolValuePtr = 0;
    +		return 0;
    +	}
     
    -	while (ip max) max = count[s]; }
    +	{
    +		U32 s;
    +		for (s = 0; s <= maxSymbolValue; s++)
    +			if (count[s] > max)
    +				max = count[s];
    +	}
     
     	return (size_t)max;
     }
     
    -
     /* FSE_count_parallel_wksp() :
      * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
      * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
    -static size_t FSE_count_parallel_wksp(
    -								unsigned* count, unsigned* maxSymbolValuePtr,
    -								const void* source, size_t sourceSize,
    -								unsigned checkMax, unsigned* const workSpace)
    +static size_t FSE_count_parallel_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned checkMax,
    +				      unsigned *const workSpace)
     {
    -	const BYTE* ip = (const BYTE*)source;
    -	const BYTE* const iend = ip+sourceSize;
    +	const BYTE *ip = (const BYTE *)source;
    +	const BYTE *const iend = ip + sourceSize;
     	unsigned maxSymbolValue = *maxSymbolValuePtr;
    -	unsigned max=0;
    -	U32* const Counting1 = workSpace;
    -	U32* const Counting2 = Counting1 + 256;
    -	U32* const Counting3 = Counting2 + 256;
    -	U32* const Counting4 = Counting3 + 256;
    +	unsigned max = 0;
    +	U32 *const Counting1 = workSpace;
    +	U32 *const Counting2 = Counting1 + 256;
    +	U32 *const Counting3 = Counting2 + 256;
    +	U32 *const Counting4 = Counting3 + 256;
     
    -	memset(Counting1, 0, 4*256*sizeof(unsigned));
    +	memset(Counting1, 0, 4 * 256 * sizeof(unsigned));
     
     	/* safety checks */
     	if (!sourceSize) {
    @@ -339,50 +365,70 @@ static size_t FSE_count_parallel_wksp(
     		*maxSymbolValuePtr = 0;
     		return 0;
     	}
    -	if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
    +	if (!maxSymbolValue)
    +		maxSymbolValue = 255; /* 0 == default */
     
     	/* by stripes of 16 bytes */
    -	{	U32 cached = ZSTD_read32(ip); ip += 4;
    -		while (ip < iend-15) {
    -			U32 c = cached; cached = ZSTD_read32(ip); ip += 4;
    -			Counting1[(BYTE) c     ]++;
    -			Counting2[(BYTE)(c>>8) ]++;
    -			Counting3[(BYTE)(c>>16)]++;
    -			Counting4[       c>>24 ]++;
    -			c = cached; cached = ZSTD_read32(ip); ip += 4;
    -			Counting1[(BYTE) c     ]++;
    -			Counting2[(BYTE)(c>>8) ]++;
    -			Counting3[(BYTE)(c>>16)]++;
    -			Counting4[       c>>24 ]++;
    -			c = cached; cached = ZSTD_read32(ip); ip += 4;
    -			Counting1[(BYTE) c     ]++;
    -			Counting2[(BYTE)(c>>8) ]++;
    -			Counting3[(BYTE)(c>>16)]++;
    -			Counting4[       c>>24 ]++;
    -			c = cached; cached = ZSTD_read32(ip); ip += 4;
    -			Counting1[(BYTE) c     ]++;
    -			Counting2[(BYTE)(c>>8) ]++;
    -			Counting3[(BYTE)(c>>16)]++;
    -			Counting4[       c>>24 ]++;
    +	{
    +		U32 cached = ZSTD_read32(ip);
    +		ip += 4;
    +		while (ip < iend - 15) {
    +			U32 c = cached;
    +			cached = ZSTD_read32(ip);
    +			ip += 4;
    +			Counting1[(BYTE)c]++;
    +			Counting2[(BYTE)(c >> 8)]++;
    +			Counting3[(BYTE)(c >> 16)]++;
    +			Counting4[c >> 24]++;
    +			c = cached;
    +			cached = ZSTD_read32(ip);
    +			ip += 4;
    +			Counting1[(BYTE)c]++;
    +			Counting2[(BYTE)(c >> 8)]++;
    +			Counting3[(BYTE)(c >> 16)]++;
    +			Counting4[c >> 24]++;
    +			c = cached;
    +			cached = ZSTD_read32(ip);
    +			ip += 4;
    +			Counting1[(BYTE)c]++;
    +			Counting2[(BYTE)(c >> 8)]++;
    +			Counting3[(BYTE)(c >> 16)]++;
    +			Counting4[c >> 24]++;
    +			c = cached;
    +			cached = ZSTD_read32(ip);
    +			ip += 4;
    +			Counting1[(BYTE)c]++;
    +			Counting2[(BYTE)(c >> 8)]++;
    +			Counting3[(BYTE)(c >> 16)]++;
    +			Counting4[c >> 24]++;
     		}
    -		ip-=4;
    +		ip -= 4;
     	}
     
     	/* finish last symbols */
    -	while (ipmaxSymbolValue; s--) {
    +	if (checkMax) { /* verify stats will fit into destination table */
    +		U32 s;
    +		for (s = 255; s > maxSymbolValue; s--) {
     			Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
    -			if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
    -	}   }
    +			if (Counting1[s])
    +				return ERROR(maxSymbolValue_tooSmall);
    +		}
    +	}
     
    -	{	U32 s; for (s=0; s<=maxSymbolValue; s++) {
    +	{
    +		U32 s;
    +		for (s = 0; s <= maxSymbolValue; s++) {
     			count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
    -			if (count[s] > max) max = count[s];
    -	}   }
    +			if (count[s] > max)
    +				max = count[s];
    +		}
    +	}
     
    -	while (!count[maxSymbolValue]) maxSymbolValue--;
    +	while (!count[maxSymbolValue])
    +		maxSymbolValue--;
     	*maxSymbolValuePtr = maxSymbolValue;
     	return (size_t)max;
     }
    @@ -390,18 +436,17 @@ static size_t FSE_count_parallel_wksp(
     /* FSE_countFast_wksp() :
      * Same as FSE_countFast(), but using an externally provided scratch buffer.
      * `workSpace` size must be table of >= `1024` unsigned */
    -size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    -					 const void* source, size_t sourceSize, unsigned* workSpace)
    +size_t FSE_countFast_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace)
     {
    -	if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
    +	if (sourceSize < 1500)
    +		return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
     	return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
     }
     
     /* FSE_count_wksp() :
      * Same as FSE_count(), but using an externally provided scratch buffer.
      * `workSpace` size must be table of >= `1024` unsigned */
    -size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
    -				 const void* source, size_t sourceSize, unsigned* workSpace)
    +size_t FSE_count_wksp(unsigned *count, unsigned *maxSymbolValuePtr, const void *source, size_t sourceSize, unsigned *workSpace)
     {
     	if (*maxSymbolValuePtr < 255)
     		return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
    @@ -409,7 +454,6 @@ size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
     	return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
     }
     
    -
     /*-**************************************************************
     *  FSE Compression Code
     ****************************************************************/
    @@ -421,10 +465,11 @@ size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
     	`FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
     Allocation is manual (C standard does not support variable-size structures).
     */
    -size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
    +size_t FSE_sizeof_CTable(unsigned maxSymbolValue, unsigned tableLog)
     {
    -	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
    -	return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
    +	if (tableLog > FSE_MAX_TABLELOG)
    +		return ERROR(tableLog_tooLarge);
    +	return FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue) * sizeof(U32);
     }
     
     /* provides the minimum logSize to safely represent a distribution */
    @@ -441,11 +486,16 @@ unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsi
     	U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
     	U32 tableLog = maxTableLog;
     	U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
    -	if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
    -	if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
    -	if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
    -	if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
    -	if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
    +	if (tableLog == 0)
    +		tableLog = FSE_DEFAULT_TABLELOG;
    +	if (maxBitsSrc < tableLog)
    +		tableLog = maxBitsSrc; /* Accuracy can be reduced */
    +	if (minBits > tableLog)
    +		tableLog = minBits; /* Need a minimum to safely represent all symbol values */
    +	if (tableLog < FSE_MIN_TABLELOG)
    +		tableLog = FSE_MIN_TABLELOG;
    +	if (tableLog > FSE_MAX_TABLELOG)
    +		tableLog = FSE_MAX_TABLELOG;
     	return tableLog;
     }
     
    @@ -454,11 +504,10 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
     	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
     }
     
    -
     /* Secondary normalization method.
        To be used when primary method fails. */
     
    -static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
    +static size_t FSE_normalizeM2(short *norm, U32 tableLog, const unsigned *count, size_t total, U32 maxSymbolValue)
     {
     	short const NOT_YET_ASSIGNED = -2;
     	U32 s;
    @@ -469,9 +518,9 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     	U32 const lowThreshold = (U32)(total >> tableLog);
     	U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
     
    -	for (s=0; s<=maxSymbolValue; s++) {
    +	for (s = 0; s <= maxSymbolValue; s++) {
     		if (count[s] == 0) {
    -			norm[s]=0;
    +			norm[s] = 0;
     			continue;
     		}
     		if (count[s] <= lowThreshold) {
    @@ -487,47 +536,51 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     			continue;
     		}
     
    -		norm[s]=NOT_YET_ASSIGNED;
    +		norm[s] = NOT_YET_ASSIGNED;
     	}
     	ToDistribute = (1 << tableLog) - distributed;
     
     	if ((total / ToDistribute) > lowOne) {
     		/* risk of rounding to zero */
     		lowOne = (U32)((total * 3) / (ToDistribute * 2));
    -		for (s=0; s<=maxSymbolValue; s++) {
    +		for (s = 0; s <= maxSymbolValue; s++) {
     			if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
     				norm[s] = 1;
     				distributed++;
     				total -= count[s];
     				continue;
    -		}   }
    +			}
    +		}
     		ToDistribute = (1 << tableLog) - distributed;
     	}
     
    -	if (distributed == maxSymbolValue+1) {
    +	if (distributed == maxSymbolValue + 1) {
     		/* all values are pretty poor;
     		   probably incompressible data (should have already been detected);
     		   find max, then give all remaining points to max */
     		U32 maxV = 0, maxC = 0;
    -		for (s=0; s<=maxSymbolValue; s++)
    -			if (count[s] > maxC) maxV=s, maxC=count[s];
    +		for (s = 0; s <= maxSymbolValue; s++)
    +			if (count[s] > maxC)
    +				maxV = s, maxC = count[s];
     		norm[maxV] += (short)ToDistribute;
     		return 0;
     	}
     
     	if (total == 0) {
     		/* all of the symbols were low enough for the lowOne or lowThreshold */
    -		for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
    -			if (norm[s] > 0) ToDistribute--, norm[s]++;
    +		for (s = 0; ToDistribute > 0; s = (s + 1) % (maxSymbolValue + 1))
    +			if (norm[s] > 0)
    +				ToDistribute--, norm[s]++;
     		return 0;
     	}
     
    -	{	U64 const vStepLog = 62 - tableLog;
    -		U64 const mid = (1ULL << (vStepLog-1)) - 1;
    -		U64 const rStep = ((((U64)1<> vStepLog);
     				U32 const sEnd = (U32)(end >> vStepLog);
    @@ -536,108 +589,121 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     					return ERROR(GENERIC);
     				norm[s] = (short)weight;
     				tmpTotal = end;
    -	}   }   }
    +			}
    +		}
    +	}
     
     	return 0;
     }
     
    -
    -size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
    -						   const unsigned* count, size_t total,
    -						   unsigned maxSymbolValue)
    +size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const unsigned *count, size_t total, unsigned maxSymbolValue)
     {
     	/* Sanity checks */
    -	if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
    -	if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
    -	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
    -	if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
    +	if (tableLog == 0)
    +		tableLog = FSE_DEFAULT_TABLELOG;
    +	if (tableLog < FSE_MIN_TABLELOG)
    +		return ERROR(GENERIC); /* Unsupported size */
    +	if (tableLog > FSE_MAX_TABLELOG)
    +		return ERROR(tableLog_tooLarge); /* Unsupported size */
    +	if (tableLog < FSE_minTableLog(total, maxSymbolValue))
    +		return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
     
    -	{	U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
    +	{
    +		U32 const rtbTable[] = {0, 473195, 504333, 520860, 550000, 700000, 750000, 830000};
     		U64 const scale = 62 - tableLog;
    -		U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
    -		U64 const vStep = 1ULL<<(scale-20);
    -		int stillToDistribute = 1<> tableLog);
     
    -		for (s=0; s<=maxSymbolValue; s++) {
    -			if (count[s] == total) return 0;   /* rle special case */
    -			if (count[s] == 0) { normalizedCounter[s]=0; continue; }
    +		for (s = 0; s <= maxSymbolValue; s++) {
    +			if (count[s] == total)
    +				return 0; /* rle special case */
    +			if (count[s] == 0) {
    +				normalizedCounter[s] = 0;
    +				continue;
    +			}
     			if (count[s] <= lowThreshold) {
     				normalizedCounter[s] = -1;
     				stillToDistribute--;
     			} else {
    -				short proba = (short)((count[s]*step) >> scale);
    -				if (proba<8) {
    +				short proba = (short)((count[s] * step) >> scale);
    +				if (proba < 8) {
     					U64 restToBeat = vStep * rtbTable[proba];
    -					proba += (count[s]*step) - ((U64)proba< restToBeat;
    +					proba += (count[s] * step) - ((U64)proba << scale) > restToBeat;
     				}
    -				if (proba > largestP) largestP=proba, largest=s;
    +				if (proba > largestP)
    +					largestP = proba, largest = s;
     				normalizedCounter[s] = proba;
     				stillToDistribute -= proba;
    -		}   }
    +			}
    +		}
     		if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
     			/* corner case, need another normalization method */
     			size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
    -			if (FSE_isError(errorCode)) return errorCode;
    -		}
    -		else normalizedCounter[largest] += (short)stillToDistribute;
    +			if (FSE_isError(errorCode))
    +				return errorCode;
    +		} else
    +			normalizedCounter[largest] += (short)stillToDistribute;
     	}
     
     	return tableLog;
     }
     
    -
     /* fake FSE_CTable, for raw (uncompressed) input */
    -size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
    +size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits)
     {
     	const unsigned tableSize = 1 << nbBits;
     	const unsigned tableMask = tableSize - 1;
     	const unsigned maxSymbolValue = tableMask;
    -	void* const ptr = ct;
    -	U16* const tableU16 = ( (U16*) ptr) + 2;
    -	void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1);   /* assumption : tableLog >= 1 */
    -	FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
    +	void *const ptr = ct;
    +	U16 *const tableU16 = ((U16 *)ptr) + 2;
    +	void *const FSCT = ((U32 *)ptr) + 1 /* header */ + (tableSize >> 1); /* assumption : tableLog >= 1 */
    +	FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT);
     	unsigned s;
     
     	/* Sanity checks */
    -	if (nbBits < 1) return ERROR(GENERIC);             /* min size */
    +	if (nbBits < 1)
    +		return ERROR(GENERIC); /* min size */
     
     	/* header */
    -	tableU16[-2] = (U16) nbBits;
    -	tableU16[-1] = (U16) maxSymbolValue;
    +	tableU16[-2] = (U16)nbBits;
    +	tableU16[-1] = (U16)maxSymbolValue;
     
     	/* Build table */
    -	for (s=0; s FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) {  /* test bit 2 */
    +	if ((sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) && (srcSize & 2)) { /* test bit 2 */
     		FSE_encodeSymbol(&bitC, &CState2, *--ip);
     		FSE_encodeSymbol(&bitC, &CState1, *--ip);
     		FSE_FLUSHBITS(&bitC);
     	}
     
     	/* 2 or 4 encoding per loop */
    -	while ( ip>istart ) {
    +	while (ip > istart) {
     
     		FSE_encodeSymbol(&bitC, &CState2, *--ip);
     
    -		if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */
    +		if (sizeof(bitC.bitContainer) * 8 < FSE_MAX_TABLELOG * 2 + 7) /* this test must be static */
     			FSE_FLUSHBITS(&bitC);
     
     		FSE_encodeSymbol(&bitC, &CState1, *--ip);
     
    -		if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) {  /* this test must be static */
    +		if (sizeof(bitC.bitContainer) * 8 > FSE_MAX_TABLELOG * 4 + 7) { /* this test must be static */
     			FSE_encodeSymbol(&bitC, &CState2, *--ip);
     			FSE_encodeSymbol(&bitC, &CState1, *--ip);
     		}
    @@ -706,9 +773,7 @@ static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
     	return BIT_closeCStream(&bitC);
     }
     
    -size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
    -						   const void* src, size_t srcSize,
    -						   const FSE_CTable* ct)
    +size_t FSE_compress_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const FSE_CTable *ct)
     {
     	unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
     
    @@ -718,62 +783,79 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
     		return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
     }
     
    -
     size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
     
    -#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
    -#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
    +#define CHECK_V_F(e, f)     \
    +	size_t const e = f; \
    +	if (ERR_isError(e)) \
    +	return f
    +#define CHECK_F(f)                        \
    +	{                                 \
    +		CHECK_V_F(_var_err__, f); \
    +	}
     
     /* FSE_compress_wksp() :
      * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
      * `wkspSize` size must be `(1< not compressible */
    -		if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
    +	{
    +		CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned *)scratchBuffer));
    +		if (maxCount == srcSize)
    +			return 1; /* only a single symbol in src : rle */
    +		if (maxCount == 1)
    +			return 0; /* each symbol present maximum once => not compressible */
    +		if (maxCount < (srcSize >> 7))
    +			return 0; /* Heuristic : not compressible enough */
     	}
     
     	tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
    -	CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
    +	CHECK_F(FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue));
     
     	/* Write table description header */
    -	{	CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    +	{
    +		CHECK_V_F(nc_err, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog));
     		op += nc_err;
     	}
     
     	/* Compress */
    -	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
    -	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
    -		if (cSize == 0) return 0;   /* not enough space for compressed data */
    +	CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize));
    +	{
    +		CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable));
    +		if (cSize == 0)
    +			return 0; /* not enough space for compressed data */
     		op += cSize;
     	}
     
     	/* check compressibility */
    -	if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
    +	if ((size_t)(op - ostart) >= srcSize - 1)
    +		return 0;
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -
    -#endif   /* FSE_COMMONDEFS_ONLY */
    +#endif /* FSE_COMMONDEFS_ONLY */
    diff --git a/contrib/linux-kernel/lib/zstd/fse_decompress.c b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    index 6d2c36775..245570a8a 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    @@ -37,31 +37,35 @@
      * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
      */
     
    -
     /* **************************************************************
     *  Compiler specifics
     ****************************************************************/
     #define FORCE_INLINE static __always_inline
     
    -
     /* **************************************************************
     *  Includes
     ****************************************************************/
    -#include 
    -#include      /* memcpy, memset */
     #include "bitstream.h"
     #include "fse.h"
    -
    +#include 
    +#include  /* memcpy, memset */
     
     /* **************************************************************
     *  Error Management
     ****************************************************************/
     #define FSE_isError ERR_isError
    -#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    +#define FSE_STATIC_ASSERT(c)                                   \
    +	{                                                      \
    +		enum { FSE_static_assert = 1 / (int)(!!(c)) }; \
    +	} /* use only *after* variable declarations */
     
     /* check and forward error code */
    -#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
    -
    +#define CHECK_F(f)                  \
    +	{                           \
    +		size_t const e = f; \
    +		if (FSE_isError(e)) \
    +			return e;   \
    +	}
     
     /* **************************************************************
     *  Templates
    @@ -74,89 +78,100 @@
     
     /* safety checks */
     #ifndef FSE_FUNCTION_EXTENSION
    -#  error "FSE_FUNCTION_EXTENSION must be defined"
    +#error "FSE_FUNCTION_EXTENSION must be defined"
     #endif
     #ifndef FSE_FUNCTION_TYPE
    -#  error "FSE_FUNCTION_TYPE must be defined"
    +#error "FSE_FUNCTION_TYPE must be defined"
     #endif
     
     /* Function names */
    -#define FSE_CAT(X,Y) X##Y
    -#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    -#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
    -
    +#define FSE_CAT(X, Y) X##Y
    +#define FSE_FUNCTION_NAME(X, Y) FSE_CAT(X, Y)
    +#define FSE_TYPE_NAME(X, Y) FSE_CAT(X, Y)
     
     /* Function templates */
     
    -size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
    +size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
     {
    -	void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */
    -	FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
    -	U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
    +	void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
    +	FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr);
    +	U16 symbolNext[FSE_MAX_SYMBOL_VALUE + 1];
     
     	U32 const maxSV1 = maxSymbolValue + 1;
     	U32 const tableSize = 1 << tableLog;
    -	U32 highThreshold = tableSize-1;
    +	U32 highThreshold = tableSize - 1;
     
     	/* Sanity Checks */
    -	if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
    -	if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
    +	if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE)
    +		return ERROR(maxSymbolValue_tooLarge);
    +	if (tableLog > FSE_MAX_TABLELOG)
    +		return ERROR(tableLog_tooLarge);
     
     	/* Init, lay down lowprob symbols */
    -	{	FSE_DTableHeader DTableH;
    +	{
    +		FSE_DTableHeader DTableH;
     		DTableH.tableLog = (U16)tableLog;
     		DTableH.fastMode = 1;
    -		{	S16 const largeLimit= (S16)(1 << (tableLog-1));
    +		{
    +			S16 const largeLimit = (S16)(1 << (tableLog - 1));
     			U32 s;
    -			for (s=0; s= largeLimit) DTableH.fastMode=0;
    +					if (normalizedCounter[s] >= largeLimit)
    +						DTableH.fastMode = 0;
     					symbolNext[s] = normalizedCounter[s];
    -		}   }   }
    +				}
    +			}
    +		}
     		memcpy(dt, &DTableH, sizeof(DTableH));
     	}
     
     	/* Spread symbols */
    -	{	U32 const tableMask = tableSize-1;
    +	{
    +		U32 const tableMask = tableSize - 1;
     		U32 const step = FSE_TABLESTEP(tableSize);
     		U32 s, position = 0;
    -		for (s=0; s highThreshold) position = (position + step) & tableMask;   /* lowprob area */
    -		}   }
    -		if (position!=0) return ERROR(GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */
    +				while (position > highThreshold)
    +					position = (position + step) & tableMask; /* lowprob area */
    +			}
    +		}
    +		if (position != 0)
    +			return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
     	}
     
     	/* Build Decoding table */
    -	{	U32 u;
    -		for (u=0; utableLog = 0;
     	DTableH->fastMode = 0;
    @@ -168,25 +183,25 @@ size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
     	return 0;
     }
     
    -
    -size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
    +size_t FSE_buildDTable_raw(FSE_DTable *dt, unsigned nbBits)
     {
    -	void* ptr = dt;
    -	FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
    -	void* dPtr = dt + 1;
    -	FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
    +	void *ptr = dt;
    +	FSE_DTableHeader *const DTableH = (FSE_DTableHeader *)ptr;
    +	void *dPtr = dt + 1;
    +	FSE_decode_t *const dinfo = (FSE_decode_t *)dPtr;
     	const unsigned tableSize = 1 << nbBits;
     	const unsigned tableMask = tableSize - 1;
    -	const unsigned maxSV1 = tableMask+1;
    +	const unsigned maxSV1 = tableMask + 1;
     	unsigned s;
     
     	/* Sanity checks */
    -	if (nbBits < 1) return ERROR(GENERIC);         /* min size */
    +	if (nbBits < 1)
    +		return ERROR(GENERIC); /* min size */
     
     	/* Build Decoding Table */
     	DTableH->tableLog = (U16)nbBits;
     	DTableH->fastMode = 1;
    -	for (s=0; s sizeof(bitD.bitContainer)*8)    /* This test must be static */
    +		if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */
     			BIT_reloadDStream(&bitD);
     
     		op[1] = FSE_GETSYMBOL(&state2);
     
    -		if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
    -			{ if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
    +		if (FSE_MAX_TABLELOG * 4 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */
    +		{
    +			if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) {
    +				op += 2;
    +				break;
    +			}
    +		}
     
     		op[2] = FSE_GETSYMBOL(&state1);
     
    -		if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */
    +		if (FSE_MAX_TABLELOG * 2 + 7 > sizeof(bitD.bitContainer) * 8) /* This test must be static */
     			BIT_reloadDStream(&bitD);
     
     		op[3] = FSE_GETSYMBOL(&state2);
    @@ -240,58 +258,60 @@ FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
     	/* tail */
     	/* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
     	while (1) {
    -		if (op>(omax-2)) return ERROR(dstSize_tooSmall);
    +		if (op > (omax - 2))
    +			return ERROR(dstSize_tooSmall);
     		*op++ = FSE_GETSYMBOL(&state1);
    -		if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
    +		if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) {
     			*op++ = FSE_GETSYMBOL(&state2);
     			break;
     		}
     
    -		if (op>(omax-2)) return ERROR(dstSize_tooSmall);
    +		if (op > (omax - 2))
    +			return ERROR(dstSize_tooSmall);
     		*op++ = FSE_GETSYMBOL(&state2);
    -		if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
    +		if (BIT_reloadDStream(&bitD) == BIT_DStream_overflow) {
     			*op++ = FSE_GETSYMBOL(&state1);
     			break;
    -	}   }
    +		}
    +	}
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -
    -size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
    -							const void* cSrc, size_t cSrcSize,
    -							const FSE_DTable* dt)
    +size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, const void *cSrc, size_t cSrcSize, const FSE_DTable *dt)
     {
    -	const void* ptr = dt;
    -	const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
    +	const void *ptr = dt;
    +	const FSE_DTableHeader *DTableH = (const FSE_DTableHeader *)ptr;
     	const U32 fastMode = DTableH->fastMode;
     
     	/* select fast mode (static) */
    -	if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
    +	if (fastMode)
    +		return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
     	return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
     }
     
    -
    -size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)
    +size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, unsigned maxLog)
     {
    -	const BYTE* const istart = (const BYTE*)cSrc;
    -	const BYTE* ip = istart;
    -	short counting[FSE_MAX_SYMBOL_VALUE+1];
    +	const BYTE *const istart = (const BYTE *)cSrc;
    +	const BYTE *ip = istart;
    +	short counting[FSE_MAX_SYMBOL_VALUE + 1];
     	unsigned tableLog;
     	unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
     
     	/* normal FSE decoding mode */
    -	size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
    -	if (FSE_isError(NCountLength)) return NCountLength;
    -	//if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
    -	if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
    +	size_t const NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
    +	if (FSE_isError(NCountLength))
    +		return NCountLength;
    +	// if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size; supposed to be already checked in NCountLength, only remaining
    +	// case : NCountLength==cSrcSize */
    +	if (tableLog > maxLog)
    +		return ERROR(tableLog_tooLarge);
     	ip += NCountLength;
     	cSrcSize -= NCountLength;
     
    -	CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );
    +	CHECK_F(FSE_buildDTable(workSpace, counting, maxSymbolValue, tableLog));
     
    -	return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace);   /* always return, even if it is an error code */
    +	return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
     }
     
    -
    -#endif   /* FSE_COMMONDEFS_ONLY */
    +#endif /* FSE_COMMONDEFS_ONLY */
    diff --git a/contrib/linux-kernel/lib/zstd/huf.h b/contrib/linux-kernel/lib/zstd/huf.h
    index b15767599..56abe2f1c 100644
    --- a/contrib/linux-kernel/lib/zstd/huf.h
    +++ b/contrib/linux-kernel/lib/zstd/huf.h
    @@ -40,77 +40,68 @@
     #ifndef HUF_H_298734234
     #define HUF_H_298734234
     
    -
     /* *** Dependencies *** */
    -#include     /* size_t */
    -
    +#include  /* size_t */
     
     /* ***   Tool functions *** */
    -#define HUF_BLOCKSIZE_MAX (128 * 1024)       /**< maximum input size for a single block compressed with HUF_compress */
    -size_t HUF_compressBound(size_t size);       /**< maximum compressed size (worst case) */
    +#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */
    +size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
     
     /* Error Management */
    -unsigned    HUF_isError(size_t code);        /**< tells if a return value is an error code */
    -
    +unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
     
     /* ***   Advanced function   *** */
     
     /** HUF_compress4X_wksp() :
     *   Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */
    -size_t HUF_compress4X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    -
    -
    +size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace,
    +			   size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
     
     /* *** Dependencies *** */
    -#include "mem.h"   /* U32 */
    -
    +#include "mem.h" /* U32 */
     
     /* *** Constants *** */
    -#define HUF_TABLELOG_MAX      12       /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
    -#define HUF_TABLELOG_DEFAULT  11       /* tableLog by default, when not specified */
    -#define HUF_SYMBOLVALUE_MAX  255
    +#define HUF_TABLELOG_MAX 12     /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
    +#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
    +#define HUF_SYMBOLVALUE_MAX 255
     
    -#define HUF_TABLELOG_ABSOLUTEMAX  15   /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
    +#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
     #if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
    -#  error "HUF_TABLELOG_MAX is too large !"
    +#error "HUF_TABLELOG_MAX is too large !"
     #endif
     
    -
     /* ****************************************
     *  Static allocation
     ******************************************/
     /* HUF buffer bounds */
     #define HUF_CTABLEBOUND 129
    -#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8)   /* only true if incompressible pre-filtered with fast heuristic */
    -#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size))   /* Macro version, useful for static allocation */
    +#define HUF_BLOCKBOUND(size) (size + (size >> 8) + 8)			 /* only true if incompressible pre-filtered with fast heuristic */
    +#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
     
     /* static allocation of HUF's Compression Table */
     #define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
    -	U32 name##hb[maxSymbolValue+1]; \
    -	void* name##hv = &(name##hb); \
    -	HUF_CElt* name = (HUF_CElt*)(name##hv)   /* no final ; */
    +	U32 name##hb[maxSymbolValue + 1];              \
    +	void *name##hv = &(name##hb);                  \
    +	HUF_CElt *name = (HUF_CElt *)(name##hv) /* no final ; */
     
     /* static allocation of HUF's DTable */
     typedef U32 HUF_DTable;
    -#define HUF_DTABLE_SIZE(maxTableLog)   (1 + (1<<(maxTableLog)))
    -#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
    -		HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
    -#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
    -		HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
    +#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1 << (maxTableLog)))
    +#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = {((U32)((maxTableLog)-1) * 0x01000001)}
    +#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = {((U32)(maxTableLog)*0x01000001)}
     
     /* The workspace must have alignment at least 4 and be at least this large */
     #define HUF_WORKSPACE_SIZE (6 << 10)
     #define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
     
    -
     /* ****************************************
     *  Advanced decompression functions
     ******************************************/
    -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< decodes RLE and uncompressed */
    -size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
    -size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
    -size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
    -
    +size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */
    +size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc,
    +				size_t cSrcSize);							       /**< considers RLE and uncompressed as errors */
    +size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */
    +size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */
     
     /* ****************************************
     *  HUF detailed API
    @@ -129,41 +120,41 @@ or to save and regenerate 'CTable' using external methods.
     */
     /* FSE_count() : find it within "fse.h" */
     unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
    -typedef struct HUF_CElt_s HUF_CElt;   /* incomplete type */
    -size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
    -size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
    +typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
    +size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog);
    +size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable);
     
     typedef enum {
    -   HUF_repeat_none,  /**< Cannot use the previous table */
    -   HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
    -   HUF_repeat_valid  /**< Can use the previous table and it is asumed to be valid */
    - } HUF_repeat;
    +	HUF_repeat_none,  /**< Cannot use the previous table */
    +	HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1,
    +			     4}X_repeat */
    +	HUF_repeat_valid  /**< Can use the previous table and it is asumed to be valid */
    +} HUF_repeat;
     /** HUF_compress4X_repeat() :
     *   Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
     *   If it uses hufTable it does not modify hufTable or repeat.
     *   If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
     *   If preferRepeat then the old table will always be used if valid. */
    -size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    +size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace,
    +			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat,
    +			     int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
     
     /** HUF_buildCTable_wksp() :
      *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.
      *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
      */
    -size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize);
    +size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize);
     
     /*! HUF_readStats() :
     	Read compact Huffman tree, saved by HUF_writeCTable().
     	`huffWeight` is destination buffer.
     	@return : size read from `src` , or an error Code .
     	Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
    -size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
    -					 U32* nbSymbolsPtr, U32* tableLogPtr,
    -					 const void* src, size_t srcSize);
    +size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize);
     
     /** HUF_readCTable() :
     *   Loading a CTable saved with HUF_writeCTable() */
    -size_t HUF_readCTable (HUF_CElt* CTable, unsigned maxSymbolValue, const void* src, size_t srcSize);
    -
    +size_t HUF_readCTable(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize);
     
     /*
     HUF_decompress() does the following:
    @@ -177,33 +168,36 @@ HUF_decompress() does the following:
     *   based on a set of pre-determined metrics.
     *   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
     *   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
    -U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
    +U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize);
     
    -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
    -size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize);
    -
    -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    -size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    -size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    +size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize);
    +size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize);
     
    +size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable);
    +size_t HUF_decompress4X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable);
    +size_t HUF_decompress4X4_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable);
     
     /* single stream variants */
     
    -size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    -size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
    +size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace,
    +			   size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    +size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable);
     /** HUF_compress1X_repeat() :
     *   Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
     *   If it uses hufTable it does not modify hufTable or repeat.
     *   If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
     *   If preferRepeat then the old table will always be used if valid. */
    -size_t HUF_compress1X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
    +size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace,
    +			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat,
    +			     int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
     
    -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
    -size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */
    -size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */
    +size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize);
    +size_t HUF_decompress1X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */
    +size_t HUF_decompress1X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */
     
    -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);   /**< automatic selection of sing or double symbol decoder, based on DTable */
    -size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    -size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
    +size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize,
    +				    const HUF_DTable *DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */
    +size_t HUF_decompress1X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable);
    +size_t HUF_decompress1X4_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable);
     
    -#endif   /* HUF_H_298734234 */
    +#endif /* HUF_H_298734234 */
    diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c
    index 2c1c321e7..158740129 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c
    @@ -37,23 +37,29 @@
      * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
      */
     
    -
     /* **************************************************************
     *  Includes
     ****************************************************************/
    -#include      /* memcpy, memset */
     #include "bitstream.h"
    -#include "fse.h"        /* header compression */
    +#include "fse.h" /* header compression */
     #include "huf.h"
    -
    +#include  /* memcpy, memset */
     
     /* **************************************************************
     *  Error Management
     ****************************************************************/
    -#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    -#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
    -#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
    -
    +#define HUF_STATIC_ASSERT(c)                                   \
    +	{                                                      \
    +		enum { HUF_static_assert = 1 / (int)(!!(c)) }; \
    +	} /* use only *after* variable declarations */
    +#define CHECK_V_F(e, f)     \
    +	size_t const e = f; \
    +	if (ERR_isError(e)) \
    +	return f
    +#define CHECK_F(f)                        \
    +	{                                 \
    +		CHECK_V_F(_var_err__, f); \
    +	}
     
     /* **************************************************************
     *  Utils
    @@ -63,7 +69,6 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
     	return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
     }
     
    -
     /* *******************************************************
     *  HUF : Huffman block compression
     *********************************************************/
    @@ -73,141 +78,168 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
      * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
      */
     #define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
    -size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
    +size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, size_t wtSize)
     {
    -	BYTE* const ostart = (BYTE*) dst;
    -	BYTE* op = ostart;
    -	BYTE* const oend = ostart + dstSize;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *op = ostart;
    +	BYTE *const oend = ostart + dstSize;
     
     	U32 maxSymbolValue = HUF_TABLELOG_MAX;
     	U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
     
     	FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
    -	BYTE scratchBuffer[1< not compressible */
    +	{
    +		CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize));
    +		if (maxCount == wtSize)
    +			return 1; /* only a single symbol in src : rle */
    +		if (maxCount == 1)
    +			return 0; /* each symbol present maximum once => not compressible */
     	}
     
     	tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
    -	CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
    +	CHECK_F(FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue));
     
     	/* Write table description header */
    -	{	CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
    +	{
    +		CHECK_V_F(hSize, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog));
     		op += hSize;
     	}
     
     	/* Compress */
    -	CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
    -	{	CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
    -		if (cSize == 0) return 0;   /* not enough space for compressed data */
    +	CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)));
    +	{
    +		CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable));
    +		if (cSize == 0)
    +			return 0; /* not enough space for compressed data */
     		op += cSize;
     	}
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -
     struct HUF_CElt_s {
    -  U16  val;
    -  BYTE nbBits;
    -};   /* typedef'd to HUF_CElt within "huf.h" */
    +	U16 val;
    +	BYTE nbBits;
    +}; /* typedef'd to HUF_CElt within "huf.h" */
     
     /*! HUF_writeCTable() :
     	`CTable` : Huffman tree to save, using huf representation.
     	@return : size of saved CTable */
    -size_t HUF_writeCTable (void* dst, size_t maxDstSize,
    -						const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
    +size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog)
     {
    -	BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];   /* precomputed conversion table */
    +	BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
     	BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
    -	BYTE* op = (BYTE*)dst;
    +	BYTE *op = (BYTE *)dst;
     	U32 n;
     
    -	 /* check conditions */
    -	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
    +	/* check conditions */
    +	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
    +		return ERROR(maxSymbolValue_tooLarge);
     
     	/* convert to weight */
     	bitsToWeight[0] = 0;
    -	for (n=1; n1) & (hSize < maxSymbolValue/2)) {   /* FSE compressed */
    +	{
    +		CHECK_V_F(hSize, HUF_compressWeights(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue));
    +		if ((hSize > 1) & (hSize < maxSymbolValue / 2)) { /* FSE compressed */
     			op[0] = (BYTE)hSize;
    -			return hSize+1;
    -	}   }
    +			return hSize + 1;
    +		}
    +	}
     
     	/* write raw values as 4-bits (max : 15) */
    -	if (maxSymbolValue > (256-128)) return ERROR(GENERIC);   /* should not happen : likely means source cannot be compressed */
    -	if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall);   /* not enough space within dst buffer */
    -	op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
    -	huffWeight[maxSymbolValue] = 0;   /* to be sure it doesn't cause msan issue in final combination */
    -	for (n=0; n (256 - 128))
    +		return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
    +	if (((maxSymbolValue + 1) / 2) + 1 > maxDstSize)
    +		return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
    +	op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue - 1));
    +	huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
    +	for (n = 0; n < maxSymbolValue; n += 2)
    +		op[(n / 2) + 1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n + 1]);
    +	return ((maxSymbolValue + 1) / 2) + 1;
     }
     
    -
    -size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
    +size_t HUF_readCTable(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize)
     {
    -	BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];   /* init not required, even though some static analyzer may complain */
    -	U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */
    +	BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];  /* init not required, even though some static analyzer may complain */
    +	U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
     	U32 tableLog = 0;
     	U32 nbSymbols = 0;
     
     	/* get symbol weights */
    -	CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
    +	CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize));
     
     	/* check result */
    -	if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    -	if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
    +	if (tableLog > HUF_TABLELOG_MAX)
    +		return ERROR(tableLog_tooLarge);
    +	if (nbSymbols > maxSymbolValue + 1)
    +		return ERROR(maxSymbolValue_tooSmall);
     
     	/* Prepare base value per rank */
    -	{	U32 n, nextRankStart = 0;
    -		for (n=1; n<=tableLog; n++) {
    +	{
    +		U32 n, nextRankStart = 0;
    +		for (n = 1; n <= tableLog; n++) {
     			U32 curr = nextRankStart;
    -			nextRankStart += (rankVal[n] << (n-1));
    +			nextRankStart += (rankVal[n] << (n - 1));
     			rankVal[n] = curr;
    -	}   }
    +		}
    +	}
     
     	/* fill nbBits */
    -	{	U32 n; for (n=0; nn=tableLog+1 */
    -		U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
    -		{ U32 n; for (n=0; nn=tableLog+1 */
    +		U16 valPerRank[HUF_TABLELOG_MAX + 2] = {0};
    +		{
    +			U32 n;
    +			for (n = 0; n < nbSymbols; n++)
    +				nbPerRank[CTable[n].nbBits]++;
    +		}
     		/* determine stating value per rank */
    -		valPerRank[tableLog+1] = 0;   /* for w==0 */
    -		{	U16 min = 0;
    -			U32 n; for (n=tableLog; n>0; n--) {  /* start at n=tablelog <-> w=1 */
    +		valPerRank[tableLog + 1] = 0; /* for w==0 */
    +		{
    +			U16 min = 0;
    +			U32 n;
    +			for (n = tableLog; n > 0; n--) { /* start at n=tablelog <-> w=1 */
     				valPerRank[n] = min;     /* get starting value within each rank */
     				min += nbPerRank[n];
     				min >>= 1;
    -		}   }
    +			}
    +		}
     		/* assign value within rank, symbol order */
    -		{ U32 n; for (n=0; n<=maxSymbolValue; n++) CTable[n].val = valPerRank[CTable[n].nbBits]++; }
    +		{
    +			U32 n;
    +			for (n = 0; n <= maxSymbolValue; n++)
    +				CTable[n].val = valPerRank[CTable[n].nbBits]++;
    +		}
     	}
     
     	return readSize;
     }
     
    -
     typedef struct nodeElt_s {
     	U32 count;
     	U16 parent;
    @@ -215,130 +247,153 @@ typedef struct nodeElt_s {
     	BYTE nbBits;
     } nodeElt;
     
    -static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
    +static U32 HUF_setMaxHeight(nodeElt *huffNode, U32 lastNonNull, U32 maxNbBits)
     {
     	const U32 largestBits = huffNode[lastNonNull].nbBits;
    -	if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */
    +	if (largestBits <= maxNbBits)
    +		return largestBits; /* early exit : no elt > maxNbBits */
     
     	/* there are several too large elements (at least >= 2) */
    -	{	int totalCost = 0;
    +	{
    +		int totalCost = 0;
     		const U32 baseCost = 1 << (largestBits - maxNbBits);
     		U32 n = lastNonNull;
     
     		while (huffNode[n].nbBits > maxNbBits) {
     			totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
     			huffNode[n].nbBits = (BYTE)maxNbBits;
    -			n --;
    -		}  /* n stops at huffNode[n].nbBits <= maxNbBits */
    -		while (huffNode[n].nbBits == maxNbBits) n--;   /* n end at index of smallest symbol using < maxNbBits */
    +			n--;
    +		} /* n stops at huffNode[n].nbBits <= maxNbBits */
    +		while (huffNode[n].nbBits == maxNbBits)
    +			n--; /* n end at index of smallest symbol using < maxNbBits */
     
     		/* renorm totalCost */
    -		totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */
    +		totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */
     
     		/* repay normalized cost */
    -		{	U32 const noSymbol = 0xF0F0F0F0;
    -			U32 rankLast[HUF_TABLELOG_MAX+2];
    +		{
    +			U32 const noSymbol = 0xF0F0F0F0;
    +			U32 rankLast[HUF_TABLELOG_MAX + 2];
     			int pos;
     
     			/* Get pos of last (smallest) symbol per rank */
     			memset(rankLast, 0xF0, sizeof(rankLast));
    -			{	U32 currNbBits = maxNbBits;
    -				for (pos=n ; pos >= 0; pos--) {
    -					if (huffNode[pos].nbBits >= currNbBits) continue;
    -					currNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
    -					rankLast[maxNbBits-currNbBits] = pos;
    -			}   }
    +			{
    +				U32 currNbBits = maxNbBits;
    +				for (pos = n; pos >= 0; pos--) {
    +					if (huffNode[pos].nbBits >= currNbBits)
    +						continue;
    +					currNbBits = huffNode[pos].nbBits; /* < maxNbBits */
    +					rankLast[maxNbBits - currNbBits] = pos;
    +				}
    +			}
     
     			while (totalCost > 0) {
     				U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
    -				for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
    +				for (; nBitsToDecrease > 1; nBitsToDecrease--) {
     					U32 highPos = rankLast[nBitsToDecrease];
    -					U32 lowPos = rankLast[nBitsToDecrease-1];
    -					if (highPos == noSymbol) continue;
    -					if (lowPos == noSymbol) break;
    -					{	U32 const highTotal = huffNode[highPos].count;
    +					U32 lowPos = rankLast[nBitsToDecrease - 1];
    +					if (highPos == noSymbol)
    +						continue;
    +					if (lowPos == noSymbol)
    +						break;
    +					{
    +						U32 const highTotal = huffNode[highPos].count;
     						U32 const lowTotal = 2 * huffNode[lowPos].count;
    -						if (highTotal <= lowTotal) break;
    -				}   }
    +						if (highTotal <= lowTotal)
    +							break;
    +					}
    +				}
     				/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
    -				while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))  /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    -					nBitsToDecrease ++;
    -				totalCost -= 1 << (nBitsToDecrease-1);
    -				if (rankLast[nBitsToDecrease-1] == noSymbol)
    -					rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];   /* this rank is no longer empty */
    -				huffNode[rankLast[nBitsToDecrease]].nbBits ++;
    -				if (rankLast[nBitsToDecrease] == 0)    /* special case, reached largest symbol */
    +				while (
    +				    (nBitsToDecrease <= HUF_TABLELOG_MAX) &&
    +				    (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    +					nBitsToDecrease++;
    +				totalCost -= 1 << (nBitsToDecrease - 1);
    +				if (rankLast[nBitsToDecrease - 1] == noSymbol)
    +					rankLast[nBitsToDecrease - 1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
    +				huffNode[rankLast[nBitsToDecrease]].nbBits++;
    +				if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
     					rankLast[nBitsToDecrease] = noSymbol;
     				else {
     					rankLast[nBitsToDecrease]--;
    -					if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
    -						rankLast[nBitsToDecrease] = noSymbol;   /* this rank is now empty */
    -			}   }   /* while (totalCost > 0) */
    +					if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits - nBitsToDecrease)
    +						rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
    +				}
    +			} /* while (totalCost > 0) */
     
    -			while (totalCost < 0) {  /* Sometimes, cost correction overshoot */
    -				if (rankLast[1] == noSymbol) {  /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
    -					while (huffNode[n].nbBits == maxNbBits) n--;
    -					huffNode[n+1].nbBits--;
    -					rankLast[1] = n+1;
    +			while (totalCost < 0) {		       /* Sometimes, cost correction overshoot */
    +				if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0
    +								  (using maxNbBits) */
    +					while (huffNode[n].nbBits == maxNbBits)
    +						n--;
    +					huffNode[n + 1].nbBits--;
    +					rankLast[1] = n + 1;
     					totalCost++;
     					continue;
     				}
    -				huffNode[ rankLast[1] + 1 ].nbBits--;
    +				huffNode[rankLast[1] + 1].nbBits--;
     				rankLast[1]++;
    -				totalCost ++;
    -	}   }   }   /* there are several too large elements (at least >= 2) */
    +				totalCost++;
    +			}
    +		}
    +	} /* there are several too large elements (at least >= 2) */
     
     	return maxNbBits;
     }
     
    -
     typedef struct {
     	U32 base;
     	U32 curr;
     } rankPos;
     
    -static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
    +static void HUF_sort(nodeElt *huffNode, const U32 *count, U32 maxSymbolValue)
     {
     	rankPos rank[32];
     	U32 n;
     
     	memset(rank, 0, sizeof(rank));
    -	for (n=0; n<=maxSymbolValue; n++) {
    +	for (n = 0; n <= maxSymbolValue; n++) {
     		U32 r = BIT_highbit32(count[n] + 1);
    -		rank[r].base ++;
    +		rank[r].base++;
     	}
    -	for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
    -	for (n=0; n<32; n++) rank[n].curr = rank[n].base;
    -	for (n=0; n<=maxSymbolValue; n++) {
    +	for (n = 30; n > 0; n--)
    +		rank[n - 1].base += rank[n].base;
    +	for (n = 0; n < 32; n++)
    +		rank[n].curr = rank[n].base;
    +	for (n = 0; n <= maxSymbolValue; n++) {
     		U32 const c = count[n];
    -		U32 const r = BIT_highbit32(c+1) + 1;
    +		U32 const r = BIT_highbit32(c + 1) + 1;
     		U32 pos = rank[r].curr++;
    -		while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
    +		while ((pos > rank[r].base) && (c > huffNode[pos - 1].count))
    +			huffNode[pos] = huffNode[pos - 1], pos--;
     		huffNode[pos].count = c;
    -		huffNode[pos].byte  = (BYTE)n;
    +		huffNode[pos].byte = (BYTE)n;
     	}
     }
     
    -
     /** HUF_buildCTable_wksp() :
      *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.
      *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
      */
    -#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
    -typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1];
    -size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
    +#define STARTNODE (HUF_SYMBOLVALUE_MAX + 1)
    +typedef nodeElt huffNodeTable[2 * HUF_SYMBOLVALUE_MAX + 1 + 1];
    +size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue, U32 maxNbBits, void *workSpace, size_t wkspSize)
     {
    -	nodeElt* const huffNode0 = (nodeElt*)workSpace;
    -	nodeElt* const huffNode = huffNode0+1;
    +	nodeElt *const huffNode0 = (nodeElt *)workSpace;
    +	nodeElt *const huffNode = huffNode0 + 1;
     	U32 n, nonNullRank;
     	int lowS, lowN;
     	U16 nodeNb = STARTNODE;
     	U32 nodeRoot;
     
     	/* safety checks */
    -	if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC);   /* workSpace is not large enough */
    -	if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
    -	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
    +	if (wkspSize < sizeof(huffNodeTable))
    +		return ERROR(GENERIC); /* workSpace is not large enough */
    +	if (maxNbBits == 0)
    +		maxNbBits = HUF_TABLELOG_DEFAULT;
    +	if (maxSymbolValue > HUF_SYMBOLVALUE_MAX)
    +		return ERROR(GENERIC);
     	memset(huffNode0, 0, sizeof(huffNodeTable));
     
     	/* sort, decreasing order */
    @@ -346,13 +401,18 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValu
     
     	/* init for parents */
     	nonNullRank = maxSymbolValue;
    -	while(huffNode[nonNullRank].count == 0) nonNullRank--;
    -	lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
    -	huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
    -	huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
    -	nodeNb++; lowS-=2;
    -	for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
    -	huffNode0[0].count = (U32)(1U<<31);  /* fake entry, strong barrier */
    +	while (huffNode[nonNullRank].count == 0)
    +		nonNullRank--;
    +	lowS = nonNullRank;
    +	nodeRoot = nodeNb + lowS - 1;
    +	lowN = nodeNb;
    +	huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS - 1].count;
    +	huffNode[lowS].parent = huffNode[lowS - 1].parent = nodeNb;
    +	nodeNb++;
    +	lowS -= 2;
    +	for (n = nodeNb; n <= nodeRoot; n++)
    +		huffNode[n].count = (U32)(1U << 30);
    +	huffNode0[0].count = (U32)(1U << 31); /* fake entry, strong barrier */
     
     	/* create parents */
     	while (nodeNb <= nodeRoot) {
    @@ -365,37 +425,41 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValu
     
     	/* distribute weights (unlimited tree height) */
     	huffNode[nodeRoot].nbBits = 0;
    -	for (n=nodeRoot-1; n>=STARTNODE; n--)
    -		huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
    -	for (n=0; n<=nonNullRank; n++)
    -		huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
    +	for (n = nodeRoot - 1; n >= STARTNODE; n--)
    +		huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1;
    +	for (n = 0; n <= nonNullRank; n++)
    +		huffNode[n].nbBits = huffNode[huffNode[n].parent].nbBits + 1;
     
     	/* enforce maxTableLog */
     	maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
     
     	/* fill result into tree (val, nbBits) */
    -	{	U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
    -		U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
    -		if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC);   /* check fit into table */
    -		for (n=0; n<=nonNullRank; n++)
    +	{
    +		U16 nbPerRank[HUF_TABLELOG_MAX + 1] = {0};
    +		U16 valPerRank[HUF_TABLELOG_MAX + 1] = {0};
    +		if (maxNbBits > HUF_TABLELOG_MAX)
    +			return ERROR(GENERIC); /* check fit into table */
    +		for (n = 0; n <= nonNullRank; n++)
     			nbPerRank[huffNode[n].nbBits]++;
     		/* determine stating value per rank */
    -		{	U16 min = 0;
    -			for (n=maxNbBits; n>0; n--) {
    -				valPerRank[n] = min;      /* get starting value within each rank */
    +		{
    +			U16 min = 0;
    +			for (n = maxNbBits; n > 0; n--) {
    +				valPerRank[n] = min; /* get starting value within each rank */
     				min += nbPerRank[n];
     				min >>= 1;
    -		}   }
    -		for (n=0; n<=maxSymbolValue; n++)
    -			tree[huffNode[n].byte].nbBits = huffNode[n].nbBits;   /* push nbBits per symbol, symbol order */
    -		for (n=0; n<=maxSymbolValue; n++)
    -			tree[n].val = valPerRank[tree[n].nbBits]++;   /* assign value within rank, symbol order */
    +			}
    +		}
    +		for (n = 0; n <= maxSymbolValue; n++)
    +			tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
    +		for (n = 0; n <= maxSymbolValue; n++)
    +			tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
     	}
     
     	return maxNbBits;
     }
     
    -static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
    +static size_t HUF_estimateCompressedSize(HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
     {
     	size_t nbBits = 0;
     	int s;
    @@ -405,165 +469,180 @@ static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count
     	return nbBits >> 3;
     }
     
    -static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
    -  int bad = 0;
    -  int s;
    -  for (s = 0; s <= (int)maxSymbolValue; ++s) {
    -	bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
    -  }
    -  return !bad;
    +static int HUF_validateCTable(const HUF_CElt *CTable, const unsigned *count, unsigned maxSymbolValue)
    +{
    +	int bad = 0;
    +	int s;
    +	for (s = 0; s <= (int)maxSymbolValue; ++s) {
    +		bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
    +	}
    +	return !bad;
     }
     
    -static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
    +static void HUF_encodeSymbol(BIT_CStream_t *bitCPtr, U32 symbol, const HUF_CElt *CTable)
     {
     	BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
     }
     
     size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
     
    -#define HUF_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
    +#define HUF_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
     
    -#define HUF_FLUSHBITS_1(stream) \
    -	if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)
    +#define HUF_FLUSHBITS_1(stream)                                            \
    +	if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 2 + 7) \
    +	HUF_FLUSHBITS(stream)
     
    -#define HUF_FLUSHBITS_2(stream) \
    -	if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
    +#define HUF_FLUSHBITS_2(stream)                                            \
    +	if (sizeof((stream)->bitContainer) * 8 < HUF_TABLELOG_MAX * 4 + 7) \
    +	HUF_FLUSHBITS(stream)
     
    -size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
    +size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable)
     {
    -	const BYTE* ip = (const BYTE*) src;
    -	BYTE* const ostart = (BYTE*)dst;
    -	BYTE* const oend = ostart + dstSize;
    -	BYTE* op = ostart;
    +	const BYTE *ip = (const BYTE *)src;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *const oend = ostart + dstSize;
    +	BYTE *op = ostart;
     	size_t n;
     	const unsigned fast = (dstSize >= HUF_BLOCKBOUND(srcSize));
     	BIT_CStream_t bitC;
     
     	/* init */
    -	if (dstSize < 8) return 0;   /* not enough space to compress */
    -	{ size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
    -	  if (HUF_isError(initErr)) return 0; }
    -
    -	n = srcSize & ~3;  /* join to mod 4 */
    -	switch (srcSize & 3)
    +	if (dstSize < 8)
    +		return 0; /* not enough space to compress */
     	{
    -		case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
    -				 HUF_FLUSHBITS_2(&bitC);
    -		case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
    -				 HUF_FLUSHBITS_1(&bitC);
    -		case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
    -				 HUF_FLUSHBITS(&bitC);
    -		case 0 :
    -		default: ;
    +		size_t const initErr = BIT_initCStream(&bitC, op, oend - op);
    +		if (HUF_isError(initErr))
    +			return 0;
     	}
     
    -	for (; n>0; n-=4) {  /* note : n&3==0 at this stage */
    -		HUF_encodeSymbol(&bitC, ip[n- 1], CTable);
    +	n = srcSize & ~3; /* join to mod 4 */
    +	switch (srcSize & 3) {
    +	case 3: HUF_encodeSymbol(&bitC, ip[n + 2], CTable); HUF_FLUSHBITS_2(&bitC);
    +	case 2: HUF_encodeSymbol(&bitC, ip[n + 1], CTable); HUF_FLUSHBITS_1(&bitC);
    +	case 1: HUF_encodeSymbol(&bitC, ip[n + 0], CTable); HUF_FLUSHBITS(&bitC);
    +	case 0:
    +	default:;
    +	}
    +
    +	for (; n > 0; n -= 4) { /* note : n&3==0 at this stage */
    +		HUF_encodeSymbol(&bitC, ip[n - 1], CTable);
     		HUF_FLUSHBITS_1(&bitC);
    -		HUF_encodeSymbol(&bitC, ip[n- 2], CTable);
    +		HUF_encodeSymbol(&bitC, ip[n - 2], CTable);
     		HUF_FLUSHBITS_2(&bitC);
    -		HUF_encodeSymbol(&bitC, ip[n- 3], CTable);
    +		HUF_encodeSymbol(&bitC, ip[n - 3], CTable);
     		HUF_FLUSHBITS_1(&bitC);
    -		HUF_encodeSymbol(&bitC, ip[n- 4], CTable);
    +		HUF_encodeSymbol(&bitC, ip[n - 4], CTable);
     		HUF_FLUSHBITS(&bitC);
     	}
     
     	return BIT_closeCStream(&bitC);
     }
     
    -
    -size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
    +size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable)
     {
    -	size_t const segmentSize = (srcSize+3)/4;   /* first 3 segments */
    -	const BYTE* ip = (const BYTE*) src;
    -	const BYTE* const iend = ip + srcSize;
    -	BYTE* const ostart = (BYTE*) dst;
    -	BYTE* const oend = ostart + dstSize;
    -	BYTE* op = ostart;
    +	size_t const segmentSize = (srcSize + 3) / 4; /* first 3 segments */
    +	const BYTE *ip = (const BYTE *)src;
    +	const BYTE *const iend = ip + srcSize;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *const oend = ostart + dstSize;
    +	BYTE *op = ostart;
     
    -	if (dstSize < 6 + 1 + 1 + 1 + 8) return 0;   /* minimum space to compress successfully */
    -	if (srcSize < 12) return 0;   /* no saving possible : too small input */
    -	op += 6;   /* jumpTable */
    +	if (dstSize < 6 + 1 + 1 + 1 + 8)
    +		return 0; /* minimum space to compress successfully */
    +	if (srcSize < 12)
    +		return 0; /* no saving possible : too small input */
    +	op += 6;	  /* jumpTable */
     
    -	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    -		if (cSize==0) return 0;
    +	{
    +		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
    +		if (cSize == 0)
    +			return 0;
     		ZSTD_writeLE16(ostart, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    -		if (cSize==0) return 0;
    -		ZSTD_writeLE16(ostart+2, (U16)cSize);
    +	{
    +		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
    +		if (cSize == 0)
    +			return 0;
    +		ZSTD_writeLE16(ostart + 2, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
    -		if (cSize==0) return 0;
    -		ZSTD_writeLE16(ostart+4, (U16)cSize);
    +	{
    +		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, segmentSize, CTable));
    +		if (cSize == 0)
    +			return 0;
    +		ZSTD_writeLE16(ostart + 4, (U16)cSize);
     		op += cSize;
     	}
     
     	ip += segmentSize;
    -	{	CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
    -		if (cSize==0) return 0;
    +	{
    +		CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend - op, ip, iend - ip, CTable));
    +		if (cSize == 0)
    +			return 0;
     		op += cSize;
     	}
     
    -	return op-ostart;
    +	return op - ostart;
     }
     
    -
    -static size_t HUF_compressCTable_internal(
    -				BYTE* const ostart, BYTE* op, BYTE* const oend,
    -				const void* src, size_t srcSize,
    -				unsigned singleStream, const HUF_CElt* CTable)
    +static size_t HUF_compressCTable_internal(BYTE *const ostart, BYTE *op, BYTE *const oend, const void *src, size_t srcSize, unsigned singleStream,
    +					  const HUF_CElt *CTable)
     {
    -	size_t const cSize = singleStream ?
    -						 HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) :
    -						 HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
    -	if (HUF_isError(cSize)) { return cSize; }
    -	if (cSize==0) { return 0; }   /* uncompressible */
    +	size_t const cSize =
    +	    singleStream ? HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) : HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
    +	if (HUF_isError(cSize)) {
    +		return cSize;
    +	}
    +	if (cSize == 0) {
    +		return 0;
    +	} /* uncompressible */
     	op += cSize;
     	/* check compressibility */
    -	if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
    -	return op-ostart;
    +	if ((size_t)(op - ostart) >= srcSize - 1) {
    +		return 0;
    +	}
    +	return op - ostart;
     }
     
    -
     /* `workSpace` must a table of at least 1024 unsigned */
    -static size_t HUF_compress_internal (
    -				void* dst, size_t dstSize,
    -				const void* src, size_t srcSize,
    -				unsigned maxSymbolValue, unsigned huffLog,
    -				unsigned singleStream,
    -				void* workSpace, size_t wkspSize,
    -				HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat)
    +static size_t HUF_compress_internal(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog,
    +				    unsigned singleStream, void *workSpace, size_t wkspSize, HUF_CElt *oldHufTable, HUF_repeat *repeat, int preferRepeat)
     {
    -	BYTE* const ostart = (BYTE*)dst;
    -	BYTE* const oend = ostart + dstSize;
    -	BYTE* op = ostart;
    +	BYTE *const ostart = (BYTE *)dst;
    +	BYTE *const oend = ostart + dstSize;
    +	BYTE *op = ostart;
     
    -	U32* count;
    +	U32 *count;
     	size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1);
    -	HUF_CElt* CTable;
    +	HUF_CElt *CTable;
     	size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1);
     
     	/* checks & inits */
    -	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
    -	if (!srcSize) return 0;  /* Uncompressed (note : 1 means rle, so first byte must be correct) */
    -	if (!dstSize) return 0;  /* cannot fit within dst budget */
    -	if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* curr block size limit */
    -	if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    -	if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
    -	if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
    +	if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize)
    +		return ERROR(GENERIC);
    +	if (!srcSize)
    +		return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
    +	if (!dstSize)
    +		return 0; /* cannot fit within dst budget */
    +	if (srcSize > HUF_BLOCKSIZE_MAX)
    +		return ERROR(srcSize_wrong); /* curr block size limit */
    +	if (huffLog > HUF_TABLELOG_MAX)
    +		return ERROR(tableLog_tooLarge);
    +	if (!maxSymbolValue)
    +		maxSymbolValue = HUF_SYMBOLVALUE_MAX;
    +	if (!huffLog)
    +		huffLog = HUF_TABLELOG_DEFAULT;
     
    -	count = (U32*)workSpace;
    -	workSpace = (BYTE*)workSpace + countSize;
    +	count = (U32 *)workSpace;
    +	workSpace = (BYTE *)workSpace + countSize;
     	wkspSize -= countSize;
    -	CTable = (HUF_CElt*)workSpace;
    -	workSpace = (BYTE*)workSpace + CTableSize;
    +	CTable = (HUF_CElt *)workSpace;
    +	workSpace = (BYTE *)workSpace + CTableSize;
     	wkspSize -= CTableSize;
     
     	/* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */
    @@ -572,9 +651,14 @@ static size_t HUF_compress_internal (
     	}
     
     	/* Scan input and build symbol stats */
    -	{	CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
    -		if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */
    -		if (largest <= (srcSize >> 7)+1) return 0;   /* Fast heuristic : not compressible enough */
    +	{
    +		CHECK_V_F(largest, FSE_count_wksp(count, &maxSymbolValue, (const BYTE *)src, srcSize, (U32 *)workSpace));
    +		if (largest == srcSize) {
    +			*ostart = ((const BYTE *)src)[0];
    +			return 1;
    +		} /* single symbol, rle */
    +		if (largest <= (srcSize >> 7) + 1)
    +			return 0; /* Fast heuristic : not compressible enough */
     	}
     
     	/* Check validity of previous table */
    @@ -588,14 +672,16 @@ static size_t HUF_compress_internal (
     
     	/* Build Huffman Tree */
     	huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
    -	{	CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
    +	{
    +		CHECK_V_F(maxBits, HUF_buildCTable_wksp(CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize));
     		huffLog = (U32)maxBits;
     		/* Zero the unused symbols so we can check it for validity */
     		memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
     	}
     
     	/* Write table description header */
    -	{	CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
    +	{
    +		CHECK_V_F(hSize, HUF_writeCTable(op, dstSize, CTable, maxSymbolValue, huffLog));
     		/* Check if using the previous table will be beneficial */
     		if (repeat && *repeat != HUF_repeat_none) {
     			size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
    @@ -605,45 +691,42 @@ static size_t HUF_compress_internal (
     			}
     		}
     		/* Use the new table */
    -		if (hSize + 12ul >= srcSize) { return 0; }
    +		if (hSize + 12ul >= srcSize) {
    +			return 0;
    +		}
     		op += hSize;
    -		if (repeat) { *repeat = HUF_repeat_none; }
    -		if (oldHufTable) { memcpy(oldHufTable, CTable, CTableSize); } /* Save the new table */
    +		if (repeat) {
    +			*repeat = HUF_repeat_none;
    +		}
    +		if (oldHufTable) {
    +			memcpy(oldHufTable, CTable, CTableSize);
    +		} /* Save the new table */
     	}
     	return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable);
     }
     
    -
    -size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
    -					  const void* src, size_t srcSize,
    -					  unsigned maxSymbolValue, unsigned huffLog,
    -					  void* workSpace, size_t wkspSize)
    +size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
    +			   size_t wkspSize)
     {
     	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0);
     }
     
    -size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
    -					  const void* src, size_t srcSize,
    -					  unsigned maxSymbolValue, unsigned huffLog,
    -					  void* workSpace, size_t wkspSize,
    -					  HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
    +size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
    +			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat)
     {
    -	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
    +	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat,
    +				     preferRepeat);
     }
     
    -size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
    -					  const void* src, size_t srcSize,
    -					  unsigned maxSymbolValue, unsigned huffLog,
    -					  void* workSpace, size_t wkspSize)
    +size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
    +			   size_t wkspSize)
     {
     	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0);
     }
     
    -size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
    -					  const void* src, size_t srcSize,
    -					  unsigned maxSymbolValue, unsigned huffLog,
    -					  void* workSpace, size_t wkspSize,
    -					  HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
    +size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned huffLog, void *workSpace,
    +			     size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, int preferRepeat)
     {
    -	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
    +	return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat,
    +				     preferRepeat);
     }
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index 81f90ff0f..5c38aa30d 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -42,93 +42,107 @@
     ****************************************************************/
     #define FORCE_INLINE static __always_inline
     
    -
     /* **************************************************************
     *  Dependencies
     ****************************************************************/
    -#include 
    -#include      /* memcpy, memset */
    -#include "bitstream.h"  /* BIT_* */
    -#include "fse.h"        /* header compression */
    +#include "bitstream.h" /* BIT_* */
    +#include "fse.h"       /* header compression */
     #include "huf.h"
    -
    +#include 
    +#include  /* memcpy, memset */
     
     /* **************************************************************
     *  Error Management
     ****************************************************************/
    -#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    -
    +#define HUF_STATIC_ASSERT(c)                                   \
    +	{                                                      \
    +		enum { HUF_static_assert = 1 / (int)(!!(c)) }; \
    +	} /* use only *after* variable declarations */
     
     /*-***************************/
     /*  generic DTableDesc       */
     /*-***************************/
     
    -typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
    +typedef struct {
    +	BYTE maxTableLog;
    +	BYTE tableType;
    +	BYTE tableLog;
    +	BYTE reserved;
    +} DTableDesc;
     
    -static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
    +static DTableDesc HUF_getDTableDesc(const HUF_DTable *table)
     {
     	DTableDesc dtd;
     	memcpy(&dtd, table, sizeof(dtd));
     	return dtd;
     }
     
    -
     /*-***************************/
     /*  single-symbol decoding   */
     /*-***************************/
     
    -typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2;   /* single-symbol decoding */
    +typedef struct {
    +	BYTE byte;
    +	BYTE nbBits;
    +} HUF_DEltX2; /* single-symbol decoding */
     
    -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
    +size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize)
     {
     	BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
    -	U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */
    +	U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
     	U32 tableLog = 0;
     	U32 nbSymbols = 0;
     	size_t iSize;
    -	void* const dtPtr = DTable + 1;
    -	HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
    +	void *const dtPtr = DTable + 1;
    +	HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr;
     
     	HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
    -	/* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
    +	/* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
     
     	iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
    -	if (HUF_isError(iSize)) return iSize;
    +	if (HUF_isError(iSize))
    +		return iSize;
     
     	/* Table header */
    -	{	DTableDesc dtd = HUF_getDTableDesc(DTable);
    -		if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */
    +	{
    +		DTableDesc dtd = HUF_getDTableDesc(DTable);
    +		if (tableLog > (U32)(dtd.maxTableLog + 1))
    +			return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
     		dtd.tableType = 0;
     		dtd.tableLog = (BYTE)tableLog;
     		memcpy(DTable, &dtd, sizeof(dtd));
     	}
     
     	/* Calculate starting value for each rank */
    -	{	U32 n, nextRankStart = 0;
    -		for (n=1; n> 1;
     			U32 u;
     			HUF_DEltX2 D;
    -			D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
    +			D.byte = (BYTE)n;
    +			D.nbBits = (BYTE)(tableLog + 1 - w);
     			for (u = rankVal[w]; u < rankVal[w] + length; u++)
     				dt[u] = D;
     			rankVal[w] += length;
    -	}   }
    +		}
    +	}
     
     	return iSize;
     }
     
    -
    -static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
    +static BYTE HUF_decodeSymbolX2(BIT_DStream_t *Dstream, const HUF_DEltX2 *dt, const U32 dtLog)
     {
     	size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
     	BYTE const c = dt[val].byte;
    @@ -136,23 +150,22 @@ static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, con
     	return c;
     }
     
    -#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
    -	*ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
    +#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
     
    -#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
    -	if (ZSTD_64bits() || (HUF_TABLELOG_MAX<=12)) \
    -		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
    +#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr)         \
    +	if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
    +	HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     
     #define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
    -	if (ZSTD_64bits()) \
    -		HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
    +	if (ZSTD_64bits())                     \
    +	HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     
    -FORCE_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)
    +FORCE_INLINE size_t HUF_decodeStreamX2(BYTE *p, BIT_DStream_t *const bitDPtr, BYTE *const pEnd, const HUF_DEltX2 *const dt, const U32 dtLog)
     {
    -	BYTE* const pStart = p;
    +	BYTE *const pStart = p;
     
     	/* up to 4 symbols at a time */
    -	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4)) {
    +	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd - 4)) {
     		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
     		HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
     		HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
    @@ -167,69 +180,69 @@ FORCE_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BY
     	while (p < pEnd)
     		HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
     
    -	return pEnd-pStart;
    +	return pEnd - pStart;
     }
     
    -static size_t HUF_decompress1X2_usingDTable_internal(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +static size_t HUF_decompress1X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
    -	BYTE* op = (BYTE*)dst;
    -	BYTE* const oend = op + dstSize;
    -	const void* dtPtr = DTable + 1;
    -	const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
    +	BYTE *op = (BYTE *)dst;
    +	BYTE *const oend = op + dstSize;
    +	const void *dtPtr = DTable + 1;
    +	const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;
     	BIT_DStream_t bitD;
     	DTableDesc const dtd = HUF_getDTableDesc(DTable);
     	U32 const dtLog = dtd.tableLog;
     
    -	{ size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    -	  if (HUF_isError(errorCode)) return errorCode; }
    +	{
    +		size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    +		if (HUF_isError(errorCode))
    +			return errorCode;
    +	}
     
     	HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);
     
     	/* check */
    -	if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
    +	if (!BIT_endOfDStream(&bitD))
    +		return ERROR(corruption_detected);
     
     	return dstSize;
     }
     
    -size_t HUF_decompress1X2_usingDTable(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +size_t HUF_decompress1X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc dtd = HUF_getDTableDesc(DTable);
    -	if (dtd.tableType != 0) return ERROR(GENERIC);
    +	if (dtd.tableType != 0)
    +		return ERROR(GENERIC);
     	return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     }
     
    -size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress1X2_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
    -	const BYTE* ip = (const BYTE*) cSrc;
    +	const BYTE *ip = (const BYTE *)cSrc;
     
    -	size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize);
    -	if (HUF_isError(hSize)) return hSize;
    -	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    -	ip += hSize; cSrcSize -= hSize;
    +	size_t const hSize = HUF_readDTableX2(DCtx, cSrc, cSrcSize);
    +	if (HUF_isError(hSize))
    +		return hSize;
    +	if (hSize >= cSrcSize)
    +		return ERROR(srcSize_wrong);
    +	ip += hSize;
    +	cSrcSize -= hSize;
     
    -	return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
    +	return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
     }
     
    -
    -static size_t HUF_decompress4X2_usingDTable_internal(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +static size_t HUF_decompress4X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	/* Check */
    -	if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
    +	if (cSrcSize < 10)
    +		return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
     
    -	{	const BYTE* const istart = (const BYTE*) cSrc;
    -		BYTE* const ostart = (BYTE*) dst;
    -		BYTE* const oend = ostart + dstSize;
    -		const void* const dtPtr = DTable + 1;
    -		const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
    +	{
    +		const BYTE *const istart = (const BYTE *)cSrc;
    +		BYTE *const ostart = (BYTE *)dst;
    +		BYTE *const oend = ostart + dstSize;
    +		const void *const dtPtr = DTable + 1;
    +		const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;
     
     		/* Init */
     		BIT_DStream_t bitD1;
    @@ -237,38 +250,51 @@ static size_t HUF_decompress4X2_usingDTable_internal(
     		BIT_DStream_t bitD3;
     		BIT_DStream_t bitD4;
     		size_t const length1 = ZSTD_readLE16(istart);
    -		size_t const length2 = ZSTD_readLE16(istart+2);
    -		size_t const length3 = ZSTD_readLE16(istart+4);
    +		size_t const length2 = ZSTD_readLE16(istart + 2);
    +		size_t const length3 = ZSTD_readLE16(istart + 4);
     		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
    -		const BYTE* const istart1 = istart + 6;  /* jumpTable */
    -		const BYTE* const istart2 = istart1 + length1;
    -		const BYTE* const istart3 = istart2 + length2;
    -		const BYTE* const istart4 = istart3 + length3;
    -		const size_t segmentSize = (dstSize+3) / 4;
    -		BYTE* const opStart2 = ostart + segmentSize;
    -		BYTE* const opStart3 = opStart2 + segmentSize;
    -		BYTE* const opStart4 = opStart3 + segmentSize;
    -		BYTE* op1 = ostart;
    -		BYTE* op2 = opStart2;
    -		BYTE* op3 = opStart3;
    -		BYTE* op4 = opStart4;
    +		const BYTE *const istart1 = istart + 6; /* jumpTable */
    +		const BYTE *const istart2 = istart1 + length1;
    +		const BYTE *const istart3 = istart2 + length2;
    +		const BYTE *const istart4 = istart3 + length3;
    +		const size_t segmentSize = (dstSize + 3) / 4;
    +		BYTE *const opStart2 = ostart + segmentSize;
    +		BYTE *const opStart3 = opStart2 + segmentSize;
    +		BYTE *const opStart4 = opStart3 + segmentSize;
    +		BYTE *op1 = ostart;
    +		BYTE *op2 = opStart2;
    +		BYTE *op3 = opStart3;
    +		BYTE *op4 = opStart4;
     		U32 endSignal;
     		DTableDesc const dtd = HUF_getDTableDesc(DTable);
     		U32 const dtLog = dtd.tableLog;
     
    -		if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
    -		{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    +		if (length4 > cSrcSize)
    +			return ERROR(corruption_detected); /* overflow */
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
     
     		/* 16-32 symbols per loop (4-8 symbols per stream) */
     		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    -		for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) {
    +		for (; (endSignal == BIT_DStream_unfinished) && (op4 < (oend - 7));) {
     			HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
     			HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
     			HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
    @@ -289,63 +315,71 @@ static size_t HUF_decompress4X2_usingDTable_internal(
     		}
     
     		/* check corruption */
    -		if (op1 > opStart2) return ERROR(corruption_detected);
    -		if (op2 > opStart3) return ERROR(corruption_detected);
    -		if (op3 > opStart4) return ERROR(corruption_detected);
    +		if (op1 > opStart2)
    +			return ERROR(corruption_detected);
    +		if (op2 > opStart3)
    +			return ERROR(corruption_detected);
    +		if (op3 > opStart4)
    +			return ERROR(corruption_detected);
     		/* note : op4 supposed already verified within main loop */
     
     		/* finish bitStreams one by one */
     		HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
     		HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
     		HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
    -		HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
    +		HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
     
     		/* check */
     		endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
    -		if (!endSignal) return ERROR(corruption_detected);
    +		if (!endSignal)
    +			return ERROR(corruption_detected);
     
     		/* decoded size */
     		return dstSize;
     	}
     }
     
    -
    -size_t HUF_decompress4X2_usingDTable(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +size_t HUF_decompress4X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc dtd = HUF_getDTableDesc(DTable);
    -	if (dtd.tableType != 0) return ERROR(GENERIC);
    +	if (dtd.tableType != 0)
    +		return ERROR(GENERIC);
     	return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     }
     
    -
    -size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
    -	const BYTE* ip = (const BYTE*) cSrc;
    +	const BYTE *ip = (const BYTE *)cSrc;
     
    -	size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize);
    -	if (HUF_isError(hSize)) return hSize;
    -	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    -	ip += hSize; cSrcSize -= hSize;
    +	size_t const hSize = HUF_readDTableX2(dctx, cSrc, cSrcSize);
    +	if (HUF_isError(hSize))
    +		return hSize;
    +	if (hSize >= cSrcSize)
    +		return ERROR(srcSize_wrong);
    +	ip += hSize;
    +	cSrcSize -= hSize;
     
    -	return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
    +	return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
     }
     
     /* *************************/
     /* double-symbols decoding */
     /* *************************/
    -typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4;  /* double-symbols decoding */
    +typedef struct {
    +	U16 sequence;
    +	BYTE nbBits;
    +	BYTE length;
    +} HUF_DEltX4; /* double-symbols decoding */
     
    -typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
    +typedef struct {
    +	BYTE symbol;
    +	BYTE weight;
    +} sortedSymbol_t;
     
     /* HUF_fillDTableX4Level2() :
      * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
    -static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
    -						   const U32* rankValOrigin, const int minWeight,
    -						   const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
    -						   U32 nbBitsBaseline, U16 baseSeq)
    +static void HUF_fillDTableX4Level2(HUF_DEltX4 *DTable, U32 sizeLog, const U32 consumed, const U32 *rankValOrigin, const int minWeight,
    +				   const sortedSymbol_t *sortedSymbols, const U32 sortedListSize, U32 nbBitsBaseline, U16 baseSeq)
     {
     	HUF_DEltX4 DElt;
     	U32 rankVal[HUF_TABLELOG_MAX + 1];
    @@ -354,21 +388,23 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co
     	memcpy(rankVal, rankValOrigin, sizeof(rankVal));
     
     	/* fill skipped values */
    -	if (minWeight>1) {
    +	if (minWeight > 1) {
     		U32 i, skipSize = rankVal[minWeight];
     		ZSTD_writeLE16(&(DElt.sequence), baseSeq);
    -		DElt.nbBits   = (BYTE)(consumed);
    -		DElt.length   = 1;
    +		DElt.nbBits = (BYTE)(consumed);
    +		DElt.length = 1;
     		for (i = 0; i < skipSize; i++)
     			DTable[i] = DElt;
     	}
     
     	/* fill DTable */
    -	{	U32 s; for (s=0; s= 1 */
    +			do {
    +				DTable[i++] = DElt;
    +			} while (i < end); /* since length >= 1 */
     
     			rankVal[weight] += length;
    -	}   }
    +		}
    +	}
     }
     
     typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
     
    -static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
    -						   const sortedSymbol_t* sortedList, const U32 sortedListSize,
    -						   const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
    -						   const U32 nbBitsBaseline)
    +static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart,
    +			     rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline)
     {
     	U32 rankVal[HUF_TABLELOG_MAX + 1];
    -	const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
    -	const U32 minBits  = nbBitsBaseline - maxWeight;
    +	const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
    +	const U32 minBits = nbBitsBaseline - maxWeight;
     	U32 s;
     
     	memcpy(rankVal, rankValOrigin, sizeof(rankVal));
     
     	/* fill DTable */
    -	for (s=0; s= minBits) {   /* enough room for a second symbol */
    +		if (targetLog - nbBits >= minBits) { /* enough room for a second symbol */
     			U32 sortedRank;
     			int minWeight = nbBits + scaleLog;
    -			if (minWeight < 1) minWeight = 1;
    +			if (minWeight < 1)
    +				minWeight = 1;
     			sortedRank = rankStart[minWeight];
    -			HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
    -						   rankValOrigin[nbBits], minWeight,
    -						   sortedList+sortedRank, sortedListSize-sortedRank,
    -						   nbBitsBaseline, symbol);
    +			HUF_fillDTableX4Level2(DTable + start, targetLog - nbBits, nbBits, rankValOrigin[nbBits], minWeight, sortedList + sortedRank,
    +					       sortedListSize - sortedRank, nbBitsBaseline, symbol);
     		} else {
     			HUF_DEltX4 DElt;
     			ZSTD_writeLE16(&(DElt.sequence), symbol);
     			DElt.nbBits = (BYTE)(nbBits);
     			DElt.length = 1;
    -			{	U32 const end = start + length;
    +			{
    +				U32 const end = start + length;
     				U32 u;
    -				for (u = start; u < end; u++) DTable[u] = DElt;
    -		}   }
    +				for (u = start; u < end; u++)
    +					DTable[u] = DElt;
    +			}
    +		}
     		rankVal[weight] += length;
     	}
     }
     
    -size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
    +size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize)
     {
     	BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
     	sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
    -	U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 };
    -	U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 };
    -	U32* const rankStart = rankStart0+1;
    +	U32 rankStats[HUF_TABLELOG_MAX + 1] = {0};
    +	U32 rankStart0[HUF_TABLELOG_MAX + 2] = {0};
    +	U32 *const rankStart = rankStart0 + 1;
     	rankVal_t rankVal;
     	U32 tableLog, maxW, sizeOfSort, nbSymbols;
     	DTableDesc dtd = HUF_getDTableDesc(DTable);
     	U32 const maxTableLog = dtd.maxTableLog;
     	size_t iSize;
    -	void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
    -	HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
    +	void *dtPtr = DTable + 1; /* force compiler to avoid strict-aliasing */
    +	HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr;
     
    -	HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */
    -	if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
    -	/* memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */
    +	HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
    +	if (maxTableLog > HUF_TABLELOG_MAX)
    +		return ERROR(tableLog_tooLarge);
    +	/* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
     
     	iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
    -	if (HUF_isError(iSize)) return iSize;
    +	if (HUF_isError(iSize))
    +		return iSize;
     
     	/* check result */
    -	if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
    +	if (tableLog > maxTableLog)
    +		return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
     
     	/* find maxWeight */
    -	for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
    +	for (maxW = tableLog; rankStats[maxW] == 0; maxW--) {
    +	} /* necessarily finds a solution before 0 */
     
     	/* Get start index of each weight */
    -	{	U32 w, nextRankStart = 0;
    -		for (w=1; w> consumed;
    -	}   }   }   }
    +				}
    +			}
    +		}
    +	}
     
    -	HUF_fillDTableX4(dt, maxTableLog,
    -				   sortedSymbol, sizeOfSort,
    -				   rankStart0, rankVal, maxW,
    -				   tableLog+1);
    +	HUF_fillDTableX4(dt, maxTableLog, sortedSymbol, sizeOfSort, rankStart0, rankVal, maxW, tableLog + 1);
     
     	dtd.tableLog = (BYTE)maxTableLog;
     	dtd.tableType = 1;
    @@ -506,47 +555,48 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
     	return iSize;
     }
     
    -
    -static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
    +static U32 HUF_decodeSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
     {
    -	size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
    -	memcpy(op, dt+val, 2);
    +	size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
    +	memcpy(op, dt + val, 2);
     	BIT_skipBits(DStream, dt[val].nbBits);
     	return dt[val].length;
     }
     
    -static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
    +static U32 HUF_decodeLastSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
     {
    -	size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
    -	memcpy(op, dt+val, 1);
    -	if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
    +	size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
    +	memcpy(op, dt + val, 1);
    +	if (dt[val].length == 1)
    +		BIT_skipBits(DStream, dt[val].nbBits);
     	else {
    -		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
    +		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) {
     			BIT_skipBits(DStream, dt[val].nbBits);
    -			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
    -				DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);   /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    -	}   }
    +			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8))
    +				DStream->bitsConsumed =
    +				    (sizeof(DStream->bitContainer) *
    +				     8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    +		}
    +	}
     	return 1;
     }
     
    +#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
    -#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
    +#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr)         \
    +	if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
     	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
    -#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
    -	if (ZSTD_64bits() || (HUF_TABLELOG_MAX<=12)) \
    -		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
    -
     #define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
    -	if (ZSTD_64bits()) \
    -		ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
    +	if (ZSTD_64bits())                     \
    +	ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     
    -FORCE_INLINE size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)
    +FORCE_INLINE size_t HUF_decodeStreamX4(BYTE *p, BIT_DStream_t *bitDPtr, BYTE *const pEnd, const HUF_DEltX4 *const dt, const U32 dtLog)
     {
    -	BYTE* const pStart = p;
    +	BYTE *const pStart = p;
     
     	/* up to 8 symbols at a time */
    -	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
    +	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd - (sizeof(bitDPtr->bitContainer) - 1))) {
     		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
     		HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
     		HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
    @@ -554,81 +604,81 @@ FORCE_INLINE size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* co
     	}
     
     	/* closer to end : up to 2 symbols at a time */
    -	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
    +	while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd - 2))
     		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
     
    -	while (p <= pEnd-2)
    -		HUF_DECODE_SYMBOLX4_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
    +	while (p <= pEnd - 2)
    +		HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
     
     	if (p < pEnd)
     		p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
     
    -	return p-pStart;
    +	return p - pStart;
     }
     
    -
    -static size_t HUF_decompress1X4_usingDTable_internal(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +static size_t HUF_decompress1X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	BIT_DStream_t bitD;
     
     	/* Init */
    -	{	size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    -		if (HUF_isError(errorCode)) return errorCode;
    +	{
    +		size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
    +		if (HUF_isError(errorCode))
    +			return errorCode;
     	}
     
     	/* decode */
    -	{	BYTE* const ostart = (BYTE*) dst;
    -		BYTE* const oend = ostart + dstSize;
    -		const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
    -		const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
    +	{
    +		BYTE *const ostart = (BYTE *)dst;
    +		BYTE *const oend = ostart + dstSize;
    +		const void *const dtPtr = DTable + 1; /* force compiler to not use strict-aliasing */
    +		const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;
     		DTableDesc const dtd = HUF_getDTableDesc(DTable);
     		HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
     	}
     
     	/* check */
    -	if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
    +	if (!BIT_endOfDStream(&bitD))
    +		return ERROR(corruption_detected);
     
     	/* decoded size */
     	return dstSize;
     }
     
    -size_t HUF_decompress1X4_usingDTable(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +size_t HUF_decompress1X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc dtd = HUF_getDTableDesc(DTable);
    -	if (dtd.tableType != 1) return ERROR(GENERIC);
    +	if (dtd.tableType != 1)
    +		return ERROR(GENERIC);
     	return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     }
     
    -size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress1X4_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
    -	const BYTE* ip = (const BYTE*) cSrc;
    +	const BYTE *ip = (const BYTE *)cSrc;
     
    -	size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize);
    -	if (HUF_isError(hSize)) return hSize;
    -	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    -	ip += hSize; cSrcSize -= hSize;
    +	size_t const hSize = HUF_readDTableX4(DCtx, cSrc, cSrcSize);
    +	if (HUF_isError(hSize))
    +		return hSize;
    +	if (hSize >= cSrcSize)
    +		return ERROR(srcSize_wrong);
    +	ip += hSize;
    +	cSrcSize -= hSize;
     
    -	return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
    +	return HUF_decompress1X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
     }
     
    -static size_t HUF_decompress4X4_usingDTable_internal(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +static size_t HUF_decompress4X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
    -	if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
    +	if (cSrcSize < 10)
    +		return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
     
    -	{	const BYTE* const istart = (const BYTE*) cSrc;
    -		BYTE* const ostart = (BYTE*) dst;
    -		BYTE* const oend = ostart + dstSize;
    -		const void* const dtPtr = DTable+1;
    -		const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
    +	{
    +		const BYTE *const istart = (const BYTE *)cSrc;
    +		BYTE *const ostart = (BYTE *)dst;
    +		BYTE *const oend = ostart + dstSize;
    +		const void *const dtPtr = DTable + 1;
    +		const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;
     
     		/* Init */
     		BIT_DStream_t bitD1;
    @@ -636,38 +686,51 @@ static size_t HUF_decompress4X4_usingDTable_internal(
     		BIT_DStream_t bitD3;
     		BIT_DStream_t bitD4;
     		size_t const length1 = ZSTD_readLE16(istart);
    -		size_t const length2 = ZSTD_readLE16(istart+2);
    -		size_t const length3 = ZSTD_readLE16(istart+4);
    +		size_t const length2 = ZSTD_readLE16(istart + 2);
    +		size_t const length3 = ZSTD_readLE16(istart + 4);
     		size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
    -		const BYTE* const istart1 = istart + 6;  /* jumpTable */
    -		const BYTE* const istart2 = istart1 + length1;
    -		const BYTE* const istart3 = istart2 + length2;
    -		const BYTE* const istart4 = istart3 + length3;
    -		size_t const segmentSize = (dstSize+3) / 4;
    -		BYTE* const opStart2 = ostart + segmentSize;
    -		BYTE* const opStart3 = opStart2 + segmentSize;
    -		BYTE* const opStart4 = opStart3 + segmentSize;
    -		BYTE* op1 = ostart;
    -		BYTE* op2 = opStart2;
    -		BYTE* op3 = opStart3;
    -		BYTE* op4 = opStart4;
    +		const BYTE *const istart1 = istart + 6; /* jumpTable */
    +		const BYTE *const istart2 = istart1 + length1;
    +		const BYTE *const istart3 = istart2 + length2;
    +		const BYTE *const istart4 = istart3 + length3;
    +		size_t const segmentSize = (dstSize + 3) / 4;
    +		BYTE *const opStart2 = ostart + segmentSize;
    +		BYTE *const opStart3 = opStart2 + segmentSize;
    +		BYTE *const opStart4 = opStart3 + segmentSize;
    +		BYTE *op1 = ostart;
    +		BYTE *op2 = opStart2;
    +		BYTE *op3 = opStart3;
    +		BYTE *op4 = opStart4;
     		U32 endSignal;
     		DTableDesc const dtd = HUF_getDTableDesc(DTable);
     		U32 const dtLog = dtd.tableLog;
     
    -		if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
    -		{ size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    -		{ size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    -		  if (HUF_isError(errorCode)) return errorCode; }
    +		if (length4 > cSrcSize)
    +			return ERROR(corruption_detected); /* overflow */
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
    +		{
    +			size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
    +			if (HUF_isError(errorCode))
    +				return errorCode;
    +		}
     
     		/* 16-32 symbols per loop (4-8 symbols per stream) */
     		endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
    -		for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
    +		for (; (endSignal == BIT_DStream_unfinished) & (op4 < (oend - (sizeof(bitD4.bitContainer) - 1)));) {
     			HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
     			HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
     			HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
    @@ -689,94 +752,95 @@ static size_t HUF_decompress4X4_usingDTable_internal(
     		}
     
     		/* check corruption */
    -		if (op1 > opStart2) return ERROR(corruption_detected);
    -		if (op2 > opStart3) return ERROR(corruption_detected);
    -		if (op3 > opStart4) return ERROR(corruption_detected);
    +		if (op1 > opStart2)
    +			return ERROR(corruption_detected);
    +		if (op2 > opStart3)
    +			return ERROR(corruption_detected);
    +		if (op3 > opStart4)
    +			return ERROR(corruption_detected);
     		/* note : op4 already verified within main loop */
     
     		/* finish bitStreams one by one */
     		HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
     		HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
     		HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
    -		HUF_decodeStreamX4(op4, &bitD4, oend,     dt, dtLog);
    +		HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
     
     		/* check */
    -		{ U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
    -		  if (!endCheck) return ERROR(corruption_detected); }
    +		{
    +			U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
    +			if (!endCheck)
    +				return ERROR(corruption_detected);
    +		}
     
     		/* decoded size */
     		return dstSize;
     	}
     }
     
    -
    -size_t HUF_decompress4X4_usingDTable(
    -		  void* dst,  size_t dstSize,
    -	const void* cSrc, size_t cSrcSize,
    -	const HUF_DTable* DTable)
    +size_t HUF_decompress4X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc dtd = HUF_getDTableDesc(DTable);
    -	if (dtd.tableType != 1) return ERROR(GENERIC);
    +	if (dtd.tableType != 1)
    +		return ERROR(GENERIC);
     	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     }
     
    -
    -size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
    -	const BYTE* ip = (const BYTE*) cSrc;
    +	const BYTE *ip = (const BYTE *)cSrc;
     
    -	size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize);
    -	if (HUF_isError(hSize)) return hSize;
    -	if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
    -	ip += hSize; cSrcSize -= hSize;
    +	size_t hSize = HUF_readDTableX4(dctx, cSrc, cSrcSize);
    +	if (HUF_isError(hSize))
    +		return hSize;
    +	if (hSize >= cSrcSize)
    +		return ERROR(srcSize_wrong);
    +	ip += hSize;
    +	cSrcSize -= hSize;
     
     	return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
     }
     
    -
     /* ********************************/
     /* Generic decompression selector */
     /* ********************************/
     
    -size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
    -									const void* cSrc, size_t cSrcSize,
    -									const HUF_DTable* DTable)
    +size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc const dtd = HUF_getDTableDesc(DTable);
    -	return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
    -						   HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
    +	return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
    +			     : HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
     }
     
    -size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
    -									const void* cSrc, size_t cSrcSize,
    -									const HUF_DTable* DTable)
    +size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
     {
     	DTableDesc const dtd = HUF_getDTableDesc(DTable);
    -	return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
    -						   HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
    +	return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
    +			     : HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
     }
     
    -
    -typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
    -static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
    -{
    -	/* single, double, quad */
    -	{{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */
    -	{{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */
    -	{{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */
    -	{{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */
    -	{{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */
    -	{{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */
    -	{{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */
    -	{{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */
    -	{{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */
    -	{{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */
    -	{{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
    -	{{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
    -	{{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
    -	{{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */
    -	{{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */
    -	{{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */
    +typedef struct {
    +	U32 tableTime;
    +	U32 decode256Time;
    +} algo_time_t;
    +static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = {
    +    /* single, double, quad */
    +    {{0, 0}, {1, 1}, {2, 2}},		     /* Q==0 : impossible */
    +    {{0, 0}, {1, 1}, {2, 2}},		     /* Q==1 : impossible */
    +    {{38, 130}, {1313, 74}, {2151, 38}},     /* Q == 2 : 12-18% */
    +    {{448, 128}, {1353, 74}, {2238, 41}},    /* Q == 3 : 18-25% */
    +    {{556, 128}, {1353, 74}, {2238, 47}},    /* Q == 4 : 25-32% */
    +    {{714, 128}, {1418, 74}, {2436, 53}},    /* Q == 5 : 32-38% */
    +    {{883, 128}, {1437, 74}, {2464, 61}},    /* Q == 6 : 38-44% */
    +    {{897, 128}, {1515, 75}, {2622, 68}},    /* Q == 7 : 44-50% */
    +    {{926, 128}, {1613, 75}, {2730, 75}},    /* Q == 8 : 50-56% */
    +    {{947, 128}, {1729, 77}, {3359, 77}},    /* Q == 9 : 56-62% */
    +    {{1107, 128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
    +    {{1177, 128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
    +    {{1242, 128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
    +    {{1349, 128}, {2644, 106}, {5260, 106}}, /* Q ==13 : 81-87% */
    +    {{1455, 128}, {2422, 124}, {4174, 124}}, /* Q ==14 : 87-93% */
    +    {{722, 128}, {1891, 145}, {1936, 146}},  /* Q ==15 : 93-99% */
     };
     
     /** HUF_selectDecoder() :
    @@ -784,57 +848,74 @@ static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, qu
     *   based on a set of pre-determined metrics.
     *   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
     *   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
    -U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
    +U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize)
     {
     	/* decoder timing evaluation */
    -	U32 const Q = (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 since dstSize > cSrcSize */
    +	U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
     	U32 const D256 = (U32)(dstSize >> 8);
     	U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
     	U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
    -	DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, for cache eviction */
    +	DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, for cache eviction */
     
     	return DTime1 < DTime0;
     }
     
    +typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize);
     
    -typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
    -
    -size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
     	/* validation checks */
    -	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    -	if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
    -	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
    -	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
    +	if (dstSize == 0)
    +		return ERROR(dstSize_tooSmall);
    +	if (cSrcSize > dstSize)
    +		return ERROR(corruption_detected); /* invalid */
    +	if (cSrcSize == dstSize) {
    +		memcpy(dst, cSrc, dstSize);
    +		return dstSize;
    +	} /* not compressed */
    +	if (cSrcSize == 1) {
    +		memset(dst, *(const BYTE *)cSrc, dstSize);
    +		return dstSize;
    +	} /* RLE */
     
    -	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    -		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    -						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    +	{
    +		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    +		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
     	}
     }
     
    -size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
     	/* validation checks */
    -	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    -	if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
    +	if (dstSize == 0)
    +		return ERROR(dstSize_tooSmall);
    +	if ((cSrcSize >= dstSize) || (cSrcSize <= 1))
    +		return ERROR(corruption_detected); /* invalid */
     
    -	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    -		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    -						HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    +	{
    +		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    +		return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
     	}
     }
     
    -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
    +size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize)
     {
     	/* validation checks */
    -	if (dstSize == 0) return ERROR(dstSize_tooSmall);
    -	if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
    -	if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
    -	if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
    +	if (dstSize == 0)
    +		return ERROR(dstSize_tooSmall);
    +	if (cSrcSize > dstSize)
    +		return ERROR(corruption_detected); /* invalid */
    +	if (cSrcSize == dstSize) {
    +		memcpy(dst, cSrc, dstSize);
    +		return dstSize;
    +	} /* not compressed */
    +	if (cSrcSize == 1) {
    +		memset(dst, *(const BYTE *)cSrc, dstSize);
    +		return dstSize;
    +	} /* RLE */
     
    -	{	U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    -		return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
    -						HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
    +	{
    +		U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
    +		return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
     	}
     }
    diff --git a/contrib/linux-kernel/lib/zstd/mem.h b/contrib/linux-kernel/lib/zstd/mem.h
    index d01b1238a..3a0f34c87 100644
    --- a/contrib/linux-kernel/lib/zstd/mem.h
    +++ b/contrib/linux-kernel/lib/zstd/mem.h
    @@ -21,126 +21,78 @@
     *  Dependencies
     ******************************************/
     #include 
    -#include      /* size_t, ptrdiff_t */
    -#include      /* memcpy */
    -
    +#include  /* memcpy */
    +#include   /* size_t, ptrdiff_t */
     
     /*-****************************************
     *  Compiler specifics
     ******************************************/
     #define ZSTD_STATIC static __inline __attribute__((unused))
     
    -
     /*-**************************************************************
     *  Basic Types
     *****************************************************************/
    -typedef   uint8_t BYTE;
    -typedef  uint16_t U16;
    -typedef   int16_t S16;
    -typedef  uint32_t U32;
    -typedef   int32_t S32;
    -typedef  uint64_t U64;
    -typedef   int64_t S64;
    +typedef uint8_t BYTE;
    +typedef uint16_t U16;
    +typedef int16_t S16;
    +typedef uint32_t U32;
    +typedef int32_t S32;
    +typedef uint64_t U64;
    +typedef int64_t S64;
     typedef ptrdiff_t iPtrDiff;
     typedef uintptr_t uPtrDiff;
     
    -
     /*-**************************************************************
     *  Memory I/O
     *****************************************************************/
    -ZSTD_STATIC unsigned ZSTD_32bits(void) { return sizeof(size_t)==4; }
    -ZSTD_STATIC unsigned ZSTD_64bits(void) { return sizeof(size_t)==8; }
    +ZSTD_STATIC unsigned ZSTD_32bits(void) { return sizeof(size_t) == 4; }
    +ZSTD_STATIC unsigned ZSTD_64bits(void) { return sizeof(size_t) == 8; }
     
     #if defined(__LITTLE_ENDIAN)
    -#   define ZSTD_LITTLE_ENDIAN 1
    +#define ZSTD_LITTLE_ENDIAN 1
     #else
    -#   define ZSTD_LITTLE_ENDIAN 0
    +#define ZSTD_LITTLE_ENDIAN 0
     #endif
     
    -ZSTD_STATIC unsigned ZSTD_isLittleEndian(void)
    -{
    -	return ZSTD_LITTLE_ENDIAN;
    -}
    +ZSTD_STATIC unsigned ZSTD_isLittleEndian(void) { return ZSTD_LITTLE_ENDIAN; }
     
    -ZSTD_STATIC U16 ZSTD_read16(const void* memPtr)
    -{
    -	return get_unaligned((const U16*)memPtr);
    -}
    +ZSTD_STATIC U16 ZSTD_read16(const void *memPtr) { return get_unaligned((const U16 *)memPtr); }
     
    -ZSTD_STATIC U32 ZSTD_read32(const void* memPtr)
    -{
    -	return get_unaligned((const U32*)memPtr);
    -}
    +ZSTD_STATIC U32 ZSTD_read32(const void *memPtr) { return get_unaligned((const U32 *)memPtr); }
     
    -ZSTD_STATIC U64 ZSTD_read64(const void* memPtr)
    -{
    -	return get_unaligned((const U64*)memPtr);
    -}
    +ZSTD_STATIC U64 ZSTD_read64(const void *memPtr) { return get_unaligned((const U64 *)memPtr); }
     
    -ZSTD_STATIC size_t ZSTD_readST(const void* memPtr)
    -{
    -	return get_unaligned((const size_t*)memPtr);
    -}
    +ZSTD_STATIC size_t ZSTD_readST(const void *memPtr) { return get_unaligned((const size_t *)memPtr); }
     
    -ZSTD_STATIC void ZSTD_write16(void* memPtr, U16 value)
    -{
    -	put_unaligned(value, (U16*)memPtr);
    -}
    +ZSTD_STATIC void ZSTD_write16(void *memPtr, U16 value) { put_unaligned(value, (U16 *)memPtr); }
     
    -ZSTD_STATIC void ZSTD_write32(void* memPtr, U32 value)
    -{
    -	put_unaligned(value, (U32*)memPtr);
    -}
    +ZSTD_STATIC void ZSTD_write32(void *memPtr, U32 value) { put_unaligned(value, (U32 *)memPtr); }
     
    -ZSTD_STATIC void ZSTD_write64(void* memPtr, U64 value)
    -{
    -	put_unaligned(value, (U64*)memPtr);
    -}
    +ZSTD_STATIC void ZSTD_write64(void *memPtr, U64 value) { put_unaligned(value, (U64 *)memPtr); }
     
     /*=== Little endian r/w ===*/
     
    -ZSTD_STATIC U16 ZSTD_readLE16(const void* memPtr)
    -{
    -	return get_unaligned_le16(memPtr);
    -}
    +ZSTD_STATIC U16 ZSTD_readLE16(const void *memPtr) { return get_unaligned_le16(memPtr); }
     
    -ZSTD_STATIC void ZSTD_writeLE16(void* memPtr, U16 val)
    -{
    -	put_unaligned_le16(val, memPtr);
    -}
    +ZSTD_STATIC void ZSTD_writeLE16(void *memPtr, U16 val) { put_unaligned_le16(val, memPtr); }
     
    -ZSTD_STATIC U32 ZSTD_readLE24(const void* memPtr)
    -{
    -	return ZSTD_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
    -}
    +ZSTD_STATIC U32 ZSTD_readLE24(const void *memPtr) { return ZSTD_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); }
     
    -ZSTD_STATIC void ZSTD_writeLE24(void* memPtr, U32 val)
    +ZSTD_STATIC void ZSTD_writeLE24(void *memPtr, U32 val)
     {
     	ZSTD_writeLE16(memPtr, (U16)val);
    -	((BYTE*)memPtr)[2] = (BYTE)(val>>16);
    +	((BYTE *)memPtr)[2] = (BYTE)(val >> 16);
     }
     
    -ZSTD_STATIC U32 ZSTD_readLE32(const void* memPtr)
    -{
    -	return get_unaligned_le32(memPtr);
    -}
    +ZSTD_STATIC U32 ZSTD_readLE32(const void *memPtr) { return get_unaligned_le32(memPtr); }
     
    -ZSTD_STATIC void ZSTD_writeLE32(void* memPtr, U32 val32)
    -{
    -	put_unaligned_le32(val32, memPtr);
    -}
    +ZSTD_STATIC void ZSTD_writeLE32(void *memPtr, U32 val32) { put_unaligned_le32(val32, memPtr); }
     
    -ZSTD_STATIC U64 ZSTD_readLE64(const void* memPtr)
    -{
    -	return get_unaligned_le64(memPtr);
    -}
    +ZSTD_STATIC U64 ZSTD_readLE64(const void *memPtr) { return get_unaligned_le64(memPtr); }
     
    -ZSTD_STATIC void ZSTD_writeLE64(void* memPtr, U64 val64)
    -{
    -	put_unaligned_le64(val64, memPtr);
    -}
    +ZSTD_STATIC void ZSTD_writeLE64(void *memPtr, U64 val64) { put_unaligned_le64(val64, memPtr); }
     
    -ZSTD_STATIC size_t ZSTD_readLEST(const void* memPtr)
    +ZSTD_STATIC size_t ZSTD_readLEST(const void *memPtr)
     {
     	if (ZSTD_32bits())
     		return (size_t)ZSTD_readLE32(memPtr);
    @@ -148,7 +100,7 @@ ZSTD_STATIC size_t ZSTD_readLEST(const void* memPtr)
     		return (size_t)ZSTD_readLE64(memPtr);
     }
     
    -ZSTD_STATIC void ZSTD_writeLEST(void* memPtr, size_t val)
    +ZSTD_STATIC void ZSTD_writeLEST(void *memPtr, size_t val)
     {
     	if (ZSTD_32bits())
     		ZSTD_writeLE32(memPtr, (U32)val);
    @@ -158,27 +110,15 @@ ZSTD_STATIC void ZSTD_writeLEST(void* memPtr, size_t val)
     
     /*=== Big endian r/w ===*/
     
    -ZSTD_STATIC U32 ZSTD_readBE32(const void* memPtr)
    -{
    -	return get_unaligned_be32(memPtr);
    -}
    +ZSTD_STATIC U32 ZSTD_readBE32(const void *memPtr) { return get_unaligned_be32(memPtr); }
     
    -ZSTD_STATIC void ZSTD_writeBE32(void* memPtr, U32 val32)
    -{
    -	put_unaligned_be32(val32, memPtr);
    -}
    +ZSTD_STATIC void ZSTD_writeBE32(void *memPtr, U32 val32) { put_unaligned_be32(val32, memPtr); }
     
    -ZSTD_STATIC U64 ZSTD_readBE64(const void* memPtr)
    -{
    -	return get_unaligned_be64(memPtr);
    -}
    +ZSTD_STATIC U64 ZSTD_readBE64(const void *memPtr) { return get_unaligned_be64(memPtr); }
     
    -ZSTD_STATIC void ZSTD_writeBE64(void* memPtr, U64 val64)
    -{
    -	put_unaligned_be64(val64, memPtr);
    -}
    +ZSTD_STATIC void ZSTD_writeBE64(void *memPtr, U64 val64) { put_unaligned_be64(val64, memPtr); }
     
    -ZSTD_STATIC size_t ZSTD_readBEST(const void* memPtr)
    +ZSTD_STATIC size_t ZSTD_readBEST(const void *memPtr)
     {
     	if (ZSTD_32bits())
     		return (size_t)ZSTD_readBE32(memPtr);
    @@ -186,7 +126,7 @@ ZSTD_STATIC size_t ZSTD_readBEST(const void* memPtr)
     		return (size_t)ZSTD_readBE64(memPtr);
     }
     
    -ZSTD_STATIC void ZSTD_writeBEST(void* memPtr, size_t val)
    +ZSTD_STATIC void ZSTD_writeBEST(void *memPtr, size_t val)
     {
     	if (ZSTD_32bits())
     		ZSTD_writeBE32(memPtr, (U32)val);
    @@ -194,18 +134,17 @@ ZSTD_STATIC void ZSTD_writeBEST(void* memPtr, size_t val)
     		ZSTD_writeBE64(memPtr, (U64)val);
     }
     
    -
     /* function safe only for comparisons */
    -ZSTD_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
    +ZSTD_STATIC U32 ZSTD_readMINMATCH(const void *memPtr, U32 length)
     {
    -	switch (length)
    -	{
    -	default :
    -	case 4 : return ZSTD_read32(memPtr);
    -	case 3 : if (ZSTD_isLittleEndian())
    -				return ZSTD_read32(memPtr)<<8;
    -			 else
    -				return ZSTD_read32(memPtr)>>8;
    +	switch (length) {
    +	default:
    +	case 4: return ZSTD_read32(memPtr);
    +	case 3:
    +		if (ZSTD_isLittleEndian())
    +			return ZSTD_read32(memPtr) << 8;
    +		else
    +			return ZSTD_read32(memPtr) >> 8;
     	}
     }
     
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_common.c b/contrib/linux-kernel/lib/zstd/zstd_common.c
    index 4ff3cc83b..6ebf68d2a 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_common.c
    +++ b/contrib/linux-kernel/lib/zstd/zstd_common.c
    @@ -14,29 +14,28 @@
      * ("BSD").
      */
     
    -
    -
     /*-*************************************
     *  Dependencies
     ***************************************/
     #include "error_private.h"
    -#include "zstd_internal.h"           /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
    +#include "zstd_internal.h" /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
     #include 
     
    -
     /*=**************************************************************
     *  Custom allocator
     ****************************************************************/
     
    -#define stack_push(stack, size) ({                                             \
    -		void* const ptr = ZSTD_PTR_ALIGN((stack)->ptr);                            \
    -		(stack)->ptr = (char*)ptr + (size);                                        \
    -		(stack)->ptr <= (stack)->end ? ptr : NULL;                                 \
    +#define stack_push(stack, size)                                 \
    +	({                                                      \
    +		void *const ptr = ZSTD_PTR_ALIGN((stack)->ptr); \
    +		(stack)->ptr = (char *)ptr + (size);            \
    +		(stack)->ptr <= (stack)->end ? ptr : NULL;      \
     	})
     
    -ZSTD_customMem ZSTD_initStack(void* workspace, size_t workspaceSize) {
    -	ZSTD_customMem stackMem = { ZSTD_stackAlloc, ZSTD_stackFree, workspace };
    -	ZSTD_stack* stack = (ZSTD_stack*) workspace;
    +ZSTD_customMem ZSTD_initStack(void *workspace, size_t workspaceSize)
    +{
    +	ZSTD_customMem stackMem = {ZSTD_stackAlloc, ZSTD_stackFree, workspace};
    +	ZSTD_stack *stack = (ZSTD_stack *)workspace;
     	/* Verify preconditions */
     	if (!workspace || workspaceSize < sizeof(ZSTD_stack) || workspace != ZSTD_PTR_ALIGN(workspace)) {
     		ZSTD_customMem error = {NULL, NULL, NULL};
    @@ -44,33 +43,33 @@ ZSTD_customMem ZSTD_initStack(void* workspace, size_t workspaceSize) {
     	}
     	/* Initialize the stack */
     	stack->ptr = workspace;
    -	stack->end = (char*)workspace + workspaceSize;
    +	stack->end = (char *)workspace + workspaceSize;
     	stack_push(stack, sizeof(ZSTD_stack));
     	return stackMem;
     }
     
    -void* ZSTD_stackAllocAll(void* opaque, size_t* size) {
    -	ZSTD_stack* stack = (ZSTD_stack*)opaque;
    +void *ZSTD_stackAllocAll(void *opaque, size_t *size)
    +{
    +	ZSTD_stack *stack = (ZSTD_stack *)opaque;
     	*size = stack->end - ZSTD_PTR_ALIGN(stack->ptr);
     	return stack_push(stack, *size);
     }
     
    -void* ZSTD_stackAlloc(void* opaque, size_t size) {
    -	ZSTD_stack* stack = (ZSTD_stack*)opaque;
    +void *ZSTD_stackAlloc(void *opaque, size_t size)
    +{
    +	ZSTD_stack *stack = (ZSTD_stack *)opaque;
     	return stack_push(stack, size);
     }
    -void ZSTD_stackFree(void* opaque, void* address) {
    +void ZSTD_stackFree(void *opaque, void *address)
    +{
     	(void)opaque;
     	(void)address;
     }
     
    -void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
    -{
    -	return customMem.customAlloc(customMem.opaque, size);
    -}
    +void *ZSTD_malloc(size_t size, ZSTD_customMem customMem) { return customMem.customAlloc(customMem.opaque, size); }
     
    -void ZSTD_free(void* ptr, ZSTD_customMem customMem)
    +void ZSTD_free(void *ptr, ZSTD_customMem customMem)
     {
    -	if (ptr!=NULL)
    +	if (ptr != NULL)
     		customMem.customFree(customMem.opaque, ptr);
     }
    diff --git a/contrib/linux-kernel/lib/zstd/zstd_internal.h b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    index 199513d16..cbb61c429 100644
    --- a/contrib/linux-kernel/lib/zstd/zstd_internal.h
    +++ b/contrib/linux-kernel/lib/zstd/zstd_internal.h
    @@ -23,60 +23,67 @@
     #define FORCE_INLINE static __always_inline
     #define FORCE_NOINLINE static noinline
     
    -
     /*-*************************************
     *  Dependencies
     ***************************************/
    +#include "error_private.h"
    +#include "mem.h"
     #include 
     #include 
     #include 
     #include 
    -#include "mem.h"
    -#include "error_private.h"
    -
     
     /*-*************************************
     *  shared macros
     ***************************************/
    -#define MIN(a,b) ((a)<(b) ? (a) : (b))
    -#define MAX(a,b) ((a)>(b) ? (a) : (b))
    -#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; }  /* check and Forward error code */
    -#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); }  /* check and send Error code */
    -
    +#define MIN(a, b) ((a) < (b) ? (a) : (b))
    +#define MAX(a, b) ((a) > (b) ? (a) : (b))
    +#define CHECK_F(f)                       \
    +	{                                \
    +		size_t const errcod = f; \
    +		if (ERR_isError(errcod)) \
    +			return errcod;   \
    +	} /* check and Forward error code */
    +#define CHECK_E(f, e)                    \
    +	{                                \
    +		size_t const errcod = f; \
    +		if (ERR_isError(errcod)) \
    +			return ERROR(e); \
    +	} /* check and send Error code */
     
     /*-*************************************
     *  Common constants
     ***************************************/
    -#define ZSTD_OPT_NUM    (1<<12)
    -#define ZSTD_DICT_MAGIC  0xEC30A437   /* v0.7+ */
    +#define ZSTD_OPT_NUM (1 << 12)
    +#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */
     
    -#define ZSTD_REP_NUM      3                 /* number of repcodes */
    -#define ZSTD_REP_CHECK    (ZSTD_REP_NUM)    /* number of repcodes to check by the optimal parser */
    -#define ZSTD_REP_MOVE     (ZSTD_REP_NUM-1)
    +#define ZSTD_REP_NUM 3		      /* number of repcodes */
    +#define ZSTD_REP_CHECK (ZSTD_REP_NUM) /* number of repcodes to check by the optimal parser */
    +#define ZSTD_REP_MOVE (ZSTD_REP_NUM - 1)
     #define ZSTD_REP_MOVE_OPT (ZSTD_REP_NUM)
    -static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
    +static const U32 repStartValue[ZSTD_REP_NUM] = {1, 4, 8};
     
    -#define KB *(1 <<10)
    -#define MB *(1 <<20)
    -#define GB *(1U<<30)
    +#define KB *(1 << 10)
    +#define MB *(1 << 20)
    +#define GB *(1U << 30)
     
     #define BIT7 128
    -#define BIT6  64
    -#define BIT5  32
    -#define BIT4  16
    -#define BIT1   2
    -#define BIT0   1
    +#define BIT6 64
    +#define BIT5 32
    +#define BIT4 16
    +#define BIT1 2
    +#define BIT0 1
     
     #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
    -static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
    -static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
    +static const size_t ZSTD_fcs_fieldSize[4] = {0, 2, 4, 8};
    +static const size_t ZSTD_did_fieldSize[4] = {0, 1, 2, 4};
     
    -#define ZSTD_BLOCKHEADERSIZE 3   /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
    +#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
     static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
     typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
     
    -#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
    -#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */
    +#define MIN_SEQUENCES_SIZE 1									  /* nbSeq==0 */
    +#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
     
     #define HufLog 12
     typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
    @@ -86,72 +93,66 @@ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingTy
     #define MINMATCH 3
     #define EQUAL_READ32 4
     
    -#define Litbits  8
    -#define MaxLit ((1<
    // Not ready yet !!!
    -size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
    +
    size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
     

    Return a CCtx to clean state. Useful after an error, or to interrupt an ongoing compression job and start a new one. - It's allowed to change compression parameters after a reset. + It's possible to modify compression parameters after a reset. Any internal data not yet flushed is cancelled.


    @@ -781,7 +796,8 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo >0 : `srcSize` is too small, please provide at least @result bytes on next attempt. errorCode, which can be tested using ZSTD_isError(). - Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict(). + Start decompression, with ZSTD_decompressBegin(). + If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict(). Alternatively, you can copy a prepared context, using ZSTD_copyDCtx(). Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively. @@ -823,12 +839,11 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
     size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
     void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
    -size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
    -size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
    -typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
    -ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
     

    +
    typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
    +

    Block functions

         Block functions produce and decode raw zstd blocks, without frame metadata.
         Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 3d1236d05..1d758dab7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -11,8 +11,8 @@
     /*-*************************************
     *  Tuning parameters
     ***************************************/
    -#ifndef ZSTD_DEFAULT_CLEVEL
    -#  define ZSTD_DEFAULT_CLEVEL 3
    +#ifndef ZSTD_CLEVEL_DEFAULT
    +#  define ZSTD_CLEVEL_DEFAULT 3
     #endif
     
     /*-*************************************
    @@ -86,7 +86,7 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
     /*-*************************************
     *  Context memory management
     ***************************************/
    -typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
    +typedef enum { zcss_init=0, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
     
     struct ZSTD_CCtx_s {
         const BYTE* nextSrc;    /* next block here to continue on current prefix */
    @@ -158,7 +158,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
         if (!cctx) return NULL;
         memset(cctx, 0, sizeof(ZSTD_CCtx));
         cctx->customMem = customMem;
    -    cctx->compressionLevel = ZSTD_DEFAULT_CLEVEL;
    +    cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT;
         return cctx;
     }
     
    @@ -202,24 +202,18 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
     }
     
     
    +#define ZSTD_CLEVEL_CUSTOM 999
     static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
     {
    -    if (cctx->compressionLevel==0)  return;
    +    if (cctx->compressionLevel==ZSTD_CLEVEL_CUSTOM)  return;
         cctx->params.cParams = ZSTD_getCParams(cctx->compressionLevel,
                                                cctx->frameContentSize, 0);
    -    cctx->compressionLevel = 0;
    +    cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM;
     }
     
     size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
     {
     #   define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); }
    -#   define LOADCPARAMS(cctx)                                        \
    -            if (cctx->compressionLevel!=0)  {                          \
    -                cctx->params.cParams = ZSTD_getCParams( cctx->compressionLevel,     \
    -                                           cctx->frameContentSize, 0); \
    -                cctx->compressionLevel = 0;                            \
    -            }
    -
     
         switch(param)
         {
    @@ -257,7 +251,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 cctx->params.cParams.searchLog = value;
                 return 0;
     
    -    case ZSTD_p_minMatchLength :
    +    case ZSTD_p_minMatch :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
                 ZSTD_cLevelToCParams(cctx);
    @@ -287,7 +281,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 cctx->params.fParams.contentSizeFlag = value>0;
                 return 0;
     
    -    case ZSTD_p_contentChecksumFlag : /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
    +    case ZSTD_p_checksumFlag : /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
                 cctx->params.fParams.checksumFlag = value>0;
                 return 0;
     
    @@ -319,6 +313,24 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
         return 0;
     }
     
    +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    +{
    +    ZSTD_freeCDict(cctx->cdictLocal);  /* in case one already exists */
    +    if (dict==NULL || dictSize==0) {   /* no dictionary mode */
    +        cctx->cdictLocal = NULL;
    +        cctx->cdict = NULL;
    +    } else {
    +        cctx->cdictLocal = ZSTD_createCDict_advanced(
    +                                dict, dictSize,
    +                                0 /* byReference */,
    +                                cctx->params.cParams, cctx->customMem);
    +        cctx->cdict = cctx->cdictLocal;
    +        if (cctx->cdictLocal == NULL)
    +            return ERROR(memory_allocation);
    +    }
    +    return 0;
    +}
    +
     /* Not ready yet ! */
     ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
     {
    @@ -3306,8 +3318,6 @@ size_t ZSTD_CStreamOutSize(void)
     
     static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    -    if (zcs->inBuffSize==0) return ERROR(stage_wrong);   /* zcs has not been init at least once => can't reset */
    -
         DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
     
         if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize))
    @@ -3327,7 +3337,9 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
     
         ZSTD_parameters params = zcs->params;
         params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    -    DEBUGLOG(5, "ZSTD_resetCStream : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
    +    if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
    +        params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
    +    }
         return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
     }
     
    @@ -3437,8 +3449,6 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
     
     /*======   Compression   ======*/
     
    -typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
    -
     MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
         size_t const length = MIN(dstCapacity, srcSize);
    @@ -3449,7 +3459,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
     static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                                   void* dst, size_t* dstCapacityPtr,
                             const void* src, size_t* srcSizePtr,
    -                              ZSTD_flush_e const flush)
    +                              ZSTD_EndDirective const flush)
     {
         U32 someMoreWork = 1;
         const char* const istart = (const char*)src;
    @@ -3460,10 +3470,12 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
         char* op = ostart;
     
         DEBUGLOG(5, "ZSTD_compressStream_generic \n");
    +    assert(zcs->inBuff != NULL);
    +    assert(zcs->outBuff!= NULL);
         while (someMoreWork) {
             switch(zcs->streamStage)
             {
    -        case zcss_init: return ERROR(init_missing);   /* call ZBUFF_compressInit() first ! */
    +        case zcss_init: return ERROR(init_missing);   /* call ZSTD_initCStream() first ! */
     
             case zcss_load:
                 /* complete inBuffer */
    @@ -3485,12 +3497,12 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                         cDst = op;   /* compress directly into output buffer (avoid flush stage) */
                     else
                         cDst = zcs->outBuff, oSize = zcs->outBuffSize;
    -                cSize = (flush == zsf_end) ?
    +                cSize = (flush == ZSTD_e_end) ?
                             ZSTD_compressEnd(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
                             ZSTD_compressContinue(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
                     if (ZSTD_isError(cSize)) return cSize;
                     DEBUGLOG(5, "cSize = %u \n", (U32)cSize);
    -                if (flush == zsf_end) zcs->frameEnded = 1;
    +                if (flush == ZSTD_e_end) zcs->frameEnded = 1;
                     /* prepare next block */
                     zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
                     if (zcs->inBuffTarget > zcs->inBuffSize)
    @@ -3538,14 +3550,60 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
     {
         size_t sizeRead = input->size - input->pos;
         size_t sizeWritten = output->size - output->pos;
    -    size_t const result = ZSTD_compressStream_generic(zcs,
    -                                                      (char*)(output->dst) + output->pos, &sizeWritten,
    -                                                      (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
    +    size_t const result = ZSTD_compressStream_generic(
    +                            zcs,
    +                            (char*)(output->dst) + output->pos, &sizeWritten,
    +                            (const char*)(input->src) + input->pos, &sizeRead, ZSTD_e_continue);
         input->pos += sizeRead;
         output->pos += sizeWritten;
         return result;
     }
     
    +size_t ZSTD_compress_generic_integral (
    +                            ZSTD_CCtx* cctx,
    +                            void* dst, size_t dstCapacity, size_t* dstPos,
    +                      const void* src, size_t srcSize, size_t* srcPos,
    +                            ZSTD_EndDirective endOp)
    +{
    +    /* check conditions */
    +    if (*dstPos > dstCapacity) return ERROR(GENERIC);
    +    if (*srcPos > srcSize) return ERROR(GENERIC);
    +
    +    assert(cctx!=NULL);
    +    if (cctx->streamStage == zcss_init) {
    +        /* transparent reset */
    +        ZSTD_parameters params = cctx->params;
    +        if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
    +            params.cParams = ZSTD_getCParams(cctx->compressionLevel,
    +                                    cctx->frameContentSize, 0 /* dictSize */);
    +        DEBUGLOG(5, "starting ZSTD_resetCStream");
    +        CHECK_F( ZSTD_initCStream_stage2(cctx, params, cctx->frameContentSize) );
    +    }
    +
    +    {   size_t sizeRead = srcSize - *srcPos;
    +        size_t sizeWritten = dstCapacity - *dstPos;
    +        DEBUGLOG(5, "starting ZSTD_compressStream_generic");
    +        CHECK_F( ZSTD_compressStream_generic(cctx,
    +                        (char*)dst + *dstPos, &sizeWritten,
    +                        (const char*)src + *srcPos, &sizeRead, endOp) );
    +        *srcPos += sizeRead;
    +        *dstPos += sizeWritten;
    +    }
    +    DEBUGLOG(5, "completing ZSTD_compress_generic_integral");
    +    return cctx->outBuffContentSize - cctx->outBuffFlushedSize;   /* remaining to flush */
    +}
    +
    +size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                              ZSTD_outBuffer* output,
    +                              ZSTD_inBuffer* input,
    +                              ZSTD_EndDirective endOp)
    +{
    +    return ZSTD_compress_generic_integral(cctx,
    +                output->dst, output->size, &output->pos,
    +                input->src, input->size, &input->pos,
    +                endOp);
    +}
    +
     
     /*======   Finalize   ======*/
     
    @@ -3556,9 +3614,9 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
         size_t srcSize = 0;
         size_t sizeWritten = output->size - output->pos;
         size_t const result = ZSTD_compressStream_generic(zcs,
    -                                                     (char*)(output->dst) + output->pos, &sizeWritten,
    -                                                     &srcSize, &srcSize, /* use a valid src address instead of NULL */
    -                                                      zsf_flush);
    +                                (char*)(output->dst) + output->pos, &sizeWritten,
    +                                &srcSize, &srcSize, /* use a valid src address instead of NULL */
    +                                ZSTD_e_flush);
         output->pos += sizeWritten;
         if (ZSTD_isError(result)) return result;
         return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
    @@ -3576,8 +3634,10 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
             /* flush whatever remains */
             size_t srcSize = 0;
             size_t sizeWritten = output->size - output->pos;
    -        size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten,
    -                                     &srcSize /* use a valid src address instead of NULL */, &srcSize, zsf_end);
    +        size_t const notEnded = ZSTD_compressStream_generic(zcs,
    +                                    ostart, &sizeWritten,
    +                                    &srcSize /* valid address */, &srcSize,
    +                                    ZSTD_e_end);
             size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
             op += sizeWritten;
             if (remainingToFlush) {
    @@ -3727,7 +3787,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
         size_t const addedSize = srcSize ? 0 : 500;
         U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
         U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
    -    if (compressionLevel <= 0) compressionLevel = 1;   /* 0 == default; no negative compressionLevel yet */
    +    if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* 0 == default; no negative compressionLevel yet */
         if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
         cp = ZSTD_defaultCParameters[tableID][compressionLevel];
         if (MEM_32bits()) {   /* auto-correction, for 32-bits mode */
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 4d14c8026..338091834 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -616,7 +616,7 @@ typedef enum {
                                   * More attempts result in better and slower compression.
                                   * This parameter is useless when using "fast" and "dFast" strategies.
                                   * Special: value 0 means "do not change searchLog". */
    -    ZSTD_p_minMatchLength,   /* Minimum match size (except for repeat-matches, which limit is hard-coded).
    +    ZSTD_p_minMatch,         /* Minimum size of searched matches (note : repCode matches can be smaller).
                                   * Larger values make faster compression and decompression, but decrease ratio.
                                   * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
                                   * Note that currently, for all strategies < btopt, effective minimum is 4.
    @@ -641,7 +641,7 @@ typedef enum {
     
         /* frame parameters */
         ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    -    ZSTD_p_contentChecksumFlag, /* A 32-bits content checksum is calculated and written at end of frame (default:0) */
    +    ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
         ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
     
         /* dictionary parameters */
    @@ -688,17 +688,32 @@ ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param
      *           this value is overriden by srcSize instead. */
     ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
     
    +/*! ZSTD_CCtx_loadDictionary() :
    + *  Create an internal CDict from dict buffer.
    + *  Decompression will have to use same buffer.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix,
    + *            meaning "return to no-dictionary mode".
    + *  Note 1 : Dictionary content will be copied internally,
    + *           except if ZSTD_p_refDictContent is set.
    + *  Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
    + *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    + *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    + *  Note 3 : Dictionary will be used for all future compression jobs.
    + *           To return to "no-dictionary" situation, load a NULL dictionary */
    +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);   /* Not ready yet ! */
    +
     /*! ZSTD_CCtx_refPrefix() :
      *  Reference a prefix (content-only dictionary) to bootstrap next compression job.
      *  Decompression will have to use same prefix.
      * @result : 0, or an error code (which can be tested with ZSTD_isError()).
      *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode".
    - *  Note 1 : Prefix content is referenced. It must outlive compression job.
    + *  Note 1 : Prefix buffer is referenced. It must outlive compression job.
    + *  Note 3 : Prefix is only used once. Tables are discarded at end of compression job.
    + *           If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict.
      *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
      *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    - *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    - *  Note 3 : Prefix is only used once. Tables are discarded at end of compression job.
    - *           If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict */
    + *           It's also a CPU-heavy operation, with non-negligible impact on latency. */
     ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
     
     
    @@ -730,13 +745,11 @@ ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict
     ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);  /* Not ready yet ! */
     
     
    -// Target advanced compression API
    -// Not ready yet !!!
     
     typedef enum {
    -    ZSTD_e_continue,  /* continue sending data, encoder transparently decides when to output result, depending on optimal conditions */
    -    ZSTD_e_flush,     /* flush any data provided, compressed and buffered so far - frame will continue, future data can still reference previous data for better compression */
    -    ZSTD_e_end        /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +    ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
    +    ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
     } ZSTD_EndDirective;
     
     /*! ZSTD_compressStream_generic() :
    @@ -753,19 +766,18 @@ typedef enum {
      *            It is necessary to fully flush internal buffers
      *            before changing compression parameters or start a new compression job.
      */
    -// Not ready yet !!!
     ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    -                                          void* dst, size_t dstCapacity, size_t* dstPos,
    -                                    const void* src, size_t srcSize, size_t* srcPos,
    +                                          ZSTD_outBuffer* output,
    +                                          ZSTD_inBuffer* input,
                                               ZSTD_EndDirective endOp);
     
     /*! ZSTD_CCtx_reset() :
      *  Return a CCtx to clean state.
      *  Useful after an error, or to interrupt an ongoing compression job and start a new one.
    - *  It's allowed to change compression parameters after a reset.
    + *  It's possible to modify compression parameters after a reset.
      *  Any internal data not yet flushed is cancelled.
      */
    -ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);
    +ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
     
     
     
    diff --git a/programs/fileio.c b/programs/fileio.c
    index a36abcaff..e7c58a969 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -78,9 +78,6 @@
     #define ROLLBUFFERSIZE (BLOCKSIZE*8*64)
     
     #define FIO_FRAMEHEADERSIZE  5    /* as a define, because needed to allocated table on stack */
    -#define FSE_CHECKSUM_SEED    0
    -
    -#define CACHELINE 64
     
     #define DICTSIZE_MAX (32 MB)   /* protection against large input (attack scenario) */
     
    @@ -106,6 +103,31 @@ static clock_t g_time = 0;
     #define MIN(a,b)    ((a) < (b) ? (a) : (b))
     
     
    +/*-*************************************
    +*  Errors
    +***************************************/
    +#ifndef DEBUG
    +#  define DEBUG 0
    +#endif
    +#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
    +#define EXM_THROW(error, ...)                                              \
    +{                                                                          \
    +    DISPLAYLEVEL(1, "zstd: ");                                             \
    +    DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__);  \
    +    DISPLAYLEVEL(1, "error %i : ", error);                                 \
    +    DISPLAYLEVEL(1, __VA_ARGS__);                                          \
    +    DISPLAYLEVEL(1, " \n");                                                \
    +    exit(error);                                                           \
    +}
    +
    +#define CHECK(f) {                                   \
    +    size_t const err = f;                            \
    +    if (ZSTD_isError(err)) {                         \
    +        DEBUGOUTPUT("%s \n", #f);                    \
    +        EXM_THROW(11, "%s", ZSTD_getErrorName(err)); \
    +}   }
    +
    +
     /* ************************************************************
     * Avoid fseek()'s 2GiB barrier with MSVC, MacOS, *BSD, MinGW
     ***************************************************************/
    @@ -145,7 +167,7 @@ static FIO_compressionType_t g_compressionType = FIO_zstdCompression;
     void FIO_setCompressionType(FIO_compressionType_t compressionType) { g_compressionType = compressionType; }
     static U32 g_overwrite = 0;
     void FIO_overwriteMode(void) { g_overwrite=1; }
    -static U32 g_sparseFileSupport = 1;   /* 0 : no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
    +static U32 g_sparseFileSupport = 1;   /* 0: no sparse allowed; 1: auto (file yes, stdout no); 2: force sparse */
     void FIO_setSparseWrite(unsigned sparse) { g_sparseFileSupport=sparse; }
     static U32 g_dictIDFlag = 1;
     void FIO_setDictIDFlag(unsigned dictIDFlag) { g_dictIDFlag = dictIDFlag; }
    @@ -181,23 +203,6 @@ void FIO_setOverlapLog(unsigned overlapLog){
     }
     
     
    -/*-*************************************
    -*  Exceptions
    -***************************************/
    -#ifndef DEBUG
    -#  define DEBUG 0
    -#endif
    -#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
    -#define EXM_THROW(error, ...)                                             \
    -{                                                                         \
    -    DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
    -    DISPLAYLEVEL(1, "Error %i : ", error);                                \
    -    DISPLAYLEVEL(1, __VA_ARGS__);                                         \
    -    DISPLAYLEVEL(1, " \n");                                               \
    -    exit(error);                                                          \
    -}
    -
    -
     /*-*************************************
     *  Functions
     ***************************************/
    @@ -225,7 +230,7 @@ static FILE* FIO_openSrcFile(const char* srcFileName)
             f = stdin;
             SET_BINARY_MODE(stdin);
         } else {
    -        if (!UTIL_isRegFile(srcFileName)) {
    +        if (!UTIL_isRegularFile(srcFileName)) {
                 DISPLAYLEVEL(1, "zstd: %s is not a regular file -- ignored \n",
                                 srcFileName);
                 return NULL;
    @@ -306,13 +311,13 @@ static size_t FIO_createDictBuffer(void** bufferPtr, const char* fileName)
     
         DISPLAYLEVEL(4,"Loading %s as dictionary \n", fileName);
         fileHandle = fopen(fileName, "rb");
    -    if (fileHandle==0) EXM_THROW(31, "zstd: %s: %s", fileName, strerror(errno));
    +    if (fileHandle==0) EXM_THROW(31, "%s: %s", fileName, strerror(errno));
         fileSize = UTIL_getFileSize(fileName);
         if (fileSize > DICTSIZE_MAX)
             EXM_THROW(32, "Dictionary file %s is too large (> %u MB)",
                             fileName, DICTSIZE_MAX >> 20);   /* avoid extreme cases */
         *bufferPtr = malloc((size_t)fileSize);
    -    if (*bufferPtr==NULL) EXM_THROW(34, "zstd: %s", strerror(errno));
    +    if (*bufferPtr==NULL) EXM_THROW(34, "%s", strerror(errno));
         { size_t const readSize = fread(*bufferPtr, 1, (size_t)fileSize, fileHandle);
           if (readSize!=fileSize) EXM_THROW(35, "Error reading dictionary file %s", fileName); }
         fclose(fileHandle);
    @@ -331,7 +336,7 @@ typedef struct {
         size_t srcBufferSize;
         void*  dstBuffer;
         size_t dstBufferSize;
    -#ifdef ZSTD_MULTITHREAD
    +#if !defined(ZSTD_NEWAPI) && defined(ZSTD_MULTITHREAD)
         ZSTDMT_CCtx* cctx;
     #else
         ZSTD_CStream* cctx;
    @@ -339,15 +344,19 @@ typedef struct {
     } cRess_t;
     
     static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
    -                                    U64 srcSize, int srcRegFile,
    +                                    U64 srcSize, int srcIsRegularFile,
                                         ZSTD_compressionParameters* comprParams) {
         cRess_t ress;
         memset(&ress, 0, sizeof(ress));
     
    -#ifdef ZSTD_MULTITHREAD
    +#ifdef ZSTD_NEWAPI
    +    ress.cctx = ZSTD_createCCtx();
    +    if (ress.cctx == NULL)
    +        EXM_THROW(30, "allocation error : can't create ZSTD_CCtx");
    +#elif defined(ZSTD_MULTITHREAD)
         ress.cctx = ZSTDMT_createCCtx(g_nbThreads);
         if (ress.cctx == NULL)
    -        EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
    +        EXM_THROW(30, "allocation error : can't create ZSTDMT_CCtx");
         if ((cLevel==ZSTD_maxCLevel()) && (g_overlapLog==FIO_OVERLAP_LOG_NOTSET))
             /* use complete window for overlap */
             ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_overlapSectionLog, 9);
    @@ -356,22 +365,43 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
     #else
         ress.cctx = ZSTD_createCStream();
         if (ress.cctx == NULL)
    -        EXM_THROW(30, "zstd: allocation error : can't create ZSTD_CStream");
    +        EXM_THROW(30, "allocation error : can't create ZSTD_CStream");
     #endif
         ress.srcBufferSize = ZSTD_CStreamInSize();
         ress.srcBuffer = malloc(ress.srcBufferSize);
         ress.dstBufferSize = ZSTD_CStreamOutSize();
         ress.dstBuffer = malloc(ress.dstBufferSize);
         if (!ress.srcBuffer || !ress.dstBuffer)
    -        EXM_THROW(31, "zstd: allocation error : not enough memory");
    +        EXM_THROW(31, "allocation error : not enough memory");
     
         /* dictionary */
         {   void* dictBuffer;
             size_t const dictBuffSize = FIO_createDictBuffer(&dictBuffer, dictFileName);   /* works with dictFileName==NULL */
             if (dictFileName && (dictBuffer==NULL))
    -            EXM_THROW(32, "zstd: allocation error : can't create dictBuffer");
    +            EXM_THROW(32, "allocation error : can't create dictBuffer");
    +//#define ZSTD_NEWAPI
    +#ifdef ZSTD_NEWAPI
    +        {
    +            /* frame parameters */
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_contentSizeFlag, srcIsRegularFile) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_dictIDFlag, g_dictIDFlag) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_checksumFlag, g_checksumFlag) );
    +            CHECK( ZSTD_CCtx_setPledgedSrcSize(ress.cctx, srcSize) );
    +            /* compression parameters */
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionLevel, cLevel) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_windowLog, comprParams->windowLog) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_chainLog, comprParams->chainLog) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_hashLog, comprParams->hashLog) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_searchLog, comprParams->searchLog) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_minMatch, comprParams->searchLength) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_targetLength, comprParams->targetLength) );
    +            CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionStrategy, (U32)comprParams->strategy) );
    +            /* dictionary */
    +            CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, dictBuffer, dictBuffSize) );
    +        }
    +#elif defined(ZSTD_MULTITHREAD)
             {   ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
    -            params.fParams.contentSizeFlag = srcRegFile;
    +            params.fParams.contentSizeFlag = srcIsRegularFile;
                 params.fParams.checksumFlag = g_checksumFlag;
                 params.fParams.noDictIDFlag = !g_dictIDFlag;
                 if (comprParams->windowLog) params.cParams.windowLog = comprParams->windowLog;
    @@ -381,15 +411,24 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel,
                 if (comprParams->searchLength) params.cParams.searchLength = comprParams->searchLength;
                 if (comprParams->targetLength) params.cParams.targetLength = comprParams->targetLength;
                 if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy) comprParams->strategy;
    -#ifdef ZSTD_MULTITHREAD
    -            {   size_t const errorCode = ZSTDMT_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize);
    -                if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode));
    -                ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_sectionSize, g_blockSize);
    +            CHECK( ZSTDMT_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize) );
    +            ZSTDMT_setMTCtxParameter(ress.cctx, ZSTDMT_p_sectionSize, g_blockSize);
    +        }
     #else
    -            {   size_t const errorCode = ZSTD_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize);
    -                if (ZSTD_isError(errorCode)) EXM_THROW(33, "Error initializing CStream : %s", ZSTD_getErrorName(errorCode));
    +        {   ZSTD_parameters params = ZSTD_getParams(cLevel, srcSize, dictBuffSize);
    +            params.fParams.contentSizeFlag = srcIsRegularFile;
    +            params.fParams.checksumFlag = g_checksumFlag;
    +            params.fParams.noDictIDFlag = !g_dictIDFlag;
    +            if (comprParams->windowLog) params.cParams.windowLog = comprParams->windowLog;
    +            if (comprParams->chainLog) params.cParams.chainLog = comprParams->chainLog;
    +            if (comprParams->hashLog) params.cParams.hashLog = comprParams->hashLog;
    +            if (comprParams->searchLog) params.cParams.searchLog = comprParams->searchLog;
    +            if (comprParams->searchLength) params.cParams.searchLength = comprParams->searchLength;
    +            if (comprParams->targetLength) params.cParams.targetLength = comprParams->targetLength;
    +            if (comprParams->strategy) params.cParams.strategy = (ZSTD_strategy) comprParams->strategy;
    +            CHECK( ZSTD_initCStream_advanced(ress.cctx, dictBuffer, dictBuffSize, params, srcSize) );
    +        }
     #endif
    -        }   }
             free(dictBuffer);
         }
     
    @@ -400,7 +439,7 @@ static void FIO_freeCResources(cRess_t ress)
     {
         free(ress.srcBuffer);
         free(ress.dstBuffer);
    -#ifdef ZSTD_MULTITHREAD
    +#if !defined(ZSTD_NEWAPI) && defined(ZSTD_MULTITHREAD)
         ZSTDMT_freeCCtx(ress.cctx);
     #else
         ZSTD_freeCStream(ress.cctx);   /* never fails */
    @@ -705,41 +744,40 @@ static int FIO_compressFilename_internal(cRess_t ress,
         }
     
         /* init */
    -#ifdef ZSTD_MULTITHREAD
    -    {   size_t const resetError = ZSTDMT_resetCStream(ress.cctx, fileSize);
    +#ifdef ZSTD_NEWAPI
    +    /* nothing, reset is implied */
    +#elif defined(ZSTD_MULTITHREAD)
    +    CHECK( ZSTDMT_resetCStream(ress.cctx, fileSize) );
     #else
    -    {   size_t const resetError = ZSTD_resetCStream(ress.cctx, fileSize);
    +    CHECK( ZSTD_resetCStream(ress.cctx, fileSize) );
     #endif
    -        if (ZSTD_isError(resetError))
    -            EXM_THROW(21, "Error initializing compression : %s",
    -                            ZSTD_getErrorName(resetError));
    -    }
     
         /* Main compression loop */
         while (1) {
             /* Fill input Buffer */
             size_t const inSize = fread(ress.srcBuffer, (size_t)1, ress.srcBufferSize, srcFile);
    +        ZSTD_inBuffer inBuff = { ress.srcBuffer, inSize, 0 };
             if (inSize==0) break;
             readsize += inSize;
     
    -        {   ZSTD_inBuffer  inBuff = { ress.srcBuffer, inSize, 0 };
    -            while (inBuff.pos != inBuff.size) {
    -                ZSTD_outBuffer outBuff = { ress.dstBuffer, ress.dstBufferSize, 0 };
    -#ifdef ZSTD_MULTITHREAD
    -                size_t const result = ZSTDMT_compressStream(ress.cctx, &outBuff, &inBuff);
    +        while (inBuff.pos != inBuff.size) {
    +            ZSTD_outBuffer outBuff = { ress.dstBuffer, ress.dstBufferSize, 0 };
    +#ifdef ZSTD_NEWAPI
    +            CHECK( ZSTD_compress_generic(ress.cctx,
    +                        &outBuff, &inBuff, ZSTD_e_continue) );
    +#elif defined(ZSTD_MULTITHREAD)
    +            CHECK( ZSTDMT_compressStream(ress.cctx, &outBuff, &inBuff) );
     #else
    -                size_t const result = ZSTD_compressStream(ress.cctx, &outBuff, &inBuff);
    +            CHECK( ZSTD_compressStream(ress.cctx, &outBuff, &inBuff) );
     #endif
    -                if (ZSTD_isError(result))
    -                    EXM_THROW(23, "Compression error : %s ", ZSTD_getErrorName(result));
     
    -                /* Write compressed stream */
    -                if (outBuff.pos) {
    -                    size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
    -                    if (sizeCheck!=outBuff.pos)
    -                        EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName);
    -                    compressedfilesize += outBuff.pos;
    -        }   }   }
    +            /* Write compressed stream */
    +            if (outBuff.pos) {
    +                size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
    +                if (sizeCheck!=outBuff.pos)
    +                    EXM_THROW(25, "Write error : cannot write compressed block into %s", dstFileName);
    +                compressedfilesize += outBuff.pos;
    +        }   }
             if (g_nbThreads > 1) {
                 if (!fileSize)
                     DISPLAYUPDATE(2, "\rRead : %u MB", (U32)(readsize>>20))
    @@ -762,12 +800,18 @@ static int FIO_compressFilename_internal(cRess_t ress,
         {   size_t result = 1;
             while (result!=0) {   /* note : is there any possibility of endless loop ? */
                 ZSTD_outBuffer outBuff = { ress.dstBuffer, ress.dstBufferSize, 0 };
    -#ifdef ZSTD_MULTITHREAD
    +#ifdef ZSTD_NEWAPI
    +            ZSTD_inBuffer inBuff = { NULL, 0, 0};
    +            result = ZSTD_compress_generic(ress.cctx,
    +                        &outBuff, &inBuff, ZSTD_e_end);
    +#elif defined(ZSTD_MULTITHREAD)
                 result = ZSTDMT_endStream(ress.cctx, &outBuff);
     #else
                 result = ZSTD_endStream(ress.cctx, &outBuff);
     #endif
    -            if (ZSTD_isError(result)) EXM_THROW(26, "Compression error during frame end : %s", ZSTD_getErrorName(result));
    +            if (ZSTD_isError(result))
    +                EXM_THROW(26, "Compression error during frame end : %s",
    +                            ZSTD_getErrorName(result));
                 { size_t const sizeCheck = fwrite(ress.dstBuffer, 1, outBuff.pos, dstFile);
                   if (sizeCheck!=outBuff.pos) EXM_THROW(27, "Write error : cannot write frame end into %s", dstFileName); }
                 compressedfilesize += outBuff.pos;
    @@ -856,9 +900,9 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName,
     {
         clock_t const start = clock();
         U64 const srcSize = UTIL_getFileSize(srcFileName);
    -    int const regFile = UTIL_isRegFile(srcFileName);
    +    int const isRegularFile = UTIL_isRegularFile(srcFileName);
     
    -    cRess_t const ress = FIO_createCResources(dictFileName, compressionLevel, srcSize, regFile, comprParams);
    +    cRess_t const ress = FIO_createCResources(dictFileName, compressionLevel, srcSize, isRegularFile, comprParams);
         int const result = FIO_compressFilename_dstFile(ress, dstFileName, srcFileName, compressionLevel);
     
         double const seconds = (double)(clock() - start) / CLOCKS_PER_SEC;
    @@ -879,8 +923,8 @@ int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFile
         char*  dstFileName = (char*)malloc(FNSPACE);
         size_t const suffixSize = suffix ? strlen(suffix) : 0;
         U64 const srcSize = (nbFiles != 1) ? 0 : UTIL_getFileSize(inFileNamesTable[0]) ;
    -    int const regFile = (nbFiles != 1) ? 0 : UTIL_isRegFile(inFileNamesTable[0]);
    -    cRess_t ress = FIO_createCResources(dictFileName, compressionLevel, srcSize, regFile, comprParams);
    +    int const isRegularFile = (nbFiles != 1) ? 0 : UTIL_isRegularFile(inFileNamesTable[0]);
    +    cRess_t ress = FIO_createCResources(dictFileName, compressionLevel, srcSize, isRegularFile, comprParams);
     
         /* init */
         if (dstFileName==NULL)
    @@ -958,9 +1002,7 @@ static dRess_t FIO_createDResources(const char* dictFileName)
         /* dictionary */
         {   void* dictBuffer;
             size_t const dictBufferSize = FIO_createDictBuffer(&dictBuffer, dictFileName);
    -        size_t const initError = ZSTD_initDStream_usingDict(ress.dctx, dictBuffer, dictBufferSize);
    -        if (ZSTD_isError(initError))
    -            EXM_THROW(61, "ZSTD_initDStream_usingDict error : %s", ZSTD_getErrorName(initError));
    +        CHECK( ZSTD_initDStream_usingDict(ress.dctx, dictBuffer, dictBufferSize) );
             free(dictBuffer);
         }
     
    @@ -969,10 +1011,7 @@ static dRess_t FIO_createDResources(const char* dictFileName)
     
     static void FIO_freeDResources(dRess_t ress)
     {
    -    size_t const errorCode = ZSTD_freeDStream(ress.dctx);
    -    if (ZSTD_isError(errorCode))
    -        EXM_THROW(69, "Error : can't free ZSTD_DStream context resource : %s",
    -                        ZSTD_getErrorName(errorCode));
    +    CHECK( ZSTD_freeDStream(ress.dctx) );
         free(ress.srcBuffer);
         free(ress.dstBuffer);
     }
    diff --git a/programs/util.h b/programs/util.h
    index 54ae16227..dd971e0f8 100644
    --- a/programs/util.h
    +++ b/programs/util.h
    @@ -208,7 +208,7 @@ UTIL_STATIC int UTIL_getFileStat(const char* infilename, stat_t *statbuf)
     }
     
     
    -UTIL_STATIC int UTIL_isRegFile(const char* infilename)
    +UTIL_STATIC int UTIL_isRegularFile(const char* infilename)
     {
         stat_t statbuf;
         return UTIL_getFileStat(infilename, &statbuf); /* Only need to know whether it is a regular file */
    
    From 009d604e0035bbfadd189ad9d8b883bbf83615cb Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 10:17:59 -0700
    Subject: [PATCH 078/400] ZSTD_compress_generic() supports multiple successive
     frames
    
    also : clarified streaming API implementation
    ---
     lib/compress/zstd_compress.c | 245 ++++++++++++++++++-----------------
     lib/zstd.h                   |   6 +-
     tests/Makefile               |  16 +--
     tests/zstreamtest.c          |   9 +-
     4 files changed, 141 insertions(+), 135 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 1d758dab7..b8fc8d987 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -41,7 +41,12 @@
     #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
     #  include 
        static unsigned g_debugLevel = ZSTD_DEBUG;
    -#  define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
    +#  define DEBUGLOG(l, ...) {                          \
    +                if (l<=g_debugLevel) {                \
    +                    fprintf(stderr, __FILE__ ": ");   \
    +                    fprintf(stderr, __VA_ARGS__);     \
    +                    fprintf(stderr, " \n");           \
    +            }   }
     #else
     #  define DEBUGLOG(l, ...)      {}    /* disabled */
     #endif
    @@ -185,6 +190,11 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
                + cctx->outBuffSize + cctx->inBuffSize;
     }
     
    +size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
    +{
    +    return ZSTD_sizeof_CCtx(zcs);  /* same object */
    +}
    +
     /* private API call, for dictBuilder only */
     const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
     
    @@ -423,12 +433,16 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
     }
     
     
    -static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
    +static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
    +                                 ZSTD_compressionParameters cParams2)
     {
    -    return (param1.cParams.hashLog  == param2.cParams.hashLog)
    -         & (param1.cParams.chainLog == param2.cParams.chainLog)
    -         & (param1.cParams.strategy == param2.cParams.strategy)   /* opt parser space */
    -         & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));  /* hashlog3 space */
    +    U32 bslog1 = MIN(cParams1.windowLog, 17);
    +    U32 bslog2 = MIN(cParams2.windowLog, 17);
    +    return (bslog1 == bslog2)   /* same block size */
    +         & (cParams1.hashLog  == cParams2.hashLog)
    +         & (cParams1.chainLog == cParams2.chainLog)
    +         & (cParams1.strategy == cParams2.strategy)   /* opt parser space */
    +         & ((cParams1.searchLength==3) == (cParams2.searchLength==3));  /* hashlog3 space */
     }
     
     /*! ZSTD_continueCCtx() :
    @@ -459,11 +473,12 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
                                            ZSTD_parameters params, U64 frameContentSize,
                                            ZSTD_compResetPolicy_e const crp)
     {
    -    DEBUGLOG(5, "ZSTD_resetCCtx_internal \n");
    +    DEBUGLOG(5, "ZSTD_resetCCtx_internal : wlog=%u / old=%u",
    +                params.cParams.windowLog, zc->params.cParams.windowLog);
     
         if (crp == ZSTDcrp_continue)
    -        if (ZSTD_equivalentParams(params, zc->params)) {
    -            DEBUGLOG(5, "ZSTD_equivalentParams()==1 \n");
    +        if (ZSTD_equivalentParams(params.cParams, zc->params.cParams)) {
    +            DEBUGLOG(5, "ZSTD_equivalentParams()==1");
                 zc->fseCTables_ready = 0;
                 zc->hufCTable_repeatMode = HUF_repeat_none;
                 return ZSTD_continueCCtx(zc, params, frameContentSize);
    @@ -514,7 +529,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
             /* init params */
             zc->params = params;
             zc->blockSize = blockSize;
    -        DEBUGLOG(5, "blockSize = %uK \n", (U32)blockSize>>10);
    +        DEBUGLOG(5, "blockSize = %uK", (U32)blockSize>>10);
             zc->frameContentSize = frameContentSize;
             zc->consumedSrcSize = 0;
     
    @@ -544,7 +559,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
     
             /* opt parser space */
             if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btultra)) {
    -            DEBUGLOG(5, "reserving optimal parser space ");
    +            DEBUGLOG(5, "reserving optimal parser space");
                 assert(((size_t)ptr & 3) == 0);  /* ensure ptr is properly aligned */
                 zc->seqStore.litFreq = (U32*)ptr;
                 zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<stage!=ZSTDcs_init) return ERROR(stage_wrong);
     
         memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
         {   ZSTD_parameters params = srcCCtx->params;
             params.fParams = fParams;
    -        DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u \n", !fParams.noDictIDFlag);
    +        DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u", !fParams.noDictIDFlag);
             ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
         }
     
    @@ -1063,12 +1078,6 @@ _check_compressibility:
         return op - ostart;
     }
     
    -#if 0 /* for debug */
    -#  define STORESEQ_DEBUG
    -#include    /* fprintf */
    -U32 g_startDebug = 0;
    -const BYTE* g_start = NULL;
    -#endif
     
     /*! ZSTD_storeSeq() :
         Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
    @@ -1077,16 +1086,16 @@ const BYTE* g_start = NULL;
     */
     MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
     {
    -#ifdef STORESEQ_DEBUG
    -    if (g_startDebug) {
    -        const U32 pos = (U32)((const BYTE*)literals - g_start);
    -        if (g_start==NULL) g_start = (const BYTE*)literals;
    -        if ((pos > 1895000) && (pos < 1895300))
    -            DEBUGLOG(5, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
    -                   pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
    -    }
    +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG >= 6)
    +    static const BYTE* g_start = NULL;
    +    U32 const pos = (U32)((const BYTE*)literals - g_start);
    +    if (g_start==NULL) g_start = (const BYTE*)literals;
    +    if ((pos > 0) && (pos < 1000000000))
    +        DEBUGLOG(6, "Cpos %6u :%5u literals & match %3u bytes at distance %6u",
    +               pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
     #endif
         /* copy Literals */
    +    assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + 128 KB);
         ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
         seqStorePtr->lit += litLength;
     
    @@ -2713,7 +2722,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
         size_t pos;
     
         if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
    -    DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u \n",
    +    DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
                     !params.fParams.noDictIDFlag, dictID,  dictIDSizeCode);
     
         MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
    @@ -3024,7 +3033,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
         BYTE* op = ostart;
         size_t fhSize = 0;
     
    -    DEBUGLOG(5, "ZSTD_writeEpilogue \n");
    +    DEBUGLOG(5, "ZSTD_writeEpilogue");
         if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong);  /* init missing */
     
         /* special case : empty frame */
    @@ -3062,8 +3071,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
                        const void* src, size_t srcSize)
     {
         size_t endResult;
    -    size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize,
    -                               1 /* frame mode */, 1 /* last chunk */);
    +    size_t const cSize = ZSTD_compressContinue_internal(cctx,
    +                                dst, dstCapacity, src, srcSize,
    +                                1 /* frame mode */, 1 /* last chunk */);
         if (ZSTD_isError(cSize)) return cSize;
         endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
         if (ZSTD_isError(endResult)) return endResult;
    @@ -3229,7 +3239,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
         ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
     {
         if (cdict==NULL) return ERROR(dictionary_wrong);  /* does not support NULL cdict */
    -    DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u \n", !fParams.noDictIDFlag);
    +    DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u", !fParams.noDictIDFlag);
         if (cdict->dictContentSize)
             CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) )
         else {
    @@ -3246,7 +3256,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
     size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
     {
         ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
    -    DEBUGLOG(5, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u \n", !fParams.noDictIDFlag);
    +    DEBUGLOG(5, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
         return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0);
     }
     
    @@ -3318,7 +3328,7 @@ size_t ZSTD_CStreamOutSize(void)
     
     static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    -    DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
    +    DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u", !zcs->params.fParams.noDictIDFlag);
     
         if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize))
         else CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, params, pledgedSrcSize));
    @@ -3332,17 +3342,6 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters para
         return 0;   /* ready to go */
     }
     
    -size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    -{
    -
    -    ZSTD_parameters params = zcs->params;
    -    params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    -    if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
    -        params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
    -    }
    -    return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
    -}
    -
     /* ZSTD_initCStream_internal() :
      * params are supposed validated at this stage
      * and zcs->cdict is supposed to be correct */
    @@ -3372,15 +3371,28 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
             zcs->outBuffSize = outBuffSize;
         }
     
    -    DEBUGLOG(5, "ZSTD_initCStream_stage2 : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
         return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
     }
     
    +size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
    +{
    +
    +    ZSTD_parameters params = zcs->params;
    +    params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
    +    if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
    +        params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
    +    }
    +    return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
    +}
    +
     /* ZSTD_initCStream_usingCDict_advanced() :
      * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
    -size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams)
    -{
    -    if (!cdict) return ERROR(dictionary_wrong);  /* cannot handle NULL cdict (does not know what to do) */
    +size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
    +                                            const ZSTD_CDict* cdict,
    +                                            unsigned long long pledgedSrcSize,
    +                                            ZSTD_frameParameters fParams)
    +{   /* cannot handle NULL cdict (does not know what to do) */
    +    if (!cdict) return ERROR(dictionary_wrong);
         {   ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
             params.fParams = fParams;
             zcs->cdict = cdict;
    @@ -3409,7 +3421,6 @@ static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
             zcs->cdict = zcs->cdictLocal;
         }
     
    -    DEBUGLOG(5, "ZSTD_initCStream_internal : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
         return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
     }
     
    @@ -3418,8 +3429,6 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
                                      ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
         CHECK_F( ZSTD_checkCParams(params.cParams) );
    -    DEBUGLOG(5, "ZSTD_initCStream_advanced : pledgedSrcSize == %u \n", (U32)pledgedSrcSize);
    -    DEBUGLOG(5, "wlog %u \n", params.cParams.windowLog);
         return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize);
     }
     
    @@ -3442,11 +3451,6 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
         return ZSTD_initCStream_internal(zcs, NULL, 0, params, 0);
     }
     
    -size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
    -{
    -    return ZSTD_sizeof_CCtx(zcs);   /* same object */
    -}
    -
     /*======   Compression   ======*/
     
     MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    @@ -3459,7 +3463,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
     static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                                   void* dst, size_t* dstCapacityPtr,
                             const void* src, size_t* srcSizePtr,
    -                              ZSTD_EndDirective const flush)
    +                              ZSTD_EndDirective const flushMode)
     {
         U32 someMoreWork = 1;
         const char* const istart = (const char*)src;
    @@ -3469,9 +3473,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
         char* const oend = ostart + *dstCapacityPtr;
         char* op = ostart;
     
    -    DEBUGLOG(5, "ZSTD_compressStream_generic \n");
         assert(zcs->inBuff != NULL);
         assert(zcs->outBuff!= NULL);
    +
         while (someMoreWork) {
             switch(zcs->streamStage)
             {
    @@ -3481,56 +3485,79 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                 /* complete inBuffer */
                 {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
                     size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
    -                DEBUGLOG(5, "loading %u/%u \n", (U32)loaded, (U32)toLoad);
                     zcs->inBuffPos += loaded;
                     ip += loaded;
    -                if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
    -                    someMoreWork = 0; break;  /* not enough input to get a full block : stop there, wait for more */
    -            }   }
    +                if ( (flushMode == ZSTD_e_continue)
    +                  && (zcs->inBuffPos < zcs->inBuffTarget) ) {
    +                    /* not enough input to fill full block : stop here */
    +                    someMoreWork = 0; break;
    +                }
    +                if ( (flushMode == ZSTD_e_flush)
    +                  && (zcs->inBuffPos == zcs->inToCompress) ) {
    +                    /* empty */
    +                    someMoreWork = 0; break;
    +                 }
    +             }
                 /* compress current block (note : this stage cannot be stopped in the middle) */
    -            DEBUGLOG(5, "stream compression stage (flush==%u)\n", flush);
    +            DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode);
                 {   void* cDst;
                     size_t cSize;
                     size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
                     size_t oSize = oend-op;
    +                unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);
                     if (oSize >= ZSTD_compressBound(iSize))
    -                    cDst = op;   /* compress directly into output buffer (avoid flush stage) */
    +                    cDst = op;   /* compress directly into output buffer (skip flush stage) */
                     else
                         cDst = zcs->outBuff, oSize = zcs->outBuffSize;
    -                cSize = (flush == ZSTD_e_end) ?
    -                        ZSTD_compressEnd(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
    -                        ZSTD_compressContinue(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
    +                cSize = lastBlock ?
    +                        ZSTD_compressEnd(zcs, cDst, oSize,
    +                                    zcs->inBuff + zcs->inToCompress, iSize) :
    +                        ZSTD_compressContinue(zcs, cDst, oSize,
    +                                    zcs->inBuff + zcs->inToCompress, iSize);
                     if (ZSTD_isError(cSize)) return cSize;
    -                DEBUGLOG(5, "cSize = %u \n", (U32)cSize);
    -                if (flush == ZSTD_e_end) zcs->frameEnded = 1;
    +                DEBUGLOG(5, "cSize = %u   (lastBlock:%u)", (U32)cSize, lastBlock);
    +                zcs->frameEnded = lastBlock;
                     /* prepare next block */
                     zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
                     if (zcs->inBuffTarget > zcs->inBuffSize)
    -                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;   /* note : inBuffTarget == blockSize <= inBuffSize */
    +                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
                     assert(zcs->inBuffTarget <= zcs->inBuffSize);
                     zcs->inToCompress = zcs->inBuffPos;
    -                if (cDst == op) { op += cSize; break; }   /* no need to flush */
    +                if (cDst == op) {  /* no need to flush */
    +                    op += cSize;
    +                    if (zcs->frameEnded) {
    +                        DEBUGLOG(5, "Frame directly completed");
    +                        someMoreWork = 0;
    +                        zcs->streamStage = zcss_init;
    +                    }
    +                    break;
    +                }
                     zcs->outBuffContentSize = cSize;
                     zcs->outBuffFlushedSize = 0;
    -                zcs->streamStage = zcss_flush;   /* pass-through to flush stage */
    +                zcs->streamStage = zcss_flush; /* pass-through to flush stage */
                 }
     	    /* fall-through */
             case zcss_flush:
    -            DEBUGLOG(5, "flush stage \n");
    +            DEBUGLOG(5, "flush stage");
                 {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
                     size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    -                DEBUGLOG(5, "toFlush: %u  ; flushed: %u \n", (U32)toFlush, (U32)flushed);
    +                DEBUGLOG(5, "toFlush: %u  ; flushed: %u", (U32)toFlush, (U32)flushed);
                     op += flushed;
                     zcs->outBuffFlushedSize += flushed;
                     if (toFlush!=flushed) { someMoreWork = 0; break; }  /* dst too small to store flushed data : stop there */
                     zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
    +                if (zcs->frameEnded) {
    +                    DEBUGLOG(5, "Frame completed");
    +                    someMoreWork = 0;
    +                    zcs->streamStage = zcss_init;
    +                    break;
    +                }
                     zcs->streamStage = zcss_load;
                     break;
                 }
     
             case zcss_final:
    -            someMoreWork = 0;   /* do nothing */
    -            break;
    +            someMoreWork = 0; break;  /* useless */
     
             default:
                 return ERROR(GENERIC);   /* impossible */
    @@ -3573,10 +3600,10 @@ size_t ZSTD_compress_generic_integral (
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
             ZSTD_parameters params = cctx->params;
    +        DEBUGLOG(5, "ZSTD_compress_generic_integral : transparent reset");
             if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
                 params.cParams = ZSTD_getCParams(cctx->compressionLevel,
                                         cctx->frameContentSize, 0 /* dictSize */);
    -        DEBUGLOG(5, "starting ZSTD_resetCStream");
             CHECK_F( ZSTD_initCStream_stage2(cctx, params, cctx->frameContentSize) );
         }
     
    @@ -3626,46 +3653,26 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
         BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
    -    BYTE* const oend = (BYTE*)(output->dst) + output->size;
    -    BYTE* op = ostart;
    +    size_t srcSize = 0;
    +    size_t sizeWritten = output->size - output->pos;
     
    -    DEBUGLOG(5, "ZSTD_endStream (dstCapacity : %u) \n", (U32)(oend-op));
    -    if (zcs->streamStage != zcss_final) {
    -        /* flush whatever remains */
    -        size_t srcSize = 0;
    -        size_t sizeWritten = output->size - output->pos;
    -        size_t const notEnded = ZSTD_compressStream_generic(zcs,
    -                                    ostart, &sizeWritten,
    -                                    &srcSize /* valid address */, &srcSize,
    -                                    ZSTD_e_end);
    -        size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    -        op += sizeWritten;
    -        if (remainingToFlush) {
    -            output->pos += sizeWritten;
    -            return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */
    -                   + ((zcs->params.fParams.checksumFlag > 0) * 4) /* optional 32-bits checksum */;
    -        }
    -        /* create epilogue */
    -        zcs->streamStage = zcss_final;
    -        zcs->outBuffContentSize = !notEnded ? 0 :
    -            /* write epilogue, including final empty block, into outBuff */
    -            ZSTD_compressEnd(zcs, zcs->outBuff, zcs->outBuffSize, NULL, 0);
    -        if (ZSTD_isError(zcs->outBuffContentSize)) return zcs->outBuffContentSize;
    -    }
    +    DEBUGLOG(5, "calling ZSTD_endStream with outBuff=%u bytes",
    +                (unsigned)sizeWritten);
     
    -    /* flush epilogue */
    -    {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    -        size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    -        op += flushed;
    -        zcs->outBuffFlushedSize += flushed;
    -        output->pos += op-ostart;
    -        if (toFlush==flushed) zcs->streamStage = zcss_init;  /* end reached */
    -        return toFlush - flushed;
    -    }
    +    size_t const result = ZSTD_compressStream_generic(zcs,
    +                                ostart, &sizeWritten,
    +                                &srcSize /* valid address */, &srcSize,
    +                                ZSTD_e_end);
    +    output->pos += sizeWritten;
    +    if (ZSTD_isError(result)) return result;
    +
    +    DEBUGLOG(5, "remaining to flush : %u",
    +            (unsigned)(zcs->outBuffContentSize - zcs->outBuffFlushedSize));
    +
    +    return zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     }
     
     
    -
     /*-=====  Pre-defined compression levels  =====-*/
     
     #define ZSTD_MAX_CLEVEL     22
    @@ -3781,11 +3788,11 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
     /*! ZSTD_getCParams() :
     *   @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
     *   Size values are optional, provide 0 if not known or unused */
    -ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
    +ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
     {
         ZSTD_compressionParameters cp;
    -    size_t const addedSize = srcSize ? 0 : 500;
    -    U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
    +    size_t const addedSize = srcSizeHint ? 0 : 500;
    +    U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : (U64)-1;
         U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);   /* intentional underflow for srcSizeHint == 0 */
         if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* 0 == default; no negative compressionLevel yet */
         if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
    @@ -3795,16 +3802,16 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
             if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
             if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
         }
    -    cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
    +    cp = ZSTD_adjustCParams(cp, srcSizeHint, dictSize);
         return cp;
     }
     
     /*! ZSTD_getParams() :
     *   same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
     *   All fields of `ZSTD_frameParameters` are set to default (0) */
    -ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
    +ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
         ZSTD_parameters params;
    -    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
    +    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
         memset(¶ms, 0, sizeof(params));
         params.cParams = cParams;
         return params;
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 338091834..7931bd5de 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -279,9 +279,11 @@ typedef struct ZSTD_outBuffer_s {
     *  ZSTD_endStream() instructs to finish a frame.
     *  It will perform a flush and write frame epilogue.
     *  The epilogue is required for decoders to consider a frame completed.
    -*  Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
    +*  ZSTD_endStream() may not be able to flush full data if `output->size` is too small.
     *  In which case, call again ZSTD_endStream() to complete the flush.
    -*  @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed)
    +*  @return : 0 if frame fully completed and fully flushed,
    +             or >0 if some data is still present within internal buffer
    +                  (value is minimum size estimation for remaining data to flush, but it could be more)
     *            or an error code, which can be tested using ZSTD_isError().
     *
     * *******************************************************************/
    diff --git a/tests/Makefile b/tests/Makefile
    index c275c081f..0ee182fa8 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -26,16 +26,16 @@ PYTHON ?= python3
     TESTARTEFACT := versionsTest namespaceTest
     
     
    -DEBUGFLAGS=-g -DZSTD_DEBUG=1
    -CPPFLAGS+= -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
    -           -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \
    -           $(DEBUGFLAG)
    -CFLAGS  ?= -O3
    -CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
    +DEBUGFLAGS= -g -DZSTD_DEBUG=1
    +CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \
    +            -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR)
    +CFLAGS   ?= -O3
    +CFLAGS   += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
                 -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \
                 -Wstrict-prototypes -Wundef -Wformat-security \
                 -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \
    -            -Wredundant-decls
    +            -Wredundant-decls \
    +            $(DEBUGFLAGS)
     CFLAGS  += $(MOREFLAGS)
     FLAGS    = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
     
    @@ -159,7 +159,7 @@ zstreamtest-dll : $(ZSTDDIR)/common/xxhash.c $(PRGDIR)/datagen.c zstreamtest.c
     	$(MAKE) -C $(ZSTDDIR) libzstd
     	$(CC) $(CPPFLAGS) $(CFLAGS) $^ $(LDFLAGS) -o $@$(EXT)
     
    -paramgrill : DEBUGFLAG =
    +paramgrill : DEBUGFLAGS =
     paramgrill : $(ZSTD_FILES) $(PRGDIR)/datagen.c paramgrill.c
     	$(CC)      $(FLAGS) $^ -lm -o $@$(EXT)
     
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 6c4900ebb..e9e17031c 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -189,7 +189,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* Basic compression test */
         DISPLAYLEVEL(3, "test%3i : compress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH);
    -    ZSTD_initCStream_usingDict(zc, CNBuffer, dictSize, 1);
    +    { size_t const r = ZSTD_initCStream_usingDict(zc, CNBuffer, dictSize, 1);
    +      if (ZSTD_isError(r)) goto _output_error; }
         outBuff.dst = (char*)(compressedBuffer)+cSize;
         outBuff.size = compressedBufferSize;
         outBuff.pos = 0;
    @@ -797,13 +798,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
                     while (remainingToFlush) {
                         size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog);
                         size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
    -                    U32 const enoughDstSize = (adjustedDstSize >= remainingToFlush);
                         outBuff.size = outBuff.pos + adjustedDstSize;
                         remainingToFlush = ZSTD_endStream(zc, &outBuff);
    -                    CHECK (ZSTD_isError(remainingToFlush), "flush error : %s", ZSTD_getErrorName(remainingToFlush));
    -                    CHECK (enoughDstSize && remainingToFlush,
    -                           "ZSTD_endStream() not fully flushed (%u remaining), but enough space available (%u)",
    -                           (U32)remainingToFlush, (U32)adjustedDstSize);
    +                    CHECK (ZSTD_isError(remainingToFlush), "end error : %s", ZSTD_getErrorName(remainingToFlush));
                 }   }
                 crcOrig = XXH64_digest(&xxhState);
                 cSize = outBuff.pos;
    
    From fa3671eac7097ce4ae9a1a4c53d2d1486c29d48f Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 10:51:30 -0700
    Subject: [PATCH 079/400] changed ZSTD_BLOCKSIZE_ABSOLUTEMAX into
     ZSTD_BLOCKSIZE_MAX
    
    Also :
    change ZSTD_getBlockSizeMax() into ZSTD_getBlockSize()
    created ZSTD_BLOCKSIZELOG_MAX
    ---
     doc/zstd_manual.html             | 10 ++++++----
     lib/compress/zstd_compress.c     | 26 +++++++++++++++-----------
     lib/decompress/zstd_decompress.c | 18 +++++++++---------
     lib/dictBuilder/zdict.c          |  8 ++++----
     lib/zstd.h                       |  7 ++++---
     tests/fuzzer.c                   |  1 +
     6 files changed, 39 insertions(+), 31 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index ff1ecd92f..de0ee4339 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -240,9 +240,11 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
       ZSTD_endStream() instructs to finish a frame.
       It will perform a flush and write frame epilogue.
       The epilogue is required for decoders to consider a frame completed.
    -  Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
    +  ZSTD_endStream() may not be able to flush full data if `output->size` is too small.
       In which case, call again ZSTD_endStream() to complete the flush.
    -  @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed)
    +  @return : 0 if frame fully completed and fully flushed,
    +             or >0 if some data is still present within internal buffer
    +                  (value is minimum size estimation for remaining data to flush, but it could be more)
                 or an error code, which can be tested using ZSTD_isError().
     
      
    @@ -856,7 +858,7 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
           + compression : any ZSTD_compressBegin*() variant, including with dictionary
           + decompression : any ZSTD_decompressBegin*() variant, including with dictionary
           + copyCCtx() and copyDCtx() can be used too
    -    - Block size is limited, it must be <= ZSTD_getBlockSizeMax() <= ZSTD_BLOCKSIZE_ABSOLUTEMAX
    +    - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX
           + If input is larger than a block size, it's necessary to split input data into multiple blocks
           + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead.
             Frame metadata is not that costly, and quickly becomes negligible as source size grows larger.
    @@ -869,7 +871,7 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
             Use ZSTD_insertBlock() for such a case.
     
    -

    Raw zstd block functions

    size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
    +

    Raw zstd block functions

    size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);
     size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
     size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert block into `dctx` history. Useful for uncompressed blocks */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index b8fc8d987..f2d40edc9 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -410,7 +410,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
     
     size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
     {
    -    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
    +    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
         U32    const divider = (cParams.searchLength==3) ? 3 : 4;
         size_t const maxNbSeq = blockSize / divider;
         size_t const tokenSpace = blockSize + 11*maxNbSeq;
    @@ -436,8 +436,8 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
     static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
                                      ZSTD_compressionParameters cParams2)
     {
    -    U32 bslog1 = MIN(cParams1.windowLog, 17);
    -    U32 bslog2 = MIN(cParams2.windowLog, 17);
    +    U32 bslog1 = MIN(cParams1.windowLog, ZSTD_BLOCKSIZELOG_MAX);
    +    U32 bslog2 = MIN(cParams2.windowLog, ZSTD_BLOCKSIZELOG_MAX);
         return (bslog1 == bslog2)   /* same block size */
              & (cParams1.hashLog  == cParams2.hashLog)
              & (cParams1.chainLog == cParams2.chainLog)
    @@ -484,7 +484,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
                 return ZSTD_continueCCtx(zc, params, frameContentSize);
             }
     
    -    {   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    +    {   size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
             U32    const divider = (params.cParams.searchLength==3) ? 3 : 4;
             size_t const maxNbSeq = blockSize / divider;
             size_t const tokenSpace = blockSize + 11*maxNbSeq;
    @@ -2807,14 +2807,18 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
     }
     
     
    -size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
    +size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
     {
    -    return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
    +    U32 const cLevel = cctx->compressionLevel;
    +    ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
    +                                        cctx->params.cParams :
    +                                        ZSTD_getCParams(cLevel, 0, 0);
    +    return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
     }
     
     size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
    -    size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
    +    size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
         if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
         return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
     }
    @@ -3308,7 +3312,7 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
     size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
     {
         size_t const CCtxSize = ZSTD_estimateCCtxSize(cParams);
    -    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
    +    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
         size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
         size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
         size_t const streamingSize = inBuffSize + outBuffSize;
    @@ -3319,11 +3323,11 @@ size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
     
     /*======   Initialization   ======*/
     
    -size_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    +size_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_MAX; }
     
     size_t ZSTD_CStreamOutSize(void)
     {
    -    return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
    +    return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
     }
     
     static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize)
    @@ -3350,7 +3354,7 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
                                     unsigned long long pledgedSrcSize)
     {
         assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
    -    zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
    +    zcs->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
     
         /* allocate buffers */
         {   size_t const neededInBuffSize = ((size_t)1 << params.cParams.windowLog) + zcs->blockSize;
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 0c61960ec..03f8a9204 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -117,7 +117,7 @@ struct ZSTD_DCtx_s
         ZSTD_customMem customMem;
         size_t litSize;
         size_t rleSize;
    -    BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
    +    BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
         BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
     };  /* typedef'd to ZSTD_DCtx within "zstd.h" */
     
    @@ -173,7 +173,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
     
     void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
     {
    -    size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
    +    size_t const workSpaceSize = (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
         memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize);  /* no need to copy workspace */
     }
     
    @@ -483,7 +483,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
                         litCSize = (lhc >> 22) + (istart[4] << 10);
                         break;
                     }
    -                if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    +                if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
                     if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
     
                     if (HUF_isError((litEncType==set_repeat) ?
    @@ -555,7 +555,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
                         if (srcSize<4) return ERROR(corruption_detected);   /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
                         break;
                     }
    -                if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
    +                if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
                     memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
                     dctx->litPtr = dctx->litBuffer;
                     dctx->litSize = litSize;
    @@ -1288,7 +1288,7 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
     {   /* blockType == blockCompressed */
         const BYTE* ip = (const BYTE*)src;
     
    -    if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
    +    if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
     
         /* Decode literals section */
         {   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    @@ -2120,8 +2120,8 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
     
     /* *** Initialization *** */
     
    -size_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
    -size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
    +size_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; }
    +size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
     
     size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
     {
    @@ -2185,7 +2185,7 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
     size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader)
     {
         size_t const windowSize = fHeader.windowSize;
    -    size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +    size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
         size_t const inBuffSize = blockSize;  /* no block can be larger */
         size_t const outBuffSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
         return sizeof(ZSTD_DStream) + ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
    @@ -2281,7 +2281,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
     
                 /* Adapt buffer sizes to frame header instructions */
    -            {   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +            {   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_MAX);
                     size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
                     zds->blockSize = blockSize;
                     if (zds->inBuffSize < blockSize) {
    diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c
    index 179e02eff..943ddde0f 100644
    --- a/lib/dictBuilder/zdict.c
    +++ b/lib/dictBuilder/zdict.c
    @@ -576,7 +576,7 @@ typedef struct
     {
         ZSTD_CCtx* ref;
         ZSTD_CCtx* zc;
    -    void* workPlace;   /* must be ZSTD_BLOCKSIZE_ABSOLUTEMAX allocated */
    +    void* workPlace;   /* must be ZSTD_BLOCKSIZE_MAX allocated */
     } EStats_ress_t;
     
     #define MAXREPOFFSET 1024
    @@ -585,14 +585,14 @@ static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters params,
                                 U32* countLit, U32* offsetcodeCount, U32* matchlengthCount, U32* litlengthCount, U32* repOffsets,
                                 const void* src, size_t srcSize, U32 notificationLevel)
     {
    -    size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << params.cParams.windowLog);
    +    size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_MAX, 1 << params.cParams.windowLog);
         size_t cSize;
     
         if (srcSize > blockSizeMax) srcSize = blockSizeMax;   /* protection vs large samples */
         {  size_t const errorCode = ZSTD_copyCCtx(esr.zc, esr.ref, 0);
                 if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_copyCCtx failed \n"); return; }
         }
    -    cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_ABSOLUTEMAX, src, srcSize);
    +    cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize);
         if (ZSTD_isError(cSize)) { DISPLAYLEVEL(3, "warning : could not compress sample size %u \n", (U32)srcSize); return; }
     
         if (cSize) {  /* if == 0; block is not compressible */
    @@ -700,7 +700,7 @@ static size_t ZDICT_analyzeEntropy(void*  dstBuffer, size_t maxDstSize,
         /* init */
         esr.ref = ZSTD_createCCtx();
         esr.zc = ZSTD_createCCtx();
    -    esr.workPlace = malloc(ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +    esr.workPlace = malloc(ZSTD_BLOCKSIZE_MAX);
         if (!esr.ref || !esr.zc || !esr.workPlace) {
             eSize = ERROR(memory_allocation);
             DISPLAYLEVEL(1, "Not enough memory \n");
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 7931bd5de..5e4bc156e 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -1003,7 +1003,7 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
           + compression : any ZSTD_compressBegin*() variant, including with dictionary
           + decompression : any ZSTD_decompressBegin*() variant, including with dictionary
           + copyCCtx() and copyDCtx() can be used too
    -    - Block size is limited, it must be <= ZSTD_getBlockSizeMax() <= ZSTD_BLOCKSIZE_ABSOLUTEMAX
    +    - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX
           + If input is larger than a block size, it's necessary to split input data into multiple blocks
           + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead.
             Frame metadata is not that costly, and quickly becomes negligible as source size grows larger.
    @@ -1016,9 +1016,10 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
             Use ZSTD_insertBlock() for such a case.
     */
     
    -#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024)   /* define, for static allocation */
    +#define ZSTD_BLOCKSIZELOG_MAX 17
    +#define ZSTD_BLOCKSIZE_MAX   (1<= blockSize);
             cSize = ZSTD_compressBlock(cctx, compressedBuffer, ZSTD_compressBound(blockSize), CNBuffer, blockSize);
             if (ZSTD_isError(cSize)) goto _output_error;
             DISPLAYLEVEL(4, "OK \n");
    
    From 48855fa0d2308217d99c86cfc9d83818260e4dc4 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 10:56:11 -0700
    Subject: [PATCH 080/400] fixed declaration-after-statement warning
    
    ---
     lib/compress/zstd_compress.c | 5 +----
     1 file changed, 1 insertion(+), 4 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index f2d40edc9..69b42cc80 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3660,9 +3660,6 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
         size_t srcSize = 0;
         size_t sizeWritten = output->size - output->pos;
     
    -    DEBUGLOG(5, "calling ZSTD_endStream with outBuff=%u bytes",
    -                (unsigned)sizeWritten);
    -
         size_t const result = ZSTD_compressStream_generic(zcs,
                                     ostart, &sizeWritten,
                                     &srcSize /* valid address */, &srcSize,
    @@ -3670,7 +3667,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
         output->pos += sizeWritten;
         if (ZSTD_isError(result)) return result;
     
    -    DEBUGLOG(5, "remaining to flush : %u",
    +    DEBUGLOG(5, "ZSTD_endStream : remaining to flush : %u",
                 (unsigned)(zcs->outBuffContentSize - zcs->outBuffFlushedSize));
     
         return zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    
    From 334a288d0dda5cc43a80311dabde5b990c685ca6 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 11:04:41 -0700
    Subject: [PATCH 081/400] ZSTD_CCtx_setParameter() only works during
     initialization stage
    
    and generate a stage_wrong error otherwise.
    ---
     lib/compress/zstd_compress.c | 9 ++++++++-
     1 file changed, 8 insertions(+), 1 deletion(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 69b42cc80..a3d4ebe7f 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -223,7 +223,14 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
     
     size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
     {
    -#   define CLAMPCHECK(val,min,max) { if ((valmax)) return ERROR(compressionParameter_unsupported); }
    +#   define CLAMPCHECK(val,min,max) {                         \
    +        if ((valmax)) {                         \
    +            return ERROR(compressionParameter_unsupported);  \
    +    }   }
    +
    +    if (cctx->streamStage != zcss_init) {
    +        return ERROR(stage_wrong);
    +    }
     
         switch(param)
         {
    
    From 60a557e7fd597142e9221b50c90c6fe4af7776e8 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 11:27:43 -0700
    Subject: [PATCH 082/400] fixing symbol.c test
    
    I believe it would be better to rely on fuzzer tests compiled with dll
    ---
     tests/symbols.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/symbols.c b/tests/symbols.c
    index ade3aa02c..5139a6548 100644
    --- a/tests/symbols.c
    +++ b/tests/symbols.c
    @@ -95,7 +95,7 @@ static const void *symbols[] = {
       &ZSTD_nextSrcSizeToDecompress,
       &ZSTD_decompressContinue,
       &ZSTD_nextInputType,
    -  &ZSTD_getBlockSizeMax,
    +  &ZSTD_getBlockSize,
       &ZSTD_compressBlock,
       &ZSTD_decompressBlock,
       &ZSTD_insertBlock,
    
    From a1280406b012a7a5e4f145e9b39bc96efc7cebd6 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Fri, 19 May 2017 18:01:59 -0700
    Subject: [PATCH 083/400] [libzstd] Allow users to define custom visibility
    
    ---
     lib/common/zstd_errors.h | 10 ++++++----
     lib/dictBuilder/zdict.h  | 10 ++++++----
     lib/zstd.h               | 10 ++++++----
     3 files changed, 18 insertions(+), 12 deletions(-)
    
    diff --git a/lib/common/zstd_errors.h b/lib/common/zstd_errors.h
    index de0fc8984..e067acf6e 100644
    --- a/lib/common/zstd_errors.h
    +++ b/lib/common/zstd_errors.h
    @@ -19,10 +19,12 @@ extern "C" {
     
     
     /* =====   ZSTDERRORLIB_API : control library symbols visibility   ===== */
    -#if defined(__GNUC__) && (__GNUC__ >= 4)
    -#  define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default")))
    -#else
    -#  define ZSTDERRORLIB_VISIBILITY
    +#ifndef ZSTDERRORLIB_VISIBILITY
    +#  if defined(__GNUC__) && (__GNUC__ >= 4)
    +#    define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default")))
    +#  else
    +#    define ZSTDERRORLIB_VISIBILITY
    +#  endif
     #endif
     #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
     #  define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY
    diff --git a/lib/dictBuilder/zdict.h b/lib/dictBuilder/zdict.h
    index 9b53de346..5ef2a3f5b 100644
    --- a/lib/dictBuilder/zdict.h
    +++ b/lib/dictBuilder/zdict.h
    @@ -20,10 +20,12 @@ extern "C" {
     
     
     /* =====   ZDICTLIB_API : control library symbols visibility   ===== */
    -#if defined(__GNUC__) && (__GNUC__ >= 4)
    -#  define ZDICTLIB_VISIBILITY __attribute__ ((visibility ("default")))
    -#else
    -#  define ZDICTLIB_VISIBILITY
    +#ifndef ZDICTLIB_VISIBILITY
    +#  if defined(__GNUC__) && (__GNUC__ >= 4)
    +#    define ZDICTLIB_VISIBILITY __attribute__ ((visibility ("default")))
    +#  else
    +#    define ZDICTLIB_VISIBILITY
    +#  endif
     #endif
     #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
     #  define ZDICTLIB_API __declspec(dllexport) ZDICTLIB_VISIBILITY
    diff --git a/lib/zstd.h b/lib/zstd.h
    index d96a535f3..b0aae3f73 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -19,10 +19,12 @@ extern "C" {
     
     
     /* =====   ZSTDLIB_API : control library symbols visibility   ===== */
    -#if defined(__GNUC__) && (__GNUC__ >= 4)
    -#  define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default")))
    -#else
    -#  define ZSTDLIB_VISIBILITY
    +#ifndef ZSTDLIB_VISIBILITY
    +#  if defined(__GNUC__) && (__GNUC__ >= 4)
    +#    define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default")))
    +#  else
    +#    define ZSTDLIB_VISIBILITY
    +#  endif
     #endif
     #if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
     #  define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY
    
    From 8b21ec42a93ce2154eb50afd69e612b4bea764c9 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 19 May 2017 19:46:15 -0700
    Subject: [PATCH 084/400] ZSTD_compress_generic() can handle dictionary
     compression
    
    ---
     lib/compress/zstd_compress.c | 30 +++++++++++++++++++++++++-----
     1 file changed, 25 insertions(+), 5 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index a3d4ebe7f..94f006257 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -332,15 +332,21 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
     
     ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
     {
    +    DEBUGLOG(5, "ZSTD_CCtx_loadDictionary : dictSize = %u",
    +                (unsigned)dictSize);
         ZSTD_freeCDict(cctx->cdictLocal);  /* in case one already exists */
         if (dict==NULL || dictSize==0) {   /* no dictionary mode */
             cctx->cdictLocal = NULL;
             cctx->cdict = NULL;
         } else {
    +        ZSTD_compressionParameters const cParams =
    +                cctx->compressionLevel == ZSTD_CLEVEL_CUSTOM ?
    +                cctx->params.cParams :
    +                ZSTD_getCParams(cctx->compressionLevel, 0, dictSize);
             cctx->cdictLocal = ZSTD_createCDict_advanced(
                                     dict, dictSize,
                                     0 /* byReference */,
    -                                cctx->params.cParams, cctx->customMem);
    +                                cParams, cctx->customMem);
             cctx->cdict = cctx->cdictLocal;
             if (cctx->cdictLocal == NULL)
                 return ERROR(memory_allocation);
    @@ -3175,6 +3181,7 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
     ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
                                           ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
     {
    +    DEBUGLOG(5, "ZSTD_createCDict_advanced");
         if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
         if (!customMem.customAlloc || !customMem.customFree) return NULL;
     
    @@ -3182,6 +3189,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
             ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
     
             if (!cdict || !cctx) {
    +            DEBUGLOG(5, "!cdict || !cctx");
                 ZSTD_free(cdict, customMem);
                 ZSTD_freeCCtx(cctx);
                 return NULL;
    @@ -3192,16 +3200,25 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
                 cdict->dictContent = dictBuffer;
             } else {
                 void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    -            if (!internalBuffer) { ZSTD_free(cctx, customMem); ZSTD_free(cdict, customMem); return NULL; }
    +            if (!internalBuffer) {
    +                DEBUGLOG(5, "!internalBuffer");
    +                ZSTD_free(cctx, customMem);
    +                ZSTD_free(cdict, customMem);
    +                return NULL;
    +            }
                 memcpy(internalBuffer, dictBuffer, dictSize);
                 cdict->dictBuffer = internalBuffer;
                 cdict->dictContent = internalBuffer;
             }
     
    -        {   ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, 0 /* checksumFlag */, 0 /* noDictIDFlag */ };   /* dummy */
    +        {   ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
    +                    0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
                 ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
    -            size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
    +            size_t const errorCode = ZSTD_compressBegin_advanced(cctx,
    +                                cdict->dictContent, dictSize, params, 0);
                 if (ZSTD_isError(errorCode)) {
    +                DEBUGLOG(5, "ZSTD_compressBegin_advanced error : %s",
    +                            ZSTD_getErrorName(errorCode));
                     ZSTD_free(cdict->dictBuffer, customMem);
                     ZSTD_free(cdict, customMem);
                     ZSTD_freeCCtx(cctx);
    @@ -3532,7 +3549,10 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                     zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
                     if (zcs->inBuffTarget > zcs->inBuffSize)
                         zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;
    -                assert(zcs->inBuffTarget <= zcs->inBuffSize);
    +                DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
    +                         (U32)zcs->inBuffTarget, (U32)zcs->inBuffSize);
    +                if (!lastBlock)
    +                    assert(zcs->inBuffTarget <= zcs->inBuffSize);
                     zcs->inToCompress = zcs->inBuffPos;
                     if (cDst == op) {  /* no need to flush */
                         op += cSize;
    
    From 24de7b0346c0bf867482af0c4d987164453d1970 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 22 May 2017 13:05:45 -0700
    Subject: [PATCH 085/400] Implemented ZSTD_CCtx_refCDict()
    
    ---
     lib/compress/zstd_compress.c | 14 ++++++--------
     lib/zstd.h                   |  2 +-
     2 files changed, 7 insertions(+), 9 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 94f006257..ae49938f7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -228,9 +228,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 return ERROR(compressionParameter_unsupported);  \
         }   }
     
    -    if (cctx->streamStage != zcss_init) {
    -        return ERROR(stage_wrong);
    -    }
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
     
         switch(param)
         {
    @@ -326,14 +324,14 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
     
     ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)
     {
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         cctx->frameContentSize = pledgedSrcSize;
         return 0;
     }
     
     ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
     {
    -    DEBUGLOG(5, "ZSTD_CCtx_loadDictionary : dictSize = %u",
    -                (unsigned)dictSize);
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         ZSTD_freeCDict(cctx->cdictLocal);  /* in case one already exists */
         if (dict==NULL || dictSize==0) {   /* no dictionary mode */
             cctx->cdictLocal = NULL;
    @@ -358,13 +356,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
     ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
     {
         (void)cctx; (void)prefix; (void)prefixSize; /* to be done later */
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         return ERROR(compressionParameter_unsupported);
     }
     
    -/* Not ready yet ! */
     ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
     {
    -    (void)cctx; (void)cdict;  /* to be done later */
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
    +    cctx->cdict = cdict;
         return ERROR(compressionParameter_unsupported);
     }
     
    @@ -384,7 +383,6 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
         return 0;
     }
     
    -
     /** ZSTD_cycleLog() :
      *  condition for correct operation : hashLog > 1 */
     static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 5a0206a01..83fe9d30f 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -746,7 +746,7 @@ ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict
      *           Adding a new dictionary effectively "discards" any previous one.
      *  Note 2 : CDict is just referenced, its lifetime must outlive CCtx.
      */
    -ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);  /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
     
     
     
    
    From 1ad7c82eb50a0d502fa9616920c65c53a1a01c1a Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 22 May 2017 17:06:04 -0700
    Subject: [PATCH 086/400] Implemented separation between requested and applied
     parameters
    
    first version to pass cli tests with -DZSTD_NEWAPI
    ---
     lib/compress/zstd_compress.c | 176 +++++++++++++++++++----------------
     lib/compress/zstd_opt.h      |  21 +++--
     2 files changed, 108 insertions(+), 89 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index ae49938f7..0e694d2ef 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -110,7 +110,8 @@ struct ZSTD_CCtx_s {
         U32   repToConfirm[ZSTD_REP_NUM];
         U32   dictID;
         int   compressionLevel;
    -    ZSTD_parameters params;
    +    ZSTD_parameters requestedParams;
    +    ZSTD_parameters appliedParams;
         void* workSpace;
         size_t workSpaceSize;
         size_t blockSize;
    @@ -198,7 +199,7 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
     /* private API call, for dictBuilder only */
     const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
     
    -static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) { return cctx->params; }
    +static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx) { return cctx->appliedParams; }
     
     /* older variant; will be deprecated */
     size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
    @@ -215,9 +216,9 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
     #define ZSTD_CLEVEL_CUSTOM 999
     static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
     {
    -    if (cctx->compressionLevel==ZSTD_CLEVEL_CUSTOM)  return;
    -    cctx->params.cParams = ZSTD_getCParams(cctx->compressionLevel,
    -                                           cctx->frameContentSize, 0);
    +    if (cctx->compressionLevel==ZSTD_CLEVEL_CUSTOM) return;
    +    cctx->requestedParams.cParams = ZSTD_getCParams(cctx->compressionLevel,
    +                                                    cctx->frameContentSize, 0);
         cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM;
     }
     
    @@ -242,49 +243,49 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.windowLog = value;
    +            cctx->requestedParams.cParams.windowLog = value;
                 return 0;
     
         case ZSTD_p_hashLog :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.hashLog = value;
    +            cctx->requestedParams.cParams.hashLog = value;
                 return 0;
     
         case ZSTD_p_chainLog :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.chainLog = value;
    +            cctx->requestedParams.cParams.chainLog = value;
                 return 0;
     
         case ZSTD_p_searchLog :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.searchLog = value;
    +            cctx->requestedParams.cParams.searchLog = value;
                 return 0;
     
         case ZSTD_p_minMatch :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.searchLength = value;
    +            cctx->requestedParams.cParams.searchLength = value;
                 return 0;
     
         case ZSTD_p_targetLength :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.targetLength = value;
    +            cctx->requestedParams.cParams.targetLength = value;
                 return 0;
     
         case ZSTD_p_compressionStrategy :
                 if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
                 CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
                 ZSTD_cLevelToCParams(cctx);
    -            cctx->params.cParams.strategy = (ZSTD_strategy)value;
    +            cctx->requestedParams.cParams.strategy = (ZSTD_strategy)value;
                 return 0;
     
     #if 0
    @@ -293,15 +294,16 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
     #endif
     
         case ZSTD_p_contentSizeFlag : /* Content size will be written in frame header _when known_ (default:1) */
    -            cctx->params.fParams.contentSizeFlag = value>0;
    +            cctx->requestedParams.fParams.contentSizeFlag = value>0;
                 return 0;
     
         case ZSTD_p_checksumFlag : /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
    -            cctx->params.fParams.checksumFlag = value>0;
    +            cctx->requestedParams.fParams.checksumFlag = value>0;
                 return 0;
     
    -    case ZSTD_p_dictIDFlag : /* When applicable, the dictID of used dictionary will be provided in frame header (default:1) */
    -            cctx->params.fParams.noDictIDFlag = value==0;
    +    case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
    +            DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
    +            cctx->requestedParams.fParams.noDictIDFlag = (value==0);
                 return 0;
     
         case ZSTD_p_refDictContent :   /* to be done later */
    @@ -339,7 +341,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
         } else {
             ZSTD_compressionParameters const cParams =
                     cctx->compressionLevel == ZSTD_CLEVEL_CUSTOM ?
    -                cctx->params.cParams :
    +                cctx->requestedParams.cParams :
                     ZSTD_getCParams(cctx->compressionLevel, 0, dictSize);
             cctx->cdictLocal = ZSTD_createCDict_advanced(
                                     dict, dictSize,
    @@ -461,7 +463,7 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
     static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
     {
         U32 const end = (U32)(cctx->nextSrc - cctx->base);
    -    cctx->params = params;
    +    cctx->appliedParams = params;
         cctx->frameContentSize = frameContentSize;
         cctx->consumedSrcSize = 0;
         cctx->lowLimit = end;
    @@ -485,10 +487,10 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
                                            ZSTD_compResetPolicy_e const crp)
     {
         DEBUGLOG(5, "ZSTD_resetCCtx_internal : wlog=%u / old=%u",
    -                params.cParams.windowLog, zc->params.cParams.windowLog);
    +                params.cParams.windowLog, zc->appliedParams.cParams.windowLog);
     
         if (crp == ZSTDcrp_continue)
    -        if (ZSTD_equivalentParams(params.cParams, zc->params.cParams)) {
    +        if (ZSTD_equivalentParams(params.cParams, zc->appliedParams.cParams)) {
                 DEBUGLOG(5, "ZSTD_equivalentParams()==1");
                 zc->fseCTables_ready = 0;
                 zc->hufCTable_repeatMode = HUF_repeat_none;
    @@ -538,7 +540,7 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
             }   }
     
             /* init params */
    -        zc->params = params;
    +        zc->appliedParams = params;
             zc->blockSize = blockSize;
             DEBUGLOG(5, "blockSize = %uK", (U32)blockSize>>10);
             zc->frameContentSize = frameContentSize;
    @@ -618,22 +620,24 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
      *  Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
      *  pledgedSrcSize=0 means "empty" if fParams.contentSizeFlag=1
      *  @return : 0, or an error code */
    -size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx,
    -                              ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize)
    +static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
    +                            const ZSTD_CCtx* srcCCtx,
    +                            ZSTD_frameParameters fParams,
    +                            unsigned long long pledgedSrcSize)
     {
         DEBUGLOG(5, "ZSTD_copyCCtx_internal");
         if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
     
         memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    -    {   ZSTD_parameters params = srcCCtx->params;
    +    {   ZSTD_parameters params = srcCCtx->appliedParams;
             params.fParams = fParams;
             DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u", !fParams.noDictIDFlag);
             ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
         }
     
         /* copy tables */
    -    {   size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
    -        size_t const hSize =  (size_t)1 << srcCCtx->params.cParams.hashLog;
    +    {   size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->appliedParams.cParams.chainLog);
    +        size_t const hSize =  (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
             size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
             size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
             assert((U32*)dstCCtx->chainTable == (U32*)dstCCtx->hashTable + hSize);  /* chainTable must follow hashTable */
    @@ -696,10 +700,10 @@ static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reduce
     *   rescale all indexes to avoid future overflow (indexes are U32) */
     static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
     {
    -    { U32 const hSize = 1 << zc->params.cParams.hashLog;
    +    { U32 const hSize = 1 << zc->appliedParams.cParams.hashLog;
           ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
     
    -    { U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
    +    { U32 const chainSize = (zc->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->appliedParams.cParams.chainLog);
           ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
     
         { U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
    @@ -795,7 +799,7 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
     
         if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
         {   HUF_repeat repeat = zc->hufCTable_repeatMode;
    -        int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
    +        int const preferRepeat = zc->appliedParams.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
             if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
             cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
                                           zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat)
    @@ -884,7 +888,7 @@ MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
                                   void* dst, size_t dstCapacity,
                                   size_t srcSize)
     {
    -    const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
    +    const int longOffsets = zc->appliedParams.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
         const seqStore_t* seqStorePtr = &(zc->seqStore);
         U32 count[MaxSeq+1];
         S16 norm[MaxSeq+1];
    @@ -1280,7 +1284,7 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
     static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
     {
         U32* const hashTable = zc->hashTable;
    -    U32  const hBits = zc->params.cParams.hashLog;
    +    U32  const hBits = zc->appliedParams.cParams.hashLog;
         const BYTE* const base = zc->base;
         const BYTE* ip = base + zc->nextToUpdate;
         const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    @@ -1299,7 +1303,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
                                    const U32 mls)
     {
         U32* const hashTable = cctx->hashTable;
    -    U32  const hBits = cctx->params.cParams.hashLog;
    +    U32  const hBits = cctx->appliedParams.cParams.hashLog;
         seqStore_t* seqStorePtr = &(cctx->seqStore);
         const BYTE* const base = cctx->base;
         const BYTE* const istart = (const BYTE*)src;
    @@ -1384,7 +1388,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
     static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
                            const void* src, size_t srcSize)
     {
    -    const U32 mls = ctx->params.cParams.searchLength;
    +    const U32 mls = ctx->appliedParams.cParams.searchLength;
         switch(mls)
         {
         default: /* includes case 3 */
    @@ -1405,7 +1409,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
                                      const U32 mls)
     {
         U32* hashTable = ctx->hashTable;
    -    const U32 hBits = ctx->params.cParams.hashLog;
    +    const U32 hBits = ctx->appliedParams.cParams.hashLog;
         seqStore_t* seqStorePtr = &(ctx->seqStore);
         const BYTE* const base = ctx->base;
         const BYTE* const dictBase = ctx->dictBase;
    @@ -1498,7 +1502,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
     static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
                              const void* src, size_t srcSize)
     {
    -    U32 const mls = ctx->params.cParams.searchLength;
    +    U32 const mls = ctx->appliedParams.cParams.searchLength;
         switch(mls)
         {
         default: /* includes case 3 */
    @@ -1520,9 +1524,9 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
     static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
     {
         U32* const hashLarge = cctx->hashTable;
    -    U32  const hBitsL = cctx->params.cParams.hashLog;
    +    U32  const hBitsL = cctx->appliedParams.cParams.hashLog;
         U32* const hashSmall = cctx->chainTable;
    -    U32  const hBitsS = cctx->params.cParams.chainLog;
    +    U32  const hBitsS = cctx->appliedParams.cParams.chainLog;
         const BYTE* const base = cctx->base;
         const BYTE* ip = base + cctx->nextToUpdate;
         const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
    @@ -1542,9 +1546,9 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
                                      const U32 mls)
     {
         U32* const hashLong = cctx->hashTable;
    -    const U32 hBitsL = cctx->params.cParams.hashLog;
    +    const U32 hBitsL = cctx->appliedParams.cParams.hashLog;
         U32* const hashSmall = cctx->chainTable;
    -    const U32 hBitsS = cctx->params.cParams.chainLog;
    +    const U32 hBitsS = cctx->appliedParams.cParams.chainLog;
         seqStore_t* seqStorePtr = &(cctx->seqStore);
         const BYTE* const base = cctx->base;
         const BYTE* const istart = (const BYTE*)src;
    @@ -1654,7 +1658,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
     
     static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
     {
    -    const U32 mls = ctx->params.cParams.searchLength;
    +    const U32 mls = ctx->appliedParams.cParams.searchLength;
         switch(mls)
         {
         default: /* includes case 3 */
    @@ -1675,9 +1679,9 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
                                      const U32 mls)
     {
         U32* const hashLong = ctx->hashTable;
    -    U32  const hBitsL = ctx->params.cParams.hashLog;
    +    U32  const hBitsL = ctx->appliedParams.cParams.hashLog;
         U32* const hashSmall = ctx->chainTable;
    -    U32  const hBitsS = ctx->params.cParams.chainLog;
    +    U32  const hBitsS = ctx->appliedParams.cParams.chainLog;
         seqStore_t* seqStorePtr = &(ctx->seqStore);
         const BYTE* const base = ctx->base;
         const BYTE* const dictBase = ctx->dictBase;
    @@ -1804,7 +1808,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
     static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
                              const void* src, size_t srcSize)
     {
    -    U32 const mls = ctx->params.cParams.searchLength;
    +    U32 const mls = ctx->appliedParams.cParams.searchLength;
         switch(mls)
         {
         default: /* includes case 3 */
    @@ -1830,10 +1834,10 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
                               U32 extDict)
     {
         U32*   const hashTable = zc->hashTable;
    -    U32    const hashLog = zc->params.cParams.hashLog;
    +    U32    const hashLog = zc->appliedParams.cParams.hashLog;
         size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
         U32*   const bt = zc->chainTable;
    -    U32    const btLog  = zc->params.cParams.chainLog - 1;
    +    U32    const btLog  = zc->appliedParams.cParams.chainLog - 1;
         U32    const btMask = (1 << btLog) - 1;
         U32 matchIndex = hashTable[h];
         size_t commonLengthSmaller=0, commonLengthLarger=0;
    @@ -1935,10 +1939,10 @@ static size_t ZSTD_insertBtAndFindBestMatch (
                             U32 extDict)
     {
         U32*   const hashTable = zc->hashTable;
    -    U32    const hashLog = zc->params.cParams.hashLog;
    +    U32    const hashLog = zc->appliedParams.cParams.hashLog;
         size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
         U32*   const bt = zc->chainTable;
    -    U32    const btLog  = zc->params.cParams.chainLog - 1;
    +    U32    const btLog  = zc->appliedParams.cParams.chainLog - 1;
         U32    const btMask = (1 << btLog) - 1;
         U32 matchIndex  = hashTable[h];
         size_t commonLengthSmaller=0, commonLengthLarger=0;
    @@ -2098,9 +2102,9 @@ FORCE_INLINE
     U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
     {
         U32* const hashTable  = zc->hashTable;
    -    const U32 hashLog = zc->params.cParams.hashLog;
    +    const U32 hashLog = zc->appliedParams.cParams.hashLog;
         U32* const chainTable = zc->chainTable;
    -    const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
    +    const U32 chainMask = (1 << zc->appliedParams.cParams.chainLog) - 1;
         const BYTE* const base = zc->base;
         const U32 target = (U32)(ip - base);
         U32 idx = zc->nextToUpdate;
    @@ -2126,7 +2130,7 @@ size_t ZSTD_HcFindBestMatch_generic (
                             const U32 maxNbAttempts, const U32 mls, const U32 extDict)
     {
         U32* const chainTable = zc->chainTable;
    -    const U32 chainSize = (1 << zc->params.cParams.chainLog);
    +    const U32 chainSize = (1 << zc->appliedParams.cParams.chainLog);
         const U32 chainMask = chainSize-1;
         const BYTE* const base = zc->base;
         const BYTE* const dictBase = zc->dictBase;
    @@ -2220,8 +2224,8 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
         const BYTE* const ilimit = iend - 8;
         const BYTE* const base = ctx->base + ctx->dictLimit;
     
    -    U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
    -    U32 const mls = ctx->params.cParams.searchLength;
    +    U32 const maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
    +    U32 const mls = ctx->appliedParams.cParams.searchLength;
     
         typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
                             size_t* offsetPtr,
    @@ -2384,8 +2388,8 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
         const BYTE* const dictEnd  = dictBase + dictLimit;
         const BYTE* const dictStart  = dictBase + ctx->lowLimit;
     
    -    const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
    -    const U32 mls = ctx->params.cParams.searchLength;
    +    const U32 maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
    +    const U32 mls = ctx->appliedParams.cParams.searchLength;
     
         typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
                             size_t* offsetPtr,
    @@ -2625,7 +2629,7 @@ static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int
     
     static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
    -    ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
    +    ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, zc->lowLimit < zc->dictLimit);
         const BYTE* const base = zc->base;
         const BYTE* const istart = (const BYTE*)src;
         const U32 current = (U32)(istart-base);
    @@ -2655,9 +2659,9 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
         const BYTE* ip = (const BYTE*)src;
         BYTE* const ostart = (BYTE*)dst;
         BYTE* op = ostart;
    -    U32 const maxDist = 1 << cctx->params.cParams.windowLog;
    +    U32 const maxDist = 1 << cctx->appliedParams.cParams.windowLog;
     
    -    if (cctx->params.fParams.checksumFlag && srcSize)
    +    if (cctx->appliedParams.fParams.checksumFlag && srcSize)
             XXH64_update(&cctx->xxhState, src, srcSize);
     
         while (remaining) {
    @@ -2670,9 +2674,9 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
     
             /* preemptive overflow correction */
             if (cctx->lowLimit > (3U<<29)) {
    -            U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
    +            U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->appliedParams.cParams.hashLog, cctx->appliedParams.cParams.strategy)) - 1;
                 U32 const current = (U32)(ip - cctx->base);
    -            U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
    +            U32 const newCurrent = (current & cycleMask) + (1 << cctx->appliedParams.cParams.windowLog);
                 U32 const correction = current - newCurrent;
                 ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
                 ZSTD_reduceIndex(cctx, correction);
    @@ -2770,7 +2774,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
         if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong);   /* missing init (ZSTD_compressBegin) */
     
         if (frame && (cctx->stage==ZSTDcs_init)) {
    -        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
    +        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, cctx->frameContentSize, cctx->dictID);
             if (ZSTD_isError(fhSize)) return fhSize;
             dstCapacity -= fhSize;
             dst = (char*)dst + fhSize;
    @@ -2822,7 +2826,7 @@ size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
     {
         U32 const cLevel = cctx->compressionLevel;
         ZSTD_compressionParameters cParams = (cLevel == ZSTD_CLEVEL_CUSTOM) ?
    -                                        cctx->params.cParams :
    +                                        cctx->appliedParams.cParams :
                                             ZSTD_getCParams(cLevel, 0, 0);
         return MIN (ZSTD_BLOCKSIZE_MAX, 1 << cParams.windowLog);
     }
    @@ -2853,28 +2857,28 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
         zc->nextSrc = iend;
         if (srcSize <= HASH_READ_SIZE) return 0;
     
    -    switch(zc->params.cParams.strategy)
    +    switch(zc->appliedParams.cParams.strategy)
         {
         case ZSTD_fast:
    -        ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
    +        ZSTD_fillHashTable (zc, iend, zc->appliedParams.cParams.searchLength);
             break;
     
         case ZSTD_dfast:
    -        ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
    +        ZSTD_fillDoubleHashTable (zc, iend, zc->appliedParams.cParams.searchLength);
             break;
     
         case ZSTD_greedy:
         case ZSTD_lazy:
         case ZSTD_lazy2:
             if (srcSize >= HASH_READ_SIZE)
    -            ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
    +            ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->appliedParams.cParams.searchLength);
             break;
     
         case ZSTD_btlazy2:
         case ZSTD_btopt:
         case ZSTD_btultra:
             if (srcSize >= HASH_READ_SIZE)
    -            ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
    +            ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->appliedParams.cParams.searchLog, zc->appliedParams.cParams.searchLength);
             break;
     
         default:
    @@ -2918,7 +2922,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
         BYTE scratchBuffer[1<dictID = cctx->params.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
    +    cctx->dictID = cctx->appliedParams.fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);
         dictPtr += 4;
     
         {   size_t const hufHeaderSize = HUF_readCTable(cctx->hufCTable, 255, dictPtr, dictEnd-dictPtr);
    @@ -3053,7 +3057,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
     
         /* special case : empty frame */
         if (cctx->stage == ZSTDcs_init) {
    -        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
    +        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
             if (ZSTD_isError(fhSize)) return fhSize;
             dstCapacity -= fhSize;
             op += fhSize;
    @@ -3069,7 +3073,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
             dstCapacity -= ZSTD_blockHeaderSize;
         }
     
    -    if (cctx->params.fParams.checksumFlag) {
    +    if (cctx->appliedParams.fParams.checksumFlag) {
             U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
             if (dstCapacity<4) return ERROR(dstSize_tooSmall);
             MEM_writeLE32(op, checksum);
    @@ -3092,7 +3096,7 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
         if (ZSTD_isError(cSize)) return cSize;
         endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
         if (ZSTD_isError(endResult)) return endResult;
    -    if (cctx->params.fParams.contentSizeFlag) {  /* control src size */
    +    if (cctx->appliedParams.fParams.contentSizeFlag) {  /* control src size */
             if (cctx->frameContentSize != cctx->consumedSrcSize)
                 return ERROR(srcSize_wrong);
         }
    @@ -3269,7 +3273,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
         if (cdict->dictContentSize)
             CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) )
         else {
    -        ZSTD_parameters params = cdict->refContext->params;
    +        ZSTD_parameters params = cdict->refContext->appliedParams;
             params.fParams = fParams;
             CHECK_F(ZSTD_compressBegin_internal(cctx, NULL, 0, params, pledgedSrcSize));
         }
    @@ -3352,12 +3356,16 @@ size_t ZSTD_CStreamOutSize(void)
         return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
     }
     
    -static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, ZSTD_parameters params, unsigned long long pledgedSrcSize)
    +static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
    +                                        ZSTD_parameters params,
    +                                        unsigned long long pledgedSrcSize)
     {
    -    DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u", !zcs->params.fParams.noDictIDFlag);
    +    DEBUGLOG(5, "ZSTD_resetCStream_internal");
     
    -    if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize))
    -    else CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, params, pledgedSrcSize));
    +    if (zcs->cdict)
    +        CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize))
    +    else
    +        CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, params, pledgedSrcSize));
     
         zcs->inToCompress = 0;
         zcs->inBuffPos = 0;
    @@ -3375,6 +3383,7 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
                                     const ZSTD_parameters params,
                                     unsigned long long pledgedSrcSize)
     {
    +    DEBUGLOG(5, "ZSTD_initCStream_stage2");
         assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         zcs->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
     
    @@ -3402,8 +3411,8 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
     
     size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
     {
    -
    -    ZSTD_parameters params = zcs->params;
    +    DEBUGLOG(5, "ZSTD_resetCStream");
    +    ZSTD_parameters params = zcs->requestedParams;
         params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
         if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
             params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
    @@ -3421,6 +3430,8 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
         if (!cdict) return ERROR(dictionary_wrong);
         {   ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
             params.fParams = fParams;
    +        zcs->requestedParams = params;
    +        zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
             zcs->cdict = cdict;
             return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
         }
    @@ -3430,6 +3441,8 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
     size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
     {
         ZSTD_frameParameters const fParams = { 0 /* contentSize */, 0 /* checksum */, 0 /* hideDictID */ };
    +    /* cannot handle NULL cdict (does not know what to do) */
    +    if (!cdict) return ERROR(dictionary_wrong);
         return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, 0, fParams);
     }
     
    @@ -3455,12 +3468,15 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
                                      ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
         CHECK_F( ZSTD_checkCParams(params.cParams) );
    +    zcs->requestedParams = params;
    +    zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
         return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize);
     }
     
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
     {
         ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
    +    zcs->compressionLevel = compressionLevel;
         return ZSTD_initCStream_internal(zcs, dict, dictSize, params, 0);
     }
     
    @@ -3505,7 +3521,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
         while (someMoreWork) {
             switch(zcs->streamStage)
             {
    -        case zcss_init: return ERROR(init_missing);   /* call ZSTD_initCStream() first ! */
    +        case zcss_init:
    +            /* call ZSTD_initCStream() first ! */
    +            return ERROR(init_missing);
     
             case zcss_load:
                 /* complete inBuffer */
    @@ -3628,7 +3646,7 @@ size_t ZSTD_compress_generic_integral (
         assert(cctx!=NULL);
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
    -        ZSTD_parameters params = cctx->params;
    +        ZSTD_parameters params = cctx->requestedParams;
             DEBUGLOG(5, "ZSTD_compress_generic_integral : transparent reset");
             if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
                 params.cParams = ZSTD_getCParams(cctx->compressionLevel,
    diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
    index 543761191..38c1ca620 100644
    --- a/lib/compress/zstd_opt.h
    +++ b/lib/compress/zstd_opt.h
    @@ -43,6 +43,7 @@ MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t src
         if (ssPtr->litLengthSum == 0) {
             if (srcSize <= 1024) ssPtr->staticPrices = 1;
     
    +        assert(ssPtr->litFreq!=NULL);
             for (u=0; u<=MaxLit; u++)
                 ssPtr->litFreq[u] = 0;
             for (u=0; ubase;
         const U32 current = (U32)(ip-base);
    -    const U32 hashLog = zc->params.cParams.hashLog;
    +    const U32 hashLog = zc->appliedParams.cParams.hashLog;
         const size_t h  = ZSTD_hashPtr(ip, hashLog, mls);
         U32* const hashTable = zc->hashTable;
         U32 matchIndex  = hashTable[h];
         U32* const bt   = zc->chainTable;
    -    const U32 btLog = zc->params.cParams.chainLog - 1;
    +    const U32 btLog = zc->appliedParams.cParams.chainLog - 1;
         const U32 btMask= (1U << btLog) - 1;
         size_t commonLengthSmaller=0, commonLengthLarger=0;
         const BYTE* const dictBase = zc->dictBase;
    @@ -410,10 +411,10 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
         const BYTE* const base = ctx->base;
         const BYTE* const prefixStart = base + ctx->dictLimit;
     
    -    const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
    -    const U32 sufficient_len = ctx->params.cParams.targetLength;
    -    const U32 mls = ctx->params.cParams.searchLength;
    -    const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
    +    const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
    +    const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
    +    const U32 mls = ctx->appliedParams.cParams.searchLength;
    +    const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
     
         ZSTD_optimal_t* opt = seqStorePtr->priceTable;
         ZSTD_match_t* matches = seqStorePtr->matchTable;
    @@ -663,10 +664,10 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
         const BYTE* const dictBase = ctx->dictBase;
         const BYTE* const dictEnd  = dictBase + dictLimit;
     
    -    const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
    -    const U32 sufficient_len = ctx->params.cParams.targetLength;
    -    const U32 mls = ctx->params.cParams.searchLength;
    -    const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
    +    const U32 maxSearches = 1U << ctx->appliedParams.cParams.searchLog;
    +    const U32 sufficient_len = ctx->appliedParams.cParams.targetLength;
    +    const U32 mls = ctx->appliedParams.cParams.searchLength;
    +    const U32 minMatch = (ctx->appliedParams.cParams.searchLength == 3) ? 3 : 4;
     
         ZSTD_optimal_t* opt = seqStorePtr->priceTable;
         ZSTD_match_t* matches = seqStorePtr->matchTable;
    
    From b0739bcf8f90ce2fbb8944293997f338d5f1db89 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 22 May 2017 17:45:15 -0700
    Subject: [PATCH 087/400] simplified reset by removing full-reset policy
    
    this was meant to be applied prior to dictionary loading.
    But effectively, it seems redundant with later loading stage,
    so it can be skipped safely.
    ---
     doc/zstd_manual.html         |  2 +-
     lib/compress/zstd_compress.c | 12 +++++-------
     2 files changed, 6 insertions(+), 8 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index de0ee4339..c64c4290a 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -616,7 +616,7 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
      
     


    -
    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);  /* Not ready yet ! */
    +
    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
     

    Add a prepared dictionary to cctx, to be used for next compression jobs. Note that compression parameters will be enforced from within CDict. Currently, they supercede any compression parameter previously set within CCtx. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 0e694d2ef..be85bd49f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -478,7 +478,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra return 0; } -typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e; +typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; /*! ZSTD_resetCCtx_internal() : note : `params` must be validated */ @@ -489,13 +489,13 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, DEBUGLOG(5, "ZSTD_resetCCtx_internal : wlog=%u / old=%u", params.cParams.windowLog, zc->appliedParams.cParams.windowLog); - if (crp == ZSTDcrp_continue) + if (crp == ZSTDcrp_continue) { if (ZSTD_equivalentParams(params.cParams, zc->appliedParams.cParams)) { DEBUGLOG(5, "ZSTD_equivalentParams()==1"); zc->fseCTables_ready = 0; zc->hufCTable_repeatMode = HUF_repeat_none; return ZSTD_continueCCtx(zc, params, frameContentSize); - } + } } { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog); U32 const divider = (params.cParams.searchLength==3) ? 3 : 4; @@ -631,7 +631,6 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); { ZSTD_parameters params = srcCCtx->appliedParams; params.fParams = fParams; - DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u", !fParams.noDictIDFlag); ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset); } @@ -3011,9 +3010,8 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, U64 pledgedSrcSize) { - ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue; assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); - CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, crp)); + CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, ZSTDcrp_continue)); return ZSTD_compress_insertDictionary(cctx, dict, dictSize); } @@ -3411,9 +3409,9 @@ static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs, size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) { - DEBUGLOG(5, "ZSTD_resetCStream"); ZSTD_parameters params = zcs->requestedParams; params.fParams.contentSizeFlag = (pledgedSrcSize > 0); + DEBUGLOG(5, "ZSTD_resetCStream"); if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) { params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */); } From 1880337c301de6afb60cb0401016da714f6e49c5 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 22 May 2017 18:21:51 -0700 Subject: [PATCH 088/400] Simplifier compression call graph Everything converge towards ZSTD_compressBegin_internal which delegated to ZSTD_copyCCtx_internal if cdict!=NULL. This simplifies routing which was previously depending on cdict. --- lib/compress/zstd_compress.c | 41 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index be85bd49f..b8648eb43 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -93,6 +93,13 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr) ***************************************/ typedef enum { zcss_init=0, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage; +struct ZSTD_CDict_s { + void* dictBuffer; + const void* dictContent; + size_t dictContentSize; + ZSTD_CCtx* refContext; +}; /* typedef'd tp ZSTD_CDict within "zstd.h" */ + struct ZSTD_CCtx_s { const BYTE* nextSrc; /* next block here to continue on current prefix */ const BYTE* base; /* All regular indexes relative to this position */ @@ -3008,9 +3015,15 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, * @return : 0, or an error code */ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, + const ZSTD_CDict* cdict, ZSTD_parameters params, U64 pledgedSrcSize) { assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + + if (cdict && cdict->dictContentSize>0) + return ZSTD_copyCCtx_internal(cctx, cdict->refContext, params.fParams, pledgedSrcSize); + CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, ZSTDcrp_continue)); return ZSTD_compress_insertDictionary(cctx, dict, dictSize); } @@ -3024,14 +3037,14 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, { /* compression parameters verification and optimization */ CHECK_F(ZSTD_checkCParams(params.cParams)); - return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, pledgedSrcSize); } size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); - return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, 0); } @@ -3108,7 +3121,7 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx, const void* dict,size_t dictSize, ZSTD_parameters params) { - CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize)); + CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, srcSize)); return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); } @@ -3149,13 +3162,6 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS /* ===== Dictionary API ===== */ -struct ZSTD_CDict_s { - void* dictBuffer; - const void* dictContent; - size_t dictContentSize; - ZSTD_CCtx* refContext; -}; /* typedef'd tp ZSTD_CDict within "zstd.h" */ - /*! ZSTD_estimateCDictSize() : * Estimate amount of memory that will be needed to create a dictionary with following arguments */ size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize) @@ -3267,15 +3273,11 @@ size_t ZSTD_compressBegin_usingCDict_advanced( ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) { if (cdict==NULL) return ERROR(dictionary_wrong); /* does not support NULL cdict */ - DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u", !fParams.noDictIDFlag); - if (cdict->dictContentSize) - CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) ) - else { - ZSTD_parameters params = cdict->refContext->appliedParams; + { ZSTD_parameters params = cdict->refContext->appliedParams; params.fParams = fParams; - CHECK_F(ZSTD_compressBegin_internal(cctx, NULL, 0, params, pledgedSrcSize)); + DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced"); + return ZSTD_compressBegin_internal(cctx, NULL, 0, cdict, params, pledgedSrcSize); } - return 0; } /* ZSTD_compressBegin_usingCDict() : @@ -3360,10 +3362,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, { DEBUGLOG(5, "ZSTD_resetCStream_internal"); - if (zcs->cdict) - CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs, zcs->cdict, params.fParams, pledgedSrcSize)) - else - CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, params, pledgedSrcSize)); + CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize)); zcs->inToCompress = 0; zcs->inBuffPos = 0; From 5ac72b417c438cdf36fffabb60ace0884ead500f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 23 May 2017 11:18:24 -0700 Subject: [PATCH 089/400] Buffered are now allocated inside workSpace --- lib/compress/zstd_compress.c | 115 +++++++++++++++++------------------ 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b8648eb43..0bed04fb4 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -182,10 +182,6 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx) cctx->workSpace = NULL; ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL; - ZSTD_free(cctx->inBuff, cctx->customMem); - cctx->inBuff = NULL; - ZSTD_free(cctx->outBuff, cctx->customMem); - cctx->outBuff = NULL; ZSTD_free(cctx, cctx->customMem); return 0; /* reserved as a potential error code in the future */ } @@ -487,14 +483,18 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; +typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; + /*! ZSTD_resetCCtx_internal() : - note : `params` must be validated */ -static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, - ZSTD_parameters params, U64 frameContentSize, - ZSTD_compResetPolicy_e const crp) + note : `params` are assumed fully validated at this stage */ +static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, + ZSTD_parameters params, U64 frameContentSize, + ZSTD_compResetPolicy_e const crp, + ZSTD_buffered_policy_e const zbuff) { DEBUGLOG(5, "ZSTD_resetCCtx_internal : wlog=%u / old=%u", params.cParams.windowLog, zc->appliedParams.cParams.windowLog); + assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); if (crp == ZSTDcrp_continue) { if (ZSTD_equivalentParams(params.cParams, zc->appliedParams.cParams)) { @@ -508,11 +508,15 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, U32 const divider = (params.cParams.searchLength==3) ? 3 : 4; size_t const maxNbSeq = blockSize / divider; size_t const tokenSpace = blockSize + 11*maxNbSeq; - size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog); + size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? + 0 : (1 << params.cParams.chainLog); size_t const hSize = ((size_t)1) << params.cParams.hashLog; - U32 const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog); + U32 const hashLog3 = (params.cParams.searchLength>3) ? + 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog); size_t const h3Size = ((size_t)1) << hashLog3; size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32); + size_t const buffOutSize = ZSTD_compressBound(blockSize)+1; + size_t const buffInSize = ((size_t)1 << params.cParams.windowLog) + blockSize; void* ptr; /* Check if workSpace is large enough, alloc a new one if needed */ @@ -521,8 +525,13 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, + entropyScratchSpace_size; size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<workSpaceSize < neededSpace) { DEBUGLOG(5, "Need to update workSpaceSize from %uK to %uK \n", (unsigned)zc->workSpaceSize>>10, (unsigned)neededSpace>>10); @@ -607,6 +616,13 @@ static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc, zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq; zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq; zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq; + ptr = zc->seqStore.litStart + blockSize; + + /* buffers */ + zc->inBuffSize = buffInSize; + zc->inBuff = (char*)ptr; + zc->outBuffSize = buffOutSize; + zc->outBuff = zc->inBuff + buffInSize; return 0; } @@ -636,9 +652,12 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong); memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem)); - { ZSTD_parameters params = srcCCtx->appliedParams; + { ZSTD_buffered_policy_e const zbuff = srcCCtx->inBuffSize ? + ZSTDb_buffered : ZSTDb_not_buffered; + ZSTD_parameters params = srcCCtx->appliedParams; params.fParams = fParams; - ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset); + ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, + ZSTDcrp_noMemset, zbuff); } /* copy tables */ @@ -3016,15 +3035,19 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, const ZSTD_CDict* cdict, - ZSTD_parameters params, U64 pledgedSrcSize) + ZSTD_parameters params, U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff) { + /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); assert(!((dict) && (cdict))); /* either dict or cdict, not both */ if (cdict && cdict->dictContentSize>0) - return ZSTD_copyCCtx_internal(cctx, cdict->refContext, params.fParams, pledgedSrcSize); + return ZSTD_copyCCtx_internal(cctx, cdict->refContext, + params.fParams, pledgedSrcSize); - CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, ZSTDcrp_continue)); + CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, + ZSTDcrp_continue, zbuff)); return ZSTD_compress_insertDictionary(cctx, dict, dictSize); } @@ -3037,14 +3060,16 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, { /* compression parameters verification and optimization */ CHECK_F(ZSTD_checkCParams(params.cParams)); - return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, pledgedSrcSize); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, + params, pledgedSrcSize, ZSTDb_not_buffered); } size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel) { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); - return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, 0); + return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, + params, 0, ZSTDb_not_buffered); } @@ -3121,7 +3146,8 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx, const void* dict,size_t dictSize, ZSTD_parameters params) { - CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, params, srcSize)); + CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL, + params, srcSize, ZSTDb_not_buffered)); return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize); } @@ -3272,11 +3298,12 @@ size_t ZSTD_compressBegin_usingCDict_advanced( ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize) { - if (cdict==NULL) return ERROR(dictionary_wrong); /* does not support NULL cdict */ + if (cdict==NULL) return ERROR(dictionary_wrong); { ZSTD_parameters params = cdict->refContext->appliedParams; params.fParams = fParams; DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced"); - return ZSTD_compressBegin_internal(cctx, NULL, 0, cdict, params, pledgedSrcSize); + return ZSTD_compressBegin_internal(cctx, NULL, 0, cdict, + params, pledgedSrcSize, ZSTDb_not_buffered); } } @@ -3362,7 +3389,8 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, { DEBUGLOG(5, "ZSTD_resetCStream_internal"); - CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize)); + CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, zcs->cdict, + params, pledgedSrcSize, ZSTDb_buffered)); zcs->inToCompress = 0; zcs->inBuffPos = 0; @@ -3373,39 +3401,6 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, return 0; /* ready to go */ } -/* ZSTD_initCStream_internal() : - * params are supposed validated at this stage - * and zcs->cdict is supposed to be correct */ -static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs, - const ZSTD_parameters params, - unsigned long long pledgedSrcSize) -{ - DEBUGLOG(5, "ZSTD_initCStream_stage2"); - assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); - zcs->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog); - - /* allocate buffers */ - { size_t const neededInBuffSize = ((size_t)1 << params.cParams.windowLog) + zcs->blockSize; - if (zcs->inBuffSize < neededInBuffSize) { - zcs->inBuffSize = 0; - ZSTD_free(zcs->inBuff, zcs->customMem); - zcs->inBuff = (char*)ZSTD_malloc(neededInBuffSize, zcs->customMem); - if (zcs->inBuff == NULL) return ERROR(memory_allocation); - zcs->inBuffSize = neededInBuffSize; - } - } - if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) { - size_t const outBuffSize = ZSTD_compressBound(zcs->blockSize)+1; - zcs->outBuffSize = 0; - ZSTD_free(zcs->outBuff, zcs->customMem); - zcs->outBuff = (char*)ZSTD_malloc(outBuffSize, zcs->customMem); - if (zcs->outBuff == NULL) return ERROR(memory_allocation); - zcs->outBuffSize = outBuffSize; - } - - return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); -} - size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) { ZSTD_parameters params = zcs->requestedParams; @@ -3414,7 +3409,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) { params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */); } - return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize); + return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } /* ZSTD_initCStream_usingCDict_advanced() : @@ -3430,7 +3425,7 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, zcs->requestedParams = params; zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM; zcs->cdict = cdict; - return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize); + return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } } @@ -3457,7 +3452,7 @@ static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, zcs->cdict = zcs->cdictLocal; } - return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize); + return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, @@ -3648,7 +3643,7 @@ size_t ZSTD_compress_generic_integral ( if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM) params.cParams = ZSTD_getCParams(cctx->compressionLevel, cctx->frameContentSize, 0 /* dictSize */); - CHECK_F( ZSTD_initCStream_stage2(cctx, params, cctx->frameContentSize) ); + CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); } { size_t sizeRead = srcSize - *srcPos; From c7fe262dc94b8253b6e0427cd89d4ccdf5d0cbaa Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 23 May 2017 13:16:00 -0700 Subject: [PATCH 090/400] added ZSTD_initStaticCCtx() makes it possible to statically or externally allocate CCtx. static CCtx will only use provided memory area, it will never resize nor malloc. --- doc/zstd_manual.html | 18 +++++++++- lib/compress/zstd_compress.c | 65 +++++++++++++++++++++++++++++------- lib/zstd.h | 18 +++++++++- tests/fuzzer.c | 57 +++++++++++++++++++++++++++++++ 4 files changed, 144 insertions(+), 14 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index c64c4290a..d84f8396e 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -423,6 +423,22 @@ size_t ZSTD_estimateDDictSize(size_t dictSize);

    Create a ZSTD compression context using external alloc and free functions


    +
    ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
    +

    workspace: The memory area to emplace the context into. + Provided pointer must 8-bytes aligned. + It must outlive context usage. + workspaceSize: Use ZSTD_estimateCCtxSize() or ZSTD_estimateCStreamSize() + to determine how large workspace must be to support scenario. + @return : pointer to ZSTD_CCtx*, or NULL if error (size too small) + Note : zstd will never resize nor malloc() when using a static cctx. + If it needs more memory than available, it will simply error out. + Note 2 : there is no corresponding "free" function. + Since workspace was allocated externally, it must be freed externally too. + Limitation : currently not compatible with internal CDict creation, such as + ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict(). + +


    +
    typedef enum {
         ZSTD_p_forceWindow,   /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
         ZSTD_p_forceRawDict   /* Force loading dictionary in "content-only" mode (no header analysis) */
    @@ -714,7 +730,7 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
    -size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
    +size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 0bed04fb4..deee3cfc7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -126,6 +126,7 @@ struct ZSTD_CCtx_s {
         U64 consumedSrcSize;
         XXH64_state_t xxhState;
         ZSTD_customMem customMem;
    +    size_t staticSize;
     
         seqStore_t seqStore;    /* sequences storage ptrs */
         U32* hashTable;
    @@ -175,9 +176,38 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
         return cctx;
     }
     
    +ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
    +{
    +    ZSTD_CCtx* cctx = (ZSTD_CCtx*) workspace;
    +    if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL;  /* minimum size */
    +    if ((size_t)workspace & 7) return NULL;  /* must be 8-aligned */
    +    memset(workspace, 0, workspaceSize);
    +    cctx->staticSize = workspaceSize;
    +    cctx->workSpace = (void*)(cctx+1);
    +    cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
    +
    +    /* entropy space (never moves) */
    +    /* note : this code should be shared with resetCCtx, instead of copied */
    +    {   void* ptr = cctx->workSpace;
    +        cctx->hufCTable = (HUF_CElt*)ptr;
    +        ptr = (char*)cctx->hufCTable + hufCTable_size;  /* note : HUF_CElt* is incomplete type, size is estimated via macro */
    +        cctx->offcodeCTable = (FSE_CTable*) ptr;
    +        ptr = (char*)ptr + offcodeCTable_size;
    +        cctx->matchlengthCTable = (FSE_CTable*) ptr;
    +        ptr = (char*)ptr + matchlengthCTable_size;
    +        cctx->litlengthCTable = (FSE_CTable*) ptr;
    +        ptr = (char*)ptr + litlengthCTable_size;
    +        assert(((size_t)ptr & 3) == 0);   /* ensure correct alignment */
    +        cctx->entropyScratchSpace = (unsigned*) ptr;
    +    }
    +
    +    return cctx;
    +}
    +
     size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
     {
         if (cctx==NULL) return 0;   /* support free on NULL */
    +    assert(!cctx->staticSize);  /* not compatible with static CCtx */
         ZSTD_free(cctx->workSpace, cctx->customMem);
         cctx->workSpace = NULL;
         ZSTD_freeCDict(cctx->cdictLocal);
    @@ -337,6 +367,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
     ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
     {
         if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
    +    if (cctx->staticSize) return ERROR(memory_allocation);  /* no malloc for static CCtx */
         ZSTD_freeCDict(cctx->cdictLocal);  /* in case one already exists */
         if (dict==NULL || dictSize==0) {   /* no dictionary mode */
             cctx->cdictLocal = NULL;
    @@ -448,6 +479,17 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
         return sizeof(ZSTD_CCtx) + neededSpace;
     }
     
    +size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
    +{
    +    size_t const CCtxSize = ZSTD_estimateCCtxSize(cParams);
    +    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
    +    size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
    +    size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
    +    size_t const streamingSize = inBuffSize + outBuffSize;
    +
    +    return CCtxSize + streamingSize;
    +}
    +
     
     static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1,
                                      ZSTD_compressionParameters cParams2)
    @@ -532,9 +574,14 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
                                             buffInSize + buffOutSize : 0;
                 size_t const neededSpace = entropySpace + optSpace + tableSpace
                                          + tokenSpace + bufferSpace;
    -            if (zc->workSpaceSize < neededSpace) {
    +
    +            if (zc->workSpaceSize < neededSpace) {  /* too small : resize /*/
                     DEBUGLOG(5, "Need to update workSpaceSize from %uK to %uK \n",
    -                            (unsigned)zc->workSpaceSize>>10, (unsigned)neededSpace>>10);
    +                            (unsigned)zc->workSpaceSize>>10,
    +                            (unsigned)neededSpace>>10);
    +                /* static cctx : no resize, error out */
    +                if (zc->staticSize) return ERROR(memory_allocation);
    +
                     zc->workSpaceSize = 0;
                     ZSTD_free(zc->workSpace, zc->customMem);
                     zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
    @@ -3362,16 +3409,6 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
         return ZSTD_freeCCtx(zcs);   /* same object */
     }
     
    -size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams)
    -{
    -    size_t const CCtxSize = ZSTD_estimateCCtxSize(cParams);
    -    size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
    -    size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
    -    size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
    -    size_t const streamingSize = inBuffSize + outBuffSize;
    -
    -    return CCtxSize + streamingSize;
    -}
     
     
     /*======   Initialization   ======*/
    @@ -3446,6 +3483,10 @@ static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
         zcs->cdict = NULL;
     
         if (dict && dictSize >= 8) {
    +        if (zcs->staticSize) {   /* static CCtx : never uses malloc */
    +            /* incompatible with internal cdict creation */
    +            return ERROR(memory_allocation);
    +        }
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem);
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 83fe9d30f..d25130faf 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -511,6 +511,22 @@ ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize);
      *  Create a ZSTD compression context using external alloc and free functions */
     ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
     
    +/*! ZSTD_initStaticCCtx() : initialize a fixed-size zstd compression context
    + *  workspace: The memory area to emplace the context into.
    + *             Provided pointer must 8-bytes aligned.
    + *             It must outlive context usage.
    + *  workspaceSize: Use ZSTD_estimateCCtxSize() or ZSTD_estimateCStreamSize()
    + *                 to determine how large workspace must be to support scenario.
    + * @return : pointer to ZSTD_CCtx*, or NULL if error (size too small)
    + *  Note : zstd will never resize nor malloc() when using a static cctx.
    + *         If it needs more memory than available, it will simply error out.
    + *  Note 2 : there is no corresponding "free" function.
    + *           Since workspace was allocated externally, it must be freed externally too.
    + *  Limitation : currently not compatible with internal CDict creation, such as
    + *               ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict().
    + */
    +ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
    +
     
     /* !!! Soon to be deprecated !!! */
     typedef enum {
    @@ -841,7 +857,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     /*=====   Advanced Streaming compression functions  =====*/
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
     ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
    -ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8. This result in the creation of an internal CDict */
    +ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
     ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 583018a45..a1dc6ba77 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -190,6 +190,63 @@ static int basicUnitTests(U32 seed, double compressibility)
         DISPLAYLEVEL(4, "OK \n");
     
     
    +    /* Static CCtx tests */
    +#define STATIC_CCTX_LEVEL 3
    +    DISPLAYLEVEL(4, "test%3i : create static CCtx for level %u :", testNb++, STATIC_CCTX_LEVEL);
    +    {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(STATIC_CCTX_LEVEL, 0, 0);
    +        size_t const staticCCtxSize = ZSTD_estimateCStreamSize(cParams);
    +        void* staticCCtxBuffer = malloc(staticCCtxSize);
    +        if (staticCCtxBuffer==NULL) {
    +            DISPLAY("Not enough memory, aborting\n");
    +            testResult = 1;
    +            goto _end;
    +        }
    +        {   ZSTD_CCtx* staticCCtx = ZSTD_initStaticCCtx(staticCCtxBuffer, staticCCtxSize);
    +            if (staticCCtx==NULL) goto _output_error;
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : init CCtx for level %u : ", testNb++, STATIC_CCTX_LEVEL);
    +            { size_t const r = ZSTD_compressBegin(staticCCtx, STATIC_CCTX_LEVEL);
    +              if (ZSTD_isError(r)) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : simple compression test with static CCtx : ", testNb++);
    +            CHECKPLUS(r, ZSTD_compressCCtx(staticCCtx,
    +                            compressedBuffer, ZSTD_compressBound(CNBuffSize),
    +                            CNBuffer, CNBuffSize, STATIC_CCTX_LEVEL),
    +                      cSize=r );
    +            DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
    +
    +            DISPLAYLEVEL(4, "test%3i : decompress verification test : ", testNb++);
    +            { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize);
    +              if (r != CNBuffSize) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : init CCtx for too large level (must fail) : ", testNb++);
    +            { size_t const r = ZSTD_compressBegin(staticCCtx, ZSTD_maxCLevel());
    +              if (!ZSTD_isError(r)) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : init CCtx for small level %u (should work again) : ", testNb++, 1);
    +            { size_t const r = ZSTD_compressBegin(staticCCtx, 1);
    +              if (ZSTD_isError(r)) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : init CStream for small level %u : ", testNb++, 1);
    +            { size_t const r = ZSTD_initCStream(staticCCtx, 1);
    +              if (ZSTD_isError(r)) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +
    +            DISPLAYLEVEL(4, "test%3i : init CStream with dictionary (should fail) : ", testNb++);
    +            { size_t const r = ZSTD_initCStream_usingDict(staticCCtx, CNBuffer, 64 KB, 1);
    +              if (!ZSTD_isError(r)) goto _output_error; }
    +            DISPLAYLEVEL(4, "OK \n");
    +        }
    +        free(staticCCtxBuffer);
    +    }
    +
    +
    +
         /* ZSTDMT simple MT compression test */
         DISPLAYLEVEL(4, "test%3i : create ZSTDMT CCtx : ", testNb++);
         {   ZSTDMT_CCtx* mtctx = ZSTDMT_createCCtx(2);
    
    From b81f19ffce2ce24b6d8a13a61ec554373a426d35 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 23 May 2017 15:41:55 -0700
    Subject: [PATCH 091/400] move MEM_readMINMATCH() into zstd_opt.h
    
    which is its only user.
    Use case too narrow to belong to mem.h.
    renamed to ZSTD_readMINMATCH()
    ---
     lib/common/mem.h        | 14 --------------
     lib/compress/zstd_opt.h | 24 +++++++++++++++++++-----
     2 files changed, 19 insertions(+), 19 deletions(-)
    
    diff --git a/lib/common/mem.h b/lib/common/mem.h
    index 4773a8b93..b0e5bf60b 100644
    --- a/lib/common/mem.h
    +++ b/lib/common/mem.h
    @@ -352,20 +352,6 @@ MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
     }
     
     
    -/* function safe only for comparisons */
    -MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
    -{
    -    switch (length)
    -    {
    -    default :
    -    case 4 : return MEM_read32(memPtr);
    -    case 3 : if (MEM_isLittleEndian())
    -                return MEM_read32(memPtr)<<8;
    -             else
    -                return MEM_read32(memPtr)>>8;
    -    }
    -}
    -
     #if defined (__cplusplus)
     }
     #endif
    diff --git a/lib/compress/zstd_opt.h b/lib/compress/zstd_opt.h
    index 38c1ca620..e8e98915e 100644
    --- a/lib/compress/zstd_opt.h
    +++ b/lib/compress/zstd_opt.h
    @@ -202,6 +202,20 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
         }
     
     
    +/* function safe only for comparisons */
    +MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
    +{
    +    switch (length)
    +    {
    +    default :
    +    case 4 : return MEM_read32(memPtr);
    +    case 3 : if (MEM_isLittleEndian())
    +                return MEM_read32(memPtr)<<8;
    +             else
    +                return MEM_read32(memPtr)>>8;
    +    }
    +}
    +
     
     /* Update hashTable3 up to ip (excluded)
        Assumption : always within prefix (i.e. not within extDict) */
    @@ -268,7 +282,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
                     if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
                 } else {
                     match = dictBase + matchIndex3;
    -                if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
    +                if (ZSTD_readMINMATCH(match, MINMATCH) == ZSTD_readMINMATCH(ip, MINMATCH))    /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
                         currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
                 }
     
    @@ -440,7 +454,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
                 for (i=(ip == anchor); i 0) && (repCur < (S32)(ip-prefixStart))
    -                    && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
    +                    && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repCur, minMatch))) {
                         mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
                         if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
                             best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
    @@ -525,7 +539,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
                     for (i=(opt[cur].mlen != 1); i 0) && (repCur < (S32)(inr-prefixStart))
    -                       && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
    +                       && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(inr - repCur, minMatch))) {
                            mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
     
                            if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
    @@ -699,7 +713,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
                     const BYTE* const repMatch = repBase + repIndex;
                     if ( (repCur > 0 && repCur <= (S32)current)
                        && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    -                   && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    +                   && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
                         /* repcode detected we should take it */
                         const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
                         mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    @@ -795,7 +809,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
                         const BYTE* const repMatch = repBase + repIndex;
                         if ( (repCur > 0 && repCur <= (S32)(current+cur))
                           && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex))  /* intentional overflow */
    -                      && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
    +                      && (ZSTD_readMINMATCH(inr, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
                             /* repcode detected */
                             const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
                             mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
    
    From 11ea2f7fda3a9508438066dab6c333210c328ea2 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 23 May 2017 16:19:43 -0700
    Subject: [PATCH 092/400] Merged ZSTD_DCtx and ZSTD_DStream objects
    
    They are now the same object.
    It's recommended to keep both types in source code
    as previous versions of library (   /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
     #  define ZSTD_PREFETCH(ptr)   _mm_prefetch((const char*)ptr, _MM_HINT_T0)
    @@ -63,13 +62,27 @@
     #  define ZSTD_PREFETCH(ptr)   /* disabled */
     #endif
     
    +
     /*-*************************************
    -*  Macros
    +*  Errors
     ***************************************/
     #define ZSTD_isError ERR_isError   /* for inlining */
     #define FSE_isError  ERR_isError
     #define HUF_isError  ERR_isError
     
    +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
    +#  include 
    +   static unsigned g_debugLevel = ZSTD_DEBUG;
    +#  define DEBUGLOG(l, ...) {                          \
    +                if (l<=g_debugLevel) {                \
    +                    fprintf(stderr, __FILE__ ": ");   \
    +                    fprintf(stderr, __VA_ARGS__);     \
    +                    fprintf(stderr, " \n");           \
    +            }   }
    +#else
    +#  define DEBUGLOG(l, ...)      {}    /* disabled */
    +#endif
    +
     
     /*_*******************************************************
     *  Memory operations
    @@ -85,6 +98,9 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
                    ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
                    ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
     
    +typedef enum { zdss_init=0, zdss_loadHeader,
    +               zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
    +
     typedef struct {
         FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
         FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
    @@ -119,9 +135,34 @@ struct ZSTD_DCtx_s
         size_t rleSize;
         BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
         BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
    +
    +    /* streaming */
    +    ZSTD_DDict* ddictLocal;
    +    const ZSTD_DDict* ddict;
    +    ZSTD_dStreamStage streamStage;
    +    char*  inBuff;
    +    size_t inBuffSize;
    +    size_t inPos;
    +    size_t maxWindowSize;
    +    char*  outBuff;
    +    size_t outBuffSize;
    +    size_t outStart;
    +    size_t outEnd;
    +    size_t blockSize;
    +    size_t lhSize;
    +    void* legacyContext;
    +    U32 previousLegacyVersion;
    +    U32 legacyVersion;
    +    U32 hostageByte;
     };  /* typedef'd to ZSTD_DCtx within "zstd.h" */
     
    -size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { return (dctx==NULL) ? 0 : sizeof(ZSTD_DCtx); }
    +size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
    +{
    +    if (dctx==NULL) return 0;   /* support sizeof NULL */
    +    return sizeof(*dctx)
    +           + ZSTD_sizeof_DDict(dctx->ddictLocal)
    +           + dctx->inBuffSize + dctx->outBuffSize;
    +}
     
     size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
     
    @@ -154,8 +195,11 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
     
         dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
         if (!dctx) return NULL;
    +    memset(dctx, 0, sizeof(*dctx));
         memcpy(&dctx->customMem, &customMem, sizeof(customMem));
    -    ZSTD_decompressBegin(dctx);
    +    ZSTD_decompressBegin(dctx);   /* cannot fail */
    +    dctx->streamStage = zdss_init;
    +    dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
         return dctx;
     }
     
    @@ -167,8 +211,20 @@ ZSTD_DCtx* ZSTD_createDCtx(void)
     size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
     {
         if (dctx==NULL) return 0;   /* support free on NULL */
    -    ZSTD_free(dctx, dctx->customMem);
    -    return 0;   /* reserved as a potential error code in the future */
    +    {   ZSTD_customMem const cMem = dctx->customMem;
    +        ZSTD_freeDDict(dctx->ddictLocal);
    +        dctx->ddictLocal = NULL;
    +        ZSTD_free(dctx->inBuff, cMem);
    +        dctx->inBuff = NULL;
    +        ZSTD_free(dctx->outBuff, cMem);
    +        dctx->outBuff = NULL;
    +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
    +        if (dctx->legacyContext)
    +            ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
    +#endif
    +        ZSTD_free(dctx, cMem);
    +        return 0;
    +    }
     }
     
     void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
    @@ -230,7 +286,8 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src
         if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
             if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
                 /* skippable frame */
    -            if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
    +            if (srcSize < ZSTD_skippableHeaderSize)
    +                return ZSTD_skippableHeaderSize; /* magic number + frame length */
                 memset(zfhPtr, 0, sizeof(*zfhPtr));
                 zfhPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
                 zfhPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
    @@ -253,11 +310,13 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src
             U32 windowSize = 0;
             U32 dictID = 0;
             U64 frameContentSize = 0;
    -        if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported);   /* reserved bits, which must be zero */
    +        if ((fhdByte & 0x08) != 0)
    +            return ERROR(frameParameter_unsupported);   /* reserved bits, must be zero */
             if (!singleSegment) {
                 BYTE const wlByte = ip[pos++];
                 U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
    -            if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge);  /* avoids issue with 1 << windowLog */
    +            if (windowLog > ZSTD_WINDOWLOG_MAX)
    +                return ERROR(frameParameter_windowTooLarge);
                 windowSize = (1U << windowLog);
                 windowSize += (windowSize >> 3) * (wlByte&7);
             }
    @@ -321,51 +380,48 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
      *  @return : decompressed size of the frames contained */
     unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
     {
    -    {
    -        unsigned long long totalDstSize = 0;
    -        while (srcSize >= ZSTD_frameHeaderSize_prefix) {
    -            const U32 magicNumber = MEM_readLE32(src);
    +    unsigned long long totalDstSize = 0;
     
    -            if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    -                size_t skippableSize;
    -                if (srcSize < ZSTD_skippableHeaderSize)
    -                    return ERROR(srcSize_wrong);
    -                skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    -                                ZSTD_skippableHeaderSize;
    -                if (srcSize < skippableSize) {
    -                    return ZSTD_CONTENTSIZE_ERROR;
    -                }
    +    while (srcSize >= ZSTD_frameHeaderSize_prefix) {
    +        const U32 magicNumber = MEM_readLE32(src);
     
    -                src = (const BYTE *)src + skippableSize;
    -                srcSize -= skippableSize;
    -                continue;
    +        if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
    +            size_t skippableSize;
    +            if (srcSize < ZSTD_skippableHeaderSize)
    +                return ERROR(srcSize_wrong);
    +            skippableSize = MEM_readLE32((const BYTE *)src + 4) +
    +                            ZSTD_skippableHeaderSize;
    +            if (srcSize < skippableSize) {
    +                return ZSTD_CONTENTSIZE_ERROR;
                 }
     
    -            {
    -                unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
    -                if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
    -
    -                /* check for overflow */
    -                if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
    -                totalDstSize += ret;
    -            }
    -            {
    -                size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
    -                if (ZSTD_isError(frameSrcSize)) {
    -                    return ZSTD_CONTENTSIZE_ERROR;
    -                }
    -
    -                src = (const BYTE *)src + frameSrcSize;
    -                srcSize -= frameSrcSize;
    -            }
    +            src = (const BYTE *)src + skippableSize;
    +            srcSize -= skippableSize;
    +            continue;
             }
     
    -        if (srcSize) {
    -            return ZSTD_CONTENTSIZE_ERROR;
    -        }
    +        {   unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
    +            if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
     
    -        return totalDstSize;
    +            /* check for overflow */
    +            if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
    +            totalDstSize += ret;
    +        }
    +        {   size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
    +            if (ZSTD_isError(frameSrcSize)) {
    +                return ZSTD_CONTENTSIZE_ERROR;
    +            }
    +
    +            src = (const BYTE *)src + frameSrcSize;
    +            srcSize -= frameSrcSize;
    +        }
         }
    +
    +    if (srcSize) {
    +        return ZSTD_CONTENTSIZE_ERROR;
    +    }
    +
    +    return totalDstSize;
     }
     
     /** ZSTD_getDecompressedSize() :
    @@ -2044,35 +2100,6 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
     *   Streaming decompression
     *====================================*/
     
    -typedef enum { zdss_init, zdss_loadHeader,
    -               zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
    -
    -/* *** Resource management *** */
    -struct ZSTD_DStream_s {
    -    ZSTD_DCtx* dctx;
    -    ZSTD_DDict* ddictLocal;
    -    const ZSTD_DDict* ddict;
    -    ZSTD_frameHeader fParams;
    -    ZSTD_dStreamStage stage;
    -    char*  inBuff;
    -    size_t inBuffSize;
    -    size_t inPos;
    -    size_t maxWindowSize;
    -    char*  outBuff;
    -    size_t outBuffSize;
    -    size_t outStart;
    -    size_t outEnd;
    -    size_t blockSize;
    -    BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];   /* tmp buffer to store frame header */
    -    size_t lhSize;
    -    ZSTD_customMem customMem;
    -    void* legacyContext;
    -    U32 previousLegacyVersion;
    -    U32 legacyVersion;
    -    U32 hostageByte;
    -};   /* typedef'd to ZSTD_DStream within "zstd.h" */
    -
    -
     ZSTD_DStream* ZSTD_createDStream(void)
     {
         return ZSTD_createDStream_advanced(defaultCustomMem);
    @@ -2080,41 +2107,12 @@ ZSTD_DStream* ZSTD_createDStream(void)
     
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
     {
    -    ZSTD_DStream* zds;
    -
    -    if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree) return NULL;
    -
    -    zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
    -    if (zds==NULL) return NULL;
    -    memset(zds, 0, sizeof(ZSTD_DStream));
    -    memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
    -    zds->dctx = ZSTD_createDCtx_advanced(customMem);
    -    if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
    -    zds->stage = zdss_init;
    -    zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
    -    return zds;
    +    return ZSTD_createDCtx_advanced(customMem);
     }
     
     size_t ZSTD_freeDStream(ZSTD_DStream* zds)
     {
    -    if (zds==NULL) return 0;   /* support free on null */
    -    {   ZSTD_customMem const cMem = zds->customMem;
    -        ZSTD_freeDCtx(zds->dctx);
    -        zds->dctx = NULL;
    -        ZSTD_freeDDict(zds->ddictLocal);
    -        zds->ddictLocal = NULL;
    -        ZSTD_free(zds->inBuff, cMem);
    -        zds->inBuff = NULL;
    -        ZSTD_free(zds->outBuff, cMem);
    -        zds->outBuff = NULL;
    -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
    -        if (zds->legacyContext)
    -            ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
    -#endif
    -        ZSTD_free(zds, cMem);
    -        return 0;
    -    }
    +    return ZSTD_freeDCtx(zds);
     }
     
     
    @@ -2125,7 +2123,7 @@ size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
     
     size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
     {
    -    zds->stage = zdss_loadHeader;
    +    zds->streamStage = zdss_loadHeader;
         zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
         ZSTD_freeDDict(zds->ddictLocal);
         if (dict && dictSize >= 8) {
    @@ -2154,7 +2152,7 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
     
     size_t ZSTD_resetDStream(ZSTD_DStream* zds)
     {
    -    zds->stage = zdss_loadHeader;
    +    zds->streamStage = zdss_loadHeader;
         zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
         zds->legacyVersion = 0;
         zds->hostageByte = 0;
    @@ -2175,11 +2173,7 @@ size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
     
     size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
     {
    -    if (zds==NULL) return 0;   /* support sizeof NULL */
    -    return sizeof(*zds)
    -           + ZSTD_sizeof_DCtx(zds->dctx)
    -           + ZSTD_sizeof_DDict(zds->ddictLocal)
    -           + zds->inBuffSize + zds->outBuffSize;
    +    return ZSTD_sizeof_DCtx(zds);
     }
     
     size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader)
    @@ -2218,7 +2212,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     #endif
     
         while (someMoreWork) {
    -        switch(zds->stage)
    +        switch(zds->streamStage)
             {
             case zdss_init :
                 ZSTD_resetDStream(zds);   /* transparent reset on starting decoding a new frame */
    @@ -2259,22 +2253,22 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                     && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
                     size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
                     if (cSize <= (size_t)(iend-istart)) {
    -                    size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
    +                    size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds->ddict);
                         if (ZSTD_isError(decompressedSize)) return decompressedSize;
                         ip = istart + cSize;
                         op += decompressedSize;
    -                    zds->dctx->expected = 0;
    -                    zds->stage = zdss_init;
    +                    zds->expected = 0;
    +                    zds->streamStage = zdss_init;
                         someMoreWork = 0;
                         break;
                 }   }
     
                 /* Consume header */
    -            CHECK_F(ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict));
    -            {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    -                CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    -                {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -                    CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
    +            CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
    +            {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds);  /* == ZSTD_frameHeaderSize_prefix */
    +                CHECK_F(ZSTD_decompressContinue(zds, NULL, 0, zds->headerBuffer, h1Size));
    +                {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds);
    +                    CHECK_F(ZSTD_decompressContinue(zds, NULL, 0, zds->headerBuffer+h1Size, h2Size));
                 }   }
     
                 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
    @@ -2285,6 +2279,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                     size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
                     zds->blockSize = blockSize;
                     if (zds->inBuffSize < blockSize) {
    +                    DEBUGLOG(4, "inBuff  : from %u to %u",
    +                                (U32)zds->inBuffSize, (U32)blockSize);
                         ZSTD_free(zds->inBuff, zds->customMem);
                         zds->inBuffSize = 0;
                         zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    @@ -2292,41 +2288,43 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                         zds->inBuffSize = blockSize;
                     }
                     if (zds->outBuffSize < neededOutSize) {
    +                    DEBUGLOG(4, "outBuff : from %u to %u",
    +                                (U32)zds->outBuffSize, (U32)neededOutSize);
                         ZSTD_free(zds->outBuff, zds->customMem);
                         zds->outBuffSize = 0;
                         zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
                         if (zds->outBuff == NULL) return ERROR(memory_allocation);
                         zds->outBuffSize = neededOutSize;
                 }   }
    -            zds->stage = zdss_read;
    +            zds->streamStage = zdss_read;
                 /* pass-through */
     
             case zdss_read:
    -            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
                     if (neededInSize==0) {  /* end of frame */
    -                    zds->stage = zdss_init;
    +                    zds->streamStage = zdss_init;
                         someMoreWork = 0;
                         break;
                     }
                     if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
    -                    const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    -                    size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    +                    const int isSkipFrame = ZSTD_isSkipFrame(zds);
    +                    size_t const decodedSize = ZSTD_decompressContinue(zds,
                             zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
                             ip, neededInSize);
                         if (ZSTD_isError(decodedSize)) return decodedSize;
                         ip += neededInSize;
                         if (!decodedSize && !isSkipFrame) break;   /* this was just a header */
                         zds->outEnd = zds->outStart + decodedSize;
    -                    zds->stage = zdss_flush;
    +                    zds->streamStage = zdss_flush;
                         break;
                     }
                     if (ip==iend) { someMoreWork = 0; break; }   /* no more input */
    -                zds->stage = zdss_load;
    +                zds->streamStage = zdss_load;
                     /* pass-through */
                 }
     
             case zdss_load:
    -            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
                     size_t const toLoad = neededInSize - zds->inPos;   /* should always be <= remaining space within inBuff */
                     size_t loadedSize;
                     if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected);   /* should never happen */
    @@ -2336,15 +2334,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                     if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */
     
                     /* decode loaded input */
    -                {  const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
    -                   size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
    +                {  const int isSkipFrame = ZSTD_isSkipFrame(zds);
    +                   size_t const decodedSize = ZSTD_decompressContinue(zds,
                             zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
                             zds->inBuff, neededInSize);
                         if (ZSTD_isError(decodedSize)) return decodedSize;
                         zds->inPos = 0;   /* input is consumed */
    -                    if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; }   /* this was just a header */
    +                    if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; }   /* this was just a header */
                         zds->outEnd = zds->outStart +  decodedSize;
    -                    zds->stage = zdss_flush;
    +                    zds->streamStage = zdss_flush;
                         /* pass-through */
                 }   }
     
    @@ -2354,7 +2352,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                     op += flushedSize;
                     zds->outStart += flushedSize;
                     if (flushedSize == toFlushSize) {  /* flush completed */
    -                    zds->stage = zdss_read;
    +                    zds->streamStage = zdss_read;
                         if (zds->outStart + zds->blockSize > zds->outBuffSize)
                             zds->outStart = zds->outEnd = 0;
                         break;
    @@ -2369,11 +2367,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
         /* result */
         input->pos += (size_t)(ip-istart);
         output->pos += (size_t)(op-ostart);
    -    {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +    {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
             if (!nextSrcSizeHint) {   /* frame fully decoded */
                 if (zds->outEnd == zds->outStart) {  /* output fully flushed */
                     if (zds->hostageByte) {
    -                    if (input->pos >= input->size) { zds->stage = zdss_read; return 1; }  /* can't release hostage (not present) */
    +                    if (input->pos >= input->size) {
    +                        /* can't release hostage (not present) */
    +                        zds->streamStage = zdss_read;
    +                        return 1;
    +                    }
                         input->pos++;  /* release hostage */
                     }
                     return 0;
    @@ -2384,7 +2386,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }
                 return 1;
             }
    -        nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block);   /* preload header of next block */
    +        nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block);   /* preload header of next block */
             if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC);   /* should never happen */
             nextSrcSizeHint -= zds->inPos;   /* already loaded*/
             return nextSrcSizeHint;
    diff --git a/lib/zstd.h b/lib/zstd.h
    index d25130faf..81f9eb737 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -329,7 +329,8 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output
     *            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
     * *******************************************************************************/
     
    -typedef struct ZSTD_DStream_s ZSTD_DStream;
    +//typedef struct ZSTD_DStream_s ZSTD_DStream;
    +typedef ZSTD_DCtx ZSTD_DStream;
     /*===== ZSTD_DStream management functions =====*/
     ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
     ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
    
    From e87cad1053e5a50ce280bd346b016fe294b64605 Mon Sep 17 00:00:00 2001
    From: codicodi 
    Date: Wed, 24 May 2017 10:48:10 +0200
    Subject: [PATCH 093/400] CMake improvements
    
    ---
     build/cmake/CMakeLists.txt                    | 10 +++
     .../AddZstdCompilationFlags.cmake             | 25 +-----
     build/cmake/lib/CMakeLists.txt                | 79 +++++++++++--------
     build/cmake/programs/CMakeLists.txt           | 14 ++--
     4 files changed, 68 insertions(+), 60 deletions(-)
    
    diff --git a/build/cmake/CMakeLists.txt b/build/cmake/CMakeLists.txt
    index 5c4eca61c..6e30c5325 100644
    --- a/build/cmake/CMakeLists.txt
    +++ b/build/cmake/CMakeLists.txt
    @@ -18,6 +18,9 @@ LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
     INCLUDE(AddZstdCompilationFlags)
     ADD_ZSTD_COMPILATION_FLAGS()
     
    +# Always hide XXHash symbols
    +ADD_DEFINITIONS(-DXXH_NAMESPACE=ZSTD_)
    +
     #-----------------------------------------------------------------------------
     # Options
     #-----------------------------------------------------------------------------
    @@ -30,6 +33,9 @@ ENDIF (UNIX)
     OPTION(ZSTD_BUILD_PROGRAMS "BUILD PROGRAMS" ON)
     OPTION(ZSTD_BUILD_CONTRIB "BUILD CONTRIB" OFF)
     OPTION(ZSTD_BUILD_TESTS "BUILD TESTS" OFF)
    +if (MSVC)
    +    OPTION(ZSTD_USE_STATIC_RUNTIME "LINK TO STATIC RUN-TIME LIBRARIES" OFF)
    +endif ()
     
     IF (ZSTD_LEGACY_SUPPORT)
         MESSAGE(STATUS "ZSTD_LEGACY_SUPPORT defined!")
    @@ -45,6 +51,10 @@ ENDIF (ZSTD_LEGACY_SUPPORT)
     ADD_SUBDIRECTORY(lib)
     
     IF (ZSTD_BUILD_PROGRAMS)
    +    IF (NOT ZSTD_BUILD_STATIC)
    +        MESSAGE(SEND_ERROR "You need to build static library to build zstd CLI")
    +    ENDIF (NOT ZSTD_BUILD_STATIC)
    +
         ADD_SUBDIRECTORY(programs)
     ENDIF (ZSTD_BUILD_PROGRAMS)
     
    diff --git a/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake b/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake
    index e812418e3..a7dc08ea7 100644
    --- a/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake
    +++ b/build/cmake/CMakeModules/AddZstdCompilationFlags.cmake
    @@ -34,27 +34,11 @@ MACRO(ADD_ZSTD_COMPILATION_FLAGS)
             EnableCompilerFlag("-Wcast-qual" true true)
             EnableCompilerFlag("-Wstrict-prototypes" true false)
         elseif (MSVC) # Add specific compilation flags for Windows Visual
    -        EnableCompilerFlag("/Wall" true true)
    -
    -        # Only for DEBUG version
    -        EnableCompilerFlag("/RTC1" true true)
    -        EnableCompilerFlag("/Zc:forScope" true true)
    -        EnableCompilerFlag("/Gd" true true)
    -        EnableCompilerFlag("/analyze:stacksize25000" true true)
    -
    -        if (MSVC80 OR MSVC90 OR MSVC10 OR MSVC11)
    -            # To avoid compiler warning (level 4) C4571, compile with /EHa if you still want
    -            # your catch(...) blocks to catch structured exceptions.
    -            EnableCompilerFlag("/EHa" false true)
    -        endif (MSVC80 OR MSVC90 OR MSVC10 OR MSVC11)
     
             set(ACTIVATE_MULTITHREADED_COMPILATION "ON" CACHE BOOL "activate multi-threaded compilation (/MP flag)")
    -        if (ACTIVATE_MULTITHREADED_COMPILATION)
    +        if (CMAKE_GENERATOR MATCHES "Visual Studio" AND ACTIVATE_MULTITHREADED_COMPILATION)
                 EnableCompilerFlag("/MP" true true)
             endif ()
    -
    -        #For exceptions
    -        EnableCompilerFlag("/EHsc" true true)
             
             # UNICODE SUPPORT
             EnableCompilerFlag("/D_UNICODE" true true)
    @@ -71,15 +55,12 @@ MACRO(ADD_ZSTD_COMPILATION_FLAGS)
             string(REPLACE ";" " " ${flag_var} "${${flag_var}}")
         ENDFOREACH (flag_var)
     
    -    if (MSVC)
    -        # Replace /MT to /MD flag
    -        # Replace /O2 to /O3 flag
    +    if (MSVC AND ZSTD_USE_STATIC_RUNTIME)
             FOREACH (flag_var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
                      CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
                      CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
                      CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
    -            STRING(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
    -            STRING(REGEX REPLACE "/O2" "/Ox" ${flag_var} "${${flag_var}}")
    +            STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
             ENDFOREACH (flag_var)
         endif ()
     
    diff --git a/build/cmake/lib/CMakeLists.txt b/build/cmake/lib/CMakeLists.txt
    index 429d49449..f763733bc 100644
    --- a/build/cmake/lib/CMakeLists.txt
    +++ b/build/cmake/lib/CMakeLists.txt
    @@ -13,7 +13,12 @@
     PROJECT(libzstd)
     
     SET(CMAKE_INCLUDE_CURRENT_DIR TRUE)
    -OPTION(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" OFF)
    +OPTION(ZSTD_BUILD_STATIC "BUILD STATIC LIBRARIES" ON)
    +OPTION(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" ON)
    +
    +IF(NOT ZSTD_BUILD_SHARED AND NOT ZSTD_BUILD_STATIC)
    +    MESSAGE(SEND_ERROR "You need to build at least one flavor of libstd")
    +ENDIF()
     
     # Define library directory, where sources and header files are located
     SET(LIBRARY_DIR ${ZSTD_SOURCE_DIR}/lib)
    @@ -90,43 +95,44 @@ IF (MSVC)
     ENDIF (MSVC)
     
     # Split project to static and shared libraries build
    -ADD_LIBRARY(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
    +IF (ZSTD_BUILD_SHARED)
    +    ADD_LIBRARY(libzstd_shared SHARED ${Sources} ${Headers} ${PlatformDependResources})
    +ENDIF (ZSTD_BUILD_SHARED)
     IF (ZSTD_BUILD_STATIC)
         ADD_LIBRARY(libzstd_static STATIC ${Sources} ${Headers})
     ENDIF (ZSTD_BUILD_STATIC)
     
     # Add specific compile definitions for MSVC project
     IF (MSVC)
    -    SET_PROPERTY(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS")
    +    IF (ZSTD_BUILD_SHARED)
    +        SET_PROPERTY(TARGET libzstd_shared APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_DLL_EXPORT=1;ZSTD_HEAPMODE=0;_CONSOLE;_CRT_SECURE_NO_WARNINGS")
    +    ENDIF (ZSTD_BUILD_SHARED)
         IF (ZSTD_BUILD_STATIC)
             SET_PROPERTY(TARGET libzstd_static APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_HEAPMODE=0;_CRT_SECURE_NO_WARNINGS")
         ENDIF (ZSTD_BUILD_STATIC)
     ENDIF (MSVC)
     
    -# Define library base name
    +# With MSVC static library needs to be renamed to avoid conflict with import library
     IF (MSVC)
    -
    -    IF (CMAKE_SIZEOF_VOID_P MATCHES "8")
    -        SET(LIBRARY_BASE_NAME "zstdlib_x64")
    -    ELSE ()
    -        SET(LIBRARY_BASE_NAME "zstdlib_x86")
    -    ENDIF (CMAKE_SIZEOF_VOID_P MATCHES "8")
    +    SET(STATIC_LIBRARY_BASE_NAME zstd_static)
     ELSE ()
    -    SET(LIBRARY_BASE_NAME zstd)
    +    SET(STATIC_LIBRARY_BASE_NAME zstd)
     ENDIF (MSVC)
     
     # Define static and shared library names
    -SET_TARGET_PROPERTIES(
    -        libzstd_shared
    -        PROPERTIES
    -        OUTPUT_NAME ${LIBRARY_BASE_NAME}
    -        SOVERSION ${LIBVER_MAJOR}.${LIBVER_MINOR}.${LIBVER_RELEASE})
    +IF (ZSTD_BUILD_SHARED)
    +    SET_TARGET_PROPERTIES(
    +            libzstd_shared
    +            PROPERTIES
    +            OUTPUT_NAME zstd
    +            SOVERSION ${LIBVER_MAJOR}.${LIBVER_MINOR}.${LIBVER_RELEASE})
    +ENDIF (ZSTD_BUILD_SHARED)
     
     IF (ZSTD_BUILD_STATIC)
         SET_TARGET_PROPERTIES(
                 libzstd_static
                 PROPERTIES
    -            OUTPUT_NAME ${LIBRARY_BASE_NAME})
    +            OUTPUT_NAME ${STATIC_LIBRARY_BASE_NAME})
     ENDIF (ZSTD_BUILD_STATIC)
     
     IF (UNIX)
    @@ -141,20 +147,29 @@ IF (UNIX)
                 -P "${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig.cmake"
                 COMMENT "Creating pkg-config file")
     
    -    # install target
    -    INSTALL(FILES ${LIBRARY_DIR}/zstd.h ${LIBRARY_DIR}/deprecated/zbuff.h ${LIBRARY_DIR}/dictBuilder/zdict.h DESTINATION "include")
         INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/libzstd.pc" DESTINATION "share/pkgconfig")
    -    INSTALL(TARGETS libzstd_shared LIBRARY DESTINATION "lib")
    -    IF (ZSTD_BUILD_STATIC)
    -        INSTALL(TARGETS libzstd_static ARCHIVE DESTINATION "lib")
    -    ENDIF (ZSTD_BUILD_STATIC)
    -
    -    # uninstall target
    -    CONFIGURE_FILE(
    -            "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
    -            "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    -            IMMEDIATE @ONLY)
    -
    -    ADD_CUSTOM_TARGET(uninstall
    -            COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
     ENDIF (UNIX)
    +
    +# install target
    +INSTALL(FILES 
    +    ${LIBRARY_DIR}/zstd.h 
    +    ${LIBRARY_DIR}/deprecated/zbuff.h 
    +    ${LIBRARY_DIR}/dictBuilder/zdict.h 
    +    ${LIBRARY_DIR}/common/zstd_errors.h
    +    DESTINATION "include")
    +
    +IF (ZSTD_BUILD_SHARED)
    +    INSTALL(TARGETS libzstd_shared RUNTIME DESTINATION "bin" LIBRARY DESTINATION "lib" ARCHIVE DESTINATION "lib")
    +ENDIF()
    +IF (ZSTD_BUILD_STATIC)
    +    INSTALL(TARGETS libzstd_static ARCHIVE DESTINATION "lib")
    +ENDIF (ZSTD_BUILD_STATIC)
    +
    +# uninstall target
    +CONFIGURE_FILE(
    +        "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
    +        "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    +        IMMEDIATE @ONLY)
    +
    +ADD_CUSTOM_TARGET(uninstall
    +        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
    diff --git a/build/cmake/programs/CMakeLists.txt b/build/cmake/programs/CMakeLists.txt
    index cb6aa9218..98ca6cca0 100644
    --- a/build/cmake/programs/CMakeLists.txt
    +++ b/build/cmake/programs/CMakeLists.txt
    @@ -30,14 +30,16 @@ IF (MSVC)
     ENDIF (MSVC)
     
     ADD_EXECUTABLE(zstd ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c ${PROGRAMS_DIR}/bench.c ${PROGRAMS_DIR}/datagen.c ${PROGRAMS_DIR}/dibio.c ${PlatformDependResources})
    -TARGET_LINK_LIBRARIES(zstd libzstd_shared)
    -ADD_CUSTOM_TARGET(zstdcat ALL ${CMAKE_COMMAND} -E create_symlink zstd zstdcat DEPENDS zstd COMMENT "Creating zstdcat symlink")
    -ADD_CUSTOM_TARGET(unzstd ALL ${CMAKE_COMMAND} -E create_symlink zstd unzstd DEPENDS zstd COMMENT "Creating unzstd symlink")
    +TARGET_LINK_LIBRARIES(zstd libzstd_static)
     INSTALL(TARGETS zstd RUNTIME DESTINATION "bin")
    -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/zstdcat DESTINATION "bin")
    -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/unzstd DESTINATION "bin")
     
     IF (UNIX)
    +    ADD_CUSTOM_TARGET(zstdcat ALL ${CMAKE_COMMAND} -E create_symlink zstd zstdcat DEPENDS zstd COMMENT "Creating zstdcat symlink")
    +    ADD_CUSTOM_TARGET(unzstd ALL ${CMAKE_COMMAND} -E create_symlink zstd unzstd DEPENDS zstd COMMENT "Creating unzstd symlink")
    +    INSTALL(TARGETS zstd RUNTIME DESTINATION "bin")
    +    INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/zstdcat DESTINATION "bin")
    +    INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/unzstd DESTINATION "bin")
    +
         ADD_CUSTOM_TARGET(zstd.1 ALL
             ${CMAKE_COMMAND} -E copy ${PROGRAMS_DIR}/zstd.1 .
             COMMENT "Copying manpage zstd.1")
    @@ -48,7 +50,7 @@ IF (UNIX)
         INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/unzstd.1 DESTINATION "share/man/man1")
     
         ADD_EXECUTABLE(zstd-frugal ${PROGRAMS_DIR}/zstdcli.c ${PROGRAMS_DIR}/fileio.c)
    -    TARGET_LINK_LIBRARIES(zstd-frugal libzstd_shared)
    +    TARGET_LINK_LIBRARIES(zstd-frugal libzstd_static)
         SET_PROPERTY(TARGET zstd-frugal APPEND PROPERTY COMPILE_DEFINITIONS "ZSTD_NOBENCH;ZSTD_NODICT")
     ENDIF (UNIX)
     
    
    From 2e4db3e531e224118a316d50174300116a2f99ca Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 24 May 2017 13:15:19 -0700
    Subject: [PATCH 094/400] fixed performance regression with ZSTD_decompress()
     on small files
    
    memset() was a quick fix to initialization problems,
    but initialize too much space (tables, buffers)
    which show up in decompression speed of ZSTD_decompress()
    since it needs to recreate DCtx at each invocation.
    
    Fixed by only initialization relevant pointers and size fields.
    ---
     lib/decompress/zstd_decompress.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index aabfa6d94..8cf500445 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -195,11 +195,16 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
     
         dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
         if (!dctx) return NULL;
    -    memset(dctx, 0, sizeof(*dctx));
         memcpy(&dctx->customMem, &customMem, sizeof(customMem));
         ZSTD_decompressBegin(dctx);   /* cannot fail */
         dctx->streamStage = zdss_init;
         dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
    +    dctx->ddict   = NULL;
    +    dctx->ddictLocal = NULL;
    +    dctx->inBuff  = NULL;
    +    dctx->outBuff = NULL;
    +    dctx->inBuffSize = 0;
    +    dctx->outBuffSize= 0;
         return dctx;
     }
     
    
    From 55fc1f91fd16d1ebddd4787788876fc14878abe6 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 24 May 2017 13:50:10 -0700
    Subject: [PATCH 095/400] [zstd] Fix up formatting edge cases for clang-format
    
    ---
     lib/compress/huf_compress.c      |  3 +-
     lib/compress/zstd_compress.c     |  7 +--
     lib/decompress/huf_decompress.c  |  3 +-
     lib/decompress/zstd_decompress.c | 95 ++++++++++++++++----------------
     4 files changed, 55 insertions(+), 53 deletions(-)
    
    diff --git a/lib/compress/huf_compress.c b/lib/compress/huf_compress.c
    index 7248c2513..7af0789a9 100644
    --- a/lib/compress/huf_compress.c
    +++ b/lib/compress/huf_compress.c
    @@ -266,7 +266,8 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
                             if (highTotal <= lowTotal) break;
                     }   }
                     /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
    -                while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))  /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    +                /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    +                while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
                         nBitsToDecrease ++;
                     totalCost -= 1 << (nBitsToDecrease-1);
                     if (rankLast[nBitsToDecrease-1] == noSymbol)
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index edf4609f7..3ba1748f0 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -1950,8 +1950,8 @@ U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
     }
     
     
    -
    -FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
    +/* inlining is important to hardwire a hot branch (template emulation) */
    +FORCE_INLINE
     size_t ZSTD_HcFindBestMatch_generic (
                             ZSTD_CCtx* zc,   /* Index table will be updated */
                             const BYTE* const ip, const BYTE* const iLimit,
    @@ -2557,8 +2557,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
         U32   const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
         BYTE  const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
         U32   const fcsCode = params.fParams.contentSizeFlag ?
    -                     (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) :   /* 0-3 */
    -                      0;
    +                     (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */
         BYTE  const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
         size_t pos;
     
    diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c
    index ea35c3620..d40b3be04 100644
    --- a/lib/decompress/huf_decompress.c
    +++ b/lib/decompress/huf_decompress.c
    @@ -545,7 +545,8 @@ static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DE
             if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
                 BIT_skipBits(DStream, dt[val].nbBits);
                 if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
    -                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);   /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    +                /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    +                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
         }   }
         return 1;
     }
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 0c61960ec..ea64edeed 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -2240,7 +2240,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                             return hSize; /* error */
                     }   }
     #else
    -                return hSize;
    +                    return hSize;
     #endif
                     if (hSize != 0) {   /* need more input */
                         size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */
    @@ -2252,53 +2252,54 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                         }
                         memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
                         break;
    -            }   }
    -
    -            /* check for single-pass mode opportunity */
    -            if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    -                && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
    -                size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
    -                if (cSize <= (size_t)(iend-istart)) {
    -                    size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
    -                    if (ZSTD_isError(decompressedSize)) return decompressedSize;
    -                    ip = istart + cSize;
    -                    op += decompressedSize;
    -                    zds->dctx->expected = 0;
    -                    zds->stage = zdss_init;
    -                    someMoreWork = 0;
    -                    break;
    -            }   }
    -
    -            /* Consume header */
    -            CHECK_F(ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict));
    -            {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    -                CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    -                {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    -                    CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
    -            }   }
    -
    -            zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
    -            if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
    -
    -            /* Adapt buffer sizes to frame header instructions */
    -            {   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    -                size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
    -                zds->blockSize = blockSize;
    -                if (zds->inBuffSize < blockSize) {
    -                    ZSTD_free(zds->inBuff, zds->customMem);
    -                    zds->inBuffSize = 0;
    -                    zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    -                    if (zds->inBuff == NULL) return ERROR(memory_allocation);
    -                    zds->inBuffSize = blockSize;
                     }
    -                if (zds->outBuffSize < neededOutSize) {
    -                    ZSTD_free(zds->outBuff, zds->customMem);
    -                    zds->outBuffSize = 0;
    -                    zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
    -                    if (zds->outBuff == NULL) return ERROR(memory_allocation);
    -                    zds->outBuffSize = neededOutSize;
    -            }   }
    -            zds->stage = zdss_read;
    +
    +                /* check for single-pass mode opportunity */
    +                if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    +                    && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
    +                    size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
    +                    if (cSize <= (size_t)(iend-istart)) {
    +                        size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
    +                        if (ZSTD_isError(decompressedSize)) return decompressedSize;
    +                        ip = istart + cSize;
    +                        op += decompressedSize;
    +                        zds->dctx->expected = 0;
    +                        zds->stage = zdss_init;
    +                        someMoreWork = 0;
    +                        break;
    +                }   }
    +
    +                /* Consume header */
    +                CHECK_F(ZSTD_decompressBegin_usingDDict(zds->dctx, zds->ddict));
    +                {   size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);  /* == ZSTD_frameHeaderSize_prefix */
    +                    CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
    +                    {   size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
    +                        CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
    +                }   }
    +
    +                zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
    +                if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
    +
    +                /* Adapt buffer sizes to frame header instructions */
    +                {   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
    +                    size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
    +                    zds->blockSize = blockSize;
    +                    if (zds->inBuffSize < blockSize) {
    +                        ZSTD_free(zds->inBuff, zds->customMem);
    +                        zds->inBuffSize = 0;
    +                        zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    +                        if (zds->inBuff == NULL) return ERROR(memory_allocation);
    +                        zds->inBuffSize = blockSize;
    +                    }
    +                    if (zds->outBuffSize < neededOutSize) {
    +                        ZSTD_free(zds->outBuff, zds->customMem);
    +                        zds->outBuffSize = 0;
    +                        zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
    +                        if (zds->outBuff == NULL) return ERROR(memory_allocation);
    +                        zds->outBuffSize = neededOutSize;
    +                }   }
    +                zds->stage = zdss_read;
    +            }
                 /* pass-through */
     
             case zdss_read:
    
    From 74b12f401455dcd50a8e858b7bb18acd9eecacc7 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 24 May 2017 13:52:36 -0700
    Subject: [PATCH 096/400] [linux-kernel] Fix some up clang-format edge cases
    
    ---
     contrib/linux-kernel/kernelize.sh              | 1 +
     contrib/linux-kernel/lib/zstd/compress.c       | 5 ++---
     contrib/linux-kernel/lib/zstd/decompress.c     | 2 +-
     contrib/linux-kernel/lib/zstd/fse.h            | 4 ----
     contrib/linux-kernel/lib/zstd/fse_compress.c   | 4 ----
     contrib/linux-kernel/lib/zstd/fse_decompress.c | 4 ----
     contrib/linux-kernel/lib/zstd/huf_compress.c   | 5 ++---
     contrib/linux-kernel/lib/zstd/huf_decompress.c | 5 ++---
     8 files changed, 8 insertions(+), 22 deletions(-)
    
    diff --git a/contrib/linux-kernel/kernelize.sh b/contrib/linux-kernel/kernelize.sh
    index 35ef5ed9f..21aa2ecdc 100755
    --- a/contrib/linux-kernel/kernelize.sh
    +++ b/contrib/linux-kernel/kernelize.sh
    @@ -96,6 +96,7 @@ then
       check_not_present_in_file STATIC_ASSERT ${LIB}mem.h
       check_not_present_in_file "#define ZSTD_STATIC_ASSERT" ${LIB}compress.c
       check_not_present MEM_STATIC
    +  check_not_present FSE_COMMONDEFS_ONLY
       check_not_present "#if 0"
       check_not_present "#if 1"
       check_not_present _MSC_VER
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index 39b8c3b8f..f2940a146 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -2412,9 +2412,8 @@ static size_t ZSTD_writeFrameHeader(void *dst, size_t dstCapacity, ZSTD_paramete
     	U32 const windowSize = 1U << params.cParams.windowLog;
     	U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
     	BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
    -	U32 const fcsCode = params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU)
    -							   : /* 0-3 */
    -				0;
    +	U32 const fcsCode =
    +	    params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU) : 0; /* 0-3 */
     	BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag << 2) + (singleSegment << 5) + (fcsCode << 6));
     	size_t pos;
     
    diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c
    index 2926b36fc..def10ea4d 100644
    --- a/contrib/linux-kernel/lib/zstd/decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/decompress.c
    @@ -2300,7 +2300,6 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB
     				ip += toLoad;
     				break;
     			}
    -		}
     
     			/* check for single-pass mode opportunity */
     			if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    @@ -2355,6 +2354,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB
     				}
     			}
     			zds->stage = zdss_read;
    +		}
     		/* pass-through */
     
     		case zdss_read: {
    diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h
    index 9749755c3..bc2962aec 100644
    --- a/contrib/linux-kernel/lib/zstd/fse.h
    +++ b/contrib/linux-kernel/lib/zstd/fse.h
    @@ -536,8 +536,6 @@ ZSTD_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t *DStatePtr, BIT_DStream_t *bi
     
     ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr) { return DStatePtr->state == 0; }
     
    -#ifndef FSE_COMMONDEFS_ONLY
    -
     /* **************************************************************
     *  Tuning parameters
     ****************************************************************/
    @@ -567,8 +565,6 @@ ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr) { return DSt
     #define FSE_FUNCTION_EXTENSION
     #define FSE_DECODE_TYPE FSE_decode_t
     
    -#endif /* !FSE_COMMONDEFS_ONLY */
    -
     /* ***************************************************************
     *  Constants
     *****************************************************************/
    diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c
    index 6bb810ff8..e016bb177 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c
    @@ -180,8 +180,6 @@ size_t FSE_buildCTable_wksp(FSE_CTable *ct, const short *normalizedCounter, unsi
     	return 0;
     }
     
    -#ifndef FSE_COMMONDEFS_ONLY
    -
     /*-**************************************************************
     *  FSE NCount encoding-decoding
     ****************************************************************/
    @@ -857,5 +855,3 @@ size_t FSE_compress_wksp(void *dst, size_t dstSize, const void *src, size_t srcS
     
     	return op - ostart;
     }
    -
    -#endif /* FSE_COMMONDEFS_ONLY */
    diff --git a/contrib/linux-kernel/lib/zstd/fse_decompress.c b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    index 245570a8a..96cf89ff9 100644
    --- a/contrib/linux-kernel/lib/zstd/fse_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/fse_decompress.c
    @@ -161,8 +161,6 @@ size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned
     	return 0;
     }
     
    -#ifndef FSE_COMMONDEFS_ONLY
    -
     /*-*******************************************************
     *  Decompression (Byte symbols)
     *********************************************************/
    @@ -313,5 +311,3 @@ size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size
     
     	return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
     }
    -
    -#endif /* FSE_COMMONDEFS_ONLY */
    diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c
    index 158740129..e82a136a1 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_compress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c
    @@ -305,9 +305,8 @@ static U32 HUF_setMaxHeight(nodeElt *huffNode, U32 lastNonNull, U32 maxNbBits)
     					}
     				}
     				/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
    -				while (
    -				    (nBitsToDecrease <= HUF_TABLELOG_MAX) &&
    -				    (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    +				/* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    +				while ((nBitsToDecrease <= HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
     					nBitsToDecrease++;
     				totalCost -= 1 << (nBitsToDecrease - 1);
     				if (rankLast[nBitsToDecrease - 1] == noSymbol)
    diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    index 5c38aa30d..950c19443 100644
    --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c
    +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c
    @@ -573,9 +573,8 @@ static U32 HUF_decodeLastSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DE
     		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) {
     			BIT_skipBits(DStream, dt[val].nbBits);
     			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8))
    -				DStream->bitsConsumed =
    -				    (sizeof(DStream->bitContainer) *
    -				     8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    +				/* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    +				DStream->bitsConsumed = (sizeof(DStream->bitContainer) * 8);
     		}
     	}
     	return 1;
    
    From ba183005d340daf28a39f11e92d422e1831f94a1 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 24 May 2017 15:42:24 -0700
    Subject: [PATCH 097/400] merged DStream's inBuff and outBuff into a single
     buffer
    
    Saves one malloc().
    Also : makes it easier to implement static allocation
    ---
     lib/decompress/zstd_decompress.c | 31 +++++++++++++------------------
     1 file changed, 13 insertions(+), 18 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 8cf500445..1552fec3f 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -202,7 +202,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
         dctx->ddict   = NULL;
         dctx->ddictLocal = NULL;
         dctx->inBuff  = NULL;
    -    dctx->outBuff = NULL;
         dctx->inBuffSize = 0;
         dctx->outBuffSize= 0;
         return dctx;
    @@ -221,8 +220,6 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
             dctx->ddictLocal = NULL;
             ZSTD_free(dctx->inBuff, cMem);
             dctx->inBuff = NULL;
    -        ZSTD_free(dctx->outBuff, cMem);
    -        dctx->outBuff = NULL;
     #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
             if (dctx->legacyContext)
                 ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
    @@ -2225,9 +2222,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     
             case zdss_loadHeader :
                 {   size_t const hSize = ZSTD_getFrameHeader(&zds->fParams, zds->headerBuffer, zds->lhSize);
    -                if (ZSTD_isError(hSize))
    +                if (ZSTD_isError(hSize)) {
     #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
    -                {   U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
    +                    U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
                         if (legacyVersion) {
                             const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL;
                             size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
    @@ -2237,10 +2234,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                             return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
                         } else {
                             return hSize; /* error */
    -                }   }
    +                    }
     #else
    -                return hSize;
    +                    return hSize;
     #endif
    +                }
                     if (hSize != 0) {   /* need more input */
                         size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */
                         if (toLoad > (size_t)(iend-ip)) {   /* not enough input to load full header */
    @@ -2283,22 +2281,19 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 {   size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_MAX);
                     size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
                     zds->blockSize = blockSize;
    -                if (zds->inBuffSize < blockSize) {
    +                if ((zds->inBuffSize < blockSize) || (zds->outBuffSize < neededOutSize)) {
    +                    size_t const bufferSize = blockSize + neededOutSize;
                         DEBUGLOG(4, "inBuff  : from %u to %u",
                                     (U32)zds->inBuffSize, (U32)blockSize);
    -                    ZSTD_free(zds->inBuff, zds->customMem);
    -                    zds->inBuffSize = 0;
    -                    zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
    -                    if (zds->inBuff == NULL) return ERROR(memory_allocation);
    -                    zds->inBuffSize = blockSize;
    -                }
    -                if (zds->outBuffSize < neededOutSize) {
                         DEBUGLOG(4, "outBuff : from %u to %u",
                                     (U32)zds->outBuffSize, (U32)neededOutSize);
    -                    ZSTD_free(zds->outBuff, zds->customMem);
    +                    ZSTD_free(zds->inBuff, zds->customMem);
    +                    zds->inBuffSize = 0;
                         zds->outBuffSize = 0;
    -                    zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
    -                    if (zds->outBuff == NULL) return ERROR(memory_allocation);
    +                    zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
    +                    if (zds->inBuff == NULL) return ERROR(memory_allocation);
    +                    zds->inBuffSize = blockSize;
    +                    zds->outBuff = zds->inBuff + zds->inBuffSize;
                         zds->outBuffSize = neededOutSize;
                 }   }
                 zds->streamStage = zdss_read;
    
    From 0fdc71c3dc1e8cbef7416218c46d39ad0631381a Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 24 May 2017 17:41:41 -0700
    Subject: [PATCH 098/400] added ZSTD_initStaticDCtx()
    
    ---
     doc/zstd_manual.html             |  16 +++++
     lib/compress/zstd_compress.c     |   2 +-
     lib/decompress/zstd_decompress.c | 103 ++++++++++++++++++++-----------
     lib/zstd.h                       |  18 +++++-
     tests/fuzzer.c                   |  41 +++++++++---
     5 files changed, 135 insertions(+), 45 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index d84f8396e..72da13650 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -691,6 +691,22 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
     

    Create a ZSTD decompression context using external alloc and free functions


    +
    ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize);
    +

    workspace: The memory area to emplace the context into. + Provided pointer must 8-bytes aligned. + It must outlive context usage. + workspaceSize: Use ZSTD_estimateDCtxSize() or ZSTD_estimateDStreamSize() + to determine how large workspace must be to support scenario. + @return : pointer to ZSTD_DCtx*, or NULL if error (size too small) + Note : zstd will never resize nor malloc() when using a static dctx. + If it needs more memory than available, it will simply error out. + Note 2 : there is no corresponding "free" function. + Since workspace was allocated externally, it must be freed externally. + Limitation : currently not compatible with internal DDict creation, + such as ZSTD_initDStream_usingDict(). + +


    +
    ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
     

    Create a digested dictionary, ready to start decompression operation without startup delay. Dictionary content is simply referenced, and therefore stays in dictBuffer. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index deee3cfc7..58ed98e9b 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -190,7 +190,7 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize) /* note : this code should be shared with resetCCtx, instead of copied */ { void* ptr = cctx->workSpace; cctx->hufCTable = (HUF_CElt*)ptr; - ptr = (char*)cctx->hufCTable + hufCTable_size; /* note : HUF_CElt* is incomplete type, size is estimated via macro */ + ptr = (char*)cctx->hufCTable + hufCTable_size; cctx->offcodeCTable = (FSE_CTable*) ptr; ptr = (char*)ptr + offcodeCTable_size; cctx->matchlengthCTable = (FSE_CTable*) ptr; diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 1552fec3f..2db493e51 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -133,8 +133,7 @@ struct ZSTD_DCtx_s ZSTD_customMem customMem; size_t litSize; size_t rleSize; - BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; - BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; + size_t staticSize; /* streaming */ ZSTD_DDict* ddictLocal; @@ -154,6 +153,10 @@ struct ZSTD_DCtx_s U32 previousLegacyVersion; U32 legacyVersion; U32 hostageByte; + + /* workspace */ + BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) @@ -186,24 +189,45 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) return 0; } -ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) { - ZSTD_DCtx* dctx; - - if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem; - if (!customMem.customAlloc || !customMem.customFree) return NULL; - - dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem); - if (!dctx) return NULL; - memcpy(&dctx->customMem, &customMem, sizeof(customMem)); ZSTD_decompressBegin(dctx); /* cannot fail */ - dctx->streamStage = zdss_init; + dctx->staticSize = 0; dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; dctx->ddict = NULL; dctx->ddictLocal = NULL; dctx->inBuff = NULL; dctx->inBuffSize = 0; dctx->outBuffSize= 0; + dctx->streamStage = zdss_init; +} + +ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) +{ + ZSTD_DCtx* dctx; + + if (!customMem.customAlloc && !customMem.customFree) + customMem = defaultCustomMem; + if (!customMem.customAlloc || !customMem.customFree) + return NULL; + + dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem); + if (!dctx) return NULL; + memcpy(&dctx->customMem, &customMem, sizeof(customMem)); + ZSTD_initDCtx_internal(dctx); + return dctx; +} + +ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) +{ + ZSTD_DCtx* dctx = (ZSTD_DCtx*) workspace; + + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ + + ZSTD_initDCtx_internal(dctx); + dctx->staticSize = workspaceSize; + dctx->inBuff = (char*)(dctx+1); return dctx; } @@ -229,10 +253,11 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) } } +/* no longer appropriate */ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) { - size_t const workSpaceSize = (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max; - memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */ + size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); + memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ } @@ -2283,15 +2308,22 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->blockSize = blockSize; if ((zds->inBuffSize < blockSize) || (zds->outBuffSize < neededOutSize)) { size_t const bufferSize = blockSize + neededOutSize; - DEBUGLOG(4, "inBuff : from %u to %u", + DEBUGLOG(5, "inBuff : from %u to %u", (U32)zds->inBuffSize, (U32)blockSize); - DEBUGLOG(4, "outBuff : from %u to %u", + DEBUGLOG(5, "outBuff : from %u to %u", (U32)zds->outBuffSize, (U32)neededOutSize); - ZSTD_free(zds->inBuff, zds->customMem); - zds->inBuffSize = 0; - zds->outBuffSize = 0; - zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); - if (zds->inBuff == NULL) return ERROR(memory_allocation); + if (zds->staticSize) { /* static DCtx */ + DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize); + assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* already checked at init */ + if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx)) + return ERROR(memory_allocation); + } else { + ZSTD_free(zds->inBuff, zds->customMem); + zds->inBuffSize = 0; + zds->outBuffSize = 0; + zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); + if (zds->inBuff == NULL) return ERROR(memory_allocation); + } zds->inBuffSize = blockSize; zds->outBuff = zds->inBuff + zds->inBuffSize; zds->outBuffSize = neededOutSize; @@ -2317,11 +2349,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->outEnd = zds->outStart + decodedSize; zds->streamStage = zdss_flush; break; - } - if (ip==iend) { someMoreWork = 0; break; } /* no more input */ - zds->streamStage = zdss_load; - /* pass-through */ - } + } } + if (ip==iend) { someMoreWork = 0; break; } /* no more input */ + zds->streamStage = zdss_load; + /* pass-through */ case zdss_load: { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); @@ -2342,9 +2373,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB zds->inPos = 0; /* input is consumed */ if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; } /* this was just a header */ zds->outEnd = zds->outStart + decodedSize; - zds->streamStage = zdss_flush; - /* pass-through */ } } + zds->streamStage = zdss_flush; + /* pass-through */ case zdss_flush: { size_t const toFlushSize = zds->outEnd - zds->outStart; @@ -2356,11 +2387,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB if (zds->outStart + zds->blockSize > zds->outBuffSize) zds->outStart = zds->outEnd = 0; break; - } - /* cannot complete flush */ - someMoreWork = 0; - break; - } + } } + /* cannot complete flush */ + someMoreWork = 0; + break; + default: return ERROR(GENERIC); /* impossible */ } } @@ -2377,15 +2408,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB return 1; } input->pos++; /* release hostage */ - } + } /* zds->hostageByte */ return 0; - } + } /* zds->outEnd == zds->outStart */ if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ zds->hostageByte=1; } return 1; - } + } /* nextSrcSizeHint==0 */ nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */ if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */ nextSrcSizeHint -= zds->inPos; /* already loaded*/ diff --git a/lib/zstd.h b/lib/zstd.h index 81f9eb737..bb043e486 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -529,7 +529,7 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); -/* !!! Soon to be deprecated !!! */ +/* !!! To be deprecated !!! */ typedef enum { ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */ ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */ @@ -815,6 +815,22 @@ ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size); * Create a ZSTD decompression context using external alloc and free functions */ ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem); +/*! ZSTD_initStaticDCtx() : initialize a fixed-size zstd decompression context + * workspace: The memory area to emplace the context into. + * Provided pointer must 8-bytes aligned. + * It must outlive context usage. + * workspaceSize: Use ZSTD_estimateDCtxSize() or ZSTD_estimateDStreamSize() + * to determine how large workspace must be to support scenario. + * @return : pointer to ZSTD_DCtx*, or NULL if error (size too small) + * Note : zstd will never resize nor malloc() when using a static dctx. + * If it needs more memory than available, it will simply error out. + * Note 2 : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + * Limitation : currently not compatible with internal DDict creation, + * such as ZSTD_initDStream_usingDict(). + */ +ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize); + /*! ZSTD_createDDict_byReference() : * Create a digested dictionary, ready to start decompression operation without startup delay. * Dictionary content is simply referenced, and therefore stays in dictBuffer. diff --git a/tests/fuzzer.c b/tests/fuzzer.c index a1dc6ba77..b2de6ec69 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -74,7 +74,6 @@ static clock_t FUZ_clockSpan(clock_t cStart) return clock() - cStart; /* works even when overflow; max span ~ 30mn */ } - #define FUZ_rotl32(x,r) ((x << r) | (x >> (32 - r))) static unsigned FUZ_rand(unsigned* src) { @@ -104,6 +103,7 @@ static unsigned FUZ_highbit32(U32 v32) #define CHECK_V(var, fn) size_t const var = fn; if (ZSTD_isError(var)) goto _output_error #define CHECK(fn) { CHECK_V(err, fn); } #define CHECKPLUS(var, fn, more) { CHECK_V(var, fn); more; } + static int basicUnitTests(U32 seed, double compressibility) { size_t const CNBuffSize = 5 MB; @@ -195,14 +195,19 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(4, "test%3i : create static CCtx for level %u :", testNb++, STATIC_CCTX_LEVEL); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(STATIC_CCTX_LEVEL, 0, 0); size_t const staticCCtxSize = ZSTD_estimateCStreamSize(cParams); - void* staticCCtxBuffer = malloc(staticCCtxSize); - if (staticCCtxBuffer==NULL) { + void* const staticCCtxBuffer = malloc(staticCCtxSize); + size_t const staticDCtxSize = ZSTD_estimateDCtxSize(); + void* const staticDCtxBuffer = malloc(staticDCtxSize); + if (staticCCtxBuffer==NULL || staticDCtxBuffer==NULL) { + free(staticCCtxBuffer); + free(staticDCtxBuffer); DISPLAY("Not enough memory, aborting\n"); testResult = 1; goto _end; } { ZSTD_CCtx* staticCCtx = ZSTD_initStaticCCtx(staticCCtxBuffer, staticCCtxSize); - if (staticCCtx==NULL) goto _output_error; + ZSTD_DCtx* staticDCtx = ZSTD_initStaticDCtx(staticDCtxBuffer, staticDCtxSize); + if ((staticCCtx==NULL) || (staticDCtx==NULL)) goto _output_error; DISPLAYLEVEL(4, "OK \n"); DISPLAYLEVEL(4, "test%3i : init CCtx for level %u : ", testNb++, STATIC_CCTX_LEVEL); @@ -215,13 +220,24 @@ static int basicUnitTests(U32 seed, double compressibility) compressedBuffer, ZSTD_compressBound(CNBuffSize), CNBuffer, CNBuffSize, STATIC_CCTX_LEVEL), cSize=r ); - DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", + (U32)cSize, (double)cSize/CNBuffSize*100); - DISPLAYLEVEL(4, "test%3i : decompress verification test : ", testNb++); - { size_t const r = ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize); + DISPLAYLEVEL(4, "test%3i : simple decompression test with static DCtx : ", testNb++); + { size_t const r = ZSTD_decompressDCtx(staticDCtx, + decodedBuffer, CNBuffSize, + compressedBuffer, cSize); if (r != CNBuffSize) goto _output_error; } DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(4, "test%3i : check decompressed result : ", testNb++); + { size_t u; + for (u=0; u Date: Thu, 25 May 2017 13:56:46 -0700 Subject: [PATCH 099/400] [linux-kernel] Fix clang-format edge case with goto labels --- contrib/linux-kernel/lib/zstd/compress.c | 26 +++++++++++++----------- contrib/linux-kernel/lib/zstd/zstd_opt.h | 4 ++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c index f2940a146..42236a3e1 100644 --- a/contrib/linux-kernel/lib/zstd/compress.c +++ b/contrib/linux-kernel/lib/zstd/compress.c @@ -816,14 +816,15 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa } /* check compressibility */ -_check_compressibility : { - size_t const minGain = ZSTD_minGain(srcSize); - size_t const maxCSize = srcSize - minGain; - if ((size_t)(op - ostart) >= maxCSize) { - zc->flagStaticHufTable = HUF_repeat_none; - return 0; +_check_compressibility: + { + size_t const minGain = ZSTD_minGain(srcSize); + size_t const maxCSize = srcSize - minGain; + if ((size_t)(op - ostart) >= maxCSize) { + zc->flagStaticHufTable = HUF_repeat_none; + return 0; + } } -} /* confirm repcodes */ { @@ -1990,11 +1991,12 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx *ctx, const void *src, size_t src } /* store sequence */ - _storeSequence : { - size_t const litLength = start - anchor; - ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH); - anchor = ip = start + matchLength; - } +_storeSequence: + { + size_t const litLength = start - anchor; + ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH); + anchor = ip = start + matchLength; + } /* check immediate repcode */ while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) { diff --git a/contrib/linux-kernel/lib/zstd/zstd_opt.h b/contrib/linux-kernel/lib/zstd/zstd_opt.h index 468c14368..55e1b4cba 100644 --- a/contrib/linux-kernel/lib/zstd/zstd_opt.h +++ b/contrib/linux-kernel/lib/zstd/zstd_opt.h @@ -628,7 +628,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx *ctx, const void *src, size_t srcS cur = last_pos - best_mlen; /* store sequence */ - _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ +_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ opt[0].mlen = 1; while (1) { @@ -942,7 +942,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx *ctx, const void *src, siz cur = last_pos - best_mlen; /* store sequence */ - _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ +_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */ opt[0].mlen = 1; while (1) { From 25989e361c70d6ab85ece7f864dab60cf3164183 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 25 May 2017 15:07:37 -0700 Subject: [PATCH 100/400] updated ZSTD_estimate?DictSize() to pass parameter byReference resulting ?Dict object is smaller when created byReference. Seems better than a documentation note. --- doc/zstd_manual.html | 21 ++++++++++++++++++--- lib/compress/zstd_compress.c | 5 +++-- lib/decompress/zstd_decompress.c | 6 +++--- lib/zstd.h | 26 +++++++++++++++++++++----- tests/fuzzer.c | 7 ++++--- tests/zstreamtest.c | 6 ++++-- 6 files changed, 53 insertions(+), 18 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 72da13650..f6a09ef0c 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -412,9 +412,9 @@ size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader); In this case, get additional size by using ZSTD_estimate?DictSize


    -
    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize);
    -size_t ZSTD_estimateDDictSize(size_t dictSize);
    -

    Note : if dictionary is created "byReference", reduce estimation by dictSize +

    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference);
    +size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
    +

    Note : dictionary created "byReference" are smaller


    Advanced compression functions

    
    @@ -718,6 +718,21 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
     

    Create a ZSTD_DDict using external alloc and free, optionally by reference


    +
    ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
    +                                 const void* dict, size_t dictSize,
    +                                 unsigned byReference);
    +

    Generate a digested dictionary in provided memory area. + workspace: The memory area to emplace the dictionary into. + Provided pointer must 8-bytes aligned. + It must outlive dictionary usage. + workspaceSize: Use ZSTD_estimateDDictSize() + to determine how large workspace must be. + @return : pointer to ZSTD_DDict*, or NULL if error (size too small) + Note : there is no corresponding "free" function. + Since workspace was allocated externally, it must be freed externally. + +


    +
    unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
     

    Provides the dictID stored within dictionary. if @return == 0, the dictionary is not conformant with Zstandard specification. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 58ed98e9b..aa9f64c5c 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3237,10 +3237,11 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS /*! ZSTD_estimateCDictSize() : * Estimate amount of memory that will be needed to create a dictionary with following arguments */ -size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize) +size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference) { cParams = ZSTD_adjustCParams(cParams, 0, dictSize); - return sizeof(ZSTD_CDict) + dictSize + ZSTD_estimateCCtxSize(cParams); + return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize(cParams) + + (byReference ? 0 : dictSize); } size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 2db493e51..8b1381184 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2053,10 +2053,10 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict) /*! ZSTD_estimateDDictSize() : * Estimate amount of memory that will be needed to create a dictionary for decompression. - * Note : if dictionary is created "byReference", reduce this amount by dictSize */ -size_t ZSTD_estimateDDictSize(size_t dictSize) + * Note : dictionary created "byReference" are smaller */ +size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference) { - return dictSize + sizeof(ZSTD_DDict); + return sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize); } size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) diff --git a/lib/zstd.h b/lib/zstd.h index bb043e486..de3b2c30d 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -345,8 +345,6 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output #endif /* ZSTD_H_235446 */ -#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) -#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY /**************************************************************************************** * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS @@ -356,6 +354,9 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output * Use them only in association with static linking. * ***************************************************************************************/ +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY + /* --- Constants ---*/ #define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */ #define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U @@ -500,9 +501,9 @@ ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams); ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader); /*! ZSTD_estimate?DictSize() : - * Note : if dictionary is created "byReference", reduce estimation by dictSize */ -ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize); -ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize); + * Note : dictionary created "byReference" are smaller */ +ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference); +ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference); /*************************************** @@ -842,6 +843,21 @@ ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, siz ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem); +/*! ZSTD_initStaticDDict() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateDDictSize() + * to determine how large workspace must be. + * @return : pointer to ZSTD_DDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +ZSTDLIB_API ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, + unsigned byReference); + /*! ZSTD_getDictID_fromDict() : * Provides the dictID stored within dictionary. * if @return == 0, the dictionary is not conformant with Zstandard specification. diff --git a/tests/fuzzer.c b/tests/fuzzer.c index b2de6ec69..83b95974f 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -490,14 +490,15 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); - size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize); + size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize, 1); DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize); } DISPLAYLEVEL(4, "test%3i : compress with preprocessed dictionary : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); - ZSTD_customMem customMem = { NULL, NULL, NULL }; - ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1, cParams, customMem); + ZSTD_customMem const customMem = { NULL, NULL, NULL }; + ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, + 1 /* by Referece */, cParams, customMem); cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize), CNBuffer, CNBuffSize, cdict); ZSTD_freeCDict(cdict); diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index e9e17031c..0f73b8cd4 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -209,7 +209,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo DISPLAYLEVEL(3, "test%3i : estimate CStream size : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize); size_t const s = ZSTD_estimateCStreamSize(cParams) - + ZSTD_estimateCDictSize(cParams, dictSize); /* uses ZSTD_initCStream_usingDict() */ + /* uses ZSTD_initCStream_usingDict() */ + + ZSTD_estimateCDictSize(cParams, dictSize, 0); if (ZSTD_isError(s)) goto _output_error; DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s); } @@ -281,7 +282,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo if (gfhError!=0) goto _output_error; DISPLAYLEVEL(5, " (windowSize : %u) ", fhi.windowSize); { size_t const s = ZSTD_estimateDStreamSize(fhi) - + ZSTD_estimateDDictSize(dictSize); /* uses ZSTD_initDStream_usingDict() */ + /* uses ZSTD_initDStream_usingDict() */ + + ZSTD_estimateDDictSize(dictSize, 0); if (ZSTD_isError(s)) goto _output_error; DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s); } } From 57827f906f63eee0afaa51b2a82f6d2967f6f138 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 25 May 2017 15:44:06 -0700 Subject: [PATCH 101/400] added ZSTD_initStaticDDict() --- doc/zstd_manual.html | 5 +-- lib/decompress/zstd_decompress.c | 59 ++++++++++++++++++++++---------- lib/zstd.h | 5 +-- tests/fuzzer.c | 13 ++++++- 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index f6a09ef0c..5040dd7d3 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -709,8 +709,9 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic

    ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
     

    Create a digested dictionary, ready to start decompression operation without startup delay. - Dictionary content is simply referenced, and therefore stays in dictBuffer. - It is important that dictBuffer outlives DDict, it must remain read accessible throughout the lifetime of DDict + Dictionary content is referenced, and therefore stays in dictBuffer. + It is important that dictBuffer outlives DDict, + it must remain read accessible throughout the lifetime of DDict


    ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 8b1381184..e3721929e 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -1987,6 +1987,27 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
     }
     
     
    +static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, unsigned byReference)
    +{
    +    if ((byReference) || (!dict) || (!dictSize)) {
    +        ddict->dictBuffer = NULL;
    +        ddict->dictContent = dict;
    +    } else {
    +        void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);
    +        if (!internalBuffer) return ERROR(memory_allocation);
    +        memcpy(internalBuffer, dict, dictSize);
    +        ddict->dictBuffer = internalBuffer;
    +        ddict->dictContent = internalBuffer;
    +    }
    +    ddict->dictSize = dictSize;
    +    ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    +
    +    /* parse dictionary content */
    +    CHECK_F( ZSTD_loadEntropy_inDDict(ddict) );
    +
    +    return 0;
    +}
    +
     ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
     {
         if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    @@ -1996,24 +2017,10 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
             if (!ddict) return NULL;
             ddict->cMem = customMem;
     
    -        if ((byReference) || (!dict) || (!dictSize)) {
    -            ddict->dictBuffer = NULL;
    -            ddict->dictContent = dict;
    -        } else {
    -            void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
    -            if (!internalBuffer) { ZSTD_freeDDict(ddict); return NULL; }
    -            memcpy(internalBuffer, dict, dictSize);
    -            ddict->dictBuffer = internalBuffer;
    -            ddict->dictContent = internalBuffer;
    +        if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, byReference) )) {
    +            ZSTD_freeDDict(ddict);
    +            return NULL;
             }
    -        ddict->dictSize = dictSize;
    -        ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    -        /* parse dictionary content */
    -        {   size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
    -            if (ZSTD_isError(errorCode)) {
    -                ZSTD_freeDDict(ddict);
    -                return NULL;
    -        }   }
     
             return ddict;
         }
    @@ -2029,7 +2036,6 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
         return ZSTD_createDDict_advanced(dict, dictSize, 0, allocator);
     }
     
    -
     /*! ZSTD_createDDict_byReference() :
      *  Create a digested dictionary, to start decompression without startup delay.
      *  Dictionary content is simply referenced, it will be accessed during decompression.
    @@ -2041,6 +2047,23 @@ ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize
     }
     
     
    +ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
    +                                 const void* dict, size_t dictSize,
    +                                 unsigned byReference)
    +{
    +    size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
    +    ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
    +    if (workspaceSize < neededSpace) return NULL;  /* minimum size */
    +    if (!byReference) {
    +        memcpy(ddict+1, dict, dictSize);  /* local copy */
    +        dict = ddict+1;
    +    }
    +    if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, 1 /* byRef */) ))
    +        return NULL;
    +    return ddict;
    +}
    +
    +
     size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
     {
         if (ddict==NULL) return 0;   /* support free on NULL */
    diff --git a/lib/zstd.h b/lib/zstd.h
    index de3b2c30d..82501994e 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -834,8 +834,9 @@ ZSTDLIB_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize
     
     /*! ZSTD_createDDict_byReference() :
      *  Create a digested dictionary, ready to start decompression operation without startup delay.
    - *  Dictionary content is simply referenced, and therefore stays in dictBuffer.
    - *  It is important that dictBuffer outlives DDict, it must remain read accessible throughout the lifetime of DDict */
    + *  Dictionary content is referenced, and therefore stays in dictBuffer.
    + *  It is important that dictBuffer outlives DDict,
    + *  it must remain read accessible throughout the lifetime of DDict */
     ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
     
     /*! ZSTD_createDDict_advanced() :
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 83b95974f..90cfe648b 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -405,13 +405,24 @@ static int basicUnitTests(U32 seed, double compressibility)
             DISPLAYLEVEL(4, "OK \n");
     
             DISPLAYLEVEL(4, "test%3i : decompress with DDict : ", testNb++);
    -        {   ZSTD_DDict* const ddict = ZSTD_createDDict_byReference(CNBuffer, dictSize);
    +        {   ZSTD_DDict* const ddict = ZSTD_createDDict(CNBuffer, dictSize);
                 size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict);
                 if (r != CNBuffSize - dictSize) goto _output_error;
                 DISPLAYLEVEL(4, "OK (size of DDict : %u) \n", (U32)ZSTD_sizeof_DDict(ddict));
                 ZSTD_freeDDict(ddict);
             }
     
    +        DISPLAYLEVEL(4, "test%3i : decompress with static DDict : ", testNb++);
    +        {   size_t const ddictBufferSize = ZSTD_estimateDDictSize(dictSize, 0);
    +            void* ddictBuffer = malloc(ddictBufferSize);
    +            if (ddictBuffer == NULL) goto _output_error;
    +            {   ZSTD_DDict* const ddict = ZSTD_initStaticDDict(ddictBuffer, ddictBufferSize, CNBuffer, dictSize, 0);
    +                size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict);
    +                if (r != CNBuffSize - dictSize) goto _output_error;
    +            }
    +            DISPLAYLEVEL(4, "OK (size of static DDict : %u) \n", (U32)ddictBufferSize);
    +        }
    +
             DISPLAYLEVEL(4, "test%3i : check content size on duplicated context : ", testNb++);
             {   size_t const testSize = CNBuffSize / 3;
                 {   ZSTD_parameters p = ZSTD_getParams(2, testSize, dictSize);
    
    From 1ea655c76518e96f02d43de88c7644d4916fd5d0 Mon Sep 17 00:00:00 2001
    From: "Dmitry V. Levin" 
    Date: Thu, 25 May 2017 23:43:05 +0000
    Subject: [PATCH 102/400] Fix typo in libzstd.a-mt make rules
    
    The macro name is ZSTD_MULTITHREAD, not ZSTD_MULTHREAD.
    
    Fixes: ca6fae78080d ("Add MT enabled targets for libzstd")
    ---
     lib/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/Makefile b/lib/Makefile
    index f492c6bd1..d0c3c8264 100644
    --- a/lib/Makefile
    +++ b/lib/Makefile
    @@ -73,7 +73,7 @@ libzstd.a: $(ZSTD_OBJ)
     	@echo compiling static library
     	@$(AR) $(ARFLAGS) $@ $^
     
    -libzstd.a-mt: CPPFLAGS += -DZSTD_MULTHREAD
    +libzstd.a-mt: CPPFLAGS += -DZSTD_MULTITHREAD
     libzstd.a-mt: libzstd.a
     
     $(LIBZSTD): LDFLAGS += -shared -fPIC -fvisibility=hidden
    
    From cdf7e82222758cecb01438f09cf1f7b08bf1688d Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Thu, 25 May 2017 18:05:49 -0700
    Subject: [PATCH 103/400] Added ZSTD_initStaticCDict()
    
    ---
     doc/zstd_manual.html             |  22 +++++-
     lib/compress/zstd_compress.c     | 111 ++++++++++++++++++++++---------
     lib/decompress/zstd_decompress.c |   3 +-
     lib/zstd.h                       |  23 ++++++-
     tests/fuzzer.c                   |  23 +++++++
     5 files changed, 145 insertions(+), 37 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 5040dd7d3..a4b59bc46 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -408,8 +408,8 @@ size_t ZSTD_estimateDCtxSize(void);
     
    size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
     size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
     

    Note : if streaming is init with function ZSTD_init?Stream_usingDict(), - an internal ?Dict will be created, which size is not estimated. - In this case, get additional size by using ZSTD_estimate?DictSize + an internal ?Dict will be created, which size is not estimated here. + In this case, get total size by adding ZSTD_estimate?DictSize


    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference);
    @@ -460,6 +460,24 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
     

    Create a ZSTD_CDict using external alloc and free, and customized compression parameters


    +
    ZSTD_CDict* ZSTD_initStaticCDict(
    +                void* workspace, size_t workspaceSize,
    +          const void* dict, size_t dictSize, unsigned byReference,
    +                ZSTD_compressionParameters cParams);
    +

    Generate a digested dictionary in provided memory area. + workspace: The memory area to emplace the dictionary into. + Provided pointer must 8-bytes aligned. + It must outlive dictionary usage. + workspaceSize: Use ZSTD_estimateCDictSize() + to determine how large workspace must be. + cParams : use ZSTD_getCParams() to transform a compression level + into its relevants cParams. + @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + Note : there is no corresponding "free" function. + Since workspace was allocated externally, it must be freed externally. + +


    +
    ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
     

    @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. `estimatedSrcSize` value is optional, select 0 if not known diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index aa9f64c5c..0e93abccb 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3239,7 +3239,6 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS * Estimate amount of memory that will be needed to create a dictionary with following arguments */ size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference) { - cParams = ZSTD_adjustCParams(cParams, 0, dictSize); return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize(cParams) + (byReference ? 0 : dictSize); } @@ -3258,6 +3257,34 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_ return params; } +static size_t ZSTD_initCDict_internal( + ZSTD_CDict* cdict, + const void* dictBuffer, size_t dictSize, unsigned byReference, + ZSTD_compressionParameters cParams) +{ + if ((byReference) || (!dictBuffer) || (!dictSize)) { + cdict->dictBuffer = NULL; + cdict->dictContent = dictBuffer; + } else { + void* const internalBuffer = ZSTD_malloc(dictSize, cdict->refContext->customMem); + if (!internalBuffer) return ERROR(memory_allocation); + memcpy(internalBuffer, dictBuffer, dictSize); + cdict->dictBuffer = internalBuffer; + cdict->dictContent = internalBuffer; + } + cdict->dictContentSize = dictSize; + + { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, + 0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */ + ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams); + CHECK_F( ZSTD_compressBegin_advanced(cdict->refContext, + cdict->dictContent, dictSize, + params, 0 /* srcSize */) ); + } + + return 0; +} + ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference, ZSTD_compressionParameters cParams, ZSTD_customMem customMem) { @@ -3269,44 +3296,19 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem); if (!cdict || !cctx) { - DEBUGLOG(5, "!cdict || !cctx"); ZSTD_free(cdict, customMem); ZSTD_freeCCtx(cctx); return NULL; } + cdict->refContext = cctx; - if ((byReference) || (!dictBuffer) || (!dictSize)) { - cdict->dictBuffer = NULL; - cdict->dictContent = dictBuffer; - } else { - void* const internalBuffer = ZSTD_malloc(dictSize, customMem); - if (!internalBuffer) { - DEBUGLOG(5, "!internalBuffer"); - ZSTD_free(cctx, customMem); - ZSTD_free(cdict, customMem); - return NULL; - } - memcpy(internalBuffer, dictBuffer, dictSize); - cdict->dictBuffer = internalBuffer; - cdict->dictContent = internalBuffer; + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dictBuffer, dictSize, byReference, + cParams) )) { + ZSTD_freeCDict(cdict); + return NULL; } - { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, - 0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */ - ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams); - size_t const errorCode = ZSTD_compressBegin_advanced(cctx, - cdict->dictContent, dictSize, params, 0); - if (ZSTD_isError(errorCode)) { - DEBUGLOG(5, "ZSTD_compressBegin_advanced error : %s", - ZSTD_getErrorName(errorCode)); - ZSTD_free(cdict->dictBuffer, customMem); - ZSTD_free(cdict, customMem); - ZSTD_freeCCtx(cctx); - return NULL; - } } - - cdict->refContext = cctx; - cdict->dictContentSize = dictSize; return cdict; } } @@ -3336,6 +3338,51 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict) } } +/*! ZSTD_initStaticCDict_advanced() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateCDictSize() + * to determine how large workspace must be. + * cParams : use ZSTD_getCParams() to transform a compression level + * into its relevants cParams. + * @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, unsigned byReference, + ZSTD_compressionParameters cParams) +{ + size_t const cctxSize = ZSTD_estimateCCtxSize(cParams); + size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize) + + cctxSize; + ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace; + void* ptr; + DEBUGLOG(2, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7); + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + DEBUGLOG(2, "(workspaceSize < neededSize) : (%u < %u) => %u", + (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize)); + if (workspaceSize < neededSize) return NULL; + + if (!byReference) { + memcpy(cdict+1, dict, dictSize); + dict = cdict+1; + ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize; + } else { + ptr = cdict+1; + } + cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize); + + if (ZSTD_isError( ZSTD_initCDict_internal(cdict, + dict, dictSize, 1 /* by Reference */, + cParams) )) + return NULL; + + return cdict; +} + static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) { return ZSTD_getParamsFromCCtx(cdict->refContext); } diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index e3721929e..fe7446ab2 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2053,7 +2053,8 @@ ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize, { size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize); ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace; - if (workspaceSize < neededSpace) return NULL; /* minimum size */ + if ((size_t)workspace & 7) return NULL; /* 8-aligned */ + if (workspaceSize < neededSpace) return NULL; if (!byReference) { memcpy(ddict+1, dict, dictSize); /* local copy */ dict = ddict+1; diff --git a/lib/zstd.h b/lib/zstd.h index 82501994e..b1d8ecadd 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -495,8 +495,8 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimate?StreamSize() : * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), - * an internal ?Dict will be created, which size is not estimated. - * In this case, get additional size by using ZSTD_estimate?DictSize */ + * an internal ?Dict will be created, which size is not estimated here. + * In this case, get total size by adding ZSTD_estimate?DictSize */ ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams); ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader); @@ -540,6 +540,7 @@ typedef enum { * @result : 0, or an error code (which can be tested with ZSTD_isError()) */ ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value); + /*! ZSTD_createCDict_byReference() : * Create a digested dictionary for compression * Dictionary content is simply referenced, and therefore stays in dictBuffer. @@ -551,6 +552,24 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, siz ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_compressionParameters cParams, ZSTD_customMem customMem); +/*! ZSTD_initStaticCDict_advanced() : + * Generate a digested dictionary in provided memory area. + * workspace: The memory area to emplace the dictionary into. + * Provided pointer must 8-bytes aligned. + * It must outlive dictionary usage. + * workspaceSize: Use ZSTD_estimateCDictSize() + * to determine how large workspace must be. + * cParams : use ZSTD_getCParams() to transform a compression level + * into its relevants cParams. + * @return : pointer to ZSTD_CDict*, or NULL if error (size too small) + * Note : there is no corresponding "free" function. + * Since workspace was allocated externally, it must be freed externally. + */ +ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict( + void* workspace, size_t workspaceSize, + const void* dict, size_t dictSize, unsigned byReference, + ZSTD_compressionParameters cParams); + /*! ZSTD_getCParams() : * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize. * `estimatedSrcSize` value is optional, select 0 if not known */ diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 90cfe648b..ee0aff08c 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -531,6 +531,29 @@ static int basicUnitTests(U32 seed, double compressibility) if (r != CNBuffSize) goto _output_error); DISPLAYLEVEL(4, "OK \n"); + DISPLAYLEVEL(4, "test%3i : compress with static CDict : ", testNb++); + { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); + size_t const cdictSize = ZSTD_estimateCDictSize(cParams, dictSize, 0); + void* const cdictBuffer = malloc(cdictSize); + if (cdictBuffer==NULL) goto _output_error; + { ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize, + dictBuffer, dictSize, 0 /* by Reference */, + cParams); + if (cdict == NULL) { + DISPLAY("ZSTD_initStaticCDict failed "); + goto _output_error; + } + cSize = ZSTD_compress_usingCDict(cctx, + compressedBuffer, ZSTD_compressBound(CNBuffSize), + CNBuffer, CNBuffSize, cdict); + if (ZSTD_isError(cSize)) { + DISPLAY("ZSTD_compress_usingCDict failed "); + goto _output_error; + } } + free(cdictBuffer); + } + DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100); + DISPLAYLEVEL(4, "test%3i : ZSTD_compress_usingCDict_advanced, no contentSize, no dictID : ", testNb++); { ZSTD_frameParameters const fParams = { 0 /* frameSize */, 1 /* checksum */, 1 /* noDictID*/ }; ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize); From 7028cbd7fdf153feb795251af9cae20bbbe22975 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 25 May 2017 18:29:08 -0700 Subject: [PATCH 104/400] fixed a few code comments : ZSTD_getFrameParams => ZSTD_getFrameHeader --- doc/zstd_manual.html | 8 ++++---- lib/zstd.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index a4b59bc46..4d5df5977 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -93,7 +93,7 @@ note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. Always ensure result fits within application's authorized limits. Each application can set its own limits. - note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. + note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameHeader() to know more.


    Helper functions

    int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */
    @@ -773,7 +773,7 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
         Note : this use case also happens when using a non-conformant dictionary.
       - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
       - This is not a Zstandard frame.
    -  When identifying the exact failure cause, it's possible to use ZSTD_getFrameParams(), which will provide a more precise error code. 
    +  When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. 
     


    Advanced streaming functions

    
    @@ -850,7 +850,7 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
       Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
       A ZSTD_DCtx object can be re-used multiple times.
     
    -  First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
    +  First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
       It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
       such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
       and the dictionary ID used.
    @@ -897,7 +897,7 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
       b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
       c) Frame Content - any content (User Data) of length equal to Frame Size
       For skippable frames ZSTD_decompressContinue() always returns 0.
    -  For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
    +  For skippable frames ZSTD_getFrameHeader() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
         Note : If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might actually be a Zstd encoded frame with no content.
                For purposes of decompression, it is valid in both cases to skip the frame using
                ZSTD_findFrameCompressedSize to find its size in bytes.
    diff --git a/lib/zstd.h b/lib/zstd.h
    index b1d8ecadd..bc3d7a0e9 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -112,7 +112,7 @@ ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
      *   note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
      *            Always ensure result fits within application's authorized limits.
      *            Each application can set its own limits.
    - *   note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
    + *   note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameHeader() to know more. */
     ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
     
     
    @@ -899,7 +899,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
      *    Note : this use case also happens when using a non-conformant dictionary.
      *  - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
      *  - This is not a Zstandard frame.
    - *  When identifying the exact failure cause, it's possible to use ZSTD_getFrameParams(), which will provide a more precise error code. */
    + *  When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */
     ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     
     
    @@ -994,7 +994,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
       Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
       A ZSTD_DCtx object can be re-used multiple times.
     
    -  First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
    +  First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
       It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
       such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
       and the dictionary ID used.
    @@ -1041,7 +1041,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
       b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
       c) Frame Content - any content (User Data) of length equal to Frame Size
       For skippable frames ZSTD_decompressContinue() always returns 0.
    -  For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
    +  For skippable frames ZSTD_getFrameHeader() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
         Note : If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might actually be a Zstd encoded frame with no content.
                For purposes of decompression, it is valid in both cases to skip the frame using
                ZSTD_findFrameCompressedSize to find its size in bytes.
    
    From 53a67ec1a6efee9df0426061b7c1e1acc9f3707d Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Thu, 25 May 2017 18:34:13 -0700
    Subject: [PATCH 105/400] [linux-kernel] Fix duplicate symbols when built-in to
     kernel
    
    ---
     contrib/linux-kernel/lib/zstd/Makefile |  17 +++-
     contrib/linux-kernel/zstd.diff         | 121 ++++++++++++-------------
     2 files changed, 72 insertions(+), 66 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/Makefile b/contrib/linux-kernel/lib/zstd/Makefile
    index aa5eb4d68..dd0a359c1 100644
    --- a/contrib/linux-kernel/lib/zstd/Makefile
    +++ b/contrib/linux-kernel/lib/zstd/Makefile
    @@ -3,7 +3,16 @@ obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
     
     ccflags-y += -O3
     
    -zstd_compress-y := entropy_common.o fse_decompress.o zstd_common.o \
    -				fse_compress.o huf_compress.o compress.o
    -zstd_decompress-y := entropy_common.o fse_decompress.o zstd_common.o \
    -				huf_decompress.o decompress.o
    +# Object files unique to zstd_compress and zstd_decompress
    +zstd_compress-y := fse_compress.o huf_compress.o compress.o
    +zstd_decompress-y := huf_decompress.o decompress.o
    +
    +# These object files are shared between the modules.
    +# Always add them to zstd_compress.
    +# Unless both zstd_compress and zstd_decompress are built in
    +# then also add them to zstd_decompress.
    +zstd_compress-y += entropy_common.o fse_decompress.o zstd_common.o
    +
    +ifneq ($(CONFIG_ZSTD_COMPRESS)$(CONFIG_ZSTD_DECOMPRESS),yy)
    +	zstd_decompress-y += entropy_common.o fse_decompress.o zstd_common.o
    +endif
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff
    index 579e4b19a..285961ab2 100644
    --- a/contrib/linux-kernel/zstd.diff
    +++ b/contrib/linux-kernel/zstd.diff
    @@ -1195,22 +1195,31 @@ index e16f94a..0cfd529 100644
      
     diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile
     new file mode 100644
    -index 0000000..aa5eb4d
    +index 0000000..dd0a359
     --- /dev/null
     +++ b/lib/zstd/Makefile
    -@@ -0,0 +1,9 @@
    +@@ -0,0 +1,18 @@
     +obj-$(CONFIG_ZSTD_COMPRESS) += zstd_compress.o
     +obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd_decompress.o
     +
     +ccflags-y += -O3
     +
    -+zstd_compress-y := entropy_common.o fse_decompress.o zstd_common.o \
    -+				fse_compress.o huf_compress.o compress.o
    -+zstd_decompress-y := entropy_common.o fse_decompress.o zstd_common.o \
    -+				huf_decompress.o decompress.o
    ++# Object files unique to zstd_compress and zstd_decompress
    ++zstd_compress-y := fse_compress.o huf_compress.o compress.o
    ++zstd_decompress-y := huf_decompress.o decompress.o
    ++
    ++# These object files are shared between the modules.
    ++# Always add them to zstd_compress.
    ++# Unless both zstd_compress and zstd_decompress are built in
    ++# then also add them to zstd_decompress.
    ++zstd_compress-y += entropy_common.o fse_decompress.o zstd_common.o
    ++
    ++ifneq ($(CONFIG_ZSTD_COMPRESS)$(CONFIG_ZSTD_DECOMPRESS),yy)
    ++	zstd_decompress-y += entropy_common.o fse_decompress.o zstd_common.o
    ++endif
     diff --git a/lib/zstd/bitstream.h b/lib/zstd/bitstream.h
     new file mode 100644
    -index 0000000..0fa6db1
    +index 0000000..a826b99
     --- /dev/null
     +++ b/lib/zstd/bitstream.h
     @@ -0,0 +1,374 @@
    @@ -1329,7 +1338,7 @@ index 0000000..0fa6db1
     +	BIT_DStream_completed = 2,
     +	BIT_DStream_overflow = 3
     +} BIT_DStream_status; /* result of BIT_reloadDStream() */
    -+		      /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
    ++/* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
     +
     +ZSTD_STATIC size_t BIT_initDStream(BIT_DStream_t *bitD, const void *srcBuffer, size_t srcSize);
     +ZSTD_STATIC size_t BIT_readBits(BIT_DStream_t *bitD, unsigned nbBits);
    @@ -1590,10 +1599,10 @@ index 0000000..0fa6db1
     +#endif /* BITSTREAM_H_MODULE */
     diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
     new file mode 100644
    -index 0000000..6c07a04
    +index 0000000..42236a3
     --- /dev/null
     +++ b/lib/zstd/compress.c
    -@@ -0,0 +1,3461 @@
    +@@ -0,0 +1,3463 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
    @@ -2412,14 +2421,15 @@ index 0000000..6c07a04
     +	}
     +
     +/* check compressibility */
    -+_check_compressibility : {
    -+	size_t const minGain = ZSTD_minGain(srcSize);
    -+	size_t const maxCSize = srcSize - minGain;
    -+	if ((size_t)(op - ostart) >= maxCSize) {
    -+		zc->flagStaticHufTable = HUF_repeat_none;
    -+		return 0;
    ++_check_compressibility:
    ++	{
    ++		size_t const minGain = ZSTD_minGain(srcSize);
    ++		size_t const maxCSize = srcSize - minGain;
    ++		if ((size_t)(op - ostart) >= maxCSize) {
    ++			zc->flagStaticHufTable = HUF_repeat_none;
    ++			return 0;
    ++		}
     +	}
    -+}
     +
     +	/* confirm repcodes */
     +	{
    @@ -3392,10 +3402,11 @@ index 0000000..6c07a04
     +	return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
     +}
     +
    -+FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
    -+    size_t
    -+    ZSTD_HcFindBestMatch_generic(ZSTD_CCtx *zc, /* Index table will be updated */
    -+				 const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls, const U32 extDict)
    ++/* inlining is important to hardwire a hot branch (template emulation) */
    ++FORCE_INLINE
    ++size_t ZSTD_HcFindBestMatch_generic(ZSTD_CCtx *zc, /* Index table will be updated */
    ++				    const BYTE *const ip, const BYTE *const iLimit, size_t *offsetPtr, const U32 maxNbAttempts, const U32 mls,
    ++				    const U32 extDict)
     +{
     +	U32 *const chainTable = zc->chainTable;
     +	const U32 chainSize = (1 << zc->params.cParams.chainLog);
    @@ -3585,11 +3596,12 @@ index 0000000..6c07a04
     +		}
     +
     +	/* store sequence */
    -+	_storeSequence : {
    -+		size_t const litLength = start - anchor;
    -+		ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH);
    -+		anchor = ip = start + matchLength;
    -+	}
    ++_storeSequence:
    ++		{
    ++			size_t const litLength = start - anchor;
    ++			ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength - MINMATCH);
    ++			anchor = ip = start + matchLength;
    ++		}
     +
     +		/* check immediate repcode */
     +		while ((ip <= ilimit) && ((offset_2 > 0) & (ZSTD_read32(ip) == ZSTD_read32(ip - offset_2)))) {
    @@ -4007,9 +4019,8 @@ index 0000000..6c07a04
     +	U32 const windowSize = 1U << params.cParams.windowLog;
     +	U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
     +	BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
    -+	U32 const fcsCode = params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU)
    -+							   : /* 0-3 */
    -+				0;
    ++	U32 const fcsCode =
    ++	    params.fParams.contentSizeFlag ? (pledgedSrcSize >= 256) + (pledgedSrcSize >= 65536 + 256) + (pledgedSrcSize >= 0xFFFFFFFFU) : 0; /* 0-3 */
     +	BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag << 2) + (singleSegment << 5) + (fcsCode << 6));
     +	size_t pos;
     +
    @@ -5057,7 +5068,7 @@ index 0000000..6c07a04
     +MODULE_DESCRIPTION("Zstd Compressor");
     diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c
     new file mode 100644
    -index 0000000..2926b36
    +index 0000000..def10ea
     --- /dev/null
     +++ b/lib/zstd/decompress.c
     @@ -0,0 +1,2508 @@
    @@ -7363,7 +7374,6 @@ index 0000000..2926b36
     +				ip += toLoad;
     +				break;
     +			}
    -+		}
     +
     +			/* check for single-pass mode opportunity */
     +			if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
    @@ -7418,6 +7428,7 @@ index 0000000..2926b36
     +				}
     +			}
     +			zds->stage = zdss_read;
    ++		}
     +		/* pass-through */
     +
     +		case zdss_read: {
    @@ -7880,10 +7891,10 @@ index 0000000..1a60b31
     +#endif /* ERROR_H_MODULE */
     diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h
     new file mode 100644
    -index 0000000..9749755
    +index 0000000..bc2962a
     --- /dev/null
     +++ b/lib/zstd/fse.h
    -@@ -0,0 +1,588 @@
    +@@ -0,0 +1,584 @@
     +/*
     + * FSE : Finite State Entropy codec
     + * Public Prototypes declaration
    @@ -8422,8 +8433,6 @@ index 0000000..9749755
     +
     +ZSTD_STATIC unsigned FSE_endOfDState(const FSE_DState_t *DStatePtr) { return DStatePtr->state == 0; }
     +
    -+#ifndef FSE_COMMONDEFS_ONLY
    -+
     +/* **************************************************************
     +*  Tuning parameters
     +****************************************************************/
    @@ -8453,8 +8462,6 @@ index 0000000..9749755
     +#define FSE_FUNCTION_EXTENSION
     +#define FSE_DECODE_TYPE FSE_decode_t
     +
    -+#endif /* !FSE_COMMONDEFS_ONLY */
    -+
     +/* ***************************************************************
     +*  Constants
     +*****************************************************************/
    @@ -8474,10 +8481,10 @@ index 0000000..9749755
     +#endif /* FSE_H */
     diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c
     new file mode 100644
    -index 0000000..6bb810f
    +index 0000000..e016bb1
     --- /dev/null
     +++ b/lib/zstd/fse_compress.c
    -@@ -0,0 +1,861 @@
    +@@ -0,0 +1,857 @@
     +/*
     + * FSE : Finite State Entropy encoder
     + * Copyright (C) 2013-2015, Yann Collet.
    @@ -8660,8 +8667,6 @@ index 0000000..6bb810f
     +	return 0;
     +}
     +
    -+#ifndef FSE_COMMONDEFS_ONLY
    -+
     +/*-**************************************************************
     +*  FSE NCount encoding-decoding
     +****************************************************************/
    @@ -9337,14 +9342,12 @@ index 0000000..6bb810f
     +
     +	return op - ostart;
     +}
    -+
    -+#endif /* FSE_COMMONDEFS_ONLY */
     diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c
     new file mode 100644
    -index 0000000..245570a
    +index 0000000..96cf89f
     --- /dev/null
     +++ b/lib/zstd/fse_decompress.c
    -@@ -0,0 +1,317 @@
    +@@ -0,0 +1,313 @@
     +/*
     + * FSE : Finite State Entropy decoder
     + * Copyright (C) 2013-2015, Yann Collet.
    @@ -9508,8 +9511,6 @@ index 0000000..245570a
     +	return 0;
     +}
     +
    -+#ifndef FSE_COMMONDEFS_ONLY
    -+
     +/*-*******************************************************
     +*  Decompression (Byte symbols)
     +*********************************************************/
    @@ -9660,8 +9661,6 @@ index 0000000..245570a
     +
     +	return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
     +}
    -+
    -+#endif /* FSE_COMMONDEFS_ONLY */
     diff --git a/lib/zstd/huf.h b/lib/zstd/huf.h
     new file mode 100644
     index 0000000..56abe2f
    @@ -9873,10 +9872,10 @@ index 0000000..56abe2f
     +#endif /* HUF_H_298734234 */
     diff --git a/lib/zstd/huf_compress.c b/lib/zstd/huf_compress.c
     new file mode 100644
    -index 0000000..1587401
    +index 0000000..e82a136
     --- /dev/null
     +++ b/lib/zstd/huf_compress.c
    -@@ -0,0 +1,732 @@
    +@@ -0,0 +1,731 @@
     +/*
     + * Huffman encoder, part of New Generation Entropy library
     + * Copyright (C) 2013-2016, Yann Collet.
    @@ -10184,9 +10183,8 @@ index 0000000..1587401
     +					}
     +				}
     +				/* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
    -+				while (
    -+				    (nBitsToDecrease <= HUF_TABLELOG_MAX) &&
    -+				    (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    ++				/* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
    ++				while ((nBitsToDecrease <= HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
     +					nBitsToDecrease++;
     +				totalCost -= 1 << (nBitsToDecrease - 1);
     +				if (rankLast[nBitsToDecrease - 1] == noSymbol)
    @@ -10611,10 +10609,10 @@ index 0000000..1587401
     +}
     diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c
     new file mode 100644
    -index 0000000..5c38aa3
    +index 0000000..950c194
     --- /dev/null
     +++ b/lib/zstd/huf_decompress.c
    -@@ -0,0 +1,921 @@
    +@@ -0,0 +1,920 @@
     +/*
     + * Huffman decoder, part of New Generation Entropy library
     + * Copyright (C) 2013-2016, Yann Collet.
    @@ -11190,9 +11188,8 @@ index 0000000..5c38aa3
     +		if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) {
     +			BIT_skipBits(DStream, dt[val].nbBits);
     +			if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8))
    -+				DStream->bitsConsumed =
    -+				    (sizeof(DStream->bitContainer) *
    -+				     8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    ++				/* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
    ++				DStream->bitsConsumed = (sizeof(DStream->bitContainer) * 8);
     +		}
     +	}
     +	return 1;
    @@ -12051,7 +12048,7 @@ index 0000000..6748719
     +#endif /* ZSTD_CCOMMON_H_MODULE */
     diff --git a/lib/zstd/zstd_opt.h b/lib/zstd/zstd_opt.h
     new file mode 100644
    -index 0000000..468c143
    +index 0000000..55e1b4c
     --- /dev/null
     +++ b/lib/zstd/zstd_opt.h
     @@ -0,0 +1,1014 @@
    @@ -12685,7 +12682,7 @@ index 0000000..468c143
     +		cur = last_pos - best_mlen;
     +
     +	/* store sequence */
    -+	_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
    ++_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
     +		opt[0].mlen = 1;
     +
     +		while (1) {
    @@ -12999,7 +12996,7 @@ index 0000000..468c143
     +		cur = last_pos - best_mlen;
     +
     +	/* store sequence */
    -+	_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
    ++_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
     +		opt[0].mlen = 1;
     +
     +		while (1) {
    
    From b8136f019a7dc50b51fc51e68cfd38bace101057 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Sat, 27 May 2017 00:03:08 -0700
    Subject: [PATCH 106/400] static dctx is incompatible with legacy support
    
    documented, and runtime tested
    ---
     doc/zstd_manual.html             | 3 ++-
     lib/decompress/zstd_decompress.c | 9 ++++++++-
     lib/zstd.h                       | 3 ++-
     3 files changed, 12 insertions(+), 3 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index a4b59bc46..156e7dd92 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -718,7 +718,8 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
      @return : pointer to ZSTD_DCtx*, or NULL if error (size too small)
       Note : zstd will never resize nor malloc() when using a static dctx.
              If it needs more memory than available, it will simply error out.
    -  Note 2 : there is no corresponding "free" function.
    +  Note 2 : static dctx is incompatible with legacy support
    +  Note 3 : there is no corresponding "free" function.
                Since workspace was allocated externally, it must be freed externally.
       Limitation : currently not compatible with internal DDict creation,
                    such as ZSTD_initDStream_usingDict().
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index fe7446ab2..a59724386 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -1586,6 +1586,8 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
                 size_t decodedSize;
                 size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
                 if (ZSTD_isError(frameSize)) return frameSize;
    +            /* legacy support is incompatible with static dctx */
    +            if (dctx->staticSize) return ERROR(memory_allocation);
     
                 decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
     
    @@ -2258,8 +2260,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
         U32 someMoreWork = 1;
     
     #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
    -    if (zds->legacyVersion)
    +    if (zds->legacyVersion) {
    +        /* legacy support is incompatible with static dctx */
    +        if (zds->staticSize) return ERROR(memory_allocation);
             return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
    +    }
     #endif
     
         while (someMoreWork) {
    @@ -2277,6 +2282,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                         if (legacyVersion) {
                             const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL;
                             size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
    +                        /* legacy support is incompatible with static dctx */
    +                        if (zds->staticSize) return ERROR(memory_allocation);
                             CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
                                                            dict, dictSize));
                             zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
    diff --git a/lib/zstd.h b/lib/zstd.h
    index b1d8ecadd..3bbdb76f5 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -844,7 +844,8 @@ ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
      * @return : pointer to ZSTD_DCtx*, or NULL if error (size too small)
      *  Note : zstd will never resize nor malloc() when using a static dctx.
      *         If it needs more memory than available, it will simply error out.
    - *  Note 2 : there is no corresponding "free" function.
    + *  Note 2 : static dctx is incompatible with legacy support
    + *  Note 3 : there is no corresponding "free" function.
      *           Since workspace was allocated externally, it must be freed externally.
      *  Limitation : currently not compatible with internal DDict creation,
      *               such as ZSTD_initDStream_usingDict().
    
    From e07115910137fda805c1ef14f7834ca7ba896677 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Sat, 27 May 2017 00:21:33 -0700
    Subject: [PATCH 107/400] mtctx->jobs allocate its own memory space
    
    to make ZSTDMT_CCtx_s size predictable
    so that it can be included in CCtx
    ---
     lib/compress/zstdmt_compress.c | 13 ++++++++-----
     1 file changed, 8 insertions(+), 5 deletions(-)
    
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index fc7f52a29..d41825e80 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -271,6 +271,7 @@ _endJob:
     
     struct ZSTDMT_CCtx_s {
         POOL_ctx* factory;
    +    ZSTDMT_jobDescription* jobs;
         ZSTDMT_bufferPool* buffPool;
         ZSTDMT_CCtxPool* cctxPool;
         pthread_mutex_t jobCompleted_mutex;
    @@ -294,10 +295,9 @@ struct ZSTDMT_CCtx_s {
         size_t sectionSize;
         ZSTD_CDict* cdict;
         ZSTD_CStream* cstream;
    -    ZSTDMT_jobDescription jobs[1];   /* variable size (must lies at the end) */
     };
     
    -ZSTDMT_CCtx *ZSTDMT_createCCtx(unsigned nbThreads)
    +ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads)
     {
         ZSTDMT_CCtx* cctx;
         U32 const minNbJobs = nbThreads + 2;
    @@ -306,7 +306,7 @@ ZSTDMT_CCtx *ZSTDMT_createCCtx(unsigned nbThreads)
         DEBUGLOG(5, "nbThreads : %u  ; minNbJobs : %u ;  nbJobsLog2 : %u ;  nbJobs : %u  \n",
                 nbThreads, minNbJobs, nbJobsLog2, nbJobs);
         if ((nbThreads < 1) | (nbThreads > ZSTDMT_NBTHREADS_MAX)) return NULL;
    -    cctx = (ZSTDMT_CCtx*) calloc(1, sizeof(ZSTDMT_CCtx) + nbJobs*sizeof(ZSTDMT_jobDescription));
    +    cctx = (ZSTDMT_CCtx*) calloc(1, sizeof(ZSTDMT_CCtx));
         if (!cctx) return NULL;
         cctx->nbThreads = nbThreads;
         cctx->jobIDMask = nbJobs - 1;
    @@ -314,9 +314,10 @@ ZSTDMT_CCtx *ZSTDMT_createCCtx(unsigned nbThreads)
         cctx->sectionSize = 0;
         cctx->overlapRLog = 3;
         cctx->factory = POOL_create(nbThreads, 1);
    +    cctx->jobs = malloc(nbJobs * sizeof(*cctx->jobs));
         cctx->buffPool = ZSTDMT_createBufferPool(nbThreads);
         cctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads);
    -    if (!cctx->factory | !cctx->buffPool | !cctx->cctxPool) {  /* one object was not created */
    +    if (!cctx->factory | !cctx->jobs | !cctx->buffPool | !cctx->cctxPool) {
             ZSTDMT_freeCCtx(cctx);
             return NULL;
         }
    @@ -356,6 +357,7 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
         POOL_free(mtctx->factory);
         if (!mtctx->allJobsCompleted) ZSTDMT_releaseAllJobResources(mtctx); /* stop workers first */
         ZSTDMT_freeBufferPool(mtctx->buffPool);  /* release job resources into pools first */
    +    free(mtctx->jobs);
         ZSTDMT_freeCCtxPool(mtctx->cctxPool);
         ZSTD_freeCDict(mtctx->cdict);
         ZSTD_freeCStream(mtctx->cstream);
    @@ -491,7 +493,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
     /* =======      Streaming API     ======= */
     /* ====================================== */
     
    -static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) {
    +static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
    +{
         while (zcs->doneJobID < zcs->nextJobID) {
             unsigned const jobID = zcs->doneJobID & zcs->jobIDMask;
             PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex);
    
    From b6dec4c3ae18786d6183274b3bcb5fe7387ea2bc Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Sat, 27 May 2017 17:09:06 -0700
    Subject: [PATCH 108/400] fixed minor cast warning
    
    ---
     lib/compress/zstdmt_compress.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index d41825e80..0c6bc7249 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -314,7 +314,7 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads)
         cctx->sectionSize = 0;
         cctx->overlapRLog = 3;
         cctx->factory = POOL_create(nbThreads, 1);
    -    cctx->jobs = malloc(nbJobs * sizeof(*cctx->jobs));
    +    cctx->jobs = (ZSTDMT_jobDescription*) malloc(nbJobs * sizeof(*cctx->jobs));
         cctx->buffPool = ZSTDMT_createBufferPool(nbThreads);
         cctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads);
         if (!cctx->factory | !cctx->jobs | !cctx->buffPool | !cctx->cctxPool) {
    
    From 44e45e8423f1a8590009456dc48cda1164d90aed Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 16:12:06 -0700
    Subject: [PATCH 109/400] added ZSTDMT_createCCtx_advanced()
    
    make it possible to use custom allocators
    ---
     doc/zstd_manual.html           |   2 +
     lib/common/zstd_common.c       |  27 +++++-
     lib/common/zstd_internal.h     |   1 +
     lib/compress/zstdmt_compress.c | 151 +++++++++++++++++++--------------
     lib/compress/zstdmt_compress.h |   1 +
     lib/zstd.h                     |   2 +
     6 files changed, 118 insertions(+), 66 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 360a6e77a..2c66409cb 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -338,6 +338,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     

    Custom memory allocation functions

    typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
     typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
     typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
    +/* use this constant to defer to stdlib's functions */
    +static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL};
     

    Frame size functions

    
     
    diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
    index 5e207e7d1..9b46df1d8 100644
    --- a/lib/common/zstd_common.c
    +++ b/lib/common/zstd_common.c
    @@ -12,7 +12,8 @@
     /*-*************************************
     *  Dependencies
     ***************************************/
    -#include          /* malloc */
    +#include       /* malloc, calloc, free */
    +#include       /* memset */
     #include "error_private.h"
     #define ZSTD_STATIC_LINKING_ONLY
     #include "zstd.h"
    @@ -65,11 +66,29 @@ void ZSTD_defaultFreeFunction(void* opaque, void* address)
     
     void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
     {
    -    return customMem.customAlloc(customMem.opaque, size);
    +    if (customMem.customAlloc)
    +        return customMem.customAlloc(customMem.opaque, size);
    +    return malloc(size);
    +}
    +
    +void* ZSTD_calloc(size_t size, ZSTD_customMem customMem)
    +{
    +    if (customMem.customAlloc) {
    +        /* calloc implemented as malloc+memset;
    +         * not as efficient, but our best guess for custom malloc */
    +        void* const ptr = customMem.customAlloc(customMem.opaque, size);
    +        memset(ptr, 0, size);
    +        return ptr;
    +    }
    +    return calloc(1, size);
     }
     
     void ZSTD_free(void* ptr, ZSTD_customMem customMem)
     {
    -    if (ptr!=NULL)
    -        customMem.customFree(customMem.opaque, ptr);
    +    if (ptr!=NULL) {
    +        if (customMem.customFree)
    +            customMem.customFree(customMem.opaque, ptr);
    +        else
    +            free(ptr);
    +    }
     }
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index 2533333ba..5ab4aaeff 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -244,6 +244,7 @@ void ZSTD_defaultFreeFunction(void* opaque, void* address);
     static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
     #endif
     void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
    +void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
     void ZSTD_free(void* ptr, ZSTD_customMem customMem);
     
     
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 0c6bc7249..bd3de4586 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -19,29 +19,33 @@
     
     
     /* ======   Dependencies   ====== */
    -#include    /* malloc */
    -#include    /* memcpy */
    -#include "pool.h"     /* threadpool */
    +#include      /* memcpy, memset */
    +#include "pool.h"       /* threadpool */
     #include "threading.h"  /* mutex */
    -#include "zstd_internal.h"   /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
    +#include "zstd_internal.h"  /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
     #include "zstdmt_compress.h"
     
     
     /* ======   Debug   ====== */
    -#if 0
    +#if defined(ZSTDMT_DEBUG)
     
     #  include 
     #  include 
     #  include 
    -   static unsigned g_debugLevel = 5;
    -#  define DEBUGLOGRAW(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __VA_ARGS__); }
    -#  define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
    +#  define DEBUGLOGRAW(l, ...) if (l<=ZSTDMT_DEBUG) { fprintf(stderr, __VA_ARGS__); }
    +#  define DEBUGLOG(l, ...) {            \
    +    if (l<=ZSTDMT_DEBUG) {              \
    +        fprintf(stderr, __FILE__ ": "); \
    +        fprintf(stderr, __VA_ARGS__);   \
    +        fprintf(stderr, " \n");         \
    +    }                                   \
    +}
     
    -#  define DEBUG_PRINTHEX(l,p,n) { \
    -    unsigned debug_u;                   \
    -    for (debug_u=0; debug_u<(n); debug_u++)           \
    +#  define DEBUG_PRINTHEX(l,p,n) {            \
    +    unsigned debug_u;                        \
    +    for (debug_u=0; debug_u<(n); debug_u++)  \
             DEBUGLOGRAW(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \
    -    DEBUGLOGRAW(l, " \n");       \
    +    DEBUGLOGRAW(l, " \n");                   \
     }
     
     static unsigned long long GetCurrentClockTimeMicroseconds(void)
    @@ -54,17 +58,18 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void)
     }
     
     #define MUTEX_WAIT_TIME_DLEVEL 5
    -#define PTHREAD_MUTEX_LOCK(mutex) \
    -if (g_debugLevel>=MUTEX_WAIT_TIME_DLEVEL) { \
    -    unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
    -    pthread_mutex_lock(mutex); \
    -    {   unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
    -        unsigned long long const elapsedTime = (afterTime-beforeTime); \
    -        if (elapsedTime > 1000) {  /* or whatever threshold you like; I'm using 1 millisecond here */ \
    -            DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
    -               elapsedTime, #mutex); \
    -    }   } \
    -} else pthread_mutex_lock(mutex);
    +#define PTHREAD_MUTEX_LOCK(mutex) {               \
    +    if (ZSTDMT_DEBUG>=MUTEX_WAIT_TIME_DLEVEL) {   \
    +        unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
    +        pthread_mutex_lock(mutex);                \
    +        {   unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
    +            unsigned long long const elapsedTime = (afterTime-beforeTime); \
    +            if (elapsedTime > 1000) {  /* or whatever threshold you like; I'm using 1 millisecond here */ \
    +                DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
    +                   elapsedTime, #mutex);          \
    +        }   }                                     \
    +    } else pthread_mutex_lock(mutex);             \
    +}
     
     #else
     
    @@ -87,16 +92,19 @@ static const buffer_t g_nullBuffer = { NULL, 0 };
     typedef struct ZSTDMT_bufferPool_s {
         unsigned totalBuffers;
         unsigned nbBuffers;
    +    ZSTD_customMem cMem;
         buffer_t bTable[1];   /* variable size */
     } ZSTDMT_bufferPool;
     
    -static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbThreads)
    +static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbThreads, ZSTD_customMem cMem)
     {
         unsigned const maxNbBuffers = 2*nbThreads + 2;
    -    ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)calloc(1, sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t));
    +    ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc(
    +        sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);
         if (bufPool==NULL) return NULL;
         bufPool->totalBuffers = maxNbBuffers;
         bufPool->nbBuffers = 0;
    +    bufPool->cMem = cMem;
         return bufPool;
     }
     
    @@ -105,8 +113,8 @@ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
         unsigned u;
         if (!bufPool) return;   /* compatibility with free on NULL */
         for (u=0; utotalBuffers; u++)
    -        free(bufPool->bTable[u].start);
    -    free(bufPool);
    +        ZSTD_free(bufPool->bTable[u].start, bufPool->cMem);
    +    ZSTD_free(bufPool, bufPool->cMem);
     }
     
     /* assumption : invocation from main thread only ! */
    @@ -115,13 +123,15 @@ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* pool, size_t bSize)
         if (pool->nbBuffers) {   /* try to use an existing buffer */
             buffer_t const buf = pool->bTable[--(pool->nbBuffers)];
             size_t const availBufferSize = buf.size;
    -        if ((availBufferSize >= bSize) & (availBufferSize <= 10*bSize))   /* large enough, but not too much */
    +        if ((availBufferSize >= bSize) & (availBufferSize <= 10*bSize))
    +            /* large enough, but not too much */
                 return buf;
    -        free(buf.start);   /* size conditions not respected : scratch this buffer and create a new one */
    +        /* size conditions not respected : scratch this buffer, create new one */
    +        ZSTD_free(buf.start, pool->cMem);
         }
         /* create new buffer */
         {   buffer_t buffer;
    -        void* const start = malloc(bSize);
    +        void* const start = ZSTD_malloc(bSize, pool->cMem);
             if (start==NULL) bSize = 0;
             buffer.start = start;   /* note : start can be NULL if malloc fails ! */
             buffer.size = bSize;
    @@ -138,7 +148,7 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* pool, buffer_t buf)
             return;
         }
         /* Reached bufferPool capacity (should not happen) */
    -    free(buf.start);
    +    ZSTD_free(buf.start, pool->cMem);
     }
     
     
    @@ -147,6 +157,7 @@ static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* pool, buffer_t buf)
     typedef struct {
         unsigned totalCCtx;
         unsigned availCCtx;
    +    ZSTD_customMem cMem;
         ZSTD_CCtx* cctx[1];   /* variable size */
     } ZSTDMT_CCtxPool;
     
    @@ -158,18 +169,21 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
         unsigned u;
         for (u=0; utotalCCtx; u++)
             ZSTD_freeCCtx(pool->cctx[u]);  /* note : compatible with free on NULL */
    -    free(pool);
    +    ZSTD_free(pool, pool->cMem);
     }
     
     /* ZSTDMT_createCCtxPool() :
      * implies nbThreads >= 1 , checked by caller ZSTDMT_createCCtx() */
    -static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads)
    +static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads,
    +                                            ZSTD_customMem cMem)
     {
    -    ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) calloc(1, sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*));
    +    ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc(
    +        sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*), cMem);
         if (!cctxPool) return NULL;
    +    cctxPool->cMem = cMem;
         cctxPool->totalCCtx = nbThreads;
         cctxPool->availCCtx = 1;   /* at least one cctx for single-thread mode */
    -    cctxPool->cctx[0] = ZSTD_createCCtx();
    +    cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem);
         if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }
         DEBUGLOG(1, "cctxPool created, with %u threads", nbThreads);
         return cctxPool;
    @@ -232,7 +246,7 @@ void ZSTDMT_compressChunk(void* jobDescription)
                      job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize);
         if (job->cdict) {  /* should only happen for first segment */
             size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize);
    -        if (job->cdict) DEBUGLOG(3, "using CDict ");
    +        if (job->cdict) DEBUGLOG(3, "using CDict");
             if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; }
         } else {  /* srcStart points at reloaded section */
             if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0;  /* ensure no srcSize control */
    @@ -293,43 +307,56 @@ struct ZSTDMT_CCtx_s {
         unsigned overlapRLog;
         unsigned long long frameContentSize;
         size_t sectionSize;
    +    ZSTD_customMem cMem;
         ZSTD_CDict* cdict;
         ZSTD_CStream* cstream;
     };
     
    -ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads)
    +ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
     {
    -    ZSTDMT_CCtx* cctx;
    +    ZSTDMT_CCtx* mtctx;
         U32 const minNbJobs = nbThreads + 2;
         U32 const nbJobsLog2 = ZSTD_highbit32(minNbJobs) + 1;
         U32 const nbJobs = 1 << nbJobsLog2;
    -    DEBUGLOG(5, "nbThreads : %u  ; minNbJobs : %u ;  nbJobsLog2 : %u ;  nbJobs : %u  \n",
    -            nbThreads, minNbJobs, nbJobsLog2, nbJobs);
    +    DEBUGLOG(5, "nbThreads: %u ; minNbJobs: %u ; nbJobsLog2: %u ; nbJobs: %u",
    +                nbThreads, minNbJobs, nbJobsLog2, nbJobs);
    +
         if ((nbThreads < 1) | (nbThreads > ZSTDMT_NBTHREADS_MAX)) return NULL;
    -    cctx = (ZSTDMT_CCtx*) calloc(1, sizeof(ZSTDMT_CCtx));
    -    if (!cctx) return NULL;
    -    cctx->nbThreads = nbThreads;
    -    cctx->jobIDMask = nbJobs - 1;
    -    cctx->allJobsCompleted = 1;
    -    cctx->sectionSize = 0;
    -    cctx->overlapRLog = 3;
    -    cctx->factory = POOL_create(nbThreads, 1);
    -    cctx->jobs = (ZSTDMT_jobDescription*) malloc(nbJobs * sizeof(*cctx->jobs));
    -    cctx->buffPool = ZSTDMT_createBufferPool(nbThreads);
    -    cctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads);
    -    if (!cctx->factory | !cctx->jobs | !cctx->buffPool | !cctx->cctxPool) {
    -        ZSTDMT_freeCCtx(cctx);
    +    if ((cMem.customAlloc!=NULL) ^ (cMem.customFree!=NULL))
    +        /* invalid custom allocator */
    +        return NULL;
    +
    +    mtctx = (ZSTDMT_CCtx*) ZSTD_calloc(sizeof(ZSTDMT_CCtx), cMem);
    +    if (!mtctx) return NULL;
    +    mtctx->cMem = cMem;
    +    mtctx->nbThreads = nbThreads;
    +    mtctx->jobIDMask = nbJobs - 1;
    +    mtctx->allJobsCompleted = 1;
    +    mtctx->sectionSize = 0;
    +    mtctx->overlapRLog = 3;
    +    mtctx->factory = POOL_create(nbThreads, 1);
    +    mtctx->jobs = (ZSTDMT_jobDescription*)ZSTD_calloc(
    +        nbJobs * sizeof(*mtctx->jobs), cMem);
    +    mtctx->buffPool = ZSTDMT_createBufferPool(nbThreads, cMem);
    +    mtctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads, cMem);
    +    if (!mtctx->factory | !mtctx->jobs | !mtctx->buffPool | !mtctx->cctxPool) {
    +        ZSTDMT_freeCCtx(mtctx);
             return NULL;
         }
         if (nbThreads==1) {
    -        cctx->cstream = ZSTD_createCStream();
    -        if (!cctx->cstream) {
    -            ZSTDMT_freeCCtx(cctx); return NULL;
    +        mtctx->cstream = ZSTD_createCStream_advanced(cMem);
    +        if (!mtctx->cstream) {
    +            ZSTDMT_freeCCtx(mtctx); return NULL;
         }   }
    -    pthread_mutex_init(&cctx->jobCompleted_mutex, NULL);   /* Todo : check init function return */
    -    pthread_cond_init(&cctx->jobCompleted_cond, NULL);
    -    DEBUGLOG(4, "mt_cctx created, for %u threads \n", nbThreads);
    -    return cctx;
    +    pthread_mutex_init(&mtctx->jobCompleted_mutex, NULL);   /* Todo : check init function return */
    +    pthread_cond_init(&mtctx->jobCompleted_cond, NULL);
    +    DEBUGLOG(4, "mt_cctx created, for %u threads", nbThreads);
    +    return mtctx;
    +}
    +
    +ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads)
    +{
    +    return ZSTDMT_createCCtx_advanced(nbThreads, ZSTD_defaultCMem);
     }
     
     /* ZSTDMT_releaseAllJobResources() :
    @@ -357,13 +384,13 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
         POOL_free(mtctx->factory);
         if (!mtctx->allJobsCompleted) ZSTDMT_releaseAllJobResources(mtctx); /* stop workers first */
         ZSTDMT_freeBufferPool(mtctx->buffPool);  /* release job resources into pools first */
    -    free(mtctx->jobs);
    +    ZSTD_free(mtctx->jobs, mtctx->cMem);
         ZSTDMT_freeCCtxPool(mtctx->cctxPool);
         ZSTD_freeCDict(mtctx->cdict);
         ZSTD_freeCStream(mtctx->cstream);
         pthread_mutex_destroy(&mtctx->jobCompleted_mutex);
         pthread_cond_destroy(&mtctx->jobCompleted_cond);
    -    free(mtctx);
    +    ZSTD_free(mtctx, mtctx->cMem);
         return 0;
     }
     
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index 27f78ee03..92f7d8d0b 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -28,6 +28,7 @@
     
     typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;
     ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads);
    +ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem);
     ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* cctx);
     
     ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* cctx,
    diff --git a/lib/zstd.h b/lib/zstd.h
    index d3a4d1783..d4c24e7b3 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -421,6 +421,8 @@ typedef struct {
     typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
     typedef void  (*ZSTD_freeFunction) (void* opaque, void* address);
     typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
    +/* use this constant to defer to stdlib's functions */
    +static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL};
     
     /***************************************
     *  Frame size functions
    
    From 5bcef1ada223c1b1de5634eab4c4c071d9536c5c Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 16:37:19 -0700
    Subject: [PATCH 110/400] removed mtctx->cstream
    
    use the first cctx in pool when ZSTDMT is used in single-thread mode
    now that cctx and cstream are the same object.
    ---
     lib/compress/zstdmt_compress.c | 66 ++++++++++++++++++++++------------
     1 file changed, 44 insertions(+), 22 deletions(-)
    
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index bd3de4586..ca5cd6aee 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -27,7 +27,13 @@
     
     
     /* ======   Debug   ====== */
    -#if defined(ZSTDMT_DEBUG)
    +#if defined(ZSTDMT_DEBUG) && (ZSTDMT_DEBUG>=1)
    +#  include 
    +#else
    +#  define assert(condition) ((void)0)
    +#endif
    +
    +#if defined(ZSTDMT_DEBUG) && (ZSTDMT_DEBUG>=2)
     
     #  include 
     #  include 
    @@ -309,7 +315,6 @@ struct ZSTDMT_CCtx_s {
         size_t sectionSize;
         ZSTD_customMem cMem;
         ZSTD_CDict* cdict;
    -    ZSTD_CStream* cstream;
     };
     
     ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
    @@ -343,11 +348,6 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem)
             ZSTDMT_freeCCtx(mtctx);
             return NULL;
         }
    -    if (nbThreads==1) {
    -        mtctx->cstream = ZSTD_createCStream_advanced(cMem);
    -        if (!mtctx->cstream) {
    -            ZSTDMT_freeCCtx(mtctx); return NULL;
    -    }   }
         pthread_mutex_init(&mtctx->jobCompleted_mutex, NULL);   /* Todo : check init function return */
         pthread_cond_init(&mtctx->jobCompleted_cond, NULL);
         DEBUGLOG(4, "mt_cctx created, for %u threads", nbThreads);
    @@ -387,7 +387,6 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
         ZSTD_free(mtctx->jobs, mtctx->cMem);
         ZSTDMT_freeCCtxPool(mtctx->cctxPool);
         ZSTD_freeCDict(mtctx->cdict);
    -    ZSTD_freeCStream(mtctx->cstream);
         pthread_mutex_destroy(&mtctx->jobCompleted_mutex);
         pthread_cond_destroy(&mtctx->jobCompleted_cond);
         ZSTD_free(mtctx, mtctx->cMem);
    @@ -540,8 +539,12 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
                                         ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
         ZSTD_customMem const cmem = { NULL, NULL, NULL };
    -    DEBUGLOG(3, "Started new compression, with windowLog : %u", params.cParams.windowLog);
    -    if (zcs->nbThreads==1) return ZSTD_initCStream_advanced(zcs->cstream, dict, dictSize, params, pledgedSrcSize);
    +    DEBUGLOG(3, "Started new compression, with windowLog : %u",
    +                    params.cParams.windowLog);
    +    if (zcs->nbThreads==1)
    +        return ZSTD_initCStream_advanced(zcs->cctxPool->cctx[0],
    +                                        dict, dictSize,
    +                                        params, pledgedSrcSize);
         if (zcs->allJobsCompleted == 0) {   /* previous job not correctly finished */
             ZSTDMT_waitForAllJobsCompleted(zcs);
             ZSTDMT_releaseAllJobResources(zcs);
    @@ -587,7 +590,8 @@ size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* zcs,
      * pledgedSrcSize is optional and can be zero == unknown */
     size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
     {
    -    if (zcs->nbThreads==1) return ZSTD_resetCStream(zcs->cstream, pledgedSrcSize);
    +    if (zcs->nbThreads==1)
    +        return ZSTD_resetCStream(zcs->cctxPool->cctx[0], pledgedSrcSize);
         return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params, pledgedSrcSize);
     }
     
    @@ -612,13 +616,16 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi
             return ERROR(memory_allocation);
         }
     
    -    DEBUGLOG(4, "preparing job %u to compress %u bytes with %u preload ", zcs->nextJobID, (U32)srcSize, (U32)zcs->dictSize);
    +    DEBUGLOG(4, "preparing job %u to compress %u bytes with %u preload ",
    +                zcs->nextJobID, (U32)srcSize, (U32)zcs->dictSize);
         zcs->jobs[jobID].src = zcs->inBuff.buffer;
         zcs->jobs[jobID].srcStart = zcs->inBuff.buffer.start;
         zcs->jobs[jobID].srcSize = srcSize;
    -    zcs->jobs[jobID].dictSize = zcs->dictSize;   /* note : zcs->inBuff.filled is presumed >= srcSize + dictSize */
    +    zcs->jobs[jobID].dictSize = zcs->dictSize;
    +    assert(zcs->inBuff.filled >= srcSize + zcs->dictSize);
         zcs->jobs[jobID].params = zcs->params;
    -    if (zcs->nextJobID) zcs->jobs[jobID].params.fParams.checksumFlag = 0;  /* do not calculate checksum within sections, just keep it in header for first section */
    +    /* do not calculate checksum within sections, but write it in header for first section */
    +    if (zcs->nextJobID) zcs->jobs[jobID].params.fParams.checksumFlag = 0;
         zcs->jobs[jobID].cdict = zcs->nextJobID==0 ? zcs->cdict : NULL;
         zcs->jobs[jobID].fullFrameSize = zcs->frameContentSize;
         zcs->jobs[jobID].dstBuff = dstBuffer;
    @@ -643,8 +650,12 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi
             }
             DEBUGLOG(5, "inBuff filled to %u", (U32)zcs->inBuff.filled);
             zcs->inBuff.filled -= srcSize + zcs->dictSize - newDictSize;
    -        DEBUGLOG(5, "new job : filled to %u, with %u dict and %u src", (U32)zcs->inBuff.filled, (U32)newDictSize, (U32)(zcs->inBuff.filled - newDictSize));
    -        memmove(zcs->inBuff.buffer.start, (const char*)zcs->jobs[jobID].srcStart + zcs->dictSize + srcSize - newDictSize, zcs->inBuff.filled);
    +        DEBUGLOG(5, "new job : filled to %u, with %u dict and %u src",
    +                    (U32)zcs->inBuff.filled, (U32)newDictSize,
    +                    (U32)(zcs->inBuff.filled - newDictSize));
    +        memmove(zcs->inBuff.buffer.start,
    +            (const char*)zcs->jobs[jobID].srcStart + zcs->dictSize + srcSize - newDictSize,
    +            zcs->inBuff.filled);
             DEBUGLOG(5, "new inBuff pre-filled");
             zcs->dictSize = newDictSize;
         } else {
    @@ -653,10 +664,16 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi
             zcs->dictSize = 0;
             zcs->frameEnded = 1;
             if (zcs->nextJobID == 0)
    -            zcs->params.fParams.checksumFlag = 0;   /* single chunk : checksum is calculated directly within worker thread */
    +            /* single chunk exception : checksum is calculated directly within worker thread */
    +            zcs->params.fParams.checksumFlag = 0;
         }
     
    -    DEBUGLOG(3, "posting job %u : %u bytes  (end:%u) (note : doneJob = %u=>%u)", zcs->nextJobID, (U32)zcs->jobs[jobID].srcSize, zcs->jobs[jobID].lastChunk, zcs->doneJobID, zcs->doneJobID & zcs->jobIDMask);
    +    DEBUGLOG(3, "posting job %u : %u bytes  (end:%u) (note : doneJob = %u=>%u)",
    +                zcs->nextJobID,
    +                (U32)zcs->jobs[jobID].srcSize,
    +                zcs->jobs[jobID].lastChunk,
    +                zcs->doneJobID,
    +                zcs->doneJobID & zcs->jobIDMask);
         POOL_add(zcs->factory, ZSTDMT_compressChunk, &zcs->jobs[jobID]);   /* this call is blocking when thread worker pool is exhausted */
         zcs->nextJobID++;
         return 0;
    @@ -729,8 +746,11 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi
     size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
     {
         size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize;
    -    if (zcs->frameEnded) return ERROR(stage_wrong);   /* current frame being ended. Only flush is allowed. Restart with init */
    -    if (zcs->nbThreads==1) return ZSTD_compressStream(zcs->cstream, output, input);
    +    if (zcs->frameEnded)
    +        /* current frame being ended. Only flush is allowed. Restart with init */
    +        return ERROR(stage_wrong);
    +    if (zcs->nbThreads==1)
    +        return ZSTD_compressStream(zcs->cctxPool->cctx[0], output, input);
     
         /* fill input buffer */
         {   size_t const toLoad = MIN(input->size - input->pos, zcs->inBuffSize - zcs->inBuff.filled);
    @@ -770,12 +790,14 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp
     
     size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
     {
    -    if (zcs->nbThreads==1) return ZSTD_flushStream(zcs->cstream, output);
    +    if (zcs->nbThreads==1)
    +        return ZSTD_flushStream(zcs->cctxPool->cctx[0], output);
         return ZSTDMT_flushStream_internal(zcs, output, 0);
     }
     
     size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
     {
    -    if (zcs->nbThreads==1) return ZSTD_endStream(zcs->cstream, output);
    +    if (zcs->nbThreads==1)
    +        return ZSTD_endStream(zcs->cctxPool->cctx[0], output);
         return ZSTDMT_flushStream_internal(zcs, output, 1);
     }
    
    From ae728a43b848633cf327f901ea8838f2aa1a1e3d Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 17:11:39 -0700
    Subject: [PATCH 111/400] removed defaultCustomMem
    
    now ZSTD_customCMem is promoted as new default.
    
    Advantages : ZSTD_customCMem = { NULL, NULL, NULL},
    so it's natural default after a memset.
    
    ZSTD_customCMem is public constant
    (defaultCustomMem was private only).
    
    Also : makes it possible to introduce ZSTD_calloc(),
    which can now default to stdlib's calloc()
    when it detects system default.
    
    Fixed zlibwrapper which depended on defaultCustomMem.
    ---
     lib/common/zstd_common.c         | 14 --------------
     lib/common/zstd_internal.h       |  5 -----
     lib/compress/zstd_compress.c     | 17 +++++++----------
     lib/compress/zstdmt_compress.h   |  1 +
     lib/decompress/zstd_decompress.c | 11 ++++-------
     zlibWrapper/zstd_zlibwrapper.c   | 11 ++++-------
     6 files changed, 16 insertions(+), 43 deletions(-)
    
    diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
    index 9b46df1d8..801483960 100644
    --- a/lib/common/zstd_common.c
    +++ b/lib/common/zstd_common.c
    @@ -50,20 +50,6 @@ const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString
     /*=**************************************************************
     *  Custom allocator
     ****************************************************************/
    -/* default uses stdlib */
    -void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
    -{
    -    void* address = malloc(size);
    -    (void)opaque;
    -    return address;
    -}
    -
    -void ZSTD_defaultFreeFunction(void* opaque, void* address)
    -{
    -    (void)opaque;
    -    free(address);
    -}
    -
     void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
     {
         if (customMem.customAlloc)
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index 5ab4aaeff..fedaac697 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -238,11 +238,6 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
     int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
     
     /* custom memory allocation functions */
    -void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
    -void ZSTD_defaultFreeFunction(void* opaque, void* address);
    -#ifndef ZSTD_DLL_IMPORT
    -static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
    -#endif
     void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
     void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
     void ZSTD_free(void* ptr, ZSTD_customMem customMem);
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 1feec765e..7c2fd520f 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -158,15 +158,14 @@ struct ZSTD_CCtx_s {
     
     ZSTD_CCtx* ZSTD_createCCtx(void)
     {
    -    return ZSTD_createCCtx_advanced(defaultCustomMem);
    +    return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
     }
     
     ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
     {
         ZSTD_CCtx* cctx;
     
    -    if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
         cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
         if (!cctx) return NULL;
    @@ -3225,9 +3224,9 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
         size_t result;
         ZSTD_CCtx ctxBody;
         memset(&ctxBody, 0, sizeof(ctxBody));
    -    memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
    +    ctxBody.customMem = ZSTD_defaultCMem;
         result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
    -    ZSTD_free(ctxBody.workSpace, defaultCustomMem);  /* can't free ctxBody itself, as it's on stack; free only heap content */
    +    ZSTD_free(ctxBody.workSpace, ZSTD_defaultCMem);  /* can't free ctxBody itself, as it's on stack; free only heap content */
         return result;
     }
     
    @@ -3288,8 +3287,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
                                           ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
     {
         DEBUGLOG(5, "ZSTD_createCDict_advanced");
    -    if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
         {   ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
             ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
    @@ -3442,12 +3440,11 @@ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
     
     ZSTD_CStream* ZSTD_createCStream(void)
     {
    -    return ZSTD_createCStream_advanced(defaultCustomMem);
    +    return ZSTD_createCStream_advanced(ZSTD_defaultCMem);
     }
     
     ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
    -{
    -    /* CStream and CCtx are now same object */
    +{   /* CStream and CCtx are now same object */
         return ZSTD_createCCtx_advanced(customMem);
     }
     
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index 92f7d8d0b..94fef7c07 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -57,6 +57,7 @@ ZSTDLIB_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output);
     ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* dict, size_t dictSize,  /**< dict can be released after init, a local copy is preserved within zcs */
                                               ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
     
    +
     /* ZSDTMT_parameter :
      * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
     typedef enum {
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index a59724386..7dfcddb1b 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -206,9 +206,7 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
     {
         ZSTD_DCtx* dctx;
     
    -    if (!customMem.customAlloc && !customMem.customFree)
    -        customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree)
    +    if (!customMem.customAlloc ^ !customMem.customFree)
             return NULL;
     
         dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
    @@ -233,7 +231,7 @@ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
     
     ZSTD_DCtx* ZSTD_createDCtx(void)
     {
    -    return ZSTD_createDCtx_advanced(defaultCustomMem);
    +    return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
     }
     
     size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
    @@ -2012,8 +2010,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_
     
     ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
     {
    -    if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
    -    if (!customMem.customAlloc || !customMem.customFree) return NULL;
    +    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
         {   ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
             if (!ddict) return NULL;
    @@ -2155,7 +2152,7 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
     
     ZSTD_DStream* ZSTD_createDStream(void)
     {
    -    return ZSTD_createDStream_advanced(defaultCustomMem);
    +    return ZSTD_createDStream_advanced(ZSTD_defaultCMem);
     }
     
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
    diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c
    index 1960d19e9..a078cf556 100644
    --- a/zlibWrapper/zstd_zlibwrapper.c
    +++ b/zlibWrapper/zstd_zlibwrapper.c
    @@ -8,6 +8,7 @@
      */
     
     
    +#include 
     #include                  /* vsprintf */
     #include                 /* va_list, for z_gzprintf */
     #define NO_DUMMY_DECL
    @@ -117,10 +118,8 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
               memcpy(&zwc->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
             }
         } else {
    -        zwc = (ZWRAP_CCtx*)defaultCustomMem.customAlloc(defaultCustomMem.opaque, sizeof(ZWRAP_CCtx));
    +        zwc = (ZWRAP_CCtx*)calloc(1, sizeof(*zwc));
             if (zwc==NULL) return NULL;
    -        memset(zwc, 0, sizeof(ZWRAP_CCtx));
    -        memcpy(&zwc->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
         }
     
         return zwc;
    @@ -219,7 +218,7 @@ int ZWRAP_deflateReset_keepDict(z_streamp strm)
             return deflateReset(strm);
     
         { ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
    -      if (zwc) { 
    +      if (zwc) {
               zwc->streamEnd = 0;
               zwc->totalInBytes = 0;
           }
    @@ -459,10 +458,8 @@ ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
               memcpy(&zwd->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
             }
         } else {
    -        zwd = (ZWRAP_DCtx*)defaultCustomMem.customAlloc(defaultCustomMem.opaque, sizeof(ZWRAP_DCtx));
    +        zwd = (ZWRAP_DCtx*)calloc(1, sizeof(*zwd));
             if (zwd==NULL) return NULL;
    -        memset(zwd, 0, sizeof(ZWRAP_DCtx));
    -        memcpy(&zwd->customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
         }
     
         MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_FRAMEHEADERSIZE_MIN);   /* if compilation fails here, assertion is false */
    
    From deee6e523f81671e84f93ceb6be3e1a47387cc25 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 17:42:00 -0700
    Subject: [PATCH 112/400] expose ZSTD_compress_generic_simpleArgs()
    
    which is a binding towards ZSTD_compress_generic()
    using only integral types for arguments.
    ---
     doc/zstd_manual.html           | 13 +++++++++
     lib/compress/zstd_compress.c   | 51 +++++++++++++++++++---------------
     lib/compress/zstdmt_compress.c |  3 +-
     lib/zstd.h                     | 14 ++++++++++
     4 files changed, 57 insertions(+), 24 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 2c66409cb..3b7f32870 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -698,6 +698,19 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic
      
     


    +
    size_t ZSTD_compress_generic_simpleArgs (
    +                ZSTD_CCtx* cctx,
    +                void* dst, size_t dstCapacity, size_t* dstPos,
    +          const void* src, size_t srcSize, size_t* srcPos,
    +                ZSTD_EndDirective endOp);
    +

    Same as ZSTD_compress_generic(), + but using only simple integral types as arguments. + Argument list is less expressive than ZSTD_{in,out}Buffer, + but can be helpful for binders towards dynamic languages + which have troubles handling structures containing memory pointers. + +


    +

    Advanced decompression functions

    
     
     
    unsigned ZSTD_isFrame(const void* buffer, size_t size);
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 7c2fd520f..b046a2c5f 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3710,49 +3710,54 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf
         return result;
     }
     
    -size_t ZSTD_compress_generic_integral (
    -                            ZSTD_CCtx* cctx,
    -                            void* dst, size_t dstCapacity, size_t* dstPos,
    -                      const void* src, size_t srcSize, size_t* srcPos,
    -                            ZSTD_EndDirective endOp)
    +size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                              ZSTD_outBuffer* output,
    +                              ZSTD_inBuffer* input,
    +                              ZSTD_EndDirective endOp)
     {
         /* check conditions */
    -    if (*dstPos > dstCapacity) return ERROR(GENERIC);
    -    if (*srcPos > srcSize) return ERROR(GENERIC);
    +    if (output->pos > output->size) return ERROR(GENERIC);
    +    if (input->pos  > input->size)  return ERROR(GENERIC);
     
         assert(cctx!=NULL);
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
             ZSTD_parameters params = cctx->requestedParams;
    -        DEBUGLOG(5, "ZSTD_compress_generic_integral : transparent reset");
    +        DEBUGLOG(5, "ZSTD_compress_generic : transparent reset");
             if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
                 params.cParams = ZSTD_getCParams(cctx->compressionLevel,
                                         cctx->frameContentSize, 0 /* dictSize */);
             CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) );
         }
     
    -    {   size_t sizeRead = srcSize - *srcPos;
    -        size_t sizeWritten = dstCapacity - *dstPos;
    +    {   size_t sizeRead = input->size - input->pos;
    +        size_t sizeWritten = output->size - output->pos;
             DEBUGLOG(5, "starting ZSTD_compressStream_generic");
             CHECK_F( ZSTD_compressStream_generic(cctx,
    -                        (char*)dst + *dstPos, &sizeWritten,
    -                        (const char*)src + *srcPos, &sizeRead, endOp) );
    -        *srcPos += sizeRead;
    -        *dstPos += sizeWritten;
    +                        (char*)output->dst + output->pos, &sizeWritten,
    +                        (const char*)input->src + input->pos, &sizeRead, endOp) );
    +        input->pos += sizeRead;
    +        output->pos += sizeWritten;
         }
         DEBUGLOG(5, "completing ZSTD_compress_generic_integral");
    -    return cctx->outBuffContentSize - cctx->outBuffFlushedSize;   /* remaining to flush */
    +    return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
     }
     
    -size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    -                              ZSTD_outBuffer* output,
    -                              ZSTD_inBuffer* input,
    -                              ZSTD_EndDirective endOp)
    +size_t ZSTD_compress_generic_simpleArgs (
    +                            ZSTD_CCtx* cctx,
    +                            void* dst, size_t dstCapacity, size_t* dstPos,
    +                      const void* src, size_t srcSize, size_t* srcPos,
    +                            ZSTD_EndDirective endOp)
     {
    -    return ZSTD_compress_generic_integral(cctx,
    -                output->dst, output->size, &output->pos,
    -                input->src, input->size, &input->pos,
    -                endOp);
    +    ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
    +    ZSTD_inBuffer  input  = { src, srcSize, *srcPos };
    +
    +    size_t const hint = ZSTD_compress_generic(cctx, &output, &input, endOp);
    +    if (ZSTD_isError(hint)) return hint;
    +
    +    *dstPos = output.pos;
    +    *srcPos = input.pos;
    +    return hint;
     }
     
     
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index ca5cd6aee..b2c82e489 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -783,7 +783,8 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp
         }
     
         /* check if there is any data available to flush */
    -    DEBUGLOG(5, "zcs->doneJobID : %u  ; zcs->nextJobID : %u ", zcs->doneJobID, zcs->nextJobID);
    +    DEBUGLOG(5, "zcs->doneJobID : %u  ; zcs->nextJobID : %u",
    +            zcs->doneJobID, zcs->nextJobID);
         return ZSTDMT_flushNextJob(zcs, output, 1);
     }
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index d4c24e7b3..1fc35fc55 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -823,6 +823,20 @@ ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
     
     
    +/*! ZSTD_compress_generic_simpleArgs() :
    + *  Same as ZSTD_compress_generic(),
    + *  but using only simple integral types as arguments.
    + *  Argument list is less expressive than ZSTD_{in,out}Buffer,
    + *  but can be helpful for binders towards dynamic languages
    + *  which have troubles handling structures containing memory pointers.
    + */
    +size_t ZSTD_compress_generic_simpleArgs (
    +                            ZSTD_CCtx* cctx,
    +                            void* dst, size_t dstCapacity, size_t* dstPos,
    +                      const void* src, size_t srcSize, size_t* srcPos,
    +                            ZSTD_EndDirective endOp);
    +
    +
     
     /*--- Advanced decompression functions ---*/
     
    
    From c4f46b94ce6ba497c75b0b44d9e45a0d2872602d Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 17:45:37 -0700
    Subject: [PATCH 113/400] ZSTD_createCCtx_advanced() now uses ZSTD_calloc()
    
    initially uses calloc() instead of memset().
    
    Performance improvement is unlikely measurable,
    since ZSTD_CCtx is now very small,
    with all tables transferred into workSpace.
    ---
     lib/compress/zstd_compress.c | 3 +--
     1 file changed, 1 insertion(+), 2 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index b046a2c5f..00a93e6e5 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -167,9 +167,8 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
     
         if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
    -    cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
    +    cctx = (ZSTD_CCtx*) ZSTD_calloc(sizeof(ZSTD_CCtx), customMem);
         if (!cctx) return NULL;
    -    memset(cctx, 0, sizeof(ZSTD_CCtx));
         cctx->customMem = customMem;
         cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT;
         return cctx;
    
    From 01b1549f83e58db9494234285fbf6673b2ed7f04 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 30 May 2017 18:10:26 -0700
    Subject: [PATCH 114/400] finally converted ZSTD_compressStream_generic() to
     use {in,ou}Buffer
    
    replacing the older read/write variables from ZBUFF_* era.
    Mostly to help code readability.
    
    Fixed relevant callers.
    ---
     lib/compress/zstd_compress.c | 96 +++++++++++++++---------------------
     1 file changed, 41 insertions(+), 55 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 00a93e6e5..90ee1bb6d 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3571,7 +3571,8 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
     
     /*======   Compression   ======*/
     
    -MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
    +MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
    +                           const void* src, size_t srcSize)
     {
         size_t const length = MIN(dstCapacity, srcSize);
         memcpy(dst, src, length);
    @@ -3579,18 +3580,19 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src,
     }
     
     static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
    -                              void* dst, size_t* dstCapacityPtr,
    -                        const void* src, size_t* srcSizePtr,
    -                              ZSTD_EndDirective const flushMode)
    +                                        ZSTD_outBuffer* output,
    +                                        ZSTD_inBuffer* input,
    +                                        ZSTD_EndDirective const flushMode)
     {
         U32 someMoreWork = 1;
    -    const char* const istart = (const char*)src;
    -    const char* const iend = istart + *srcSizePtr;
    -    const char* ip = istart;
    -    char* const ostart = (char*)dst;
    -    char* const oend = ostart + *dstCapacityPtr;
    -    char* op = ostart;
    +    const char* const istart = (const char*)input->src;
    +    const char* const iend = istart + input->size;
    +    const char* ip = istart + input->pos;
    +    char* const ostart = (char*)output->dst;
    +    char* const oend = ostart + output->size;
    +    char* op = ostart + output->pos;
     
    +    /* expected to be already allocated */
         assert(zcs->inBuff != NULL);
         assert(zcs->outBuff!= NULL);
     
    @@ -3604,7 +3606,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
             case zcss_load:
                 /* complete inBuffer */
                 {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
    -                size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
    +                size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos,
    +                                                    toLoad, ip, iend-ip);
                     zcs->inBuffPos += loaded;
                     ip += loaded;
                     if ( (flushMode == ZSTD_e_continue)
    @@ -3663,11 +3666,16 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
             case zcss_flush:
                 DEBUGLOG(5, "flush stage");
                 {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
    -                size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
    +                size_t const flushed = ZSTD_limitCopy(op, oend-op,
    +                            zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
                     DEBUGLOG(5, "toFlush: %u  ; flushed: %u", (U32)toFlush, (U32)flushed);
                     op += flushed;
                     zcs->outBuffFlushedSize += flushed;
    -                if (toFlush!=flushed) { someMoreWork = 0; break; }  /* dst too small to store flushed data : stop there */
    +                if (toFlush!=flushed) {
    +                    /* dst too small to store flushed data : stop there */
    +                    someMoreWork = 0;
    +                    break;
    +                }
                     zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
                     if (zcs->frameEnded) {
                         DEBUGLOG(5, "Frame completed");
    @@ -3687,8 +3695,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
             }
         }
     
    -    *srcSizePtr = ip - istart;
    -    *dstCapacityPtr = op - ostart;
    +    input->pos = ip - istart;
    +    output->pos = op - ostart;
         if (zcs->frameEnded) return 0;
         {   size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
             if (hintInSize==0) hintInSize = zcs->blockSize;
    @@ -3698,15 +3706,11 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
     
     size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
     {
    -    size_t sizeRead = input->size - input->pos;
    -    size_t sizeWritten = output->size - output->pos;
    -    size_t const result = ZSTD_compressStream_generic(
    -                            zcs,
    -                            (char*)(output->dst) + output->pos, &sizeWritten,
    -                            (const char*)(input->src) + input->pos, &sizeRead, ZSTD_e_continue);
    -    input->pos += sizeRead;
    -    output->pos += sizeWritten;
    -    return result;
    +    /* check conditions */
    +    if (output->pos > output->size) return ERROR(GENERIC);
    +    if (input->pos  > input->size)  return ERROR(GENERIC);
    +
    +    return ZSTD_compressStream_generic(zcs, output, input, ZSTD_e_continue);
     }
     
     size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    @@ -3717,8 +3721,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
         /* check conditions */
         if (output->pos > output->size) return ERROR(GENERIC);
         if (input->pos  > input->size)  return ERROR(GENERIC);
    -
         assert(cctx!=NULL);
    +
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
             ZSTD_parameters params = cctx->requestedParams;
    @@ -3729,15 +3733,9 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
             CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) );
         }
     
    -    {   size_t sizeRead = input->size - input->pos;
    -        size_t sizeWritten = output->size - output->pos;
    -        DEBUGLOG(5, "starting ZSTD_compressStream_generic");
    -        CHECK_F( ZSTD_compressStream_generic(cctx,
    -                        (char*)output->dst + output->pos, &sizeWritten,
    -                        (const char*)input->src + input->pos, &sizeRead, endOp) );
    -        input->pos += sizeRead;
    -        output->pos += sizeWritten;
    -    }
    +    DEBUGLOG(5, "starting ZSTD_compressStream_generic");
    +    CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
    +
         DEBUGLOG(5, "completing ZSTD_compress_generic_integral");
         return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
     }
    @@ -3750,13 +3748,14 @@ size_t ZSTD_compress_generic_simpleArgs (
     {
         ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
         ZSTD_inBuffer  input  = { src, srcSize, *srcPos };
    -
    +    /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
         size_t const hint = ZSTD_compress_generic(cctx, &output, &input, endOp);
         if (ZSTD_isError(hint)) return hint;
     
         *dstPos = output.pos;
         *srcPos = input.pos;
         return hint;
    +
     }
     
     
    @@ -3766,34 +3765,21 @@ size_t ZSTD_compress_generic_simpleArgs (
     *   @return : amount of data remaining to flush */
     size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    size_t srcSize = 0;
    -    size_t sizeWritten = output->size - output->pos;
    -    size_t const result = ZSTD_compressStream_generic(zcs,
    -                                (char*)(output->dst) + output->pos, &sizeWritten,
    -                                &srcSize, &srcSize, /* use a valid src address instead of NULL */
    -                                ZSTD_e_flush);
    -    output->pos += sizeWritten;
    -    if (ZSTD_isError(result)) return result;
    -    return zcs->outBuffContentSize - zcs->outBuffFlushedSize;   /* remaining to flush */
    +    ZSTD_inBuffer input = { &input, 0, 0 };
    +    if (output->pos > output->size) return ERROR(GENERIC);
    +    CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_flush) );
    +    return zcs->outBuffContentSize - zcs->outBuffFlushedSize;  /* remaining to flush */
     }
     
     
     size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
    -    size_t srcSize = 0;
    -    size_t sizeWritten = output->size - output->pos;
    -
    -    size_t const result = ZSTD_compressStream_generic(zcs,
    -                                ostart, &sizeWritten,
    -                                &srcSize /* valid address */, &srcSize,
    -                                ZSTD_e_end);
    -    output->pos += sizeWritten;
    -    if (ZSTD_isError(result)) return result;
    +    ZSTD_inBuffer input = { &input, 0, 0 };
    +    if (output->pos > output->size) return ERROR(GENERIC);
    +    CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_end) );
     
         DEBUGLOG(5, "ZSTD_endStream : remaining to flush : %u",
                 (unsigned)(zcs->outBuffContentSize - zcs->outBuffFlushedSize));
    -
         return zcs->outBuffContentSize - zcs->outBuffFlushedSize;
     }
     
    
    From 9a691e0f55062156c2f5902405fe0d9b9394a9ab Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 31 May 2017 01:17:44 -0700
    Subject: [PATCH 115/400] fixed visual warnings
    
    ---
     lib/common/zstd_internal.h   | 1 +
     lib/compress/zstd_compress.c | 6 ++++--
     2 files changed, 5 insertions(+), 2 deletions(-)
    
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index fedaac697..6f9b4ef1f 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -18,6 +18,7 @@
     #  include                     /* For Visual 2005 */
     #  pragma warning(disable : 4100)        /* disable: C4100: unreferenced formal parameter */
     #  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
    +#  pragma warning(disable : 4204)        /* disable: C4204: non-constant aggregate initializer */
     #  pragma warning(disable : 4324)        /* disable: C4324: padded structure */
     #else
     #  if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 90ee1bb6d..d57d909a7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3765,7 +3765,8 @@ size_t ZSTD_compress_generic_simpleArgs (
     *   @return : amount of data remaining to flush */
     size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    ZSTD_inBuffer input = { &input, 0, 0 };
    +    const char dummy[8] = {0};
    +    ZSTD_inBuffer input = { dummy, 0, 0 };
         if (output->pos > output->size) return ERROR(GENERIC);
         CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_flush) );
         return zcs->outBuffContentSize - zcs->outBuffFlushedSize;  /* remaining to flush */
    @@ -3774,7 +3775,8 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     
     size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    ZSTD_inBuffer input = { &input, 0, 0 };
    +    const char dummy[8] = {0};
    +    ZSTD_inBuffer input = { dummy, 0, 0 };
         if (output->pos > output->size) return ERROR(GENERIC);
         CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_end) );
     
    
    From 18ab5affa509170bbd5226a1bcde732bedcb3d65 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 31 May 2017 09:59:22 -0700
    Subject: [PATCH 116/400] fixed visual warning
    
    ---
     lib/compress/zstd_compress.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 90ee1bb6d..fa574a226 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3575,7 +3575,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
                                const void* src, size_t srcSize)
     {
         size_t const length = MIN(dstCapacity, srcSize);
    -    memcpy(dst, src, length);
    +    if (length) memcpy(dst, src, length);
         return length;
     }
     
    @@ -3765,7 +3765,7 @@ size_t ZSTD_compress_generic_simpleArgs (
     *   @return : amount of data remaining to flush */
     size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    ZSTD_inBuffer input = { &input, 0, 0 };
    +    ZSTD_inBuffer input = { NULL, 0, 0 };
         if (output->pos > output->size) return ERROR(GENERIC);
         CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_flush) );
         return zcs->outBuffContentSize - zcs->outBuffFlushedSize;  /* remaining to flush */
    @@ -3774,7 +3774,7 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     
     size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     {
    -    ZSTD_inBuffer input = { &input, 0, 0 };
    +    ZSTD_inBuffer input = { NULL, 0, 0 };
         if (output->pos > output->size) return ERROR(GENERIC);
         CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_end) );
     
    
    From cd2892fd1eddc9e4cb7375b2a0167668c69a1981 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Thu, 1 Jun 2017 09:44:54 -0700
    Subject: [PATCH 117/400] protected impossible switch(){default:} with
     assert(0)
    
    can be converted into assume(0) in some future
    ---
     lib/compress/zstd_compress.c | 125 ++++++++++++++++++-----------------
     1 file changed, 65 insertions(+), 60 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index ddbeaf56e..175a7b2b0 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -265,80 +265,82 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
         switch(param)
         {
         case ZSTD_p_compressionLevel :
    -            if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel();   /* cap max compression level */
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            cctx->compressionLevel = value;
    -            return 0;
    +        if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel();   /* cap max compression level */
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        cctx->compressionLevel = value;
    +        return 0;
     
         case ZSTD_p_windowLog :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.windowLog = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.windowLog = value;
    +        return 0;
     
         case ZSTD_p_hashLog :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.hashLog = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.hashLog = value;
    +        return 0;
     
         case ZSTD_p_chainLog :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.chainLog = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.chainLog = value;
    +        return 0;
     
         case ZSTD_p_searchLog :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.searchLog = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.searchLog = value;
    +        return 0;
     
         case ZSTD_p_minMatch :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.searchLength = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.searchLength = value;
    +        return 0;
     
         case ZSTD_p_targetLength :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.targetLength = value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.targetLength = value;
    +        return 0;
     
         case ZSTD_p_compressionStrategy :
    -            if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    -            CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
    -            ZSTD_cLevelToCParams(cctx);
    -            cctx->requestedParams.cParams.strategy = (ZSTD_strategy)value;
    -            return 0;
    +        if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
    +        CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
    +        ZSTD_cLevelToCParams(cctx);
    +        cctx->requestedParams.cParams.strategy = (ZSTD_strategy)value;
    +        return 0;
     
     #if 0
         case ZSTD_p_windowSize :   /* to be done later */
    -            return ERROR(compressionParameter_unsupported);
    +        return ERROR(compressionParameter_unsupported);
     #endif
     
    -    case ZSTD_p_contentSizeFlag : /* Content size will be written in frame header _when known_ (default:1) */
    -            cctx->requestedParams.fParams.contentSizeFlag = value>0;
    -            return 0;
    +    case ZSTD_p_contentSizeFlag :
    +        /* Content size written in frame header _when known_ (default:1) */
    +        cctx->requestedParams.fParams.contentSizeFlag = value>0;
    +        return 0;
     
    -    case ZSTD_p_checksumFlag : /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
    -            cctx->requestedParams.fParams.checksumFlag = value>0;
    -            return 0;
    +    case ZSTD_p_checksumFlag :
    +        /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */
    +        cctx->requestedParams.fParams.checksumFlag = value>0;
    +        return 0;
     
         case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
    -            DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
    -            cctx->requestedParams.fParams.noDictIDFlag = (value==0);
    -            return 0;
    +        DEBUGLOG(5, "set dictIDFlag = %u", (value>0));
    +        cctx->requestedParams.fParams.noDictIDFlag = (value==0);
    +        return 0;
     
         case ZSTD_p_refDictContent :   /* to be done later */
    -            return ERROR(compressionParameter_unsupported);
    +        return ERROR(compressionParameter_unsupported);
     
         case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
                                        * even when referencing into Dictionary content
    @@ -348,8 +350,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
                 return 0;
     
         case ZSTD_p_rawContentDict :  /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    -            cctx->forceRawDict = value>0;
    -            return 0;
    +        cctx->forceRawDict = value>0;
    +        return 0;
     
         default: return ERROR(parameter_unknown);
         }
    @@ -811,10 +813,11 @@ static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void
             case 2: /* 2 - 2 - 12 */
                 MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
                 break;
    -        default:   /*note : should not be necessary : flSize is within {1,2,3} */
             case 3: /* 2 - 2 - 20 */
                 MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
                 break;
    +        default:   /* not necessary : flSize is {1,2,3} */
    +            assert(0);
         }
     
         memcpy(ostart + flSize, src, srcSize);
    @@ -836,10 +839,11 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons
             case 2: /* 2 - 2 - 12 */
                 MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
                 break;
    -        default:   /*note : should not be necessary : flSize is necessarily within {1,2,3} */
             case 3: /* 2 - 2 - 20 */
                 MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
                 break;
    +        default:   /* not necessary : flSize is {1,2,3} */
    +            assert(0);
         }
     
         ostart[flSize] = *(const BYTE*)src;
    @@ -901,13 +905,14 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
                 MEM_writeLE32(ostart, lhc);
                 break;
             }
    -    default:   /* should not be necessary, lhSize is only {3,4,5} */
         case 5: /* 2 - 2 - 18 - 18 */
             {   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
                 MEM_writeLE32(ostart, lhc);
                 ostart[4] = (BYTE)(cLitSize >> 10);
                 break;
             }
    +    default:   /* not possible : lhSize is {3,4,5} */
    +        assert(0);
         }
         return lhSize+cLitSize;
     }
    @@ -2814,7 +2819,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
         if (!singleSegment) op[pos++] = windowLogByte;
         switch(dictIDSizeCode)
         {
    -        default:   /* impossible */
    +        default:  assert(0); /* impossible */
             case 0 : break;
             case 1 : op[pos] = (BYTE)(dictID); pos++; break;
             case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
    @@ -2822,7 +2827,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
         }
         switch(fcsCode)
         {
    -        default:   /* impossible */
    +        default:  assert(0); /* impossible */
             case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
             case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
             case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
    @@ -2951,7 +2956,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
             break;
     
         default:
    -        return ERROR(GENERIC);   /* strategy doesn't exist; impossible */
    +        assert(0);  /* not possible : not a valid strategy id */
         }
     
         zc->nextToUpdate = (U32)(iend - zc->base);
    @@ -3691,8 +3696,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
             case zcss_final:
                 someMoreWork = 0; break;  /* useless */
     
    -        default:
    -            return ERROR(GENERIC);   /* impossible */
    +        default: /* impossible */
    +            assert(0);
             }
         }
     
    
    From c4a5a21c5c4e75b24839267a4f0472948a0159cf Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Thu, 1 Jun 2017 17:56:14 -0700
    Subject: [PATCH 118/400] created ZSTDMT_sizeof_CCtx() and POOL_sizeof()
    
    required by ZSTD_sizeofCCtx() while adding a ZSTDMT_CCtx*
    ---
     lib/common/pool.c              |  7 ++++++
     lib/common/pool.h              |  5 +++++
     lib/compress/zstd_compress.c   | 12 ++++++++--
     lib/compress/zstdmt_compress.c | 40 +++++++++++++++++++++++++++++++++-
     lib/compress/zstdmt_compress.h | 17 ++++++++++-----
     5 files changed, 73 insertions(+), 8 deletions(-)
    
    diff --git a/lib/common/pool.c b/lib/common/pool.c
    index e439fe1b0..05adcf1ce 100644
    --- a/lib/common/pool.c
    +++ b/lib/common/pool.c
    @@ -146,6 +146,13 @@ void POOL_free(POOL_ctx *ctx) {
         free(ctx);
     }
     
    +size_t POOL_sizeof(POOL_ctx *ctx) {
    +    if (ctx==NULL) return 0;  /* supports sizeof NULL */
    +    return sizeof(*ctx)
    +        + ctx->queueSize * sizeof(POOL_job)
    +        + ctx->numThreads * sizeof(pthread_t);
    +}
    +
     void POOL_add(void *ctxVoid, POOL_function function, void *opaque) {
         POOL_ctx *ctx = (POOL_ctx *)ctxVoid;
         if (!ctx) { return; }
    diff --git a/lib/common/pool.h b/lib/common/pool.h
    index 50cb25b12..386cd674b 100644
    --- a/lib/common/pool.h
    +++ b/lib/common/pool.h
    @@ -32,6 +32,11 @@ POOL_ctx *POOL_create(size_t numThreads, size_t queueSize);
     */
     void POOL_free(POOL_ctx *ctx);
     
    +/*! POOL_sizeof() :
    +    return memory usage of pool returned by POOL_create().
    +*/
    +size_t POOL_sizeof(POOL_ctx *ctx);
    +
     /*! POOL_function :
         The function type that can be added to a thread pool.
     */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 175a7b2b0..7924968e4 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -25,6 +25,7 @@
     #define HUF_STATIC_LINKING_ONLY
     #include "huf.h"
     #include "zstd_internal.h"  /* includes zstd.h */
    +#include "zstdmt_compress.h"
     
     
     /*-*************************************
    @@ -154,8 +155,12 @@ struct ZSTD_CCtx_s {
         size_t outBuffFlushedSize;
         ZSTD_cStreamStage streamStage;
         U32    frameEnded;
    +
    +    /* Multi-threading */
    +    ZSTDMT_CCtx* mtctx;
     };
     
    +
     ZSTD_CCtx* ZSTD_createCCtx(void)
     {
         return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
    @@ -205,11 +210,13 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
     size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
     {
         if (cctx==NULL) return 0;   /* support free on NULL */
    -    assert(!cctx->staticSize);  /* not compatible with static CCtx */
    +    if (cctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static CCtx */
         ZSTD_free(cctx->workSpace, cctx->customMem);
         cctx->workSpace = NULL;
         ZSTD_freeCDict(cctx->cdictLocal);
         cctx->cdictLocal = NULL;
    +    ZSTDMT_freeCCtx(cctx->mtctx);
    +    cctx->mtctx = NULL;
         ZSTD_free(cctx, cctx->customMem);
         return 0;   /* reserved as a potential error code in the future */
     }
    @@ -219,7 +226,8 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
         if (cctx==NULL) return 0;   /* support sizeof on NULL */
         return sizeof(*cctx) + cctx->workSpaceSize
                + ZSTD_sizeof_CDict(cctx->cdictLocal)
    -           + cctx->outBuffSize + cctx->inBuffSize;
    +           + cctx->outBuffSize + cctx->inBuffSize
    +           + ZSTDMT_sizeof_CCtx(cctx->mtctx);
     }
     
     size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index b2c82e489..57c0360b0 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -123,6 +123,19 @@ static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
         ZSTD_free(bufPool, bufPool->cMem);
     }
     
    +/* only works at initialization, not during compression */
    +static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool)
    +{
    +    size_t const poolSize = sizeof(*bufPool)
    +                            + (bufPool->totalBuffers - 1) * sizeof(buffer_t);
    +    unsigned u;
    +    size_t totalBufferSize = 0;
    +    for (u=0; utotalBuffers; u++)
    +        totalBufferSize += bufPool->bTable[u].size;
    +
    +    return poolSize + totalBufferSize;
    +}
    +
     /* assumption : invocation from main thread only ! */
     static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* pool, size_t bSize)
     {
    @@ -181,7 +194,7 @@ static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
     /* ZSTDMT_createCCtxPool() :
      * implies nbThreads >= 1 , checked by caller ZSTDMT_createCCtx() */
     static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads,
    -                                            ZSTD_customMem cMem)
    +                                              ZSTD_customMem cMem)
     {
         ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc(
             sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*), cMem);
    @@ -195,6 +208,20 @@ static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads,
         return cctxPool;
     }
     
    +/* only works during initialization phase, not during compression */
    +static size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool)
    +{
    +    unsigned const nbThreads = cctxPool->totalCCtx;
    +    size_t const poolSize = sizeof(*cctxPool)
    +                            + (nbThreads-1)*sizeof(ZSTD_CCtx*);
    +    unsigned u;
    +    size_t totalCCtxSize = 0;
    +    for (u=0; ucctx[u]);
    +
    +    return poolSize + totalCCtxSize;
    +}
    +
     static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* pool)
     {
         if (pool->availCCtx) {
    @@ -393,6 +420,17 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
         return 0;
     }
     
    +size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)
    +{
    +    if (mtctx == NULL) return 0;   /* supports sizeof NULL */
    +    return sizeof(*mtctx)
    +        + POOL_sizeof(mtctx->factory)
    +        + ZSTDMT_sizeof_bufferPool(mtctx->buffPool)
    +        + (mtctx->jobIDMask+1) * sizeof(ZSTDMT_jobDescription)
    +        + ZSTDMT_sizeof_CCtxPool(mtctx->cctxPool)
    +        + ZSTD_sizeof_CDict(mtctx->cdict);
    +}
    +
     size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value)
     {
         switch(parameter)
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index 94fef7c07..ff7f21687 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -24,14 +24,21 @@
     #include "zstd.h"     /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
     
     
    -/* ===   Simple one-pass functions   === */
    -
    +/* ===   Memory management   === */
     typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;
     ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads);
    -ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem);
    -ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* cctx);
    +ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads,
    +                                                    ZSTD_customMem cMem);
    +ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
     
    -ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* cctx,
    +ZSTDLIB_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
    +ZSTDLIB_API size_t ZSTDMT_estimateCCtxSize(ZSTD_compressionParameters cParams,
    +                                           unsigned nbThreads);
    +
    +
    +/* ===   Simple buffer-to-butter one-pass function   === */
    +
    +ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
                                void* dst, size_t dstCapacity,
                          const void* src, size_t srcSize,
                                int compressionLevel);
    
    From c35e535002bf6b178f6c5ff53ce9b348fa8de427 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Thu, 1 Jun 2017 18:44:06 -0700
    Subject: [PATCH 119/400] added support for multithreading parameters
    
    ---
     lib/compress/zstd_compress.c   | 31 ++++++++++++++++++++++++++++---
     lib/compress/zstdmt_compress.c |  2 +-
     lib/compress/zstdmt_compress.h |  2 +-
     lib/zstd.h                     | 13 +++++++------
     4 files changed, 37 insertions(+), 11 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 7924968e4..8f7c200b2 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -157,6 +157,7 @@ struct ZSTD_CCtx_s {
         U32    frameEnded;
     
         /* Multi-threading */
    +    U32 nbThreads;
         ZSTDMT_CCtx* mtctx;
     };
     
    @@ -353,9 +354,33 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
         case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
                                        * even when referencing into Dictionary content
                                        * default : 0 when using a CDict, 1 when using a Prefix */
    -            cctx->forceWindow = value>0;
    -            cctx->loadedDictEnd = 0;
    -            return 0;
    +        cctx->forceWindow = value>0;
    +        cctx->loadedDictEnd = 0;
    +        return 0;
    +
    +    case ZSTD_p_nbThreads:
    +        if (value==0) return 0;
    +#ifndef ZSTD_MULTITHREAD
    +        if (value > 1) return ERROR(compressionParameter_unsupported);
    +#endif
    +        if ((value>1) && (cctx->nbThreads != value)) {
    +            ZSTDMT_freeCCtx(cctx->mtctx);
    +            cctx->nbThreads = value;
    +            cctx->mtctx = ZSTDMT_createCCtx(value);
    +            if (cctx->mtctx == NULL) return ERROR(memory_allocation);
    +        }
    +        cctx->nbThreads = 1;
    +        return 0;
    +
    +    case ZSTDMT_p_jobSize:
    +        if (cctx->nbThreads <= 1) return ERROR(compressionParameter_unsupported);
    +        assert(cctx->mtctx != NULL);
    +        return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_sectionSize, value);
    +
    +    case ZSTDMT_p_overlapSizeLog:
    +        if (cctx->nbThreads <= 1) return ERROR(compressionParameter_unsupported);
    +        assert(cctx->mtctx != NULL);
    +        return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
     
         case ZSTD_p_rawContentDict :  /* load dictionary in "content-only" mode (no header analysis) (default:0) */
             cctx->forceRawDict = value>0;
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 57c0360b0..0d6014608 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -439,7 +439,7 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter,
             mtctx->sectionSize = value;
             return 0;
         case ZSTDMT_p_overlapSectionLog :
    -    DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value);
    +        DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value);
             mtctx->overlapRLog = (value >= 9) ? 0 : 9 - value;
             return 0;
         default :
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index ff7f21687..336215995 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -33,7 +33,7 @@ ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
     
     ZSTDLIB_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
     ZSTDLIB_API size_t ZSTDMT_estimateCCtxSize(ZSTD_compressionParameters cParams,
    -                                           unsigned nbThreads);
    +                                           unsigned nbThreads);   /* not ready yet */
     
     
     /* ===   Simple buffer-to-butter one-pass function   === */
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 1fc35fc55..c71ed493e 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -491,7 +491,8 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
      *  These functions make it possible to estimate memory usage
      *  of a future target object, before its allocation,
      *  given a set of parameters, which vary depending on target object.
    - *  The objective is to guide decision before allocation. */
    + *  The objective is to guide decision before allocation.
    + *  Note : CCtx estimation is only correct for single-threaded compression */
     ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
     ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
     
    @@ -695,17 +696,17 @@ typedef enum {
         ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
                                  /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
     
    -#if 0
    -    /* multi-threading parameters (not ready yet !) */
    +    /* multi-threading parameters */
         ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    -                              * More threads improve speed, but increases also memory usage */
    -    ZSTDMT_p_jobSize,        /* Size of a compression job. Each job is compressed in parallel.
    +                              * More threads improve speed, but also increase memory usage.
    +                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    +                              * Special: value 0 means "do not change nbThreads" */
    +    ZSTDMT_p_jobSize,        /* Size of a compression job. Each compression job is completed in parallel.
                                   * 0 means default, which is dynamically determined based on compression parameters.
                                   * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
                                   * The minimum size is automatically and transparently enforced */
         ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job.
                                   * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    -#endif
     
         /* advanced parameters - may not remain available after API update */
         ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    
    From 6dc508539c2df7696d2c89bc422d7fd5d737949f Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 1 Jun 2017 21:18:48 -0700
    Subject: [PATCH 120/400] Moved VS2005 to the contrib directory
    
    ---
     build/VS2005/zstd/zstd.vcproj                 | 548 ------------------
     .../VS2005/fullbench/fullbench.vcproj         |   0
     .../VS2005/fuzzer/fuzzer.vcproj               |   0
     {build => contrib}/VS2005/zstd.sln            |   0
     .../VS2005/zstdlib/zstdlib.vcproj             |   0
     5 files changed, 548 deletions(-)
     delete mode 100644 build/VS2005/zstd/zstd.vcproj
     rename {build => contrib}/VS2005/fullbench/fullbench.vcproj (100%)
     rename {build => contrib}/VS2005/fuzzer/fuzzer.vcproj (100%)
     rename {build => contrib}/VS2005/zstd.sln (100%)
     rename {build => contrib}/VS2005/zstdlib/zstdlib.vcproj (100%)
    
    diff --git a/build/VS2005/zstd/zstd.vcproj b/build/VS2005/zstd/zstd.vcproj
    deleted file mode 100644
    index 46cabbf6e..000000000
    --- a/build/VS2005/zstd/zstd.vcproj
    +++ /dev/null
    @@ -1,548 +0,0 @@
    -
    -
    -	
    -		
    -		
    -	
    -	
    -	
    -	
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -	
    -	
    -	
    -	
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -		
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -			
    -		
    -	
    -	
    -	
    -
    diff --git a/build/VS2005/fullbench/fullbench.vcproj b/contrib/VS2005/fullbench/fullbench.vcproj
    similarity index 100%
    rename from build/VS2005/fullbench/fullbench.vcproj
    rename to contrib/VS2005/fullbench/fullbench.vcproj
    diff --git a/build/VS2005/fuzzer/fuzzer.vcproj b/contrib/VS2005/fuzzer/fuzzer.vcproj
    similarity index 100%
    rename from build/VS2005/fuzzer/fuzzer.vcproj
    rename to contrib/VS2005/fuzzer/fuzzer.vcproj
    diff --git a/build/VS2005/zstd.sln b/contrib/VS2005/zstd.sln
    similarity index 100%
    rename from build/VS2005/zstd.sln
    rename to contrib/VS2005/zstd.sln
    diff --git a/build/VS2005/zstdlib/zstdlib.vcproj b/contrib/VS2005/zstdlib/zstdlib.vcproj
    similarity index 100%
    rename from build/VS2005/zstdlib/zstdlib.vcproj
    rename to contrib/VS2005/zstdlib/zstdlib.vcproj
    
    From 306701a44773a31380b4132ee6f059257613b887 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 1 Jun 2017 21:25:39 -0700
    Subject: [PATCH 121/400] adding zstd/zstd.vcproj because it was ignored during
     initial commit
    
    ---
     contrib/VS2005/zstd/zstd.vcproj | 548 ++++++++++++++++++++++++++++++++
     1 file changed, 548 insertions(+)
     create mode 100644 contrib/VS2005/zstd/zstd.vcproj
    
    diff --git a/contrib/VS2005/zstd/zstd.vcproj b/contrib/VS2005/zstd/zstd.vcproj
    new file mode 100644
    index 000000000..46cabbf6e
    --- /dev/null
    +++ b/contrib/VS2005/zstd/zstd.vcproj
    @@ -0,0 +1,548 @@
    +
    +
    +	
    +		
    +		
    +	
    +	
    +	
    +	
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +	
    +	
    +	
    +	
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +		
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +			
    +		
    +	
    +	
    +	
    +
    
    From 0ff9873324261d564eb2d884b73d7cd1644a7030 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 2 Jun 2017 10:11:03 -0700
    Subject: [PATCH 122/400] Removed VS2005 from the list of included projects
    
    ---
     build/README.md | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/build/README.md b/build/README.md
    index c4abe9efd..5a9cb1261 100644
    --- a/build/README.md
    +++ b/build/README.md
    @@ -5,7 +5,6 @@ Projects for various integrated development environments (IDE)
     
     The following projects are included with the zstd distribution:
     - `cmake` - CMake project contributed by Artyom Dymchenko
    -- `VS2005` - Visual Studio 2005 project
     - `VS2008` - Visual Studio 2008 project
     - `VS2010` - Visual Studio 2010 project (which also works well with Visual Studio 2012, 2013, 2015)
     - `VS_scripts` - command line scripts prepared for Visual Studio compilation without IDE
    
    From fa398bbed71811e5e4b4afb7b69fb5ec7964fb94 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 2 Jun 2017 10:25:30 -0700
    Subject: [PATCH 123/400] added back documentation/notification for VS2005 in
     build directory
    
    ---
     build/README.md | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/build/README.md b/build/README.md
    index 5a9cb1261..23f92cef1 100644
    --- a/build/README.md
    +++ b/build/README.md
    @@ -5,6 +5,7 @@ Projects for various integrated development environments (IDE)
     
     The following projects are included with the zstd distribution:
     - `cmake` - CMake project contributed by Artyom Dymchenko
    +- `VS2005` - Visual Studio 2005 Project (this project has been moved to the contrib directory and will no longer be supported)
     - `VS2008` - Visual Studio 2008 project
     - `VS2010` - Visual Studio 2010 project (which also works well with Visual Studio 2012, 2013, 2015)
     - `VS_scripts` - command line scripts prepared for Visual Studio compilation without IDE
    
    From d75c4ddb1be2d36f755e7f079821568471828975 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 2 Jun 2017 10:28:56 -0700
    Subject: [PATCH 124/400] added a project support notice for VS2005
    
    ---
     contrib/VS2005/README.md | 3 +++
     1 file changed, 3 insertions(+)
     create mode 100644 contrib/VS2005/README.md
    
    diff --git a/contrib/VS2005/README.md b/contrib/VS2005/README.md
    new file mode 100644
    index 000000000..ec1ef68a0
    --- /dev/null
    +++ b/contrib/VS2005/README.md
    @@ -0,0 +1,3 @@
    +## Project Support Notice
    +
    +The VS2005 Project directory has been moved to the contrib directory in order to indicate that it will no longer be supported.
    
    From 6056e4c3eb55ab7c5000818a4457241b9ccb2019 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 11:36:47 -0700
    Subject: [PATCH 125/400] added POOL_sizeof() for single-thread
    
    ---
     lib/common/pool.c | 5 +++++
     1 file changed, 5 insertions(+)
    
    diff --git a/lib/common/pool.c b/lib/common/pool.c
    index 05adcf1ce..749fa4f2f 100644
    --- a/lib/common/pool.c
    +++ b/lib/common/pool.c
    @@ -198,4 +198,9 @@ void POOL_add(void *ctx, POOL_function function, void *opaque) {
       function(opaque);
     }
     
    +size_t POOL_sizeof(POOL_ctx *ctx) {
    +    if (ctx==NULL) return 0;  /* supports sizeof NULL */
    +    return sizeof(*ctx);
    +}
    +
     #endif  /* ZSTD_MULTITHREAD */
    
    From b877e834b1f349f6861baaf237b38a4547c80ace Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 13:47:11 -0700
    Subject: [PATCH 126/400] minor indent
    
    ---
     lib/compress/zstdmt_compress.h | 9 ++++-----
     1 file changed, 4 insertions(+), 5 deletions(-)
    
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index 336215995..adbb7dfe3 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -32,16 +32,15 @@ ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads,
     ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);
     
     ZSTDLIB_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);
    -ZSTDLIB_API size_t ZSTDMT_estimateCCtxSize(ZSTD_compressionParameters cParams,
    -                                           unsigned nbThreads);   /* not ready yet */
    +ZSTDLIB_API size_t ZSTDMT_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned nbThreads);   /* not ready yet */
     
     
     /* ===   Simple buffer-to-butter one-pass function   === */
     
     ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
    -                           void* dst, size_t dstCapacity,
    -                     const void* src, size_t srcSize,
    -                           int compressionLevel);
    +                                       void* dst, size_t dstCapacity,
    +                                 const void* src, size_t srcSize,
    +                                       int compressionLevel);
     
     
     /* ===   Streaming functions   === */
    
    From dcb7535352df45c52149ea6d82b5569a08e005ae Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 14:01:21 -0700
    Subject: [PATCH 127/400] ensure zlibwrapper uses ZSTD_malloc() and ZSTD_free()
    
    which is compatible with { NULL, NULL, NULL }
    ---
     lib/common/zstd_common.c       |  2 +-
     zlibWrapper/zstd_zlibwrapper.c | 54 ++++++++++++++++------------------
     2 files changed, 27 insertions(+), 29 deletions(-)
    
    diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
    index 801483960..93187d5c0 100644
    --- a/lib/common/zstd_common.c
    +++ b/lib/common/zstd_common.c
    @@ -61,7 +61,7 @@ void* ZSTD_calloc(size_t size, ZSTD_customMem customMem)
     {
         if (customMem.customAlloc) {
             /* calloc implemented as malloc+memset;
    -         * not as efficient, but our best guess for custom malloc */
    +         * not as efficient as calloc, but next best guess for custom malloc */
             void* const ptr = customMem.customAlloc(customMem.opaque, size);
             memset(ptr, 0, size);
             return ptr;
    diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c
    index a078cf556..7a0b09db6 100644
    --- a/zlibWrapper/zstd_zlibwrapper.c
    +++ b/zlibWrapper/zstd_zlibwrapper.c
    @@ -17,7 +17,7 @@
     #include "zstd_zlibwrapper.h"
     #define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_MAGICNUMBER */
     #include "zstd.h"
    -#include "zstd_internal.h"         /* defaultCustomMem */
    +#include "zstd_internal.h"         /* ZSTD_malloc, ZSTD_free */
     
     
     #define Z_INFLATE_SYNC              8
    @@ -100,7 +100,7 @@ size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
     {
         if (zwc==NULL) return 0;   /* support free on NULL */
         if (zwc->zbc) ZSTD_freeCStream(zwc->zbc);
    -    zwc->customMem.customFree(zwc->customMem.opaque, zwc);
    +    ZSTD_free(zwc, zwc->customMem);
         return 0;
     }
     
    @@ -472,8 +472,8 @@ size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
     {
         if (zwd==NULL) return 0;   /* support free on null */
         if (zwd->zbd) ZSTD_freeDStream(zwd->zbd);
    -    if (zwd->version) zwd->customMem.customFree(zwd->customMem.opaque, zwd->version);
    -    zwd->customMem.customFree(zwd->customMem.opaque, zwd);
    +    ZSTD_free(zwd->version, zwd->customMem);
    +    ZSTD_free(zwd, zwd->customMem);
         return 0;
     }
     
    @@ -505,22 +505,21 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
             return inflateInit(strm);
         }
     
    -    {
    -    ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
    -    LOG_WRAPPERD("- inflateInit\n");
    -    if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
    +    {   ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
    +        LOG_WRAPPERD("- inflateInit\n");
    +        if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
     
    -    zwd->version = zwd->customMem.customAlloc(zwd->customMem.opaque, strlen(version) + 1);
    -    if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
    -    strcpy(zwd->version, version);
    +        zwd->version = ZSTD_malloc(strlen(version)+1, zwd->customMem);
    +        if (zwd->version == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
    +        strcpy(zwd->version, version);
     
    -    zwd->stream_size = stream_size;
    -    zwd->totalInBytes = 0;
    -    strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
    -    strm->total_in = 0;
    -    strm->total_out = 0;
    -    strm->reserved = ZWRAP_UNKNOWN_STREAM; /* mark as unknown steam */
    -    strm->adler = 0;
    +        zwd->stream_size = stream_size;
    +        zwd->totalInBytes = 0;
    +        strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
    +        strm->total_in = 0;
    +        strm->total_out = 0;
    +        strm->reserved = ZWRAP_UNKNOWN_STREAM; /* mark as unknown steam */
    +        strm->adler = 0;
         }
     
         return Z_OK;
    @@ -534,15 +533,14 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int  windowBits,
             return inflateInit2_(strm, windowBits, version, stream_size);
         }
     
    -    {
    -    int ret = z_inflateInit_ (strm, version, stream_size);
    -    LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits);
    -    if (ret == Z_OK) {
    -        ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
    -        if (zwd == NULL) return Z_STREAM_ERROR;
    -        zwd->windowBits = windowBits;
    -    }
    -    return ret;
    +    {   int ret = z_inflateInit_ (strm, version, stream_size);
    +        LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits);
    +        if (ret == Z_OK) {
    +            ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state;
    +            if (zwd == NULL) return Z_STREAM_ERROR;
    +            zwd->windowBits = windowBits;
    +        }
    +        return ret;
         }
     }
     
    @@ -552,7 +550,7 @@ int ZWRAP_inflateReset_keepDict(z_streamp strm)
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
             return inflateReset(strm);
     
    -    {   ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
    +    {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
             if (zwd == NULL) return Z_STREAM_ERROR;
             ZWRAP_initDCtx(zwd);
             zwd->decompState = ZWRAP_useReset;
    
    From 4effccbf56588582ff7963f023018c9f82bcbc07 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 14:24:58 -0700
    Subject: [PATCH 128/400] zlib_wrapper's uncompress() uses ZSTD_isFrame() for
     routing
    
    more generic and safer than using own routing for magic number comparison
    ---
     lib/common/zstd_common.c         |  2 +-
     lib/decompress/zstd_decompress.c | 16 +++++++---------
     zlibWrapper/zstd_zlibwrapper.c   | 16 ++++++++--------
     3 files changed, 16 insertions(+), 18 deletions(-)
    
    diff --git a/lib/common/zstd_common.c b/lib/common/zstd_common.c
    index 93187d5c0..f68167238 100644
    --- a/lib/common/zstd_common.c
    +++ b/lib/common/zstd_common.c
    @@ -22,7 +22,7 @@
     /*-****************************************
     *  Version
     ******************************************/
    -unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
    +unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; }
     
     const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }
     
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 7dfcddb1b..766ff0ff6 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -204,16 +204,14 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
     
     ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
     {
    -    ZSTD_DCtx* dctx;
    +    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
    -    if (!customMem.customAlloc ^ !customMem.customFree)
    -        return NULL;
    -
    -    dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
    -    if (!dctx) return NULL;
    -    memcpy(&dctx->customMem, &customMem, sizeof(customMem));
    -    ZSTD_initDCtx_internal(dctx);
    -    return dctx;
    +    {   ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
    +        if (!dctx) return NULL;
    +        dctx->customMem = customMem;
    +        ZSTD_initDCtx_internal(dctx);
    +        return dctx;
    +    }
     }
     
     ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
    diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c
    index 7a0b09db6..ed68a8a07 100644
    --- a/zlibWrapper/zstd_zlibwrapper.c
    +++ b/zlibWrapper/zstd_zlibwrapper.c
    @@ -15,7 +15,7 @@
     #define ZLIB_CONST
     #include                   /* without #define Z_PREFIX */
     #include "zstd_zlibwrapper.h"
    -#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_MAGICNUMBER */
    +#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_isFrame, ZSTD_MAGICNUMBER */
     #include "zstd.h"
     #include "zstd_internal.h"         /* ZSTD_malloc, ZSTD_free */
     
    @@ -1004,9 +1004,9 @@ ZEXTERN int ZEXPORT z_compress2 OF((Bytef *dest,   uLongf *destLen,
             return compress2(dest, destLen, source, sourceLen, level);
     
         { size_t dstCapacity = *destLen;
    -      size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
    -      if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
    -      *destLen = errorCode;
    +      size_t const cSize = ZSTD_compress(dest, dstCapacity, source, sourceLen, level);
    +      if (ZSTD_isError(cSize)) return Z_STREAM_ERROR;
    +      *destLen = cSize;
         }
         return Z_OK;
     }
    @@ -1024,13 +1024,13 @@ ZEXTERN uLong ZEXPORT z_compressBound OF((uLong sourceLen))
     ZEXTERN int ZEXPORT z_uncompress OF((Bytef *dest,   uLongf *destLen,
                                        const Bytef *source, uLong sourceLen))
     {
    -    if (sourceLen < 4 || MEM_readLE32(source) != ZSTD_MAGICNUMBER)
    +    if (!ZSTD_isFrame(source, sourceLen))
             return uncompress(dest, destLen, source, sourceLen);
     
         { size_t dstCapacity = *destLen;
    -      size_t const errorCode = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
    -      if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
    -      *destLen = errorCode;
    +      size_t const dSize = ZSTD_decompress(dest, dstCapacity, source, sourceLen);
    +      if (ZSTD_isError(dSize)) return Z_STREAM_ERROR;
    +      *destLen = dSize;
          }
         return Z_OK;
     }
    
    From 33a7e679e501005658c8a8ff81fae5d24f4d9eaa Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 17:10:49 -0700
    Subject: [PATCH 129/400] significant zlib wrapper code refactoring
    
    code indentation
    variable scope and names
    constify
    
    Only coding style changes.
    The logic should remain the same.
    ---
     lib/decompress/zstd_decompress.c |   2 +-
     zlibWrapper/Makefile             |  15 +-
     zlibWrapper/zstd_zlibwrapper.c   | 558 ++++++++++++++++---------------
     3 files changed, 305 insertions(+), 270 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 766ff0ff6..33a905a20 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -1659,7 +1659,7 @@ size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const
     
     size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
    -#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
    +#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
         size_t regenSize;
         ZSTD_DCtx* const dctx = ZSTD_createDCtx();
         if (dctx==NULL) return ERROR(memory_allocation);
    diff --git a/zlibWrapper/Makefile b/zlibWrapper/Makefile
    index 5a6378767..4e8fb4a32 100644
    --- a/zlibWrapper/Makefile
    +++ b/zlibWrapper/Makefile
    @@ -18,9 +18,12 @@ EXAMPLE_PATH = examples
     PROGRAMS_PATH = ../programs
     TEST_FILE = ../doc/zstd_compression_format.md
     
    -CPPFLAGS = -DXXH_NAMESPACE=ZSTD_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH) -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH)
    +CPPFLAGS = -DXXH_NAMESPACE=ZSTD_ -I$(ZLIB_PATH) -I$(PROGRAMS_PATH)       \
    +           -I$(ZSTDLIBDIR) -I$(ZSTDLIBDIR)/common -I$(ZLIBWRAPPER_PATH)
     CFLAGS  ?= $(MOREFLAGS) -O3 -std=gnu99
    -CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes -Wundef -Wstrict-aliasing=1
    +CFLAGS  += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wswitch-enum \
    +           -Wdeclaration-after-statement -Wstrict-prototypes -Wundef     \
    +           -Wstrict-aliasing=1
     
     
     # Define *.exe as extension for Windows systems
    @@ -48,8 +51,8 @@ test: example fitblk example_zstd fitblk_zstd zwrapbench minigzip minigzip_zstd
     	#cp example$(EXT).gz example$(EXT)_gz.gz
     	./minigzip_zstd -d example$(EXT).gz
     	@echo ---- minigzip end ----
    -	./zwrapbench -qb3B1K $(TEST_FILE)
    -	./zwrapbench -rqb1e5 ../lib ../programs ../tests
    +	./zwrapbench -qi1b3B1K $(TEST_FILE)
    +	./zwrapbench -rqi1b1e5 ../lib ../programs ../tests
     
     #valgrindTest: ZSTDLIBRARY = $(ZSTDLIBDIR)/libzstd.so
     valgrindTest: VALGRIND = LD_LIBRARY_PATH=$(ZSTDLIBDIR) valgrind --track-origins=yes --leak-check=full --error-exitcode=1
    @@ -61,8 +64,8 @@ valgrindTest: clean example fitblk example_zstd fitblk_zstd zwrapbench
     	$(VALGRIND) ./fitblk 40960 <$(TEST_FILE)
     	$(VALGRIND) ./fitblk_zstd 10240 <$(TEST_FILE)
     	$(VALGRIND) ./fitblk_zstd 40960 <$(TEST_FILE)
    -	$(VALGRIND) ./zwrapbench -qb3B1K $(TEST_FILE)
    -	$(VALGRIND) ./zwrapbench -rqb1e5 ../lib ../programs ../tests
    +	$(VALGRIND) ./zwrapbench -qi1b3B1K $(TEST_FILE)
    +	$(VALGRIND) ./zwrapbench -rqi1b1e5 ../lib ../programs ../tests
     
     #.c.o:
     #	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
    diff --git a/zlibWrapper/zstd_zlibwrapper.c b/zlibWrapper/zstd_zlibwrapper.c
    index ed68a8a07..ade3b88cd 100644
    --- a/zlibWrapper/zstd_zlibwrapper.c
    +++ b/zlibWrapper/zstd_zlibwrapper.c
    @@ -8,6 +8,13 @@
      */
     
     
    +/* ===   Tuning parameters   === */
    +#ifndef ZWRAP_USE_ZSTD
    +    #define ZWRAP_USE_ZSTD 0
    +#endif
    +
    +
    +/* ===   Dependencies   === */
     #include 
     #include                  /* vsprintf */
     #include                 /* va_list, for z_gzprintf */
    @@ -20,24 +27,23 @@
     #include "zstd_internal.h"         /* ZSTD_malloc, ZSTD_free */
     
     
    +/* ===   Constants   === */
     #define Z_INFLATE_SYNC              8
     #define ZLIB_HEADERSIZE             4
     #define ZSTD_HEADERSIZE             ZSTD_frameHeaderSize_min
     #define ZWRAP_DEFAULT_CLEVEL        3   /* Z_DEFAULT_COMPRESSION is translated to ZWRAP_DEFAULT_CLEVEL for zstd */
     
    -#define LOG_WRAPPERC(...)  /* printf(__VA_ARGS__) */
    -#define LOG_WRAPPERD(...)  /* printf(__VA_ARGS__) */
    +
    +/* ===   Debug   === */
    +#define LOG_WRAPPERC(...)  /* fprintf(stderr, __VA_ARGS__) */
    +#define LOG_WRAPPERD(...)  /* fprintf(stderr, __VA_ARGS__) */
     
     #define FINISH_WITH_GZ_ERR(msg) { (void)msg; return Z_STREAM_ERROR; }
     #define FINISH_WITH_NULL_ERR(msg) { (void)msg; return NULL; }
     
     
    -
    -#ifndef ZWRAP_USE_ZSTD
    -    #define ZWRAP_USE_ZSTD 0
    -#endif
    -
    -static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD;   /* 0 = don't use ZSTD */
    +/* ===   Wrapper   === */
    +static int g_ZWRAP_useZSTDcompression = ZWRAP_USE_ZSTD; /* 0 = don't use ZSTD */
     
     void ZWRAP_useZSTDcompression(int turn_on) { g_ZWRAP_useZSTDcompression = turn_on; }
     
    @@ -63,7 +69,7 @@ static void* ZWRAP_allocFunction(void* opaque, size_t size)
     {
         z_streamp strm = (z_streamp) opaque;
         void* address = strm->zalloc(strm->opaque, 1, (uInt)size);
    -  /*  printf("ZWRAP alloc %p, %d \n", address, (int)size); */
    +    /* LOG_WRAPPERC("ZWRAP alloc %p, %d \n", address, (int)size); */
         return address;
     }
     
    @@ -71,12 +77,12 @@ static void ZWRAP_freeFunction(void* opaque, void* address)
     {
         z_streamp strm = (z_streamp) opaque;
         strm->zfree(strm->opaque, address);
    -   /* if (address) printf("ZWRAP free %p \n", address); */
    +   /* if (address) LOG_WRAPPERC("ZWRAP free %p \n", address); */
     }
     
     
     
    -/* *** Compression *** */
    +/* ===   Compression   === */
     typedef enum { ZWRAP_useInit, ZWRAP_useReset, ZWRAP_streamEnd } ZWRAP_state_t;
     
     typedef struct {
    @@ -96,16 +102,16 @@ typedef ZWRAP_CCtx internal_state;
     
     
     
    -size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
    +static size_t ZWRAP_freeCCtx(ZWRAP_CCtx* zwc)
     {
         if (zwc==NULL) return 0;   /* support free on NULL */
    -    if (zwc->zbc) ZSTD_freeCStream(zwc->zbc);
    +    ZSTD_freeCStream(zwc->zbc);
         ZSTD_free(zwc, zwc->customMem);
         return 0;
     }
     
     
    -ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
    +static ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
     {
         ZWRAP_CCtx* zwc;
     
    @@ -114,9 +120,8 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
             if (zwc==NULL) return NULL;
             memset(zwc, 0, sizeof(ZWRAP_CCtx));
             memcpy(&zwc->allocFunc, strm, sizeof(z_stream));
    -        { ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwc->allocFunc };
    -          memcpy(&zwc->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
    -        }
    +        { ZSTD_customMem const ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwc->allocFunc };
    +          zwc->customMem = ZWRAP_customMem; }
         } else {
             zwc = (ZWRAP_CCtx*)calloc(1, sizeof(*zwc));
             if (zwc==NULL) return NULL;
    @@ -126,23 +131,25 @@ ZWRAP_CCtx* ZWRAP_createCCtx(z_streamp strm)
     }
     
     
    -int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize)
    +static int ZWRAP_initializeCStream(ZWRAP_CCtx* zwc, const void* dict, size_t dictSize, unsigned long long pledgedSrcSize)
     {
         LOG_WRAPPERC("- ZWRAP_initializeCStream=%p\n", zwc);
         if (zwc == NULL || zwc->zbc == NULL) return Z_STREAM_ERROR;
     
         if (!pledgedSrcSize) pledgedSrcSize = zwc->pledgedSrcSize;
    -    { ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize);
    -      size_t errorCode;
    -      LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n", (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy);
    -      errorCode = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize);
    -      if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR; }
    +    {   ZSTD_parameters const params = ZSTD_getParams(zwc->compressionLevel, pledgedSrcSize, dictSize);
    +        size_t initErr;
    +        LOG_WRAPPERC("pledgedSrcSize=%d windowLog=%d chainLog=%d hashLog=%d searchLog=%d searchLength=%d strategy=%d\n",
    +                    (int)pledgedSrcSize, params.cParams.windowLog, params.cParams.chainLog, params.cParams.hashLog, params.cParams.searchLog, params.cParams.searchLength, params.cParams.strategy);
    +        initErr = ZSTD_initCStream_advanced(zwc->zbc, dict, dictSize, params, pledgedSrcSize);
    +        if (ZSTD_isError(initErr)) return Z_STREAM_ERROR;
    +    }
     
         return Z_OK;
     }
     
     
    -int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error)
    +static int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error)
     {
         LOG_WRAPPERC("- ZWRAPC_finishWithError=%d\n", error);
         if (zwc) ZWRAP_freeCCtx(zwc);
    @@ -151,7 +158,7 @@ int ZWRAPC_finishWithError(ZWRAP_CCtx* zwc, z_streamp strm, int error)
     }
     
     
    -int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message)
    +static int ZWRAPC_finishWithErrorMsg(z_streamp strm, char* message)
     {
         ZWRAP_CCtx* zwc = (ZWRAP_CCtx*) strm->state;
         strm->msg = message;
    @@ -276,34 +283,36 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
         ZWRAP_CCtx* zwc;
     
         if (!g_ZWRAP_useZSTDcompression) {
    -        int res;
    -        LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
    -        res = deflate(strm, flush);
    -        return res;
    +        LOG_WRAPPERC("- deflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
    +                    (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
    +        return deflate(strm, flush);
         }
     
         zwc = (ZWRAP_CCtx*) strm->state;
         if (zwc == NULL) { LOG_WRAPPERC("zwc == NULL\n"); return Z_STREAM_ERROR; }
     
         if (zwc->zbc == NULL) {
    -        int res;
             zwc->zbc = ZSTD_createCStream_advanced(zwc->customMem);
             if (zwc->zbc == NULL) return ZWRAPC_finishWithError(zwc, strm, 0);
    -        res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
    -        if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res);
    +        { int const initErr = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
    +          if (initErr != Z_OK) return ZWRAPC_finishWithError(zwc, strm, initErr); }
             if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
         } else {
             if (zwc->totalInBytes == 0) {
                 if (zwc->comprState == ZWRAP_useReset) {
    -                size_t const errorCode = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
    -                if (ZSTD_isError(errorCode)) { LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); return ZWRAPC_finishWithError(zwc, strm, 0); }
    +                size_t const resetErr = ZSTD_resetCStream(zwc->zbc, (flush == Z_FINISH) ? strm->avail_in : zwc->pledgedSrcSize);
    +                if (ZSTD_isError(resetErr)) {
    +                    LOG_WRAPPERC("ERROR: ZSTD_resetCStream errorCode=%s\n",
    +                                ZSTD_getErrorName(resetErr));
    +                    return ZWRAPC_finishWithError(zwc, strm, 0);
    +                }
                 } else {
    -                int res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
    +                int const res = ZWRAP_initializeCStream(zwc, NULL, 0, (flush == Z_FINISH) ? strm->avail_in : 0);
                     if (res != Z_OK) return ZWRAPC_finishWithError(zwc, strm, res);
                     if (flush != Z_FINISH) zwc->comprState = ZWRAP_useReset;
                 }
    -        }
    -    }
    +        }  /* (zwc->totalInBytes == 0) */
    +    }  /* ! (zwc->zbc == NULL) */
     
         LOG_WRAPPERC("- deflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
         if (strm->avail_in > 0) {
    @@ -313,9 +322,9 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
             zwc->outBuffer.dst = strm->next_out;
             zwc->outBuffer.size = strm->avail_out;
             zwc->outBuffer.pos = 0;
    -        { size_t const errorCode = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer);
    +        { size_t const cErr = ZSTD_compressStream(zwc->zbc, &zwc->outBuffer, &zwc->inBuffer);
               LOG_WRAPPERC("deflate ZSTD_compressStream srcSize=%d dstCapacity=%d\n", (int)zwc->inBuffer.size, (int)zwc->outBuffer.size);
    -          if (ZSTD_isError(errorCode)) return ZWRAPC_finishWithError(zwc, strm, 0);
    +          if (ZSTD_isError(cErr)) return ZWRAPC_finishWithError(zwc, strm, 0);
             }
             strm->next_out += zwc->outBuffer.pos;
             strm->total_out += zwc->outBuffer.pos;
    @@ -345,8 +354,12 @@ ZEXTERN int ZEXPORT z_deflate OF((z_streamp strm, int flush))
             strm->next_out += zwc->outBuffer.pos;
             strm->total_out += zwc->outBuffer.pos;
             strm->avail_out -= zwc->outBuffer.pos;
    -        if (bytesLeft == 0) { zwc->streamEnd = 1; LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n", (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out); return Z_STREAM_END; }
    -    }
    +        if (bytesLeft == 0) {
    +            zwc->streamEnd = 1;
    +            LOG_WRAPPERC("Z_STREAM_END2 strm->total_in=%d strm->avail_out=%d strm->total_out=%d\n",
    +                        (int)strm->total_in, (int)strm->avail_out, (int)strm->total_out);
    +            return Z_STREAM_END;
    +    }   }
         else
         if (flush == Z_SYNC_FLUSH || flush == Z_PARTIAL_FLUSH) {
             size_t bytesLeft;
    @@ -409,12 +422,13 @@ ZEXTERN int ZEXPORT z_deflateParams OF((z_streamp strm,
     
     
     
    -/* *** Decompression *** */
    +/* ===   Decompression   === */
    +
     typedef enum { ZWRAP_ZLIB_STREAM, ZWRAP_ZSTD_STREAM, ZWRAP_UNKNOWN_STREAM } ZWRAP_stream_type;
     
     typedef struct {
         ZSTD_DStream* zbd;
    -    char headerBuf[16]; /* should be equal or bigger than ZSTD_frameHeaderSize_min */
    +    char headerBuf[16];   /* must be >= ZSTD_frameHeaderSize_min */
         int errorCount;
         unsigned long long totalInBytes; /* we need it as strm->total_in can be reset by user */
         ZWRAP_state_t decompState;
    @@ -426,10 +440,48 @@ typedef struct {
         char *version;
         int windowBits;
         ZSTD_customMem customMem;
    -    z_stream allocFunc; /* copy of zalloc, zfree, opaque */
    +    z_stream allocFunc; /* just to copy zalloc, zfree, opaque */
     } ZWRAP_DCtx;
     
     
    +static void ZWRAP_initDCtx(ZWRAP_DCtx* zwd)
    +{
    +    zwd->errorCount = 0;
    +    zwd->outBuffer.pos = 0;
    +    zwd->outBuffer.size = 0;
    +}
    +
    +static ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
    +{
    +    ZWRAP_DCtx* zwd;
    +    MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_FRAMEHEADERSIZE_MIN);   /* check static buffer size condition */
    +
    +    if (strm->zalloc && strm->zfree) {
    +        zwd = (ZWRAP_DCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_DCtx));
    +        if (zwd==NULL) return NULL;
    +        memset(zwd, 0, sizeof(ZWRAP_DCtx));
    +        zwd->allocFunc = *strm;  /* just to copy zalloc, zfree & opaque */
    +        { ZSTD_customMem const ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwd->allocFunc };
    +          zwd->customMem = ZWRAP_customMem; }
    +    } else {
    +        zwd = (ZWRAP_DCtx*)calloc(1, sizeof(*zwd));
    +        if (zwd==NULL) return NULL;
    +    }
    +
    +    ZWRAP_initDCtx(zwd);
    +    return zwd;
    +}
    +
    +static size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
    +{
    +    if (zwd==NULL) return 0;   /* support free on null */
    +    ZSTD_freeDStream(zwd->zbd);
    +    ZSTD_free(zwd->version, zwd->customMem);
    +    ZSTD_free(zwd, zwd->customMem);
    +    return 0;
    +}
    +
    +
     int ZWRAP_isUsingZSTDdecompression(z_streamp strm)
     {
         if (strm == NULL) return 0;
    @@ -437,59 +489,17 @@ int ZWRAP_isUsingZSTDdecompression(z_streamp strm)
     }
     
     
    -void ZWRAP_initDCtx(ZWRAP_DCtx* zwd)
    -{
    -    zwd->errorCount = 0;
    -    zwd->outBuffer.pos = 0;
    -    zwd->outBuffer.size = 0;
    -}
    -
    -
    -ZWRAP_DCtx* ZWRAP_createDCtx(z_streamp strm)
    -{
    -    ZWRAP_DCtx* zwd;
    -
    -    if (strm->zalloc && strm->zfree) {
    -        zwd = (ZWRAP_DCtx*)strm->zalloc(strm->opaque, 1, sizeof(ZWRAP_DCtx));
    -        if (zwd==NULL) return NULL;
    -        memset(zwd, 0, sizeof(ZWRAP_DCtx));
    -        memcpy(&zwd->allocFunc, strm, sizeof(z_stream));
    -        { ZSTD_customMem ZWRAP_customMem = { ZWRAP_allocFunction, ZWRAP_freeFunction, &zwd->allocFunc };
    -          memcpy(&zwd->customMem, &ZWRAP_customMem, sizeof(ZSTD_customMem));
    -        }
    -    } else {
    -        zwd = (ZWRAP_DCtx*)calloc(1, sizeof(*zwd));
    -        if (zwd==NULL) return NULL;
    -    }
    -
    -    MEM_STATIC_ASSERT(sizeof(zwd->headerBuf) >= ZSTD_FRAMEHEADERSIZE_MIN);   /* if compilation fails here, assertion is false */
    -    ZWRAP_initDCtx(zwd);
    -    return zwd;
    -}
    -
    -
    -size_t ZWRAP_freeDCtx(ZWRAP_DCtx* zwd)
    -{
    -    if (zwd==NULL) return 0;   /* support free on null */
    -    if (zwd->zbd) ZSTD_freeDStream(zwd->zbd);
    -    ZSTD_free(zwd->version, zwd->customMem);
    -    ZSTD_free(zwd, zwd->customMem);
    -    return 0;
    -}
    -
    -
    -int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error)
    +static int ZWRAPD_finishWithError(ZWRAP_DCtx* zwd, z_streamp strm, int error)
     {
         LOG_WRAPPERD("- ZWRAPD_finishWithError=%d\n", error);
    -    if (zwd) ZWRAP_freeDCtx(zwd);
    -    if (strm) strm->state = NULL;
    +    ZWRAP_freeDCtx(zwd);
    +    strm->state = NULL;
         return (error) ? error : Z_STREAM_ERROR;
     }
     
    -
    -int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message)
    +static int ZWRAPD_finishWithErrorMsg(z_streamp strm, char* message)
     {
    -    ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
    +    ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
         strm->msg = message;
         if (zwd == NULL) return Z_STREAM_ERROR;
     
    @@ -501,11 +511,11 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
                                          const char *version, int stream_size))
     {
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB) {
    -        strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
    +        strm->reserved = ZWRAP_ZLIB_STREAM;
             return inflateInit(strm);
         }
     
    -    {   ZWRAP_DCtx* zwd = ZWRAP_createDCtx(strm);
    +    {   ZWRAP_DCtx* const zwd = ZWRAP_createDCtx(strm);
             LOG_WRAPPERD("- inflateInit\n");
             if (zwd == NULL) return ZWRAPD_finishWithError(zwd, strm, 0);
     
    @@ -515,10 +525,10 @@ ZEXTERN int ZEXPORT z_inflateInit_ OF((z_streamp strm,
     
             zwd->stream_size = stream_size;
             zwd->totalInBytes = 0;
    -        strm->state = (struct internal_state*) zwd; /* use state which in not used by user */
    +        strm->state = (struct internal_state*) zwd;
             strm->total_in = 0;
             strm->total_out = 0;
    -        strm->reserved = ZWRAP_UNKNOWN_STREAM; /* mark as unknown steam */
    +        strm->reserved = ZWRAP_UNKNOWN_STREAM;
             strm->adler = 0;
         }
     
    @@ -533,7 +543,7 @@ ZEXTERN int ZEXPORT z_inflateInit2_ OF((z_streamp strm, int  windowBits,
             return inflateInit2_(strm, windowBits, version, stream_size);
         }
     
    -    {   int ret = z_inflateInit_ (strm, version, stream_size);
    +    {   int const ret = z_inflateInit_ (strm, version, stream_size);
             LOG_WRAPPERD("- inflateInit2 windowBits=%d\n", windowBits);
             if (ret == Z_OK) {
                 ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state;
    @@ -569,10 +579,10 @@ ZEXTERN int ZEXPORT z_inflateReset OF((z_streamp strm))
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
             return inflateReset(strm);
     
    -    { int ret = ZWRAP_inflateReset_keepDict(strm);
    +    { int const ret = ZWRAP_inflateReset_keepDict(strm);
           if (ret != Z_OK) return ret; }
     
    -    { ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
    +    { ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
           if (zwd == NULL) return Z_STREAM_ERROR;
           zwd->decompState = ZWRAP_useInit; }
     
    @@ -587,9 +597,9 @@ ZEXTERN int ZEXPORT z_inflateReset2 OF((z_streamp strm,
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
             return inflateReset2(strm, windowBits);
     
    -    {   int ret = z_inflateReset (strm);
    +    {   int const ret = z_inflateReset (strm);
             if (ret == Z_OK) {
    -            ZWRAP_DCtx* zwd = (ZWRAP_DCtx*)strm->state;
    +            ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*)strm->state;
                 if (zwd == NULL) return Z_STREAM_ERROR;
                 zwd->windowBits = windowBits;
             }
    @@ -607,11 +617,10 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
             return inflateSetDictionary(strm, dictionary, dictLength);
     
    -    {   size_t errorCode;
    -        ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
    +    {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
             if (zwd == NULL || zwd->zbd == NULL) return Z_STREAM_ERROR;
    -        errorCode = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength);
    -        if (ZSTD_isError(errorCode)) return ZWRAPD_finishWithError(zwd, strm, 0);
    +        { size_t const initErr = ZSTD_initDStream_usingDict(zwd->zbd, dictionary, dictLength);
    +          if (ZSTD_isError(initErr)) return ZWRAPD_finishWithError(zwd, strm, 0); }
             zwd->decompState = ZWRAP_useReset;
     
             if (zwd->totalInBytes == ZSTD_HEADERSIZE) {
    @@ -621,14 +630,14 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
                 zwd->outBuffer.dst = strm->next_out;
                 zwd->outBuffer.size = 0;
                 zwd->outBuffer.pos = 0;
    -            errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    -            LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
    -            if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) {
    -                LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n", ZSTD_getErrorName(errorCode));
    -                return ZWRAPD_finishWithError(zwd, strm, 0);
    -            }
    -        }
    -    }
    +            {   size_t const errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    +                LOG_WRAPPERD("inflateSetDictionary ZSTD_decompressStream errorCode=%d srcSize=%d dstCapacity=%d\n",
    +                             (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
    +                if (zwd->inBuffer.pos < zwd->outBuffer.size || ZSTD_isError(errorCode)) {
    +                    LOG_WRAPPERD("ERROR: ZSTD_decompressStream %s\n",
    +                                 ZSTD_getErrorName(errorCode));
    +                    return ZWRAPD_finishWithError(zwd, strm, 0);
    +    }   }   }   }
     
         return Z_OK;
     }
    @@ -637,156 +646,175 @@ ZEXTERN int ZEXPORT z_inflateSetDictionary OF((z_streamp strm,
     ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
     {
         ZWRAP_DCtx* zwd;
    -    int res;
    +
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved) {
    -        LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
    -        res = inflate(strm, flush);
    -        LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
    -        return res;
    +        int const result = inflate(strm, flush);
    +        LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
    +                     (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, result);
    +        return result;
         }
     
         if (strm->avail_in <= 0) return Z_OK;
     
    -    {   size_t errorCode, srcSize;
    -        zwd = (ZWRAP_DCtx*) strm->state;
    -        LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
    +    zwd = (ZWRAP_DCtx*) strm->state;
    +    LOG_WRAPPERD("- inflate1 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
    +                 (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
     
    -        if (zwd == NULL) return Z_STREAM_ERROR;
    -        if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END;
    +    if (zwd == NULL) return Z_STREAM_ERROR;
    +    if (zwd->decompState == ZWRAP_streamEnd) return Z_STREAM_END;
     
    -        if (zwd->totalInBytes < ZLIB_HEADERSIZE) {
    -            if (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) {
    -                if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) {
    -                    if (zwd->windowBits)
    -                        errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
    -                    else
    -                        errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
    -
    -                    strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
    -                    errorCode = ZWRAP_freeDCtx(zwd);
    -                    if (ZSTD_isError(errorCode)) goto error;
    -
    -                    if (flush == Z_INFLATE_SYNC) res = inflateSync(strm);
    -                    else res = inflate(strm, flush);
    -                    LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
    -                    return res;
    -                }
    -            } else {
    -                srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - zwd->totalInBytes);
    -                memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
    -                strm->total_in += srcSize;
    -                zwd->totalInBytes += srcSize;
    -                strm->next_in += srcSize;
    -                strm->avail_in -= srcSize;
    -                if (zwd->totalInBytes < ZLIB_HEADERSIZE) return Z_OK;
    -
    -                if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
    -                    z_stream strm2;
    -                    strm2.next_in = strm->next_in;
    -                    strm2.avail_in = strm->avail_in;
    -                    strm2.next_out = strm->next_out;
    -                    strm2.avail_out = strm->avail_out;
    -
    -                    if (zwd->windowBits)
    -                        errorCode = inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size);
    -                    else
    -                        errorCode = inflateInit_(strm, zwd->version, zwd->stream_size);
    -                    LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", (int)errorCode);
    -                    if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode);
    -
    -                    /* inflate header */
    -                    strm->next_in = (unsigned char*)zwd->headerBuf;
    -                    strm->avail_in = ZLIB_HEADERSIZE;
    -                    strm->avail_out = 0;
    -                    errorCode = inflate(strm, Z_NO_FLUSH);
    -                    LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n", (int)errorCode, (int)strm->avail_in);
    -                    if (errorCode != Z_OK) return ZWRAPD_finishWithError(zwd, strm, (int)errorCode);
    -                    if (strm->avail_in > 0) goto error;
    -
    -                    strm->next_in = strm2.next_in;
    -                    strm->avail_in = strm2.avail_in;
    -                    strm->next_out = strm2.next_out;
    -                    strm->avail_out = strm2.avail_out;
    -
    -                    strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
    -                    errorCode = ZWRAP_freeDCtx(zwd);
    -                    if (ZSTD_isError(errorCode)) goto error;
    -
    -                    if (flush == Z_INFLATE_SYNC) res = inflateSync(strm);
    -                    else res = inflate(strm, flush);
    -                    LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
    -                    return res;
    -                }
    -            }
    -        }
    -
    -        strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */
    -
    -        if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; }
    -
    -        if (!zwd->zbd) {
    -            zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem);
    -            if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; }
    -            zwd->decompState = ZWRAP_useInit;
    -        }
    -
    -        if (zwd->totalInBytes < ZSTD_HEADERSIZE)
    -        {
    -            if (zwd->totalInBytes == 0 && strm->avail_in >= ZSTD_HEADERSIZE) {
    -                if (zwd->decompState == ZWRAP_useInit) {
    -                    errorCode = ZSTD_initDStream(zwd->zbd);
    -                    if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; }
    -                } else {
    -                    errorCode = ZSTD_resetDStream(zwd->zbd);
    -                    if (ZSTD_isError(errorCode)) goto error;
    -                }
    -            } else {
    -                srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - zwd->totalInBytes);
    -                memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
    -                strm->total_in += srcSize;
    -                zwd->totalInBytes += srcSize;
    -                strm->next_in += srcSize;
    -                strm->avail_in -= srcSize;
    -                if (zwd->totalInBytes < ZSTD_HEADERSIZE) return Z_OK;
    -
    -                if (zwd->decompState == ZWRAP_useInit) {
    -                    errorCode = ZSTD_initDStream(zwd->zbd);
    -                    if (ZSTD_isError(errorCode)) { LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n", ZSTD_getErrorName(errorCode)); goto error; }
    -                } else {
    -                    errorCode = ZSTD_resetDStream(zwd->zbd);
    -                    if (ZSTD_isError(errorCode)) goto error;
    +    if (zwd->totalInBytes < ZLIB_HEADERSIZE) {
    +        if (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) {
    +            if (MEM_readLE32(strm->next_in) != ZSTD_MAGICNUMBER) {
    +                {   int const initErr = (zwd->windowBits) ?
    +                                inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) :
    +                                inflateInit_(strm, zwd->version, zwd->stream_size);
    +                    LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr);
    +                    if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr);
                     }
     
    -                zwd->inBuffer.src = zwd->headerBuf;
    -                zwd->inBuffer.size = ZSTD_HEADERSIZE;
    -                zwd->inBuffer.pos = 0;
    -                zwd->outBuffer.dst = strm->next_out;
    -                zwd->outBuffer.size = 0;
    -                zwd->outBuffer.pos = 0;
    -                errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    -                LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
    -                if (ZSTD_isError(errorCode)) {
    -                    LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(errorCode));
    +                strm->reserved = ZWRAP_ZLIB_STREAM;
    +                { size_t const freeErr = ZWRAP_freeDCtx(zwd);
    +                  if (ZSTD_isError(freeErr)) goto error; }
    +
    +                {   int const result = (flush == Z_INFLATE_SYNC) ?
    +                                        inflateSync(strm) :
    +                                        inflate(strm, flush);
    +                    LOG_WRAPPERD("- inflate3 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
    +                                 (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
    +                    return result;
    +            }   }
    +        } else {  /* ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */
    +            size_t const srcSize = MIN(strm->avail_in, ZLIB_HEADERSIZE - zwd->totalInBytes);
    +            memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
    +            strm->total_in += srcSize;
    +            zwd->totalInBytes += srcSize;
    +            strm->next_in += srcSize;
    +            strm->avail_in -= srcSize;
    +            if (zwd->totalInBytes < ZLIB_HEADERSIZE) return Z_OK;
    +
    +            if (MEM_readLE32(zwd->headerBuf) != ZSTD_MAGICNUMBER) {
    +                z_stream strm2;
    +                strm2.next_in = strm->next_in;
    +                strm2.avail_in = strm->avail_in;
    +                strm2.next_out = strm->next_out;
    +                strm2.avail_out = strm->avail_out;
    +
    +                {   int const initErr = (zwd->windowBits) ?
    +                                inflateInit2_(strm, zwd->windowBits, zwd->version, zwd->stream_size) :
    +                                inflateInit_(strm, zwd->version, zwd->stream_size);
    +                    LOG_WRAPPERD("ZLIB inflateInit errorCode=%d\n", initErr);
    +                    if (initErr != Z_OK) return ZWRAPD_finishWithError(zwd, strm, initErr);
    +                }
    +
    +                /* inflate header */
    +                strm->next_in = (unsigned char*)zwd->headerBuf;
    +                strm->avail_in = ZLIB_HEADERSIZE;
    +                strm->avail_out = 0;
    +                {   int const dErr = inflate(strm, Z_NO_FLUSH);
    +                    LOG_WRAPPERD("ZLIB inflate errorCode=%d strm->avail_in=%d\n",
    +                                  dErr, (int)strm->avail_in);
    +                    if (dErr != Z_OK)
    +                        return ZWRAPD_finishWithError(zwd, strm, dErr);
    +                }
    +                if (strm->avail_in > 0) goto error;
    +
    +                strm->next_in = strm2.next_in;
    +                strm->avail_in = strm2.avail_in;
    +                strm->next_out = strm2.next_out;
    +                strm->avail_out = strm2.avail_out;
    +
    +                strm->reserved = ZWRAP_ZLIB_STREAM; /* mark as zlib stream */
    +                { size_t const freeErr = ZWRAP_freeDCtx(zwd);
    +                  if (ZSTD_isError(freeErr)) goto error; }
    +
    +                {   int const result = (flush == Z_INFLATE_SYNC) ?
    +                                       inflateSync(strm) :
    +                                       inflate(strm, flush);
    +                    LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
    +                                 (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, res);
    +                    return result;
    +        }   }   }  /* if ! (zwd->totalInBytes == 0 && strm->avail_in >= ZLIB_HEADERSIZE) */
    +    }  /* (zwd->totalInBytes < ZLIB_HEADERSIZE) */
    +
    +    strm->reserved = ZWRAP_ZSTD_STREAM; /* mark as zstd steam */
    +
    +    if (flush == Z_INFLATE_SYNC) { strm->msg = "inflateSync is not supported!"; goto error; }
    +
    +    if (!zwd->zbd) {
    +        zwd->zbd = ZSTD_createDStream_advanced(zwd->customMem);
    +        if (zwd->zbd == NULL) { LOG_WRAPPERD("ERROR: ZSTD_createDStream_advanced\n"); goto error; }
    +        zwd->decompState = ZWRAP_useInit;
    +    }
    +
    +    if (zwd->totalInBytes < ZSTD_HEADERSIZE) {
    +        if (zwd->totalInBytes == 0 && strm->avail_in >= ZSTD_HEADERSIZE) {
    +            if (zwd->decompState == ZWRAP_useInit) {
    +                size_t const initErr = ZSTD_initDStream(zwd->zbd);
    +                if (ZSTD_isError(initErr)) {
    +                    LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n",
    +                                 ZSTD_getErrorName(initErr));
                         goto error;
                     }
    -                if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */
    +            } else {
    +                size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
    +                if (ZSTD_isError(resetErr)) goto error;
                 }
    -        }
    +        } else {
    +            size_t const srcSize = MIN(strm->avail_in, ZSTD_HEADERSIZE - zwd->totalInBytes);
    +            memcpy(zwd->headerBuf+zwd->totalInBytes, strm->next_in, srcSize);
    +            strm->total_in += srcSize;
    +            zwd->totalInBytes += srcSize;
    +            strm->next_in += srcSize;
    +            strm->avail_in -= srcSize;
    +            if (zwd->totalInBytes < ZSTD_HEADERSIZE) return Z_OK;
     
    -        zwd->inBuffer.src = strm->next_in;
    -        zwd->inBuffer.size = strm->avail_in;
    -        zwd->inBuffer.pos = 0;
    -        zwd->outBuffer.dst = strm->next_out;
    -        zwd->outBuffer.size = strm->avail_out;
    -        zwd->outBuffer.pos = 0;
    -        errorCode = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    -        LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n", (int)errorCode, (int)strm->avail_in, (int)strm->avail_out);
    -        if (ZSTD_isError(errorCode)) {
    +            if (zwd->decompState == ZWRAP_useInit) {
    +                size_t const initErr = ZSTD_initDStream(zwd->zbd);
    +                if (ZSTD_isError(initErr)) {
    +                    LOG_WRAPPERD("ERROR: ZSTD_initDStream errorCode=%s\n",
    +                                ZSTD_getErrorName(initErr));
    +                    goto error;
    +                }
    +            } else {
    +                size_t const resetErr = ZSTD_resetDStream(zwd->zbd);
    +                if (ZSTD_isError(resetErr)) goto error;
    +            }
    +
    +            zwd->inBuffer.src = zwd->headerBuf;
    +            zwd->inBuffer.size = ZSTD_HEADERSIZE;
    +            zwd->inBuffer.pos = 0;
    +            zwd->outBuffer.dst = strm->next_out;
    +            zwd->outBuffer.size = 0;
    +            zwd->outBuffer.pos = 0;
    +            {   size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    +                LOG_WRAPPERD("inflate ZSTD_decompressStream1 errorCode=%d srcSize=%d dstCapacity=%d\n",
    +                            (int)dErr, (int)zwd->inBuffer.size, (int)zwd->outBuffer.size);
    +                if (ZSTD_isError(dErr)) {
    +                    LOG_WRAPPERD("ERROR: ZSTD_decompressStream1 %s\n", ZSTD_getErrorName(dErr));
    +                    goto error;
    +            }   }
    +            if (zwd->inBuffer.pos != zwd->inBuffer.size) goto error; /* not consumed */
    +        }
    +    }   /* (zwd->totalInBytes < ZSTD_HEADERSIZE) */
    +
    +    zwd->inBuffer.src = strm->next_in;
    +    zwd->inBuffer.size = strm->avail_in;
    +    zwd->inBuffer.pos = 0;
    +    zwd->outBuffer.dst = strm->next_out;
    +    zwd->outBuffer.size = strm->avail_out;
    +    zwd->outBuffer.pos = 0;
    +    {   size_t const dErr = ZSTD_decompressStream(zwd->zbd, &zwd->outBuffer, &zwd->inBuffer);
    +        LOG_WRAPPERD("inflate ZSTD_decompressStream2 errorCode=%d srcSize=%d dstCapacity=%d\n",
    +                    (int)dErr, (int)strm->avail_in, (int)strm->avail_out);
    +        if (ZSTD_isError(dErr)) {
                 zwd->errorCount++;
    -            LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n", ZSTD_getErrorName(errorCode), zwd->errorCount);
    +            LOG_WRAPPERD("ERROR: ZSTD_decompressStream2 %s zwd->errorCount=%d\n",
    +                        ZSTD_getErrorName(dErr), zwd->errorCount);
                 if (zwd->errorCount<=1) return Z_NEED_DICT; else goto error;
             }
    -        LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n", (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size);
    +        LOG_WRAPPERD("inflate inBuffer.pos=%d inBuffer.size=%d outBuffer.pos=%d outBuffer.size=%d o\n",
    +                    (int)zwd->inBuffer.pos, (int)zwd->inBuffer.size, (int)zwd->outBuffer.pos, (int)zwd->outBuffer.size);
             strm->next_out += zwd->outBuffer.pos;
             strm->total_out += zwd->outBuffer.pos;
             strm->avail_out -= zwd->outBuffer.pos;
    @@ -794,13 +822,16 @@ ZEXTERN int ZEXPORT z_inflate OF((z_streamp strm, int flush))
             zwd->totalInBytes += zwd->inBuffer.pos;
             strm->next_in += zwd->inBuffer.pos;
             strm->avail_in -= zwd->inBuffer.pos;
    -        if (errorCode == 0) {
    -            LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n", (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
    +        if (dErr == 0) {
    +            LOG_WRAPPERD("inflate Z_STREAM_END1 avail_in=%d avail_out=%d total_in=%d total_out=%d\n",
    +                        (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out);
                 zwd->decompState = ZWRAP_streamEnd;
                 return Z_STREAM_END;
             }
    -    }
    -    LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n", (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK);
    +    }  /* dErr lifetime */
    +
    +    LOG_WRAPPERD("- inflate2 flush=%d avail_in=%d avail_out=%d total_in=%d total_out=%d res=%d\n",
    +                (int)flush, (int)strm->avail_in, (int)strm->avail_out, (int)strm->total_in, (int)strm->total_out, Z_OK);
         return Z_OK;
     
     error:
    @@ -813,13 +844,13 @@ ZEXTERN int ZEXPORT z_inflateEnd OF((z_streamp strm))
         if (g_ZWRAPdecompressionType == ZWRAP_FORCE_ZLIB || !strm->reserved)
             return inflateEnd(strm);
     
    -    LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n", (int)(strm->total_in), (int)(strm->total_out));
    -    {   size_t errorCode;
    -        ZWRAP_DCtx* zwd = (ZWRAP_DCtx*) strm->state;
    +    LOG_WRAPPERD("- inflateEnd total_in=%d total_out=%d\n",
    +                (int)(strm->total_in), (int)(strm->total_out));
    +    {   ZWRAP_DCtx* const zwd = (ZWRAP_DCtx*) strm->state;
             if (zwd == NULL) return Z_OK;  /* structures are already freed */
    +        { size_t const freeErr = ZWRAP_freeDCtx(zwd);
    +          if (ZSTD_isError(freeErr)) return Z_STREAM_ERROR; }
             strm->state = NULL;
    -        errorCode = ZWRAP_freeDCtx(zwd);
    -        if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
         }
         return Z_OK;
     }
    @@ -836,8 +867,6 @@ ZEXTERN int ZEXPORT z_inflateSync OF((z_streamp strm))
     
     
     
    -
    -
     /* Advanced compression functions */
     ZEXTERN int ZEXPORT z_deflateCopy OF((z_streamp dest,
                                         z_streamp source))
    @@ -977,7 +1006,7 @@ ZEXTERN uLong ZEXPORT z_zlibCompileFlags OF((void)) { return zlibCompileFlags();
     
     
     
    -                        /* utility functions */
    +                    /* ===   utility functions  === */
     #ifndef Z_SOLO
     
     ZEXTERN int ZEXPORT z_compress OF((Bytef *dest,   uLongf *destLen,
    @@ -986,11 +1015,14 @@ ZEXTERN int ZEXPORT z_compress OF((Bytef *dest,   uLongf *destLen,
         if (!g_ZWRAP_useZSTDcompression)
             return compress(dest, destLen, source, sourceLen);
     
    -    { size_t dstCapacity = *destLen;
    -      size_t const errorCode = ZSTD_compress(dest, dstCapacity, source, sourceLen, ZWRAP_DEFAULT_CLEVEL);
    -      LOG_WRAPPERD("z_compress sourceLen=%d dstCapacity=%d\n", (int)sourceLen, (int)dstCapacity);
    -      if (ZSTD_isError(errorCode)) return Z_STREAM_ERROR;
    -      *destLen = errorCode;
    +    {   size_t dstCapacity = *destLen;
    +        size_t const cSize = ZSTD_compress(dest, dstCapacity,
    +                                           source, sourceLen,
    +                                           ZWRAP_DEFAULT_CLEVEL);
    +        LOG_WRAPPERD("z_compress sourceLen=%d dstCapacity=%d\n",
    +                    (int)sourceLen, (int)dstCapacity);
    +        if (ZSTD_isError(cSize)) return Z_STREAM_ERROR;
    +        *destLen = cSize;
         }
         return Z_OK;
     }
    
    From 8ddf4c22d5e64736aab775990c17e6f7719316b3 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 17:16:49 -0700
    Subject: [PATCH 130/400] fixed missing initialization
    
    ---
     lib/decompress/zstd_decompress.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 33a905a20..68ec13d1a 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -209,6 +209,7 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
         {   ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
             if (!dctx) return NULL;
             dctx->customMem = customMem;
    +        dctx->legacyContext = NULL;
             ZSTD_initDCtx_internal(dctx);
             return dctx;
         }
    
    From 257a7226d8ef6049d8aa8e07f1324fbff3947050 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 17:35:11 -0700
    Subject: [PATCH 131/400] updated NEWS for v1.3.0
    
    ---
     NEWS | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/NEWS b/NEWS
    index 7d9c9c94e..ffd1e036f 100644
    --- a/NEWS
    +++ b/NEWS
    @@ -1,3 +1,11 @@
    +v1.3.0
    +cli : changed : `-t *` does no longer stop after a decompression error
    +API : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700)
    +API : changed : unified CCtx/CStream and DCtx/DStream definitions
    +API exp : changed : slowest strategy renamed ZSTD_btultra
    +new : contrib/seekable_format, demo and API, by Sean Purcell
    +changed : contrib/linux-kernel, updated version and license, by Nick Terrell
    +
     v1.2.0
     cli : changed : Multithreading enabled by default (use target zstd-nomt or HAVE_THREAD=0 to disable)
     cli : new : command -T0 means "detect and use nb of cores", by Sean Purcell
    
    From 86bd83ef121fe683903dadd8135c7ca12cec4e51 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 17:43:55 -0700
    Subject: [PATCH 132/400] completed NEWS for v1.3.0
    
    ---
     NEWS | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/NEWS b/NEWS
    index ffd1e036f..9f1298126 100644
    --- a/NEWS
    +++ b/NEWS
    @@ -1,8 +1,9 @@
     v1.3.0
     cli : changed : `-t *` does no longer stop after a decompression error
    -API : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700)
    -API : changed : unified CCtx/CStream and DCtx/DStream definitions
    -API exp : changed : slowest strategy renamed ZSTD_btultra
    +API exp : new advanced API : ZSTD_compress_generic(), ZSTD_CCtx_setParameter()
    +API exp : new : API for static or external allocation : ZSTD_initStatic?Ctx()
    +API exp : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700)
    +API exp : changed : strongest strategy renamed ZSTD_btultra
     new : contrib/seekable_format, demo and API, by Sean Purcell
     changed : contrib/linux-kernel, updated version and license, by Nick Terrell
     
    
    From 58e8d793e18e0884de6072f1bb6dec9b6847cb4f Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 2 Jun 2017 18:20:48 -0700
    Subject: [PATCH 133/400] made debug definitions common within zstd_internal.h
    
    ---
     doc/zstd_manual.html             | 13 ++++++-----
     lib/common/bitstream.h           | 14 ++++++-----
     lib/common/zstd_internal.h       | 31 +++++++++++++++++++++++--
     lib/compress/zstd_compress.c     | 40 ++++++--------------------------
     lib/compress/zstdmt_compress.c   | 27 ++++++++-------------
     lib/compress/zstdmt_compress.h   | 10 ++++----
     lib/decompress/zstd_decompress.c | 13 -----------
     7 files changed, 67 insertions(+), 81 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 3b7f32870..40cae8f28 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -404,7 +404,8 @@ size_t ZSTD_estimateDCtxSize(void);
     

    These functions make it possible to estimate memory usage of a future target object, before its allocation, given a set of parameters, which vary depending on target object. - The objective is to guide decision before allocation. + The objective is to guide decision before allocation. + Note : CCtx estimation is only correct for single-threaded compression


    size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    @@ -575,17 +576,17 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
         ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
                                  /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
     
    -#if 0
    -    /* multi-threading parameters (not ready yet !) */
    +    /* multi-threading parameters */
         ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    -                              * More threads improve speed, but increases also memory usage */
    -    ZSTDMT_p_jobSize,        /* Size of a compression job. Each job is compressed in parallel.
    +                              * More threads improve speed, but also increase memory usage.
    +                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    +                              * Special: value 0 means "do not change nbThreads" */
    +    ZSTDMT_p_jobSize,        /* Size of a compression job. Each compression job is completed in parallel.
                                   * 0 means default, which is dynamically determined based on compression parameters.
                                   * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
                                   * The minimum size is automatically and transparently enforced */
         ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job.
                                   * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    -#endif
     
         /* advanced parameters - may not remain available after API update */
         ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h
    index 74eb4b635..f3c9064bb 100644
    --- a/lib/common/bitstream.h
    +++ b/lib/common/bitstream.h
    @@ -58,7 +58,9 @@ extern "C" {
     #if defined(BIT_DEBUG) && (BIT_DEBUG>=1)
     #  include 
     #else
    -#  define assert(condition) ((void)0)
    +#  ifndef assert
    +#    define assert(condition) ((void)0)
    +#  endif
     #endif
     
     
    @@ -307,19 +309,19 @@ MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, si
     
     	    case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
     	            /* fall-through */
    -	
    +
     	    case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
     	            /* fall-through */
    -	
    +
     	    case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
     	            /* fall-through */
    -	
    +
     	    case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
     	            /* fall-through */
    -	
    +
     	    case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;
     	            /* fall-through */
    -	
    +
                 default: break;
             }
             { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index 6f9b4ef1f..8c627cb7a 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -51,9 +51,36 @@
     #define ZSTD_STATIC_LINKING_ONLY
     #include "zstd.h"
     #ifndef XXH_STATIC_LINKING_ONLY
    -#  define XXH_STATIC_LINKING_ONLY   /* XXH64_state_t */
    +#  define XXH_STATIC_LINKING_ONLY  /* XXH64_state_t */
    +#endif
    +#include "xxhash.h"                /* XXH_reset, update, digest */
    +
    +
    +/*-*************************************
    +*  Debug
    +***************************************/
    +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
    +#  include 
    +#else
    +#  ifndef assert
    +#    define assert(condition) ((void)0)
    +#  endif
    +#endif
    +
    +#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
    +
    +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
    +#  include 
    +   static unsigned g_debugLevel = ZSTD_DEBUG;
    +#  define DEBUGLOG(l, ...) {                          \
    +                if (l<=g_debugLevel) {                \
    +                    fprintf(stderr, __FILE__ ": ");   \
    +                    fprintf(stderr, __VA_ARGS__);     \
    +                    fprintf(stderr, " \n");           \
    +            }   }
    +#else
    +#  define DEBUGLOG(l, ...)      {}    /* disabled */
     #endif
    -#include "xxhash.h"               /* XXH_reset, update, digest */
     
     
     /*-*************************************
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 8f7c200b2..76d3614c7 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -28,31 +28,6 @@
     #include "zstdmt_compress.h"
     
     
    -/*-*************************************
    -*  Debug
    -***************************************/
    -#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
    -#  include 
    -#else
    -#  define assert(condition) ((void)0)
    -#endif
    -
    -#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
    -
    -#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
    -#  include 
    -   static unsigned g_debugLevel = ZSTD_DEBUG;
    -#  define DEBUGLOG(l, ...) {                          \
    -                if (l<=g_debugLevel) {                \
    -                    fprintf(stderr, __FILE__ ": ");   \
    -                    fprintf(stderr, __VA_ARGS__);     \
    -                    fprintf(stderr, " \n");           \
    -            }   }
    -#else
    -#  define DEBUGLOG(l, ...)      {}    /* disabled */
    -#endif
    -
    -
     /*-*************************************
     *  Constants
     ***************************************/
    @@ -3622,17 +3597,19 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
                                             ZSTD_inBuffer* input,
                                             ZSTD_EndDirective const flushMode)
     {
    -    U32 someMoreWork = 1;
         const char* const istart = (const char*)input->src;
         const char* const iend = istart + input->size;
         const char* ip = istart + input->pos;
         char* const ostart = (char*)output->dst;
         char* const oend = ostart + output->size;
         char* op = ostart + output->pos;
    +    U32 someMoreWork = 1;
     
    -    /* expected to be already allocated */
    +    /* check expectations */
         assert(zcs->inBuff != NULL);
         assert(zcs->outBuff!= NULL);
    +    assert(output->pos <= output->size);
    +    assert(input->pos <= input->size);
     
         while (someMoreWork) {
             switch(zcs->streamStage)
    @@ -3765,7 +3742,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
             ZSTD_parameters params = cctx->requestedParams;
    -        DEBUGLOG(5, "ZSTD_compress_generic : transparent reset");
             if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
                 params.cParams = ZSTD_getCParams(cctx->compressionLevel,
                                         cctx->frameContentSize, 0 /* dictSize */);
    @@ -3775,7 +3751,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
         DEBUGLOG(5, "starting ZSTD_compressStream_generic");
         CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
     
    -    DEBUGLOG(5, "completing ZSTD_compress_generic_integral");
    +    DEBUGLOG(5, "completing ZSTD_compress_generic");
         return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */
     }
     
    @@ -3788,12 +3764,10 @@ size_t ZSTD_compress_generic_simpleArgs (
         ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
         ZSTD_inBuffer  input  = { src, srcSize, *srcPos };
         /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
    -    size_t const hint = ZSTD_compress_generic(cctx, &output, &input, endOp);
    -    if (ZSTD_isError(hint)) return hint;
    -
    +    size_t const cErr = ZSTD_compress_generic(cctx, &output, &input, endOp);
         *dstPos = output.pos;
         *srcPos = input.pos;
    -    return hint;
    +    return cErr;
     
     }
     
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 0d6014608..54feb86f5 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -14,25 +14,19 @@
     
     /* ======   Compiler specifics   ====== */
     #if defined(_MSC_VER)
    -#  pragma warning(disable : 4204)        /* disable: C4204: non-constant aggregate initializer */
    +#  pragma warning(disable : 4204)   /* disable: C4204: non-constant aggregate initializer */
     #endif
     
     
     /* ======   Dependencies   ====== */
    -#include      /* memcpy, memset */
    -#include "pool.h"       /* threadpool */
    -#include "threading.h"  /* mutex */
    +#include       /* memcpy, memset */
    +#include "pool.h"        /* threadpool */
    +#include "threading.h"   /* mutex */
     #include "zstd_internal.h"  /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
     #include "zstdmt_compress.h"
     
     
     /* ======   Debug   ====== */
    -#if defined(ZSTDMT_DEBUG) && (ZSTDMT_DEBUG>=1)
    -#  include 
    -#else
    -#  define assert(condition) ((void)0)
    -#endif
    -
     #if defined(ZSTDMT_DEBUG) && (ZSTDMT_DEBUG>=2)
     
     #  include 
    @@ -573,17 +567,15 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs)
     
     
     static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
    -                                    const void* dict, size_t dictSize, unsigned updateDict,
    -                                    ZSTD_parameters params, unsigned long long pledgedSrcSize)
    +                        const void* dict, size_t dictSize, unsigned updateDict,
    +                        ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    -    ZSTD_customMem const cmem = { NULL, NULL, NULL };
    -    DEBUGLOG(3, "Started new compression, with windowLog : %u",
    -                    params.cParams.windowLog);
         if (zcs->nbThreads==1)
             return ZSTD_initCStream_advanced(zcs->cctxPool->cctx[0],
                                             dict, dictSize,
                                             params, pledgedSrcSize);
    -    if (zcs->allJobsCompleted == 0) {   /* previous job not correctly finished */
    +
    +    if (zcs->allJobsCompleted == 0) {   /* previous compression not correctly finished */
             ZSTDMT_waitForAllJobsCompleted(zcs);
             ZSTDMT_releaseAllJobResources(zcs);
             zcs->allJobsCompleted = 1;
    @@ -592,7 +584,8 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
         if (updateDict) {
             ZSTD_freeCDict(zcs->cdict); zcs->cdict = NULL;
             if (dict && dictSize) {
    -            zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0, params.cParams, cmem);
    +            zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0 /* byRef */,
    +                                                params.cParams, zcs->cMem);
                 if (zcs->cdict == NULL) return ERROR(memory_allocation);
         }   }
         zcs->frameContentSize = pledgedSrcSize;
    diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h
    index adbb7dfe3..ceff32ef6 100644
    --- a/lib/compress/zstdmt_compress.h
    +++ b/lib/compress/zstdmt_compress.h
    @@ -15,8 +15,8 @@
      #endif
     
     
    -/* Note : All prototypes defined in this file shall be considered experimental.
    - *        There is no guarantee of API continuity (yet) on any of these prototypes */
    +/* Note : All prototypes defined in this file must be considered experimental.
    + *        There is no guarantee of API continuity on any of these prototypes */
     
     /* ===   Dependencies   === */
     #include    /* size_t */
    @@ -60,8 +60,10 @@ ZSTDLIB_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output);
     #  define ZSTDMT_SECTION_SIZE_MIN (1U << 20)   /* 1 MB - Minimum size of each compression job */
     #endif
     
    -ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* dict, size_t dictSize,  /**< dict can be released after init, a local copy is preserved within zcs */
    -                                          ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be zero == unknown */
    +ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
    +                                        const void* dict, size_t dictSize,   /* dict can be released after init, a local copy is preserved within zcs */
    +                                        ZSTD_parameters params,
    +                                        unsigned long long pledgedSrcSize);  /* pledgedSrcSize is optional and can be zero == unknown */
     
     
     /* ZSDTMT_parameter :
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 68ec13d1a..bb3eed399 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -70,19 +70,6 @@
     #define FSE_isError  ERR_isError
     #define HUF_isError  ERR_isError
     
    -#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
    -#  include 
    -   static unsigned g_debugLevel = ZSTD_DEBUG;
    -#  define DEBUGLOG(l, ...) {                          \
    -                if (l<=g_debugLevel) {                \
    -                    fprintf(stderr, __FILE__ ": ");   \
    -                    fprintf(stderr, __VA_ARGS__);     \
    -                    fprintf(stderr, " \n");           \
    -            }   }
    -#else
    -#  define DEBUGLOG(l, ...)      {}    /* disabled */
    -#endif
    -
     
     /*_*******************************************************
     *  Memory operations
    
    From 8c910d2097899f44ddbe90a2251655fad4c569fa Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Sat, 3 Jun 2017 01:15:02 -0700
    Subject: [PATCH 134/400] updated ZSTDMT streaming API
    
    ZSTDMT streaming API is now similar
    and has same capabilites as single-thread streaming API.
    It makes it easier to blend them together.
    ---
     doc/zstd_manual.html           |  2 +-
     lib/common/bitstream.h         |  1 +
     lib/common/zstd_internal.h     | 29 ++++++++++++
     lib/compress/zstd_compress.c   | 83 ++++++++++++++++++----------------
     lib/compress/zstdmt_compress.c | 80 +++++++++++++++++++-------------
     lib/compress/zstdmt_compress.h |  4 ++
     lib/zstd.h                     |  2 +-
     tests/zstreamtest.c            |  8 ++--
     8 files changed, 132 insertions(+), 77 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 40cae8f28..9e565139c 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -801,7 +801,7 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
                                                  ZSTD_parameters params, unsigned long long pledgedSrcSize);  /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
     size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);  /**< note : cdict will just be referenced, and must outlive compression session */
    -size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams);  /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
    +size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize);  /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
     

    size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
     

    start a new compression job, using same parameters from previous job. diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index f3c9064bb..07b85026c 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -75,6 +75,7 @@ extern "C" { #define STREAM_ACCUMULATOR_MIN_64 57 #define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64)) + /*-****************************************** * bitStream encoding API (write forward) ********************************************/ diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 8c627cb7a..e67157c13 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -305,4 +305,33 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); +/*! ZSTD_compressBegin_internal() : + * innermost initialization function. Private use only. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * @return : 0, or an error code */ +typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; +size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, + const void* dict, size_t dictSize, + const ZSTD_CDict* cdict, + ZSTD_parameters params, U64 pledgedSrcSize, + ZSTD_buffered_policy_e zbuff); + + +/*! ZSTD_initCStream_internal() : + * Private use only. Init streaming operation. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * @return : 0, or an error code */ +size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, + const void* dict, size_t dictSize, + const ZSTD_CDict* cdict, + ZSTD_parameters params, U64 pledgedSrcSize); + + +/*! ZSTD_getParamsFromCDict() : + * as the name implies */ +ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict); + + #endif /* ZSTD_CCOMMON_H_MODULE */ diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 76d3614c7..083f891b3 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -74,7 +74,7 @@ struct ZSTD_CDict_s { const void* dictContent; size_t dictContentSize; ZSTD_CCtx* refContext; -}; /* typedef'd tp ZSTD_CDict within "zstd.h" */ +}; /* typedef'd to ZSTD_CDict within "zstd.h" */ struct ZSTD_CCtx_s { const BYTE* nextSrc; /* next block here to continue on current prefix */ @@ -533,8 +533,6 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; -typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; - /*! ZSTD_resetCCtx_internal() : note : `params` are assumed fully validated at this stage */ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, @@ -3089,7 +3087,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, /*! ZSTD_compressBegin_internal() : * @return : 0, or an error code */ -static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, +size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, const ZSTD_CDict* cdict, ZSTD_parameters params, U64 pledgedSrcSize, @@ -3392,7 +3390,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize, return cdict; } -static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) { +ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) { return ZSTD_getParamsFromCCtx(cdict->refContext); } @@ -3505,38 +3503,12 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize) return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } -/* ZSTD_initCStream_usingCDict_advanced() : - * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ -size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, - const ZSTD_CDict* cdict, - unsigned long long pledgedSrcSize, - ZSTD_frameParameters fParams) -{ /* cannot handle NULL cdict (does not know what to do) */ - if (!cdict) return ERROR(dictionary_wrong); - { ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict); - params.fParams = fParams; - zcs->requestedParams = params; - zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM; - zcs->cdict = cdict; - return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); - } -} - -/* note : cdict must outlive compression session */ -size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict) -{ - ZSTD_frameParameters const fParams = { 0 /* contentSize */, 0 /* checksum */, 0 /* hideDictID */ }; - /* cannot handle NULL cdict (does not know what to do) */ - if (!cdict) return ERROR(dictionary_wrong); - return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, 0, fParams); -} - -static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, - const void* dict, size_t dictSize, - ZSTD_parameters params, unsigned long long pledgedSrcSize) +size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, + const void* dict, size_t dictSize, const ZSTD_CDict* cdict, + ZSTD_parameters params, unsigned long long pledgedSrcSize) { assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); - zcs->cdict = NULL; + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ if (dict && dictSize >= 8) { if (zcs->staticSize) { /* static CCtx : never uses malloc */ @@ -3544,14 +3516,46 @@ static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, return ERROR(memory_allocation); } ZSTD_freeCDict(zcs->cdictLocal); + zcs->cdict = NULL; zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem); if (zcs->cdictLocal == NULL) return ERROR(memory_allocation); zcs->cdict = zcs->cdictLocal; + } else { + if (cdict) { + ZSTD_parameters const cdictParams = ZSTD_getParamsFromCDict(cdict); + params.cParams = cdictParams.cParams; /* cParams are enforced from cdict */ + } + zcs->cdict = cdict; } + zcs->requestedParams = params; + zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM; return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize); } +/* ZSTD_initCStream_usingCDict_advanced() : + * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ +size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fParams, + unsigned long long pledgedSrcSize) +{ /* cannot handle NULL cdict (does not know what to do) */ + if (!cdict) return ERROR(dictionary_wrong); + { ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict); + params.fParams = fParams; + return ZSTD_initCStream_internal(zcs, + NULL, 0, cdict, + params, pledgedSrcSize); + } +} + +/* note : cdict must outlive compression session */ +size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict) +{ + ZSTD_frameParameters const fParams = { 0 /* contentSize */, 0 /* checksum */, 0 /* hideDictID */ }; + return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, 0); /* note : will check that cdict != NULL */ +} + size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) @@ -3559,27 +3563,27 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, CHECK_F( ZSTD_checkCParams(params.cParams) ); zcs->requestedParams = params; zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM; - return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize); + return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, pledgedSrcSize); } size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel) { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize); zcs->compressionLevel = compressionLevel; - return ZSTD_initCStream_internal(zcs, dict, dictSize, params, 0); + return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL, params, 0); } size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize) { ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0); params.fParams.contentSizeFlag = (pledgedSrcSize>0); - return ZSTD_initCStream_internal(zcs, NULL, 0, params, pledgedSrcSize); + return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, params, pledgedSrcSize); } size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel) { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0); - return ZSTD_initCStream_internal(zcs, NULL, 0, params, 0); + return ZSTD_initCStream_internal(zcs, NULL, 0, NULL, params, 0); } /*====== Compression ======*/ @@ -3606,6 +3610,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, U32 someMoreWork = 1; /* check expectations */ + DEBUGLOG(5, "ZSTD_compressStream_generic"); assert(zcs->inBuff != NULL); assert(zcs->outBuff!= NULL); assert(output->pos <= output->size); diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 54feb86f5..c71dcd63b 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -27,19 +27,12 @@ /* ====== Debug ====== */ -#if defined(ZSTDMT_DEBUG) && (ZSTDMT_DEBUG>=2) +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2) # include # include # include -# define DEBUGLOGRAW(l, ...) if (l<=ZSTDMT_DEBUG) { fprintf(stderr, __VA_ARGS__); } -# define DEBUGLOG(l, ...) { \ - if (l<=ZSTDMT_DEBUG) { \ - fprintf(stderr, __FILE__ ": "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, " \n"); \ - } \ -} +# define DEBUGLOGRAW(l, ...) if (l<=ZSTD_DEBUG) { fprintf(stderr, __VA_ARGS__); } # define DEBUG_PRINTHEX(l,p,n) { \ unsigned debug_u; \ @@ -59,7 +52,7 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void) #define MUTEX_WAIT_TIME_DLEVEL 5 #define PTHREAD_MUTEX_LOCK(mutex) { \ - if (ZSTDMT_DEBUG>=MUTEX_WAIT_TIME_DLEVEL) { \ + if (ZSTD_DEBUG>=MUTEX_WAIT_TIME_DLEVEL) { \ unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \ pthread_mutex_lock(mutex); \ { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \ @@ -73,7 +66,6 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void) #else -# define DEBUGLOG(l, ...) {} /* disabled */ # define PTHREAD_MUTEX_LOCK(m) pthread_mutex_lock(m) # define DEBUG_PRINTHEX(l,p,n) {} @@ -259,7 +251,7 @@ typedef struct { pthread_mutex_t* jobCompleted_mutex; pthread_cond_t* jobCompleted_cond; ZSTD_parameters params; - ZSTD_CDict* cdict; + const ZSTD_CDict* cdict; unsigned long long fullFrameSize; } ZSTDMT_jobDescription; @@ -273,7 +265,7 @@ void ZSTDMT_compressChunk(void* jobDescription) job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize); if (job->cdict) { /* should only happen for first segment */ size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize); - if (job->cdict) DEBUGLOG(3, "using CDict"); + DEBUGLOG(3, "using CDict"); if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; } } else { /* srcStart points at reloaded section */ if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */ @@ -335,7 +327,8 @@ struct ZSTDMT_CCtx_s { unsigned long long frameContentSize; size_t sectionSize; ZSTD_customMem cMem; - ZSTD_CDict* cdict; + ZSTD_CDict* cdictLocal; + const ZSTD_CDict* cdict; }; ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem) @@ -407,7 +400,7 @@ size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx) ZSTDMT_freeBufferPool(mtctx->buffPool); /* release job resources into pools first */ ZSTD_free(mtctx->jobs, mtctx->cMem); ZSTDMT_freeCCtxPool(mtctx->cctxPool); - ZSTD_freeCDict(mtctx->cdict); + ZSTD_freeCDict(mtctx->cdictLocal); pthread_mutex_destroy(&mtctx->jobCompleted_mutex); pthread_cond_destroy(&mtctx->jobCompleted_cond); ZSTD_free(mtctx, mtctx->cMem); @@ -422,7 +415,7 @@ size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx) + ZSTDMT_sizeof_bufferPool(mtctx->buffPool) + (mtctx->jobIDMask+1) * sizeof(ZSTDMT_jobDescription) + ZSTDMT_sizeof_CCtxPool(mtctx->cctxPool) - + ZSTD_sizeof_CDict(mtctx->cdict); + + ZSTD_sizeof_CDict(mtctx->cdictLocal); } size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value) @@ -567,28 +560,38 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, - const void* dict, size_t dictSize, unsigned updateDict, + const void* dict, size_t dictSize, const ZSTD_CDict* cdict, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - if (zcs->nbThreads==1) - return ZSTD_initCStream_advanced(zcs->cctxPool->cctx[0], - dict, dictSize, - params, pledgedSrcSize); + /* params are supposed to be fully validated at this point */ + assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); + assert(!((dict) && (cdict))); /* either dict or cdict, not both */ + + if (zcs->nbThreads==1) { + return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0], + dict, dictSize, cdict, + params, pledgedSrcSize); + } if (zcs->allJobsCompleted == 0) { /* previous compression not correctly finished */ ZSTDMT_waitForAllJobsCompleted(zcs); ZSTDMT_releaseAllJobResources(zcs); zcs->allJobsCompleted = 1; } + zcs->params = params; - if (updateDict) { - ZSTD_freeCDict(zcs->cdict); zcs->cdict = NULL; - if (dict && dictSize) { - zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0 /* byRef */, - params.cParams, zcs->cMem); - if (zcs->cdict == NULL) return ERROR(memory_allocation); - } } zcs->frameContentSize = pledgedSrcSize; + if (dict) { + ZSTD_freeCDict(zcs->cdictLocal); + zcs->cdict = NULL; + zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* byRef */, + params.cParams, zcs->cMem); + if (zcs->cdictLocal == NULL) return ERROR(memory_allocation); + zcs->cdict = zcs->cdictLocal; + } else { + zcs->cdict = cdict; + } + zcs->targetDictSize = (zcs->overlapRLog>=9) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog); DEBUGLOG(3, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); @@ -610,13 +613,25 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, return 0; } -size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* zcs, +size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - return ZSTDMT_initCStream_internal(zcs, dict, dictSize, 1, params, pledgedSrcSize); + return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, NULL, params, pledgedSrcSize); } +size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fParams, + unsigned long long pledgedSrcSize) +{ + ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict); + if (cdict==NULL) return ERROR(GENERIC); /* method incompatible with NULL cdict */ + params.fParams = fParams; + return ZSTDMT_initCStream_internal(mtctx, NULL, 0, cdict, params, pledgedSrcSize); +} + + /* ZSTDMT_resetCStream() : * pledgedSrcSize is optional and can be zero == unknown */ size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize) @@ -628,7 +643,7 @@ size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize) size_t ZSTDMT_initCStream(ZSTDMT_CCtx* zcs, int compressionLevel) { ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0); - return ZSTDMT_initCStream_internal(zcs, NULL, 0, 1, params, 0); + return ZSTDMT_initCStream_internal(zcs, NULL, 0, NULL, params, 0); } @@ -780,8 +795,9 @@ size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBu if (zcs->frameEnded) /* current frame being ended. Only flush is allowed. Restart with init */ return ERROR(stage_wrong); - if (zcs->nbThreads==1) + if (zcs->nbThreads==1) { return ZSTD_compressStream(zcs->cctxPool->cctx[0], output, input); + } /* fill input buffer */ { size_t const toLoad = MIN(input->size - input->pos, zcs->inBuffSize - zcs->inBuff.filled); diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h index ceff32ef6..267ed3e2f 100644 --- a/lib/compress/zstdmt_compress.h +++ b/lib/compress/zstdmt_compress.h @@ -65,6 +65,10 @@ ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, ZSTD_parameters params, unsigned long long pledgedSrcSize); /* pledgedSrcSize is optional and can be zero == unknown */ +ZSTDLIB_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx, + const ZSTD_CDict* cdict, + ZSTD_frameParameters fparams, + unsigned long long pledgedSrcSize); /* note : zero means empty */ /* ZSDTMT_parameter : * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */ diff --git a/lib/zstd.h b/lib/zstd.h index c71ed493e..b7fbbea1c 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -932,7 +932,7 @@ ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dic ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */ ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */ -ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ +ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */ /*! ZSTD_resetCStream() : * start a new compression job, using same parameters from previous job. diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 0f73b8cd4..17772856e 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -486,7 +486,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictionary.filled); ZSTD_frameParameters const fParams = { 1 /* contentSize */, 1 /* checksum */, 1 /* noDictID */}; ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, 1 /* byReference */, cParams, customMem); - size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, CNBufferSize, fParams); + size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, fParams, CNBufferSize); if (ZSTD_isError(initError)) goto _output_error; cSize = 0; outBuff.dst = compressedBuffer; @@ -497,7 +497,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo inBuff.pos = 0; { size_t const r = ZSTD_compressStream(zc, &outBuff, &inBuff); if (ZSTD_isError(r)) goto _output_error; } - if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ { size_t const r = ZSTD_endStream(zc, &outBuff); if (r != 0) goto _output_error; } /* error, or some data not flushed */ cSize = outBuff.pos; @@ -991,8 +991,8 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; U32 const cLevel = (FUZ_rand(&lseed) % - (ZSTD_maxCLevel() - - (MAX(testLog, dictLog) / cLevelLimiter))) + + (ZSTD_maxCLevel() - + (MAX(testLog, dictLog) / cLevelLimiter))) + 1; maxTestSize = FUZ_rLogLength(&lseed, testLog); oldTestLog = testLog; From 51235393e30beea59aa6c17908c71a4f7d0da818 Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Sun, 4 Jun 2017 22:06:25 -0700 Subject: [PATCH 135/400] fixed fullbench project for VS2010+ --- build/VS2010/fullbench/fullbench.vcxproj | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build/VS2010/fullbench/fullbench.vcxproj b/build/VS2010/fullbench/fullbench.vcxproj index e16f5e1db..2bff4ca47 100644 --- a/build/VS2010/fullbench/fullbench.vcxproj +++ b/build/VS2010/fullbench/fullbench.vcxproj @@ -156,26 +156,32 @@ + + + - + + - - + + + + From 8bcbf42617c7cdda17911614d54e61b6e41cfc34 Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Sun, 4 Jun 2017 23:52:00 -0700 Subject: [PATCH 136/400] fixed g++ prototype mismatch --- Makefile | 2 +- lib/common/zstd_internal.h | 6 +++--- programs/windres/zstd32.res | Bin 1044 -> 1044 bytes programs/windres/zstd64.res | Bin 1044 -> 1044 bytes 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 54652665b..d7a00e431 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ clean: #------------------------------------------------------------------------------ # make install is validated only for Linux, OSX, Hurd and some BSD targets #------------------------------------------------------------------------------ -ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly NetBSD)) +ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU FreeBSD DragonFly NetBSD MSYS_NT)) HOST_OS = POSIX CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index e67157c13..bd2ad10ff 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -324,9 +324,9 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, * must receive dict, or cdict, or none, but not both. * @return : 0, or an error code */ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, - const void* dict, size_t dictSize, - const ZSTD_CDict* cdict, - ZSTD_parameters params, U64 pledgedSrcSize); + const void* dict, size_t dictSize, + const ZSTD_CDict* cdict, + ZSTD_parameters params, unsigned long long pledgedSrcSize); /*! ZSTD_getParamsFromCDict() : diff --git a/programs/windres/zstd32.res b/programs/windres/zstd32.res index b5dd78db717ce9c7ddb2f69a9bc81804e51aedf6..d6caf985ed2a9469d7a06c8518fc8af5780e34d5 100644 GIT binary patch delta 47 qcmbQjF@ Date: Mon, 5 Jun 2017 00:12:13 -0700 Subject: [PATCH 137/400] minor fix for -Wdocumentation --- lib/common/zstd_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index bd2ad10ff..77f6e5672 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -305,12 +305,12 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); +typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; /*! ZSTD_compressBegin_internal() : * innermost initialization function. Private use only. * expects params to be valid. * must receive dict, or cdict, or none, but not both. * @return : 0, or an error code */ -typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, const ZSTD_CDict* cdict, From 901435e9ef324b7e639bb9027ad544677b338f00 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 5 Jun 2017 14:45:31 -0700 Subject: [PATCH 138/400] setup basic functions for adding --list functionality --- programs/fileio.c | 5 +++++ programs/fileio.h | 1 + programs/zstdcli.c | 17 ++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 44152b0b1..466faf385 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -862,6 +862,11 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, return result; } +int FIO_listFile(const char* infilename){ + DISPLAY("FILE DETECTED: %s\n", infilename); + DISPLAY("working\n"); + return 0; +} int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFiles, const char* suffix, diff --git a/programs/fileio.h b/programs/fileio.h index 65da98d7f..4ca1a2b38 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -70,6 +70,7 @@ int FIO_compressFilename (const char* outfilename, const char* infilename, const @return : 0 == ok; 1 == pb with src file. */ int FIO_decompressFilename (const char* outfilename, const char* infilename, const char* dictFileName); +int FIO_listFile(const char* infilename); /*-************************************* * Multiple File functions diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 32fef9993..be0a447bb 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -117,6 +117,7 @@ static int usage_advanced(const char* programName) DISPLAY( " -v : verbose mode; specify multiple times to increase verbosity\n"); DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n"); DISPLAY( " -c : force write to standard output, even if it is the console\n"); + DISPLAY( " -l : print information about zstd compressed files.\n"); #ifndef ZSTD_NOCOMPRESS DISPLAY( "--ultra : enable levels beyond %i, up to %i (requires more memory)\n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel()); #ifdef ZSTD_MULTITHREAD @@ -310,7 +311,7 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi } -typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train } zstd_operation_mode; +typedef enum { zom_compress, zom_decompress, zom_test, zom_bench, zom_train, zom_list } zstd_operation_mode; #define CLEAN_RETURN(i) { operationResult = (i); goto _end; } @@ -531,7 +532,7 @@ int main(int argCount, const char* argv[]) argument++; memLimit = readU32FromChar(&argument); break; - + case 'l': operation=zom_list; argument++; break; #ifdef UTIL_HAS_CREATEFILELIST /* recursive */ case 'r': recursive=1; argument++; break; @@ -672,7 +673,17 @@ int main(int argCount, const char* argv[]) } } #endif - + if(operation==zom_list){ + DISPLAY("===========================================\n"); + DISPLAY("Printing information about compressed files\n"); + DISPLAY("===========================================\n"); + unsigned u; + DISPLAY("Number of files listed: %d\n", filenameIdx); + for(u=0; u Date: Mon, 5 Jun 2017 15:00:06 -0700 Subject: [PATCH 139/400] added in check suffix check to ensure file was compressed with zstd --- programs/fileio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 466faf385..7a8907ab9 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -864,7 +864,11 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, int FIO_listFile(const char* infilename){ DISPLAY("FILE DETECTED: %s\n", infilename); - DISPLAY("working\n"); + const char* const suffixPtr = strrchr(infilename, '.'); + if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ + DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", infilename); + return 1; + } return 0; } From f35e2de61c32fadc4ab3876c4c8029556bfa0bd1 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 5 Jun 2017 18:32:48 -0700 Subject: [PATCH 140/400] linked newAPI to ZSTDMT --- doc/zstd_manual.html | 2 +- lib/compress/zstd_compress.c | 22 +++++++++++++++++++--- lib/compress/zstdmt_compress.c | 25 ++++++++++++++++++++++--- lib/compress/zstdmt_compress.h | 13 +++++++++++++ lib/zstd.h | 2 +- 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 9e565139c..523c49bb4 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -707,7 +707,7 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic

    Same as ZSTD_compress_generic(), but using only simple integral types as arguments. Argument list is less expressive than ZSTD_{in,out}Buffer, - but can be helpful for binders towards dynamic languages + but can be helpful for binders to dynamic languages which have troubles handling structures containing memory pointers.


    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 083f891b3..48eb24ddf 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3734,6 +3734,16 @@ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuf return ZSTD_compressStream_generic(zcs, output, input, ZSTD_e_continue); } +/*! ZSTDMT_initCStream_internal() : + * Private use only. Init streaming operation. + * expects params to be valid. + * must receive dict, or cdict, or none, but not both. + * @return : 0, or an error code */ +size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, + const void* dict, size_t dictSize, const ZSTD_CDict* cdict, + ZSTD_parameters params, unsigned long long pledgedSrcSize); + + size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, @@ -3750,12 +3760,19 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM) params.cParams = ZSTD_getCParams(cctx->compressionLevel, cctx->frameContentSize, 0 /* dictSize */); - CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); + if (cctx->nbThreads > 1) { + CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->frameContentSize) ); + } else { + CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); + } } + + if (cctx->nbThreads > 1) { + DEBUGLOG(5, "starting ZSTDMT_compressStream_generic"); + return ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp) ; } DEBUGLOG(5, "starting ZSTD_compressStream_generic"); CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); - DEBUGLOG(5, "completing ZSTD_compress_generic"); return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */ } @@ -3773,7 +3790,6 @@ size_t ZSTD_compress_generic_simpleArgs ( *dstPos = output.pos; *srcPos = input.pos; return cErr; - } diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index c71dcd63b..09ac51218 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -559,9 +559,9 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) } -static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, - const void* dict, size_t dictSize, const ZSTD_CDict* cdict, - ZSTD_parameters params, unsigned long long pledgedSrcSize) +size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, + const void* dict, size_t dictSize, const ZSTD_CDict* cdict, + ZSTD_parameters params, unsigned long long pledgedSrcSize) { /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); @@ -849,3 +849,22 @@ size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) return ZSTD_endStream(zcs->cctxPool->cctx[0], output); return ZSTDMT_flushStream_internal(zcs, output, 1); } + +size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp) +{ + CHECK_F (ZSTDMT_compressStream(mtctx, output, input)); + switch(endOp) + { + case ZSTD_e_flush: + return ZSTDMT_flushStream(mtctx, output); + case ZSTD_e_end: + return ZSTDMT_endStream(mtctx, output); + case ZSTD_e_continue: + return 1; + default: + return ERROR(GENERIC); + } +} diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h index 267ed3e2f..8b0ca824f 100644 --- a/lib/compress/zstdmt_compress.h +++ b/lib/compress/zstdmt_compress.h @@ -85,6 +85,19 @@ typedef enum { ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value); +/*! ZSTDMT_compressStream_generic() : + * Combines ZSTDMT_compressStream() with ZSTDMT_flushStream() or ZSTDMT_endStream() + * depending on flush directive + * @return : minimum amount of data still to be flushed + * 0 if fully flushed + * or an error code */ +ZSTDLIB_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp); + + + #if defined (__cplusplus) } #endif diff --git a/lib/zstd.h b/lib/zstd.h index b7fbbea1c..357af9194 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -828,7 +828,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx); /* Not ready yet ! */ * Same as ZSTD_compress_generic(), * but using only simple integral types as arguments. * Argument list is less expressive than ZSTD_{in,out}Buffer, - * but can be helpful for binders towards dynamic languages + * but can be helpful for binders to dynamic languages * which have troubles handling structures containing memory pointers. */ size_t ZSTD_compress_generic_simpleArgs ( From 0f06f4f2663269161820a9dfa9a9fdfa11adf78e Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 6 Jun 2017 09:21:42 -0700 Subject: [PATCH 141/400] added display for compressed size --- programs/fileio.c | 12 +++++++++++- programs/fileio.h | 2 +- programs/zstdcli.c | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 7a8907ab9..c836020c9 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -862,13 +862,23 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, return result; } -int FIO_listFile(const char* infilename){ +int FIO_listFile(const char* infilename, int displayLevel){ DISPLAY("FILE DETECTED: %s\n", infilename); const char* const suffixPtr = strrchr(infilename, '.'); if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", infilename); return 1; } + else{ + U64 const compSize = UTIL_getFileSize(infilename); + if(displayLevel<=2){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY(" %7.2f MB\n", (double)compSize/(1 MB)); + } + else{ + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)compSize/(1 MB), compSize); + } + } return 0; } diff --git a/programs/fileio.h b/programs/fileio.h index 4ca1a2b38..b28ba1de7 100644 --- a/programs/fileio.h +++ b/programs/fileio.h @@ -70,7 +70,7 @@ int FIO_compressFilename (const char* outfilename, const char* infilename, const @return : 0 == ok; 1 == pb with src file. */ int FIO_decompressFilename (const char* outfilename, const char* infilename, const char* dictFileName); -int FIO_listFile(const char* infilename); +int FIO_listFile(const char* infilename, int displayLevel); /*-************************************* * Multiple File functions diff --git a/programs/zstdcli.c b/programs/zstdcli.c index be0a447bb..74f2606bc 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -680,7 +680,7 @@ int main(int argCount, const char* argv[]) unsigned u; DISPLAY("Number of files listed: %d\n", filenameIdx); for(u=0; u Date: Thu, 8 Jun 2017 17:06:30 -0700 Subject: [PATCH 142/400] added code for generating dictionary/test files randomly. Still need to make sure dictionary ID matches --- tests/decodecorpus.c | 104 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 8 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index f7b3c854f..8f2e652cd 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1121,13 +1121,12 @@ static void initFrame(frame_t* fr) } /* Return the final seed */ -static U32 generateFrame(U32 seed, frame_t* fr) +static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize) { /* generate a complete frame */ DISPLAYLEVEL(1, "frame seed: %u\n", seed); - initFrame(fr); - + writeFrameHeader(&seed, fr); writeBlocks(&seed, fr); writeChecksum(fr); @@ -1135,6 +1134,7 @@ static U32 generateFrame(U32 seed, frame_t* fr) return seed; } + /*-******************************************************* * Test Mode *********************************************************/ @@ -1215,7 +1215,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS else DISPLAYUPDATE("\r%u ", fnum); - seed = generateFrame(seed, &fr); + seed = generateFrame(seed, &fr, 0, 0); { size_t const r = testDecodeSimple(&fr); if (ZSTD_isError(r)) { @@ -1250,7 +1250,7 @@ static int generateFile(U32 seed, const char* const path, DISPLAY("seed: %u\n", seed); - generateFrame(seed, &fr); + generateFrame(seed, &fr, 0, 0); outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, path); if (origPath) { @@ -1272,7 +1272,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); - seed = generateFrame(seed, &fr); + seed = generateFrame(seed, &fr, 0, 0); if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1294,6 +1294,81 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, return 0; } +static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path, + const char* const origPath, const size_t dictSize) +{ + const size_t minDictSize = 8; + char outPath[MAX_PATH]; + U32 dictID; + BYTE* dictStart; + unsigned fnum; + ZSTD_DCtx* dctx = ZSTD_createDCtx(); + if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { + DISPLAY("Error: path too long\n"); + return 1; + } + + /* Generate the dictionary randomly first */ + if(dictSize < minDictSize){ + DISPLAY("Error: dictionary size (%zu) is too small\n", dictSize); + } + else{ + /* variable declaration */ + dictStart = malloc(dictSize); + size_t pos = 0; + dictID = RAND(&seed) + 1; + + /* write dictionary magic number */ + MEM_writeLE32(dictStart + pos, ZSTD_DICT_MAGIC); + pos += 4; + + /* write random dictionary ID */ + MEM_writeLE32(dictStart + pos, dictID); + pos += 4; + + /* randomly generate the rest of the dictionary */ + RAND_buffer(&seed, dictStart + pos, dictSize-8); + outputBuffer(dictStart, dictSize, outPath); + } + + /* generate random compressed/decompressed files */ + for (fnum = 0; fnum < numFiles; fnum++) { + frame_t fr; + size_t returnValue; + BYTE* decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); + + DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); + + seed = generateFrame(seed, &fr, 1, dictSize); + + if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { + DISPLAY("Error: path too long\n"); + return 1; + } + outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath); + + if (origPath) { + if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) { + DISPLAY("Error: path too long\n"); + return 1; + } + outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath); + } + + /* if asked, supply the decompressed version */ + + returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE, + fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, + dictStart,dictSize); + + } + + + /* write uncompressed versions of files */ + DISPLAY("This is origPath: %s\nAnd this is numFiles: %d\n", origPath, numFiles); + return 0; +} + /*_******************************************************* * Command line @@ -1350,6 +1425,8 @@ int main(int argc, char** argv) int testMode = 0; const char* path = NULL; const char* origPath = NULL; + int genDict = 0; + unsigned dictSize = (10 << 10); /* 10 kB default */ int argNb; @@ -1410,6 +1487,10 @@ int main(int argc, char** argv) argument++; if (strcmp(argument, "content-size") == 0) { opts.contentSize = 1; + } else if(strcmp(argument, "train-dict") == 0){ + argument += 11; + dictSize = readInt(&argument); + genDict = 1; } else { advancedUsage(argv[0]); return 1; @@ -1441,9 +1522,16 @@ int main(int argc, char** argv) return 1; } - if (numFiles == 0) { + if (numFiles == 0 && genDict == 0) { return generateFile(seed, path, origPath); - } else { + } else if (genDict == 0){ return generateCorpus(seed, numFiles, path, origPath); + } else if (numFiles == 0){ + /* should generate a single file with a dictionary */ + return generateCorpusWithDict(seed, 1, path, origPath, dictSize); + } else{ + /* should generate multiple files with a dictionary */ + return generateCorpusWithDict(seed, numFiles, path, origPath, dictSize); } + } From 233ee5334ee0e2dc549530e500a20c8cec1a4586 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 8 Jun 2017 17:11:33 -0700 Subject: [PATCH 143/400] set the lower bits of frame header descriptor if dictionary is needed --- tests/decodecorpus.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 8f2e652cd..502ea3339 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -240,7 +240,7 @@ struct { } opts; /* advanced options on generation */ /* Generate and write a random frame header */ -static void writeFrameHeader(U32* seed, frame_t* frame) +static void writeFrameHeader(U32* seed, frame_t* frame, int genDict) { BYTE* const op = frame->data; size_t pos = 0; @@ -308,6 +308,8 @@ static void writeFrameHeader(U32* seed, frame_t* frame) { BYTE const frameHeaderDescriptor = (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2)); + if(genDict) + frameHeaderDescriptor += 3; /* set lower bits for dictionary ID */ op[pos++] = frameHeaderDescriptor; } @@ -1126,8 +1128,8 @@ static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize) /* generate a complete frame */ DISPLAYLEVEL(1, "frame seed: %u\n", seed); initFrame(fr); - - writeFrameHeader(&seed, fr); + + writeFrameHeader(&seed, fr, genDict); writeBlocks(&seed, fr); writeChecksum(fr); From 125ed5996881bd0502c87de865d46d6627493585 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 8 Jun 2017 17:27:15 -0700 Subject: [PATCH 144/400] made sure dictionary ID was being written in the frame header of each file --- tests/decodecorpus.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 502ea3339..bdcfd9e23 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -240,7 +240,7 @@ struct { } opts; /* advanced options on generation */ /* Generate and write a random frame header */ -static void writeFrameHeader(U32* seed, frame_t* frame, int genDict) +static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, size_t dictSize) { BYTE* const op = frame->data; size_t pos = 0; @@ -306,17 +306,18 @@ static void writeFrameHeader(U32* seed, frame_t* frame, int genDict) pos += 4; { + int dictBits = genDict ? 3 : 0; BYTE const frameHeaderDescriptor = - (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2)); - if(genDict) - frameHeaderDescriptor += 3; /* set lower bits for dictionary ID */ + (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2) | dictBits); op[pos++] = frameHeaderDescriptor; } if (!singleSegment) { op[pos++] = windowByte; } - + if(genDict) { + MEM_writeLE32(op + pos, (U32) dictSize); + } if (contentSizeFlag) { switch (fcsCode) { default: /* Impossible */ @@ -1129,7 +1130,7 @@ static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize) DISPLAYLEVEL(1, "frame seed: %u\n", seed); initFrame(fr); - writeFrameHeader(&seed, fr, genDict); + writeFrameHeader(&seed, fr, genDict, dictSize); writeBlocks(&seed, fr); writeChecksum(fr); From 11c3987baff48b03fe4ea10a7a15bd7dd7887914 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Fri, 9 Jun 2017 09:48:56 -0700 Subject: [PATCH 145/400] added code to extend the offset when a dictionary is detected --- tests/decodecorpus.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index bdcfd9e23..632acabb8 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -608,7 +608,7 @@ static inline void initSeqStore(seqStore_t *seqStore) { /* Randomly generate sequence commands */ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, - size_t contentSize, size_t literalsSize) + size_t contentSize, size_t literalsSize, int genDict, size_t dictSize) { /* The total length of all the matches */ size_t const remainingMatch = contentSize - literalsSize; @@ -665,6 +665,12 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, MIN(frame->header.windowSize, (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) + 1; + if(genDict && (RAND(seed) & 1)) { + /* need to occasionally generate offsets that go past the start */ + /* we still need to be within the windowSize however */ + const U32 lenPastStart = RAND(seed) % dictSize; + offset = MIN(frame->header.windowSize, offset+lenPastStart); + } offsetCode = offset + ZSTD_REP_MOVE; repIndex = 2; } else { @@ -934,7 +940,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr, } static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize, - size_t literalsSize) + size_t literalsSize, int genDict, size_t dictSize) { seqStore_t seqStore; size_t numSequences; @@ -943,14 +949,14 @@ static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize, initSeqStore(&seqStore); /* randomly generate sequences */ - numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize); + numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize, genDict, dictSize); /* write them out to the frame data */ CHECKERR(writeSequences(seed, frame, &seqStore, numSequences)); return numSequences; } -static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize) +static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize, int genDict, size_t dictSize) { BYTE* const blockStart = (BYTE*)frame->data; size_t literalsSize; @@ -962,7 +968,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize DISPLAYLEVEL(4, " literals size: %u\n", (U32)literalsSize); - nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize); + nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize, genDict, dictSize); DISPLAYLEVEL(4, " number of sequences: %u\n", (U32)nbSeq); @@ -970,7 +976,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize } static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, - int lastBlock) + int lastBlock, int genDict, size_t dictSize) { int const blockTypeDesc = RAND(seed) % 8; size_t blockSize; @@ -1010,7 +1016,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, frame->oldStats = frame->stats; frame->data = op; - compressedSize = writeCompressedBlock(seed, frame, contentSize); + compressedSize = writeCompressedBlock(seed, frame, contentSize, genDict, dictSize); if (compressedSize > contentSize) { blockType = 0; memcpy(op, frame->src, contentSize); @@ -1036,7 +1042,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, frame->data = op; } -static void writeBlocks(U32* seed, frame_t* frame) +static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize) { size_t contentLeft = frame->header.contentSize; size_t const maxBlockSize = MIN(MAX_BLOCK_SIZE, frame->header.windowSize); @@ -1059,7 +1065,7 @@ static void writeBlocks(U32* seed, frame_t* frame) } } - writeBlock(seed, frame, blockContentSize, lastBlock); + writeBlock(seed, frame, blockContentSize, lastBlock, genDict, dictSize); contentLeft -= blockContentSize; if (lastBlock) break; @@ -1131,7 +1137,7 @@ static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize) initFrame(fr); writeFrameHeader(&seed, fr, genDict, dictSize); - writeBlocks(&seed, fr); + writeBlocks(&seed, fr, genDict, dictSize); writeChecksum(fr); return seed; From be9b0ae627f68ee428aa70258dd0f3b4e119ecad Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Fri, 9 Jun 2017 13:41:34 -0700 Subject: [PATCH 146/400] added error function for different compilation modes --- tests/roundTripCrash.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c index a296d4160..88282b45d 100644 --- a/tests/roundTripCrash.c +++ b/tests/roundTripCrash.c @@ -68,6 +68,15 @@ static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize return pos; } +static void crashWithMessage(const char* message, int errorCode){ + /* abort if AFL/libfuzzer, exit otherwise */ + fprintf(stderr, "%s", message); + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */ + abort(); + #else + exit(errorCode); + #endif +} static void roundTripCheck(const void* srcBuff, size_t srcBuffSize) { From 37e1b1488b70e43bc77279922e412a067ce69eaa Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Fri, 9 Jun 2017 13:57:18 -0700 Subject: [PATCH 147/400] removed previous double free crash, used new crash function --- tests/roundTripCrash.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/roundTripCrash.c b/tests/roundTripCrash.c index 88282b45d..77c6737ee 100644 --- a/tests/roundTripCrash.c +++ b/tests/roundTripCrash.c @@ -68,9 +68,8 @@ static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize return pos; } -static void crashWithMessage(const char* message, int errorCode){ +static void crash(int errorCode){ /* abort if AFL/libfuzzer, exit otherwise */ - fprintf(stderr, "%s", message); #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */ abort(); #else @@ -83,7 +82,6 @@ static void roundTripCheck(const void* srcBuff, size_t srcBuffSize) size_t const cBuffSize = ZSTD_compressBound(srcBuffSize); void* cBuff = malloc(cBuffSize); void* rBuff = malloc(cBuffSize); - #define CRASH { free(cBuff); free(cBuff); } /* double free, to crash program */ if (!cBuff || !rBuff) { fprintf(stderr, "not enough memory ! \n"); @@ -93,15 +91,15 @@ static void roundTripCheck(const void* srcBuff, size_t srcBuffSize) { size_t const result = roundTripTest(rBuff, cBuffSize, cBuff, cBuffSize, srcBuff, srcBuffSize); if (ZSTD_isError(result)) { fprintf(stderr, "roundTripTest error : %s \n", ZSTD_getErrorName(result)); - CRASH; + crash(1); } if (result != srcBuffSize) { fprintf(stderr, "Incorrect regenerated size : %u != %u\n", (unsigned)result, (unsigned)srcBuffSize); - CRASH; + crash(1); } if (checkBuffers(srcBuff, rBuff, srcBuffSize) != srcBuffSize) { fprintf(stderr, "Silent decoding corruption !!!"); - CRASH; + crash(1); } } From 23aace9778745c9f3bf6246f3d92abc8c9b8193b Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 11 Jun 2017 18:32:36 -0700 Subject: [PATCH 148/400] added control stage to MT mode --- lib/compress/zstd_compress.c | 6 ++++-- lib/compress/zstdmt_compress.c | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 48eb24ddf..338dd7472 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3762,13 +3762,15 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, cctx->frameContentSize, 0 /* dictSize */); if (cctx->nbThreads > 1) { CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->frameContentSize) ); + cctx->streamStage = zcss_load; } else { CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); } } if (cctx->nbThreads > 1) { - DEBUGLOG(5, "starting ZSTDMT_compressStream_generic"); - return ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp) ; + size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); + if (ZSTD_isError(flushMin)) cctx->streamStage = zcss_init; + return flushMin; } DEBUGLOG(5, "starting ZSTD_compressStream_generic"); diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 09ac51218..098412824 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -851,11 +851,11 @@ size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) } size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input, - ZSTD_EndDirective endOp) + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp) { - CHECK_F (ZSTDMT_compressStream(mtctx, output, input)); + CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); switch(endOp) { case ZSTD_e_flush: From 9e6a2eaab6941bad2f34708b0057d4314dee1988 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 11 Jun 2017 18:39:46 -0700 Subject: [PATCH 149/400] added MT support to NEWAPI --- programs/fileio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index e7c58a969..bbf52168a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -379,10 +379,9 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, size_t const dictBuffSize = FIO_createDictBuffer(&dictBuffer, dictFileName); /* works with dictFileName==NULL */ if (dictFileName && (dictBuffer==NULL)) EXM_THROW(32, "allocation error : can't create dictBuffer"); -//#define ZSTD_NEWAPI + #ifdef ZSTD_NEWAPI - { - /* frame parameters */ + { /* frame parameters */ CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_contentSizeFlag, srcIsRegularFile) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_dictIDFlag, g_dictIDFlag) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_checksumFlag, g_checksumFlag) ); @@ -396,6 +395,8 @@ static cRess_t FIO_createCResources(const char* dictFileName, int cLevel, CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_minMatch, comprParams->searchLength) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_targetLength, comprParams->targetLength) ); CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_compressionStrategy, (U32)comprParams->strategy) ); + /* multi-threading */ + CHECK( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_p_nbThreads, g_nbThreads) ); /* dictionary */ CHECK( ZSTD_CCtx_loadDictionary(ress.cctx, dictBuffer, dictBuffSize) ); } From f129fd39703183920ecd673bf6a94a2322b92771 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 11 Jun 2017 18:46:09 -0700 Subject: [PATCH 150/400] disabled MT code path when ZSTD_MULTITHREAD is not defined --- lib/compress/zstd_compress.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 338dd7472..db672da04 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3760,18 +3760,24 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM) params.cParams = ZSTD_getCParams(cctx->compressionLevel, cctx->frameContentSize, 0 /* dictSize */); + +#ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->frameContentSize) ); cctx->streamStage = zcss_load; - } else { + } else +#endif + { CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); } } +#ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); if (ZSTD_isError(flushMin)) cctx->streamStage = zcss_init; return flushMin; } +#endif DEBUGLOG(5, "starting ZSTD_compressStream_generic"); CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); From 385f8d96b7f94f1d2a46cf2e6b0517c697d74261 Mon Sep 17 00:00:00 2001 From: Muhammad Azeem Date: Mon, 12 Jun 2017 11:09:44 +0800 Subject: [PATCH 151/400] Minor grammatical changes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eee92f917..f37be4542 100644 --- a/README.md +++ b/README.md @@ -67,11 +67,11 @@ Previous charts provide results applicable to typical file and stream scenarios The smaller the amount of data to compress, the more difficult it is to compress. This problem is common to all compression algorithms, and reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new data set, there is no "past" to build upon. To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data. -Training Zstandard is achieved by provide it with a few samples (one file per sample). The result of this training is stored in a file called "dictionary", which must be loaded before compression and decompression. +Training Zstandard is achieved by providing it with a few samples (one file per sample). The result of this training is stored in a file called "dictionary", which must be loaded before compression and decompression. Using this dictionary, the compression ratio achievable on small data improves dramatically. The following example uses the `github-users` [sample set](https://github.com/facebook/zstd/releases/tag/v1.1.3), created from [github public API](https://developer.github.com/v3/users/#get-all-users). -It consists of roughly 10K records weighting about 1KB each. +It consists of roughly 10K records weighing about 1KB each. Compression Ratio | Compression Speed | Decompression Speed ------------------|-------------------|-------------------- From bb0aaf9579a295594bc92b2d0762829c0c609508 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 12 Jun 2017 05:19:15 -0700 Subject: [PATCH 152/400] minor man update on -B# option in benchmark mode --- programs/zstd.1 | 6 +++--- programs/zstd.1.md | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/programs/zstd.1 b/programs/zstd.1 index 427146795..7e2e99159 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -1,5 +1,5 @@ . -.TH "ZSTD" "1" "May 2017" "zstd 1.3.0" "User Commands" +.TH "ZSTD" "1" "June 2017" "zstd 1.3.0" "User Commands" . .SH "NAME" \fBzstd\fR \- zstd, zstdmt, unzstd, zstdcat \- Compress or decompress \.zst files @@ -235,8 +235,8 @@ benchmark file(s) using multiple compression levels, from \fB\-b#\fR to \fB\-e#\ minimum evaluation time, in seconds (default : 3s), benchmark mode only . .TP -\fB\-B#\fR -cut file into independent blocks of size # (default: no block) +\fB\-B#\fR, \fB\-\-block\-size=#\fR +cut file(s) into independent blocks of size # (default: no block) . .TP \fB\-\-priority=rt\fR diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 2f5a6747e..4e731ddba 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -230,8 +230,8 @@ BENCHMARK benchmark file(s) using multiple compression levels, from `-b#` to `-e#` (inclusive) * `-i#`: minimum evaluation time, in seconds (default : 3s), benchmark mode only -* `-B#`: - cut file into independent blocks of size # (default: no block) +* `-B#`, `--block-size=#`: + cut file(s) into independent blocks of size # (default: no block) * `--priority=rt`: set process priority to real-time From a3d54cf73d9927fe528d7d2b019286f84999a535 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 10:58:34 -0700 Subject: [PATCH 153/400] added line spacing for clarity --- programs/fileio.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index c836020c9..a7812d73a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -867,18 +867,20 @@ int FIO_listFile(const char* infilename, int displayLevel){ const char* const suffixPtr = strrchr(infilename, '.'); if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", infilename); - return 1; + DISPLAY("\n"); + return 1; } else{ - U64 const compSize = UTIL_getFileSize(infilename); + U64 const compSize = UTIL_getFileSize(infilename); if(displayLevel<=2){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY(" %7.2f MB\n", (double)compSize/(1 MB)); + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY(" %7.2f MB\n", (double)compSize/(1 MB)); } else{ DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)compSize/(1 MB), compSize); } } + DISPLAY("\n"); return 0; } From 786b7cac27634e87a1cebdf3055e762fd15180f0 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 13:46:39 -0700 Subject: [PATCH 154/400] added code to analyze the first frame header --- programs/fileio.c | 70 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index a7812d73a..bf92f6b11 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -862,22 +862,78 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, return result; } -int FIO_listFile(const char* infilename, int displayLevel){ - DISPLAY("FILE DETECTED: %s\n", infilename); - const char* const suffixPtr = strrchr(infilename, '.'); +typedef struct { + int numActualFrames; + int numSkippableFrames; + U64 decompressedSize; + U64 compressedSize; + int usesCheck; +} fileInfo_t; + +/* + * Reads information from file, stores in *info + * if successful, returns 0, otherwise returns 1 + */ +int getFileInfo(fileInfo_t* info, const char* inFileName){ + FILE* srcFile = FIO_openSrcFile(inFileName); + if(srcFile==NULL){ + return 1; + } + info->compressedSize = UTIL_getFileSize(inFileName); + BYTE* frameHeaderBuffer = malloc(ZSTD_frameHeaderSize_max); + fread(frameHeaderBuffer, ZSTD_frameHeaderSize_max, 1, srcFile); + info->decompressedSize = 0; + info->numActualFrames = 0; + info-> numSkippableFrames = 0; + + /* begin analyzing frame */ + + info->decompressedSize += ZSTD_getFrameContentSize((void*)frameHeaderBuffer, ZSTD_FRAMEHEADERSIZE_MAX); + U32 magicNumber = frameHeaderBuffer[0] + (frameHeaderBuffer[1] << 8) + (frameHeaderBuffer[2] << 16) + (frameHeaderBuffer[3] << 24); + if(magicNumber==ZSTD_MAGICNUMBER){ + info->numActualFrames++; + } + else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ + info->numSkippableFrames++; + } + const int checksumBitMask = 4; + if(frameHeaderBuffer[1] & checksumBitMask){ + DISPLAY("Uses checksum\n"); + info->usesCheck = 1; + } + return 0; +} + +int FIO_listFile(const char* inFileName, int displayLevel){ + DISPLAY("FILE DETECTED: %s\n", inFileName); + const char* const suffixPtr = strrchr(inFileName, '.'); if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ - DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", infilename); + DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", inFileName); DISPLAY("\n"); return 1; } else{ - U64 const compSize = UTIL_getFileSize(infilename); + fileInfo_t* info = malloc(sizeof(fileInfo_t)); + int error = getFileInfo(info, inFileName); + if(error==1){ + DISPLAY("An error occurred with getting file info\n"); + exit(1); + } if(displayLevel<=2){ DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY(" %7.2f MB\n", (double)compSize/(1 MB)); + DISPLAY(" %7.2f MB\n", (double)info->compressedSize/(1 MB)); } else{ - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)compSize/(1 MB), compSize); + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)info->compressedSize/(1 MB), info->compressedSize); + if(info->decompressedSize!=ZSTD_CONTENTSIZE_ERROR && info->decompressedSize!=ZSTD_CONTENTSIZE_UNKNOWN){ + DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", (double)info->decompressedSize/(1 MB), info->decompressedSize); + } + else if(info->decompressedSize==ZSTD_CONTENTSIZE_ERROR){ + DISPLAY("Decompressed Size: There was an error with getting the decompressed size\n"); + } + else{ + DISPLAY("Decompressed Size: N/A\n"); + } } } DISPLAY("\n"); From 9cb602ee25736e81a004fd6caa667ab101510e41 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 15:22:48 -0700 Subject: [PATCH 155/400] added in logic for parsing through blocks/frames --- programs/fileio.c | 101 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index bf92f6b11..a2d9b8f30 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -870,6 +870,8 @@ typedef struct { int usesCheck; } fileInfo_t; + + /* * Reads information from file, stores in *info * if successful, returns 0, otherwise returns 1 @@ -880,26 +882,93 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ return 1; } info->compressedSize = UTIL_getFileSize(inFileName); - BYTE* frameHeaderBuffer = malloc(ZSTD_frameHeaderSize_max); - fread(frameHeaderBuffer, ZSTD_frameHeaderSize_max, 1, srcFile); info->decompressedSize = 0; info->numActualFrames = 0; info-> numSkippableFrames = 0; - /* begin analyzing frame */ - - info->decompressedSize += ZSTD_getFrameContentSize((void*)frameHeaderBuffer, ZSTD_FRAMEHEADERSIZE_MAX); - U32 magicNumber = frameHeaderBuffer[0] + (frameHeaderBuffer[1] << 8) + (frameHeaderBuffer[2] << 16) + (frameHeaderBuffer[3] << 24); - if(magicNumber==ZSTD_MAGICNUMBER){ - info->numActualFrames++; - } - else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ - info->numSkippableFrames++; - } - const int checksumBitMask = 4; - if(frameHeaderBuffer[1] & checksumBitMask){ - DISPLAY("Uses checksum\n"); - info->usesCheck = 1; + while(1){ + BYTE magicNumberBuffer[4]; + int numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); + if(numBytesRead != 4) break; + U32 magicNumber = MEM_readLE32(magicNumberBuffer); + if(magicNumber==ZSTD_MAGICNUMBER){ + DISPLAY("Hello\n"); + int frameContentSizeBytes=0; + info->numActualFrames++; + BYTE frameHeaderDescriptor; + fread(&frameHeaderDescriptor, 1, 1, srcFile); + + /* calculate actual frame header size */ + int frameContentSizeFlag = frameHeaderDescriptor >> 6; + int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; + int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; + int dictionaryIDFlag = frameHeaderDescriptor & 3; + if(frameContentSizeFlag!=0){ + frameContentSizeBytes = 1 << frameContentSizeFlag; + } + else if(singleSegmentFlag){ + frameContentSizeBytes = 1; + } + int windowDescriptorBytes = singleSegmentFlag ? 0 : 1; + int dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; + int totalFrameHeaderBytes = 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; + + /* reset to beginning of from and read entire header */ + fseek(srcFile, -5, SEEK_CUR); + BYTE* frameHeader = malloc(totalFrameHeaderBytes); + fread(frameHeader, totalFrameHeaderBytes, 1, srcFile); + + /* get decompressed file size */ + info->decompressedSize = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + + /* check if checksum is used */ + if(contentChecksumFlag){ + info->usesCheck = 1; + } + + /* skip the rest of the blocks in the frame */ + int lastBlock = 0; + do{ + BYTE blockHeaderBuffer[3]; + fread(blockHeaderBuffer, 3, 1, srcFile); + U32 blockHeader = MEM_readLE24(blockHeaderBuffer); + lastBlock = blockHeader & 1; + int blockSize = (blockHeader - (blockHeader & 7)) >> 3; + fseek(srcFile, blockSize, SEEK_CUR); + }while(lastBlock != 1); + if(contentChecksumFlag){ + fseek(srcFile, 4, SEEK_CUR); + } + } + else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ + info->numSkippableFrames++; + BYTE frameSizeBuffer[4]; + fread(frameSizeBuffer, 4, 1, srcFile); + long frameSize = MEM_readLE32(frameSizeBuffer); + fseek(srcFile, frameSize, SEEK_CUR); + } + + + // int isSkippableFrame = 0; + // /* analyze the first 18 bytes (magic number + frame header) of the frame */ + // BYTE* frameHeaderBuffer = malloc(ZSTD_frameHeaderSize_max); + // fread(frameHeaderBuffer, ZSTD_frameHeaderSize_max, 1, srcFile); + // info->decompressedSize += ZSTD_getFrameContentSize((void*)frameHeaderBuffer, ZSTD_FRAMEHEADERSIZE_MAX); + // U32 magicNumber = frameHeaderBuffer[0] + (frameHeaderBuffer[1] << 8) + (frameHeaderBuffer[2] << 16) + (frameHeaderBuffer[3] << 24); + // if(magicNumber==ZSTD_MAGICNUMBER){ + // info->numActualFrames++; + // } + // else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ + // info->numSkippableFrames++; + // isSkippableFrame = 1; + // } + // const int checksumBitMask = 4; + // if(frameHeaderBuffer[1] & checksumBitMask){ + // DISPLAY("Uses checksum\n"); + // info->usesCheck = 1; + // } + + } return 0; } From 6996bd25985d13d7e4fe8274865353b0a951acd7 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 15:24:50 -0700 Subject: [PATCH 156/400] removed useless lines --- programs/fileio.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index a2d9b8f30..2e8e4a6f6 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -892,7 +892,6 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ if(numBytesRead != 4) break; U32 magicNumber = MEM_readLE32(magicNumberBuffer); if(magicNumber==ZSTD_MAGICNUMBER){ - DISPLAY("Hello\n"); int frameContentSizeBytes=0; info->numActualFrames++; BYTE frameHeaderDescriptor; @@ -948,27 +947,6 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ fseek(srcFile, frameSize, SEEK_CUR); } - - // int isSkippableFrame = 0; - // /* analyze the first 18 bytes (magic number + frame header) of the frame */ - // BYTE* frameHeaderBuffer = malloc(ZSTD_frameHeaderSize_max); - // fread(frameHeaderBuffer, ZSTD_frameHeaderSize_max, 1, srcFile); - // info->decompressedSize += ZSTD_getFrameContentSize((void*)frameHeaderBuffer, ZSTD_FRAMEHEADERSIZE_MAX); - // U32 magicNumber = frameHeaderBuffer[0] + (frameHeaderBuffer[1] << 8) + (frameHeaderBuffer[2] << 16) + (frameHeaderBuffer[3] << 24); - // if(magicNumber==ZSTD_MAGICNUMBER){ - // info->numActualFrames++; - // } - // else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ - // info->numSkippableFrames++; - // isSkippableFrame = 1; - // } - // const int checksumBitMask = 4; - // if(frameHeaderBuffer[1] & checksumBitMask){ - // DISPLAY("Uses checksum\n"); - // info->usesCheck = 1; - // } - - } return 0; } From dcd6ba6dc64f56ff80150de6a904492d372c3c32 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 15:40:47 -0700 Subject: [PATCH 157/400] incremented decompressedSize instead of setting value --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 2e8e4a6f6..d5da78479 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -918,7 +918,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ fread(frameHeader, totalFrameHeaderBytes, 1, srcFile); /* get decompressed file size */ - info->decompressedSize = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + info->decompressedSize += ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); /* check if checksum is used */ if(contentChecksumFlag){ From 6e0204470a745df9e9bbee053ca5a4e78bdf7ce6 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 15:51:59 -0700 Subject: [PATCH 158/400] displayed decompressed size --- programs/fileio.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index d5da78479..d29589544 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -866,6 +866,7 @@ typedef struct { int numActualFrames; int numSkippableFrames; U64 decompressedSize; + int canComputeDecompSize; U64 compressedSize; int usesCheck; } fileInfo_t; @@ -885,6 +886,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ info->decompressedSize = 0; info->numActualFrames = 0; info-> numSkippableFrames = 0; + info->canComputeDecompSize = 1; /* begin analyzing frame */ while(1){ BYTE magicNumberBuffer[4]; @@ -918,7 +920,13 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ fread(frameHeader, totalFrameHeaderBytes, 1, srcFile); /* get decompressed file size */ - info->decompressedSize += ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + U64 additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + if(additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR){ + info->decompressedSize += additional; + } + else{ + info->canComputeDecompSize = 0; + } /* check if checksum is used */ if(contentChecksumFlag){ @@ -966,9 +974,14 @@ int FIO_listFile(const char* inFileName, int displayLevel){ DISPLAY("An error occurred with getting file info\n"); exit(1); } + + double compressedSizeMB = (double)info->compressedSize/(1 MB); + double decompressedSizeMB = (double)info->decompressedSize/(1 MB); + DISPLAY("%d %d\n", info->canComputeDecompSize, info->usesCheck); + if(displayLevel<=2){ DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY(" %7.2f MB\n", (double)info->compressedSize/(1 MB)); + DISPLAY(" %7.2f MB %7.2f MB\n", compressedSizeMB, decompressedSizeMB); } else{ DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)info->compressedSize/(1 MB), info->compressedSize); From f3d6ab28a250445f78f01bbf92bc2de01ad4fe86 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 15:59:28 -0700 Subject: [PATCH 159/400] formated information for verbose output --- programs/fileio.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index d29589544..b8dfd898e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -977,22 +977,21 @@ int FIO_listFile(const char* inFileName, int displayLevel){ double compressedSizeMB = (double)info->compressedSize/(1 MB); double decompressedSizeMB = (double)info->decompressedSize/(1 MB); - DISPLAY("%d %d\n", info->canComputeDecompSize, info->usesCheck); if(displayLevel<=2){ DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); DISPLAY(" %7.2f MB %7.2f MB\n", compressedSizeMB, decompressedSizeMB); } else{ - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", (double)info->compressedSize/(1 MB), info->compressedSize); - if(info->decompressedSize!=ZSTD_CONTENTSIZE_ERROR && info->decompressedSize!=ZSTD_CONTENTSIZE_UNKNOWN){ - DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", (double)info->decompressedSize/(1 MB), info->decompressedSize); + DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); + DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); + if(info->canComputeDecompSize){ + DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } - else if(info->decompressedSize==ZSTD_CONTENTSIZE_ERROR){ - DISPLAY("Decompressed Size: There was an error with getting the decompressed size\n"); - } - else{ - DISPLAY("Decompressed Size: N/A\n"); + if(info->usesCheck){ + DISPLAY("Check: XXH64\n"); } } } From 173a7397170ffe2c1633cc319140b5142afe3579 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 16:14:04 -0700 Subject: [PATCH 160/400] code refactorings with explicit conversion --- programs/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index b8dfd898e..29029238e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -890,7 +890,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ /* begin analyzing frame */ while(1){ BYTE magicNumberBuffer[4]; - int numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); + size_t numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); if(numBytesRead != 4) break; U32 magicNumber = MEM_readLE32(magicNumberBuffer); if(magicNumber==ZSTD_MAGICNUMBER){ @@ -916,7 +916,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ /* reset to beginning of from and read entire header */ fseek(srcFile, -5, SEEK_CUR); - BYTE* frameHeader = malloc(totalFrameHeaderBytes); + BYTE* frameHeader = (BYTE*)malloc(totalFrameHeaderBytes); fread(frameHeader, totalFrameHeaderBytes, 1, srcFile); /* get decompressed file size */ @@ -968,7 +968,7 @@ int FIO_listFile(const char* inFileName, int displayLevel){ return 1; } else{ - fileInfo_t* info = malloc(sizeof(fileInfo_t)); + fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); int error = getFileInfo(info, inFileName); if(error==1){ DISPLAY("An error occurred with getting file info\n"); From 6e33c74133a78673f6fa5729b80ab423b0d38f9c Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 16:29:00 -0700 Subject: [PATCH 161/400] formatting issues resolved --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 29029238e..73912be5a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -985,9 +985,9 @@ int FIO_listFile(const char* inFileName, int displayLevel){ else{ DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); + DISPLAY("Compressed Size: %.2f MB (%lu B)\n", compressedSizeMB, info->compressedSize); if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Decompressed Size: %.2f MB (%lu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } if(info->usesCheck){ From 618a7b66e2977edc113516e0d362d517934e606e Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 16:53:50 -0700 Subject: [PATCH 162/400] refactoring for C90 syntax --- programs/fileio.c | 66 ++++++++++++++++++++++++++++++++-------------- programs/zstdcli.c | 8 +++--- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 73912be5a..e49d0386f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -891,36 +891,54 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ while(1){ BYTE magicNumberBuffer[4]; size_t numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); + U32 magicNumber; if(numBytesRead != 4) break; - U32 magicNumber = MEM_readLE32(magicNumberBuffer); + magicNumber = MEM_readLE32(magicNumberBuffer); if(magicNumber==ZSTD_MAGICNUMBER){ - int frameContentSizeBytes=0; - info->numActualFrames++; BYTE frameHeaderDescriptor; - fread(&frameHeaderDescriptor, 1, 1, srcFile); - + int frameContentSizeFlag; + int singleSegmentFlag; + int contentChecksumFlag; + int dictionaryIDFlag; + int frameContentSizeBytes=0; + int windowDescriptorBytes; + int dictionaryIDBytes; + int totalFrameHeaderBytes; + BYTE* frameHeader; + U64 additional; + int lastBlock; + size_t readBytes = fread(&frameHeaderDescriptor, 1, 1, srcFile); + info->numActualFrames++; + if(readBytes != 1){ + DISPLAY("There was an error with reading frame header descriptor\n"); + exit(1); + } /* calculate actual frame header size */ - int frameContentSizeFlag = frameHeaderDescriptor >> 6; - int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; - int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; - int dictionaryIDFlag = frameHeaderDescriptor & 3; + frameContentSizeFlag = frameHeaderDescriptor >> 6; + singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; + contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; + dictionaryIDFlag = frameHeaderDescriptor & 3; if(frameContentSizeFlag!=0){ frameContentSizeBytes = 1 << frameContentSizeFlag; } else if(singleSegmentFlag){ frameContentSizeBytes = 1; } - int windowDescriptorBytes = singleSegmentFlag ? 0 : 1; - int dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; - int totalFrameHeaderBytes = 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; + windowDescriptorBytes = singleSegmentFlag ? 0 : 1; + dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; + totalFrameHeaderBytes = 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; /* reset to beginning of from and read entire header */ fseek(srcFile, -5, SEEK_CUR); - BYTE* frameHeader = (BYTE*)malloc(totalFrameHeaderBytes); - fread(frameHeader, totalFrameHeaderBytes, 1, srcFile); + frameHeader = (BYTE*)malloc(totalFrameHeaderBytes); + readBytes = fread(frameHeader, 1, totalFrameHeaderBytes, srcFile); + if(readBytes != (size_t)totalFrameHeaderBytes){ + DISPLAY("There was an error reading the frame header\n"); + exit(1); + } /* get decompressed file size */ - U64 additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); if(additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR){ info->decompressedSize += additional; } @@ -934,10 +952,14 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ } /* skip the rest of the blocks in the frame */ - int lastBlock = 0; + lastBlock = 0; do{ BYTE blockHeaderBuffer[3]; - fread(blockHeaderBuffer, 3, 1, srcFile); + readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); + if(readBytes != 3){ + DISPLAY("There was a problem reading the block header\n"); + exit(1); + } U32 blockHeader = MEM_readLE24(blockHeaderBuffer); lastBlock = blockHeader & 1; int blockSize = (blockHeader - (blockHeader & 7)) >> 3; @@ -950,7 +972,11 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ info->numSkippableFrames++; BYTE frameSizeBuffer[4]; - fread(frameSizeBuffer, 4, 1, srcFile); + size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); + if(readBytes != 4){ + DISPLAY("There was an error reading skippable frame size"); + exit(1); + } long frameSize = MEM_readLE32(frameSizeBuffer); fseek(srcFile, frameSize, SEEK_CUR); } @@ -985,9 +1011,9 @@ int FIO_listFile(const char* inFileName, int displayLevel){ else{ DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%lu B)\n", compressedSizeMB, info->compressedSize); + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%lu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } if(info->usesCheck){ diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 74f2606bc..91bce8bb8 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -674,13 +674,13 @@ int main(int argCount, const char* argv[]) } #endif if(operation==zom_list){ - DISPLAY("===========================================\n"); - DISPLAY("Printing information about compressed files\n"); - DISPLAY("===========================================\n"); unsigned u; + DISPLAY("===========================================\n"); + DISPLAY("Printing information about compressed files\n"); + DISPLAY("===========================================\n"); DISPLAY("Number of files listed: %d\n", filenameIdx); for(u=0; u Date: Mon, 12 Jun 2017 17:09:08 -0700 Subject: [PATCH 163/400] more refactoring for C90 --- programs/fileio.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index e49d0386f..497e202d1 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -955,14 +955,16 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ lastBlock = 0; do{ BYTE blockHeaderBuffer[3]; + U32 blockHeader; + int blockSize; readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); if(readBytes != 3){ DISPLAY("There was a problem reading the block header\n"); exit(1); } - U32 blockHeader = MEM_readLE24(blockHeaderBuffer); + blockHeader = MEM_readLE24(blockHeaderBuffer); lastBlock = blockHeader & 1; - int blockSize = (blockHeader - (blockHeader & 7)) >> 3; + blockSize = (blockHeader - (blockHeader & 7)) >> 3; fseek(srcFile, blockSize, SEEK_CUR); }while(lastBlock != 1); if(contentChecksumFlag){ @@ -970,14 +972,15 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ } } else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ - info->numSkippableFrames++; BYTE frameSizeBuffer[4]; + long frameSize; + info->numSkippableFrames++; size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); if(readBytes != 4){ DISPLAY("There was an error reading skippable frame size"); exit(1); } - long frameSize = MEM_readLE32(frameSizeBuffer); + frameSize = MEM_readLE32(frameSizeBuffer); fseek(srcFile, frameSize, SEEK_CUR); } @@ -986,14 +989,16 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ } int FIO_listFile(const char* inFileName, int displayLevel){ - DISPLAY("FILE DETECTED: %s\n", inFileName); const char* const suffixPtr = strrchr(inFileName, '.'); + DISPLAY("FILE DETECTED: %s\n", inFileName); if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", inFileName); DISPLAY("\n"); return 1; } else{ + double compressedSizeMB; + double decompressedSizeMB; fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); int error = getFileInfo(info, inFileName); if(error==1){ @@ -1001,8 +1006,8 @@ int FIO_listFile(const char* inFileName, int displayLevel){ exit(1); } - double compressedSizeMB = (double)info->compressedSize/(1 MB); - double decompressedSizeMB = (double)info->decompressedSize/(1 MB); + compressedSizeMB = (double)info->compressedSize/(1 MB); + decompressedSizeMB = (double)info->decompressedSize/(1 MB); if(displayLevel<=2){ DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); From c828b521119b55d12fccc8ae14a949b3b8bf66ed Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 17:19:53 -0700 Subject: [PATCH 164/400] yet more refactoring --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 497e202d1..bf8d6d61b 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -974,8 +974,8 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ BYTE frameSizeBuffer[4]; long frameSize; - info->numSkippableFrames++; size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); + info->numSkippableFrames++; if(readBytes != 4){ DISPLAY("There was an error reading skippable frame size"); exit(1); From a56dcbfcf8d41724414f3cc662d6fcbc6242e3d7 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 12 Jun 2017 17:47:33 -0700 Subject: [PATCH 165/400] changed print format for non-verbose version --- programs/fileio.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index bf8d6d61b..dadb8ecb3 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1010,8 +1010,28 @@ int FIO_listFile(const char* inFileName, int displayLevel){ decompressedSizeMB = (double)info->decompressedSize/(1 MB); if(displayLevel<=2){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY(" %7.2f MB %7.2f MB\n", compressedSizeMB, decompressedSizeMB); + if(info->usesCheck && info->canComputeDecompSize){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, + compressedSizeMB/decompressedSizeMB, inFileName); + } + else if(!info->usesCheck){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, + compressedSizeMB/decompressedSizeMB, inFileName); + } + else if(!info->canComputeDecompSize){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB XXH64 %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); + } + else{ + DISPLAY("Skippable Non-Skippable Filename\n"); + DISPLAY("%9d %13d %7.2f MB %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); + } } else{ DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); From 81fa33b55a8db2256c26391b3531de16bc1f23bf Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 13 Jun 2017 10:06:49 -0700 Subject: [PATCH 166/400] cleaning up code --- programs/fileio.c | 162 +++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index dadb8ecb3..ca08c7f9d 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -872,6 +872,23 @@ typedef struct { } fileInfo_t; +int calcFrameHeaderSize(BYTE frameHeaderDescriptor){ + int frameContentSizeBytes = 0; + int windowDescriptorBytes; + int dictionaryIDBytes; + int frameContentSizeFlag = frameHeaderDescriptor >> 6; + int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; + int dictionaryIDFlag = frameHeaderDescriptor & 3; + if(frameContentSizeFlag!=0){ + frameContentSizeBytes = 1 << frameContentSizeFlag; + } + else if(singleSegmentFlag){ + frameContentSizeBytes = 1; + } + windowDescriptorBytes = singleSegmentFlag ? 0 : 1; + dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; + return 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; +} /* * Reads information from file, stores in *info @@ -896,17 +913,9 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ magicNumber = MEM_readLE32(magicNumberBuffer); if(magicNumber==ZSTD_MAGICNUMBER){ BYTE frameHeaderDescriptor; - int frameContentSizeFlag; - int singleSegmentFlag; - int contentChecksumFlag; - int dictionaryIDFlag; - int frameContentSizeBytes=0; - int windowDescriptorBytes; - int dictionaryIDBytes; int totalFrameHeaderBytes; BYTE* frameHeader; - U64 additional; - int lastBlock; + int lastBlock = 0; size_t readBytes = fread(&frameHeaderDescriptor, 1, 1, srcFile); info->numActualFrames++; if(readBytes != 1){ @@ -914,19 +923,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ exit(1); } /* calculate actual frame header size */ - frameContentSizeFlag = frameHeaderDescriptor >> 6; - singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; - contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; - dictionaryIDFlag = frameHeaderDescriptor & 3; - if(frameContentSizeFlag!=0){ - frameContentSizeBytes = 1 << frameContentSizeFlag; - } - else if(singleSegmentFlag){ - frameContentSizeBytes = 1; - } - windowDescriptorBytes = singleSegmentFlag ? 0 : 1; - dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; - totalFrameHeaderBytes = 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; + totalFrameHeaderBytes = calcFrameHeaderSize(frameHeaderDescriptor); /* reset to beginning of from and read entire header */ fseek(srcFile, -5, SEEK_CUR); @@ -938,21 +935,17 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ } /* get decompressed file size */ - additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); - if(additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR){ - info->decompressedSize += additional; - } - else{ - info->canComputeDecompSize = 0; - } - - /* check if checksum is used */ - if(contentChecksumFlag){ - info->usesCheck = 1; + { + U64 additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); + if(additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR){ + info->decompressedSize += additional; + } + else{ + info->canComputeDecompSize = 0; + } } /* skip the rest of the blocks in the frame */ - lastBlock = 0; do{ BYTE blockHeaderBuffer[3]; U32 blockHeader; @@ -967,8 +960,15 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ blockSize = (blockHeader - (blockHeader & 7)) >> 3; fseek(srcFile, blockSize, SEEK_CUR); }while(lastBlock != 1); - if(contentChecksumFlag){ - fseek(srcFile, 4, SEEK_CUR); + { + /* check if checksum is used */ + int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; + if(contentChecksumFlag){ + info->usesCheck = 1; + } + if(contentChecksumFlag){ + fseek(srcFile, 4, SEEK_CUR); + } } } else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ @@ -987,64 +987,64 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ } return 0; } +void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ + double compressedSizeMB = (double)info->compressedSize/(1 MB); + double decompressedSizeMB = (double)info->decompressedSize/(1 MB); + + if(displayLevel<=2){ + if(info->usesCheck && info->canComputeDecompSize){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, + compressedSizeMB/decompressedSizeMB, inFileName); + } + else if(!info->usesCheck){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, + compressedSizeMB/decompressedSizeMB, inFileName); + } + else if(!info->canComputeDecompSize){ + DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAY("%9d %13d %7.2f MB XXH64 %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); + } + else{ + DISPLAY("Skippable Non-Skippable Filename\n"); + DISPLAY("%9d %13d %7.2f MB %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); + } + } + else{ + DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); + DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); + if(info->canComputeDecompSize){ + DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); + } + if(info->usesCheck){ + DISPLAY("Check: XXH64\n"); + } + } + +} int FIO_listFile(const char* inFileName, int displayLevel){ const char* const suffixPtr = strrchr(inFileName, '.'); - DISPLAY("FILE DETECTED: %s\n", inFileName); + DISPLAY("File: %s\n", inFileName); if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ - DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n", inFileName); - DISPLAY("\n"); + DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n\n", inFileName); return 1; } else{ - double compressedSizeMB; - double decompressedSizeMB; fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); int error = getFileInfo(info, inFileName); if(error==1){ DISPLAY("An error occurred with getting file info\n"); exit(1); } - - compressedSizeMB = (double)info->compressedSize/(1 MB); - decompressedSizeMB = (double)info->decompressedSize/(1 MB); - - if(displayLevel<=2){ - if(info->usesCheck && info->canComputeDecompSize){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, - compressedSizeMB/decompressedSizeMB, inFileName); - } - else if(!info->usesCheck){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, - compressedSizeMB/decompressedSizeMB, inFileName); - } - else if(!info->canComputeDecompSize){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB XXH64 %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); - } - else{ - DISPLAY("Skippable Non-Skippable Filename\n"); - DISPLAY("%9d %13d %7.2f MB %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); - } - } - else{ - DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); - DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); - if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); - DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); - } - if(info->usesCheck){ - DISPLAY("Check: XXH64\n"); - } - } + displayInfo(inFileName, info, displayLevel); } DISPLAY("\n"); return 0; From f35f252e36524c14c53fbebb6c20a9e3cc73ed43 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 13 Jun 2017 11:54:43 -0700 Subject: [PATCH 167/400] added code to generate dictionary using finalizeDictionary --- tests/decodecorpus.c | 104 ++++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 632acabb8..357d831e6 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -18,6 +18,7 @@ #include "zstd.h" #include "zstd_internal.h" #include "mem.h" +#include "zdict.h" // Direct access to internal compression functions is required #include "zstd_compress.c" @@ -316,7 +317,8 @@ static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, size_t dict op[pos++] = windowByte; } if(genDict) { - MEM_writeLE32(op + pos, (U32) dictSize); + MEM_writeLE32(op + pos, (U32) dictID); + pos += 4; } if (contentSizeFlag) { switch (fcsCode) { @@ -608,7 +610,7 @@ static inline void initSeqStore(seqStore_t *seqStore) { /* Randomly generate sequence commands */ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, - size_t contentSize, size_t literalsSize, int genDict, size_t dictSize) + size_t contentSize, size_t literalsSize, int genDict, size_t dictSize, BYTE* dictContent) { /* The total length of all the matches */ size_t const remainingMatch = contentSize - literalsSize; @@ -686,11 +688,17 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, repIndex = MIN(2, offsetCode + 1); } } - } while (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart) || offset == 0); + } while (((!genDict) && (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0); { size_t j; for (j = 0; j < matchLen; j++) { - *srcPtr = *(srcPtr-offset); + if(srcPtr-offset < frame->srcStart){ + /* copy from dictionary instead of literals */ + *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-frame->srcStart))); + } + else{ + *srcPtr = *(srcPtr-offset); + } srcPtr++; } } @@ -940,7 +948,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr, } static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize, - size_t literalsSize, int genDict, size_t dictSize) + size_t literalsSize, int genDict, size_t dictSize, BYTE* dictContent) { seqStore_t seqStore; size_t numSequences; @@ -949,14 +957,14 @@ static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize, initSeqStore(&seqStore); /* randomly generate sequences */ - numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize, genDict, dictSize); + numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize, genDict, dictSize, dictContent); /* write them out to the frame data */ CHECKERR(writeSequences(seed, frame, &seqStore, numSequences)); return numSequences; } -static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize, int genDict, size_t dictSize) +static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize, int genDict, size_t dictSize, BYTE* dictContent) { BYTE* const blockStart = (BYTE*)frame->data; size_t literalsSize; @@ -968,7 +976,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize DISPLAYLEVEL(4, " literals size: %u\n", (U32)literalsSize); - nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize, genDict, dictSize); + nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize, genDict, dictSize, dictContent); DISPLAYLEVEL(4, " number of sequences: %u\n", (U32)nbSeq); @@ -976,7 +984,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize } static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, - int lastBlock, int genDict, size_t dictSize) + int lastBlock, int genDict, size_t dictSize, BYTE* dictContent) { int const blockTypeDesc = RAND(seed) % 8; size_t blockSize; @@ -1016,7 +1024,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, frame->oldStats = frame->stats; frame->data = op; - compressedSize = writeCompressedBlock(seed, frame, contentSize, genDict, dictSize); + compressedSize = writeCompressedBlock(seed, frame, contentSize, genDict, dictSize, dictContent); if (compressedSize > contentSize) { blockType = 0; memcpy(op, frame->src, contentSize); @@ -1042,7 +1050,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize, frame->data = op; } -static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize) +static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize, BYTE* dictContent) { size_t contentLeft = frame->header.contentSize; size_t const maxBlockSize = MIN(MAX_BLOCK_SIZE, frame->header.windowSize); @@ -1065,7 +1073,7 @@ static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize) } } - writeBlock(seed, frame, blockContentSize, lastBlock, genDict, dictSize); + writeBlock(seed, frame, blockContentSize, lastBlock, genDict, dictSize, dictContent); contentLeft -= blockContentSize; if (lastBlock) break; @@ -1130,14 +1138,14 @@ static void initFrame(frame_t* fr) } /* Return the final seed */ -static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize) +static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize, BYTE* dictContent) { /* generate a complete frame */ DISPLAYLEVEL(1, "frame seed: %u\n", seed); initFrame(fr); writeFrameHeader(&seed, fr, genDict, dictSize); - writeBlocks(&seed, fr, genDict, dictSize); + writeBlocks(&seed, fr, genDict, dictSize, dictContent); writeChecksum(fr); return seed; @@ -1224,7 +1232,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS else DISPLAYUPDATE("\r%u ", fnum); - seed = generateFrame(seed, &fr, 0, 0); + seed = generateFrame(seed, &fr, 0, 0, NULL); { size_t const r = testDecodeSimple(&fr); if (ZSTD_isError(r)) { @@ -1259,7 +1267,7 @@ static int generateFile(U32 seed, const char* const path, DISPLAY("seed: %u\n", seed); - generateFrame(seed, &fr, 0, 0); + generateFrame(seed, &fr, 0, 0, NULL); outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, path); if (origPath) { @@ -1281,7 +1289,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); - seed = generateFrame(seed, &fr, 0, 0); + seed = generateFrame(seed, &fr, 0, 0, NULL); if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1308,9 +1316,11 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const { const size_t minDictSize = 8; char outPath[MAX_PATH]; + BYTE* dictContent; + BYTE* fullDict; U32 dictID; - BYTE* dictStart; unsigned fnum; + BYTE* decompressedPtr; ZSTD_DCtx* dctx = ZSTD_createDCtx(); if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1318,37 +1328,50 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const } /* Generate the dictionary randomly first */ - if(dictSize < minDictSize){ - DISPLAY("Error: dictionary size (%zu) is too small\n", dictSize); - } - else{ - /* variable declaration */ - dictStart = malloc(dictSize); - size_t pos = 0; - dictID = RAND(&seed) + 1; + dictContent = malloc(dictSize-400); + dictID = RAND(&seed); + fullDict = malloc(dictSize); + RAND_buffer(&seed, dictContent, dictSize-40); + { + /* create random samples */ + unsigned numSamples = RAND(&seed); + unsigned i = 0; + size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); + size_t* curr = sampleSizes; + size_t totalSize = 0; + while(i < numSamples){ + *curr = RAND(&seed) % (4 << 20); + totalSize += *curr; + curr++; + } + ZDICT_params_t zdictParams; + BYTE* samples = malloc(totalSize); + RAND_buffer(&seed, samples, totalSize); - /* write dictionary magic number */ - MEM_writeLE32(dictStart + pos, ZSTD_DICT_MAGIC); - pos += 4; + /* set dictionary params */ + memset(&zdictParams, 0, sizeof(zdictParams)); + zdictParams.notificationLevel = 1; + zdictParams.dictID = dictID; + zdictParams.compressionLevel = 5; - /* write random dictionary ID */ - MEM_writeLE32(dictStart + pos, dictID); - pos += 4; - - /* randomly generate the rest of the dictionary */ - RAND_buffer(&seed, dictStart + pos, dictSize-8); - outputBuffer(dictStart, dictSize, outPath); + /* finalize dictionary with random samples */ + ZDICT_finalizeDictionary(fullDict, dictSize, + dictContent, dictSize-400, + samples, sampleSizes, numSamples, + zdictParams); } + + decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); /* generate random compressed/decompressed files */ for (fnum = 0; fnum < numFiles; fnum++) { frame_t fr; size_t returnValue; - BYTE* decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); + DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); - seed = generateFrame(seed, &fr, 1, dictSize); + seed = generateFrame(seed, &fr, 1, dictSize, dictContent); if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1368,13 +1391,10 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE, fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, - dictStart,dictSize); + fullDict, dictSize); } - - /* write uncompressed versions of files */ - DISPLAY("This is origPath: %s\nAnd this is numFiles: %d\n", origPath, numFiles); return 0; } From 8dd621f788f7ba147ea8e3a727517d9975c8193f Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 13 Jun 2017 14:19:35 -0700 Subject: [PATCH 168/400] changed makefile to include zdict functions, wrote out dictionary to path --- tests/Makefile | 2 +- tests/decodecorpus.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index c275c081f..debe83898 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -180,7 +180,7 @@ legacy : CPPFLAGS+= -I$(ZSTDDIR)/legacy legacy : $(ZSTD_FILES) $(wildcard $(ZSTDDIR)/legacy/*.c) legacy.c $(CC) $(FLAGS) $^ -o $@$(EXT) -decodecorpus : $(filter-out $(ZSTDDIR)/compress/zstd_compress.c, $(wildcard $(ZSTD_FILES))) decodecorpus.c +decodecorpus : $(filter-out $(ZSTDDIR)/compress/zstd_compress.c, $(wildcard $(ZSTD_FILES))) $(ZDICT_FILES) decodecorpus.c $(CC) $(FLAGS) $^ -o $@$(EXT) -lm symbols : symbols.c diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 357d831e6..32b3659d1 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -18,6 +18,7 @@ #include "zstd.h" #include "zstd_internal.h" #include "mem.h" +#define ZDICT_STATIC_LINKING_ONLY #include "zdict.h" // Direct access to internal compression functions is required @@ -241,7 +242,7 @@ struct { } opts; /* advanced options on generation */ /* Generate and write a random frame header */ -static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, size_t dictSize) +static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, U32 dictID) { BYTE* const op = frame->data; size_t pos = 0; @@ -692,9 +693,9 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, { size_t j; for (j = 0; j < matchLen; j++) { - if(srcPtr-offset < frame->srcStart){ + if((void*)(srcPtr-offset) < (void*)frame->srcStart){ /* copy from dictionary instead of literals */ - *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-frame->srcStart))); + *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-(BYTE*)frame->srcStart))); } else{ *srcPtr = *(srcPtr-offset); @@ -1138,13 +1139,13 @@ static void initFrame(frame_t* fr) } /* Return the final seed */ -static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize, BYTE* dictContent) +static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize, BYTE* dictContent, U32 dictID) { /* generate a complete frame */ DISPLAYLEVEL(1, "frame seed: %u\n", seed); initFrame(fr); - writeFrameHeader(&seed, fr, genDict, dictSize); + writeFrameHeader(&seed, fr, genDict, dictID); writeBlocks(&seed, fr, genDict, dictSize, dictContent); writeChecksum(fr); @@ -1232,7 +1233,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS else DISPLAYUPDATE("\r%u ", fnum); - seed = generateFrame(seed, &fr, 0, 0, NULL); + seed = generateFrame(seed, &fr, 0, 0, NULL, 0); { size_t const r = testDecodeSimple(&fr); if (ZSTD_isError(r)) { @@ -1267,7 +1268,7 @@ static int generateFile(U32 seed, const char* const path, DISPLAY("seed: %u\n", seed); - generateFrame(seed, &fr, 0, 0, NULL); + generateFrame(seed, &fr, 0, 0, NULL, 0); outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, path); if (origPath) { @@ -1289,7 +1290,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); - seed = generateFrame(seed, &fr, 0, 0, NULL); + seed = generateFrame(seed, &fr, 0, 0, NULL, 0); if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1314,7 +1315,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path, const char* const origPath, const size_t dictSize) { - const size_t minDictSize = 8; + DISPLAY("in generateCorpusWithDict()\n"); char outPath[MAX_PATH]; BYTE* dictContent; BYTE* fullDict; @@ -1326,7 +1327,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAY("Error: path too long\n"); return 1; } - + DISPLAY("generating the dictionary randomly\n"); /* Generate the dictionary randomly first */ dictContent = malloc(dictSize-400); dictID = RAND(&seed); @@ -1334,12 +1335,13 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const RAND_buffer(&seed, dictContent, dictSize-40); { /* create random samples */ - unsigned numSamples = RAND(&seed); + unsigned numSamples = RAND(&seed) % 50; + DISPLAY("num samples: %u\n", numSamples); unsigned i = 0; size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); size_t* curr = sampleSizes; size_t totalSize = 0; - while(i < numSamples){ + while(i++ < numSamples){ *curr = RAND(&seed) % (4 << 20); totalSize += *curr; curr++; @@ -1349,19 +1351,23 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const RAND_buffer(&seed, samples, totalSize); /* set dictionary params */ - memset(&zdictParams, 0, sizeof(zdictParams)); - zdictParams.notificationLevel = 1; + memset(&zdictParams, 0, sizeof(ZDICT_params_t)); zdictParams.dictID = dictID; - zdictParams.compressionLevel = 5; /* finalize dictionary with random samples */ ZDICT_finalizeDictionary(fullDict, dictSize, dictContent, dictSize-400, samples, sampleSizes, numSamples, zdictParams); + /* write out dictionary */ + if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){ + DISPLAY("Error: dictionary path too long\n"); + return 1; + } + outputBuffer(fullDict, dictSize, outPath); } - + DISPLAY("generating compressed files\n"); decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); /* generate random compressed/decompressed files */ for (fnum = 0; fnum < numFiles; fnum++) { @@ -1371,7 +1377,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); - seed = generateFrame(seed, &fr, 1, dictSize, dictContent); + seed = generateFrame(seed, &fr, 1, dictSize, dictContent, dictID); if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); @@ -1394,7 +1400,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const fullDict, dictSize); } - + DISPLAY("end of function\n"); return 0; } From 07cfc975bb1ea9070b934ead4ce264b1eeef2ab4 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 13 Jun 2017 17:27:02 -0700 Subject: [PATCH 169/400] debugging error with finalizeDictionary() not writing dictionary properly --- tests/decodecorpus.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 32b3659d1..8e49e65b8 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1331,18 +1331,19 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const /* Generate the dictionary randomly first */ dictContent = malloc(dictSize-400); dictID = RAND(&seed); + DISPLAY("this is the dictID that is being stored: %u\n", dictID); fullDict = malloc(dictSize); RAND_buffer(&seed, dictContent, dictSize-40); { + size_t dictWriteSize = 0; /* create random samples */ unsigned numSamples = RAND(&seed) % 50; - DISPLAY("num samples: %u\n", numSamples); unsigned i = 0; size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); size_t* curr = sampleSizes; size_t totalSize = 0; while(i++ < numSamples){ - *curr = RAND(&seed) % (4 << 20); + *curr = RAND(&seed) % (4 << 15); totalSize += *curr; curr++; } @@ -1353,12 +1354,15 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const /* set dictionary params */ memset(&zdictParams, 0, sizeof(ZDICT_params_t)); zdictParams.dictID = dictID; - /* finalize dictionary with random samples */ - ZDICT_finalizeDictionary(fullDict, dictSize, + dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, dictContent, dictSize-400, samples, sampleSizes, numSamples, zdictParams); + DISPLAY("total size: %zu %zu\n", totalSize, dictSize); + if(dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)){ + DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize)); + } /* write out dictionary */ if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){ DISPLAY("Error: dictionary path too long\n"); From aa95bc0a5f86c8746390c5363ba5b0aff798f487 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 10:54:47 -0700 Subject: [PATCH 170/400] code refactoring and adding some print statements for debugging --- tests/decodecorpus.c | 55 +++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 8e49e65b8..5a897cc4e 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1315,7 +1315,6 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path, static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path, const char* const origPath, const size_t dictSize) { - DISPLAY("in generateCorpusWithDict()\n"); char outPath[MAX_PATH]; BYTE* dictContent; BYTE* fullDict; @@ -1327,42 +1326,51 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAY("Error: path too long\n"); return 1; } - DISPLAY("generating the dictionary randomly\n"); + /* Generate the dictionary randomly first */ dictContent = malloc(dictSize-400); dictID = RAND(&seed); - DISPLAY("this is the dictID that is being stored: %u\n", dictID); fullDict = malloc(dictSize); RAND_buffer(&seed, dictContent, dictSize-40); { size_t dictWriteSize = 0; + /* create random samples */ unsigned numSamples = RAND(&seed) % 50; + BYTE* samples; unsigned i = 0; size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); - size_t* curr = sampleSizes; - size_t totalSize = 0; - while(i++ < numSamples){ - *curr = RAND(&seed) % (4 << 15); - totalSize += *curr; - curr++; + { + size_t* curr = sampleSizes; + size_t totalSize = 0; + while(i++ < numSamples){ + *curr = RAND(&seed) % (4 << 15); + totalSize += *curr; + curr++; + } + samples = malloc(totalSize); + RAND_buffer(&seed, samples, totalSize); + } + + { + /* set dictionary params */ + ZDICT_params_t zdictParams; + memset(&zdictParams, 0, sizeof(zdictParams)); + zdictParams.dictID = dictID; + zdictParams.notificationLevel = 1; + + /* finalize dictionary with random samples */ + dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, + dictContent, dictSize-400, + samples, sampleSizes, numSamples, + zdictParams); } - ZDICT_params_t zdictParams; - BYTE* samples = malloc(totalSize); - RAND_buffer(&seed, samples, totalSize); - /* set dictionary params */ - memset(&zdictParams, 0, sizeof(ZDICT_params_t)); - zdictParams.dictID = dictID; - /* finalize dictionary with random samples */ - dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, - dictContent, dictSize-400, - samples, sampleSizes, numSamples, - zdictParams); - DISPLAY("total size: %zu %zu\n", totalSize, dictSize); if(dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)){ DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize)); + return 1; } + /* write out dictionary */ if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){ DISPLAY("Error: dictionary path too long\n"); @@ -1373,6 +1381,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAY("generating compressed files\n"); decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); + /* generate random compressed/decompressed files */ for (fnum = 0; fnum < numFiles; fnum++) { frame_t fr; @@ -1403,6 +1412,10 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, fullDict, dictSize); + if(ZSTD_isError(returnValue)){ + DISPLAY("Error: %s", ZSTD_getErrorName(returnValue)); + } + } DISPLAY("end of function\n"); return 0; From 3b0e24c06be1f7ac25f1410831baa848d0f012d3 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 12:04:22 -0700 Subject: [PATCH 171/400] added error message to catch case where size not given --- tests/decodecorpus.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 5a897cc4e..9bd6506e2 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1326,12 +1326,15 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAY("Error: path too long\n"); return 1; } - + if(dictSize < 400){ + DISPLAY("Error: either no size given or given dictionary size is too small\n"); + return 1; + } /* Generate the dictionary randomly first */ dictContent = malloc(dictSize-400); dictID = RAND(&seed); fullDict = malloc(dictSize); - RAND_buffer(&seed, dictContent, dictSize-40); + RAND_buffer(&seed, dictContent, dictSize-400); { size_t dictWriteSize = 0; From ebd60349f52b58197328b84016bd365e2e2d1bfd Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 13:11:18 -0700 Subject: [PATCH 172/400] changed U64 to unsigned long to get rid of build test errors --- programs/fileio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index ca08c7f9d..9d905062f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -865,9 +865,9 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, typedef struct { int numActualFrames; int numSkippableFrames; - U64 decompressedSize; + unsigned long decompressedSize; int canComputeDecompSize; - U64 compressedSize; + unsigned long compressedSize; int usesCheck; } fileInfo_t; @@ -1018,9 +1018,9 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ else{ DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); + DISPLAY("Compressed Size: %.2f MB (%lu B)\n", compressedSizeMB, info->compressedSize); if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Decompressed Size: %.2f MB (%lu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } if(info->usesCheck){ From 607ee9f4bcad9a72425392c55934be5237042e81 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 13:23:36 -0700 Subject: [PATCH 173/400] print message when no files are given, rearrange code for readability --- programs/zstdcli.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 91bce8bb8..f8612f297 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -674,13 +674,19 @@ int main(int argCount, const char* argv[]) } #endif if(operation==zom_list){ - unsigned u; + if(filenameIdx==0){ + DISPLAY("No files given\n"); + CLEAN_RETURN(0); + } DISPLAY("===========================================\n"); DISPLAY("Printing information about compressed files\n"); DISPLAY("===========================================\n"); DISPLAY("Number of files listed: %d\n", filenameIdx); - for(u=0; u Date: Wed, 14 Jun 2017 13:26:19 -0700 Subject: [PATCH 174/400] changing formatting again --- programs/fileio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 9d905062f..2708176c1 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -865,9 +865,9 @@ int FIO_compressFilename(const char* dstFileName, const char* srcFileName, typedef struct { int numActualFrames; int numSkippableFrames; - unsigned long decompressedSize; + unsigned long long decompressedSize; int canComputeDecompSize; - unsigned long compressedSize; + unsigned long long compressedSize; int usesCheck; } fileInfo_t; @@ -899,7 +899,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ if(srcFile==NULL){ return 1; } - info->compressedSize = UTIL_getFileSize(inFileName); + info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName); info->decompressedSize = 0; info->numActualFrames = 0; info-> numSkippableFrames = 0; @@ -1018,9 +1018,9 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ else{ DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%lu B)\n", compressedSizeMB, info->compressedSize); + DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%lu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } if(info->usesCheck){ From 664ed05ff6af2190c3c65e80458343484e12bbec Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 16:42:51 -0700 Subject: [PATCH 175/400] changed randomly generated samples to randomly selected from the dictionary content --- tests/decodecorpus.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 9bd6506e2..19cf6127b 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1352,7 +1352,22 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const curr++; } samples = malloc(totalSize); - RAND_buffer(&seed, samples, totalSize); + + /* reset pointer and counter */ + curr = sampleSizes; + i = 0; + + { + /* take substring from dictionary content */ + size_t pos = 0; + const BYTE* endDict = dictContent + dictSize - 400; + while(i++ < numSamples){ + size_t currSize = *(curr++); + BYTE* startSubstring = endDict - currSize; + memcpy(samples + pos, (void*)startSubstring, currSize); + pos += currSize; + } + } } { From d93207a79f1cebffa2ab9405bf823168d73dc241 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 17:23:56 -0700 Subject: [PATCH 176/400] changed dictionary from using fixed amount of bytes for the header / entropy tables --- tests/decodecorpus.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 19cf6127b..ba1a9160a 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1316,25 +1316,30 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const const char* const origPath, const size_t dictSize) { char outPath[MAX_PATH]; - BYTE* dictContent; BYTE* fullDict; U32 dictID; unsigned fnum; BYTE* decompressedPtr; + BYTE* dictContent; + const size_t headerSize = dictSize/4; + const size_t dictContentSize = dictSize - dictSize/4; ZSTD_DCtx* dctx = ZSTD_createDCtx(); if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); return 1; } - if(dictSize < 400){ - DISPLAY("Error: either no size given or given dictionary size is too small\n"); - return 1; + { + /* use 3/4 of dictionary for content, save rest for header/entropy tables */ + if(dictContentSize < 128 || dictSize < 256){ + DISPLAY("Error: dictionary size is too small\n"); + return 1; + } } /* Generate the dictionary randomly first */ - dictContent = malloc(dictSize-400); dictID = RAND(&seed); fullDict = malloc(dictSize); - RAND_buffer(&seed, dictContent, dictSize-400); + dictContent = fullDict + headerSize; + RAND_buffer(&seed, (void*)dictContent, dictContentSize); { size_t dictWriteSize = 0; @@ -1347,7 +1352,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const size_t* curr = sampleSizes; size_t totalSize = 0; while(i++ < numSamples){ - *curr = RAND(&seed) % (4 << 15); + *curr = RAND(&seed) % dictContentSize; totalSize += *curr; curr++; } @@ -1360,7 +1365,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const { /* take substring from dictionary content */ size_t pos = 0; - const BYTE* endDict = dictContent + dictSize - 400; + BYTE* endDict = dictContent + dictContentSize; while(i++ < numSamples){ size_t currSize = *(curr++); BYTE* startSubstring = endDict - currSize; @@ -1379,7 +1384,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const /* finalize dictionary with random samples */ dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, - dictContent, dictSize-400, + dictContent, dictContentSize, samples, sampleSizes, numSamples, zdictParams); } From 03a208e27cbfe69bd58d27205c16eaf643dd22e9 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Wed, 14 Jun 2017 18:06:16 -0700 Subject: [PATCH 177/400] changed samples to geometric distribution so that it is huffman compressible --- tests/decodecorpus.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index ba1a9160a..b1f4d701a 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1344,17 +1344,22 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const size_t dictWriteSize = 0; /* create random samples */ - unsigned numSamples = RAND(&seed) % 50; + unsigned numSamples = 0; BYTE* samples; unsigned i = 0; size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); { size_t* curr = sampleSizes; size_t totalSize = 0; - while(i++ < numSamples){ - *curr = RAND(&seed) % dictContentSize; - totalSize += *curr; - curr++; + while(numSamples < 100){ + unsigned numReps = ROUND(RAND_exp(&seed, 10)); + size_t randSize = RAND(&seed) % dictContentSize; + while(numReps-- > 0){ + *curr = randSize; + totalSize += *curr; + curr++; + } + numSamples += numReps; } samples = malloc(totalSize); @@ -1374,7 +1379,6 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const } } } - { /* set dictionary params */ ZDICT_params_t zdictParams; From 52934fbfc87bef37f7e95c380c3118bcb383b2a2 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 09:47:29 -0700 Subject: [PATCH 178/400] added print statements for debugging, fixed first segfault --- tests/decodecorpus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index b1f4d701a..ec826b01e 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1354,25 +1354,27 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const while(numSamples < 100){ unsigned numReps = ROUND(RAND_exp(&seed, 10)); size_t randSize = RAND(&seed) % dictContentSize; + numSamples += numReps; while(numReps-- > 0){ *curr = randSize; totalSize += *curr; curr++; } - numSamples += numReps; } samples = malloc(totalSize); /* reset pointer and counter */ curr = sampleSizes; i = 0; - + DISPLAY("total size: %zu\n", totalSize); { /* take substring from dictionary content */ size_t pos = 0; BYTE* endDict = dictContent + dictContentSize; while(i++ < numSamples){ size_t currSize = *(curr++); + DISPLAY("current size: %zu\n", currSize); + DISPLAY("dictionary content size: %zu\n", dictContentSize); BYTE* startSubstring = endDict - currSize; memcpy(samples + pos, (void*)startSubstring, currSize); pos += currSize; From 623b8fce85a49c8d4352e240925469a2d9f88944 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 11:37:24 -0700 Subject: [PATCH 179/400] add print statements for debugging and change malloc with updated size --- tests/decodecorpus.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index ec826b01e..96799f8bc 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1347,47 +1347,47 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const unsigned numSamples = 0; BYTE* samples; unsigned i = 0; - size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); + size_t* sampleSizes = malloc(255*sizeof(size_t)); { size_t* curr = sampleSizes; size_t totalSize = 0; - while(numSamples < 100){ - unsigned numReps = ROUND(RAND_exp(&seed, 10)); + unsigned numReps = 1; + while(numSamples < 200){ size_t randSize = RAND(&seed) % dictContentSize; + unsigned counter = numReps; numSamples += numReps; - while(numReps-- > 0){ + while(counter-- > 0){ *curr = randSize; totalSize += *curr; curr++; } + numReps *= 2; } samples = malloc(totalSize); /* reset pointer and counter */ curr = sampleSizes; i = 0; - DISPLAY("total size: %zu\n", totalSize); { /* take substring from dictionary content */ size_t pos = 0; BYTE* endDict = dictContent + dictContentSize; while(i++ < numSamples){ size_t currSize = *(curr++); - DISPLAY("current size: %zu\n", currSize); - DISPLAY("dictionary content size: %zu\n", dictContentSize); BYTE* startSubstring = endDict - currSize; memcpy(samples + pos, (void*)startSubstring, currSize); pos += currSize; } } } + DISPLAY("==================done with generation====================\n"); { /* set dictionary params */ ZDICT_params_t zdictParams; memset(&zdictParams, 0, sizeof(zdictParams)); zdictParams.dictID = dictID; zdictParams.notificationLevel = 1; - + DISPLAY("===================zdict params================\n"); /* finalize dictionary with random samples */ dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, dictContent, dictContentSize, @@ -1399,7 +1399,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize)); return 1; } - + DISPLAY("=================done with finalize=================\n"); /* write out dictionary */ if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){ DISPLAY("Error: dictionary path too long\n"); @@ -1442,7 +1442,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const fullDict, dictSize); if(ZSTD_isError(returnValue)){ - DISPLAY("Error: %s", ZSTD_getErrorName(returnValue)); + DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue)); } } From e20899252904b8e18b9c5b0a6f944ae289b89910 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 12:27:32 -0700 Subject: [PATCH 180/400] cleaning up code --- programs/fileio.c | 89 ++++++++++++++++++++++++++-------------------- programs/zstdcli.c | 1 + 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 2708176c1..8af3c5a77 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -91,6 +91,7 @@ * Macros ***************************************/ #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) +#define DISPLAYOUT(...) fprintf(stdout, __VA_ARGS__) #define DISPLAYLEVEL(l, ...) { if (g_displayLevel>=l) { DISPLAY(__VA_ARGS__); } } static int g_displayLevel = 2; /* 0 : no display; 1: errors; 2 : + result + interaction + warnings; 3 : + progression; 4 : + information */ void FIO_setNotificationLevel(unsigned level) { g_displayLevel=level; } @@ -872,21 +873,13 @@ typedef struct { } fileInfo_t; -int calcFrameHeaderSize(BYTE frameHeaderDescriptor){ - int frameContentSizeBytes = 0; - int windowDescriptorBytes; - int dictionaryIDBytes; - int frameContentSizeFlag = frameHeaderDescriptor >> 6; - int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; - int dictionaryIDFlag = frameHeaderDescriptor & 3; - if(frameContentSizeFlag!=0){ - frameContentSizeBytes = 1 << frameContentSizeFlag; - } - else if(singleSegmentFlag){ - frameContentSizeBytes = 1; - } - windowDescriptorBytes = singleSegmentFlag ? 0 : 1; - dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; +static int calcFrameHeaderSize(BYTE frameHeaderDescriptor){ + const int frameContentSizeFlag = frameHeaderDescriptor >> 6; + const int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; + const int dictionaryIDFlag = frameHeaderDescriptor & 3; + const int windowDescriptorBytes = singleSegmentFlag ? 0 : 1; + const int frameContentSizeBytes = (frameContentSizeFlag != 0) ? (1 << frameContentSizeFlag) : (singleSegmentFlag ? 1 : 0); + const int dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; return 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; } @@ -894,50 +887,67 @@ int calcFrameHeaderSize(BYTE frameHeaderDescriptor){ * Reads information from file, stores in *info * if successful, returns 0, otherwise returns 1 */ -int getFileInfo(fileInfo_t* info, const char* inFileName){ - FILE* srcFile = FIO_openSrcFile(inFileName); - if(srcFile==NULL){ +static int getFileInfo(fileInfo_t* info, const char* inFileName){ + FILE* const srcFile = FIO_openSrcFile(inFileName); + if (srcFile == NULL) { + DISPLAY("Error: could not open source file %s\n", inFileName); return 1; } info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName); info->decompressedSize = 0; info->numActualFrames = 0; - info-> numSkippableFrames = 0; + info->numSkippableFrames = 0; info->canComputeDecompSize = 1; /* begin analyzing frame */ - while(1){ + for( ; ; ){ BYTE magicNumberBuffer[4]; size_t numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); U32 magicNumber; - if(numBytesRead != 4) break; + if (numBytesRead != 4) break; magicNumber = MEM_readLE32(magicNumberBuffer); - if(magicNumber==ZSTD_MAGICNUMBER){ + if (magicNumber==ZSTD_MAGICNUMBER) { BYTE frameHeaderDescriptor; int totalFrameHeaderBytes; BYTE* frameHeader; int lastBlock = 0; size_t readBytes = fread(&frameHeaderDescriptor, 1, 1, srcFile); info->numActualFrames++; - if(readBytes != 1){ - DISPLAY("There was an error with reading frame header descriptor\n"); - exit(1); + if (readBytes != 1) { + DISPLAY("Error: could not read frame header descriptor\n"); + fclose(srcFile); + + return 1; } /* calculate actual frame header size */ totalFrameHeaderBytes = calcFrameHeaderSize(frameHeaderDescriptor); /* reset to beginning of from and read entire header */ - fseek(srcFile, -5, SEEK_CUR); + { + int returnVal = fseek(srcFile, -5, SEEK_CUR); + if (returnVal!=0) { + DISPLAY("Error: could not reset to the beginning of the frame header\n"); + fclose(srcFile); + return 1; + } + } frameHeader = (BYTE*)malloc(totalFrameHeaderBytes); + if (frameHeader==NULL) { + DISPLAY("Error: could not allocate space for frameHeader\n"); + fclose(srcFile); + return 1; + } readBytes = fread(frameHeader, 1, totalFrameHeaderBytes, srcFile); - if(readBytes != (size_t)totalFrameHeaderBytes){ - DISPLAY("There was an error reading the frame header\n"); - exit(1); + if (readBytes != (size_t)totalFrameHeaderBytes) { + DISPLAY("Error: could not read frame header\n"); + fclose(srcFile); + free(frameHeader); + return 1; } /* get decompressed file size */ { U64 additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); - if(additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR){ + if (additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR) { info->decompressedSize += additional; } else{ @@ -951,7 +961,7 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ U32 blockHeader; int blockSize; readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); - if(readBytes != 3){ + if (readBytes != 3) { DISPLAY("There was a problem reading the block header\n"); exit(1); } @@ -959,37 +969,38 @@ int getFileInfo(fileInfo_t* info, const char* inFileName){ lastBlock = blockHeader & 1; blockSize = (blockHeader - (blockHeader & 7)) >> 3; fseek(srcFile, blockSize, SEEK_CUR); - }while(lastBlock != 1); + }while (lastBlock != 1); { /* check if checksum is used */ int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; - if(contentChecksumFlag){ + if (contentChecksumFlag) { info->usesCheck = 1; } - if(contentChecksumFlag){ + if (contentChecksumFlag) { fseek(srcFile, 4, SEEK_CUR); } } + free(frameHeader); } - else if(magicNumber==ZSTD_MAGIC_SKIPPABLE_START){ + else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { BYTE frameSizeBuffer[4]; long frameSize; size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); info->numSkippableFrames++; - if(readBytes != 4){ + if (readBytes != 4) { DISPLAY("There was an error reading skippable frame size"); exit(1); } frameSize = MEM_readLE32(frameSizeBuffer); fseek(srcFile, frameSize, SEEK_CUR); } - } + fclose(srcFile); return 0; } void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ - double compressedSizeMB = (double)info->compressedSize/(1 MB); - double decompressedSizeMB = (double)info->decompressedSize/(1 MB); + double const compressedSizeMB = (double)info->compressedSize/(1 MB); + double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); if(displayLevel<=2){ if(info->usesCheck && info->canComputeDecompSize){ diff --git a/programs/zstdcli.c b/programs/zstdcli.c index f8612f297..6de33ce09 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -674,6 +674,7 @@ int main(int argCount, const char* argv[]) } #endif if(operation==zom_list){ + g_displayOut = stdout; if(filenameIdx==0){ DISPLAY("No files given\n"); CLEAN_RETURN(0); From a9b77c83e58fab8992ce9318cb11033e34a86d52 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 14:13:28 -0700 Subject: [PATCH 181/400] cleaning up code for analyzing frames --- lib/decompress/zstd_decompress.c | 2 +- lib/zstd.h | 5 + programs/fileio.c | 170 +++++++++++++++---------------- 3 files changed, 90 insertions(+), 87 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index ea64edeed..af8b98d7f 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -204,7 +204,7 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size) /** ZSTD_frameHeaderSize() : * srcSize must be >= ZSTD_frameHeaderSize_prefix. * @return : size of the Frame Header */ -static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) { if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); { BYTE const fhd = ((const BYTE*)src)[4]; diff --git a/lib/zstd.h b/lib/zstd.h index b0aae3f73..53acdcdd0 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -461,6 +461,11 @@ ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t * however it does mean that all frame data must be present and valid. */ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); +/*! ZSTD_frameHeaderSize() : +* `src` should point to the start of a ZSTD frame +* `srcSize` must be >= ZSTD_frameHeaderSize_prefix. +* @return : size of the Frame Header */ +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); /*************************************** * Context memory usage diff --git a/programs/fileio.c b/programs/fileio.c index 8af3c5a77..4f92e16e8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -872,17 +872,6 @@ typedef struct { int usesCheck; } fileInfo_t; - -static int calcFrameHeaderSize(BYTE frameHeaderDescriptor){ - const int frameContentSizeFlag = frameHeaderDescriptor >> 6; - const int singleSegmentFlag = (frameHeaderDescriptor & (1 << 5)) >> 5; - const int dictionaryIDFlag = frameHeaderDescriptor & 3; - const int windowDescriptorBytes = singleSegmentFlag ? 0 : 1; - const int frameContentSizeBytes = (frameContentSizeFlag != 0) ? (1 << frameContentSizeFlag) : (singleSegmentFlag ? 1 : 0); - const int dictionaryIDBytes = dictionaryIDFlag ? 1 << (dictionaryIDFlag - 1): 0; - return 4 + 1 + windowDescriptorBytes + frameContentSizeBytes + dictionaryIDBytes; -} - /* * Reads information from file, stores in *info * if successful, returns 0, otherwise returns 1 @@ -900,78 +889,79 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ info->canComputeDecompSize = 1; /* begin analyzing frame */ for( ; ; ){ - BYTE magicNumberBuffer[4]; - size_t numBytesRead = fread(magicNumberBuffer, 1, 4, srcFile); - U32 magicNumber; - if (numBytesRead != 4) break; - magicNumber = MEM_readLE32(magicNumberBuffer); - if (magicNumber==ZSTD_MAGICNUMBER) { - BYTE frameHeaderDescriptor; - int totalFrameHeaderBytes; - BYTE* frameHeader; - int lastBlock = 0; - size_t readBytes = fread(&frameHeaderDescriptor, 1, 1, srcFile); - info->numActualFrames++; - if (readBytes != 1) { - DISPLAY("Error: could not read frame header descriptor\n"); + BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; + size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); + if (numBytesRead < ZSTD_frameHeaderSize_min) { + if(feof(srcFile)){ + DISPLAY("ran out of files\n"); + break; + } + else{ + DISPLAY("Error: did not reach end of file but ran out of frames\n"); fclose(srcFile); - return 1; } - /* calculate actual frame header size */ - totalFrameHeaderBytes = calcFrameHeaderSize(frameHeaderDescriptor); + } + U32 const magicNumber = MEM_readLE32(headerBuffer); + if (magicNumber == ZSTD_MAGICNUMBER) { + U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead); + if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { + info->canComputeDecompSize = 0; + DISPLAY("could not compute decompressed size\n"); + } + else { + info->decompressedSize += frameContentSize; + } + size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead); + if (ZSTD_isError(headerSize)) { + fclose(srcFile); + DISPLAY("Error: could not determine frame header size\n"); + return 1; + } - /* reset to beginning of from and read entire header */ { - int returnVal = fseek(srcFile, -5, SEEK_CUR); - if (returnVal!=0) { - DISPLAY("Error: could not reset to the beginning of the frame header\n"); + /* go back to the beginning of the frame */ + int const ret = fseek(srcFile, -numBytesRead, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not rewind to beginning of frame\n"); fclose(srcFile); return 1; } } - frameHeader = (BYTE*)malloc(totalFrameHeaderBytes); - if (frameHeader==NULL) { - DISPLAY("Error: could not allocate space for frameHeader\n"); - fclose(srcFile); - return 1; - } - readBytes = fread(frameHeader, 1, totalFrameHeaderBytes, srcFile); - if (readBytes != (size_t)totalFrameHeaderBytes) { - DISPLAY("Error: could not read frame header\n"); - fclose(srcFile); - free(frameHeader); - return 1; - } - /* get decompressed file size */ { - U64 additional = ZSTD_getFrameContentSize(frameHeader, totalFrameHeaderBytes); - if (additional!=ZSTD_CONTENTSIZE_UNKNOWN && additional!=ZSTD_CONTENTSIZE_ERROR) { - info->decompressedSize += additional; - } - else{ - info->canComputeDecompSize = 0; + /* skip frame header */ + int const ret = fseek(srcFile, headerSize, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not skip header\n"); + fclose(srcFile); + return 1; } } /* skip the rest of the blocks in the frame */ - do{ - BYTE blockHeaderBuffer[3]; - U32 blockHeader; - int blockSize; - readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); - if (readBytes != 3) { - DISPLAY("There was a problem reading the block header\n"); - exit(1); - } - blockHeader = MEM_readLE24(blockHeaderBuffer); - lastBlock = blockHeader & 1; - blockSize = (blockHeader - (blockHeader & 7)) >> 3; - fseek(srcFile, blockSize, SEEK_CUR); - }while (lastBlock != 1); + { + int lastBlock = 0; + int readBytes = 0; + do{ + BYTE blockHeaderBuffer[3]; + U32 blockHeader; + int blockSize; + readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); + if (readBytes != 3) { + DISPLAY("There was a problem reading the block header\n"); + fclose(srcFile); + return 1; + } + blockHeader = MEM_readLE24(blockHeaderBuffer); + lastBlock = blockHeader & 1; + blockSize = (blockHeader - (blockHeader & 7)) >> 3; + fseek(srcFile, blockSize, SEEK_CUR); + }while (lastBlock != 1); + } { /* check if checksum is used */ + BYTE frameHeaderDescriptor = headerBuffer[4]; int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; if (contentChecksumFlag) { info->usesCheck = 1; @@ -980,7 +970,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ fseek(srcFile, 4, SEEK_CUR); } } - free(frameHeader); + info->numActualFrames++; } else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { BYTE frameSizeBuffer[4]; @@ -992,7 +982,16 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ exit(1); } frameSize = MEM_readLE32(frameSizeBuffer); + { + int const ret = fseek(srcFile, frameSize, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not find end of skippable frame\n"); + fclose(srcFile); + return 1; + } + } fseek(srcFile, frameSize, SEEK_CUR); + info->numSkippableFrames++; } } fclose(srcFile); @@ -1004,51 +1003,50 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ if(displayLevel<=2){ if(info->usesCheck && info->canComputeDecompSize){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", + DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAYOUT("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, compressedSizeMB/decompressedSizeMB, inFileName); } else if(!info->usesCheck){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", + DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAYOUT("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, compressedSizeMB/decompressedSizeMB, inFileName); } else if(!info->canComputeDecompSize){ - DISPLAY("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAY("%9d %13d %7.2f MB XXH64 %s\n", + DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); + DISPLAYOUT("%9d %13d %7.2f MB XXH64 %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); } else{ - DISPLAY("Skippable Non-Skippable Filename\n"); - DISPLAY("%9d %13d %7.2f MB %s\n", + DISPLAYOUT("Skippable Non-Skippable Filename\n"); + DISPLAYOUT("%9d %13d %7.2f MB %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); } } else{ - DISPLAY("# Zstandard Frames: %d\n", info->numActualFrames); - DISPLAY("# Skippable Frames: %d\n", info->numSkippableFrames); - DISPLAY("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); - if(info->canComputeDecompSize){ - DISPLAY("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); - DISPLAY("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); + DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames); + DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames); + DISPLAYOUT("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); + if (info->canComputeDecompSize) { + DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); + DISPLAYOUT("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } - if(info->usesCheck){ - DISPLAY("Check: XXH64\n"); + if (info->usesCheck) { + DISPLAYOUT("Check: XXH64\n"); } } - } int FIO_listFile(const char* inFileName, int displayLevel){ const char* const suffixPtr = strrchr(inFileName, '.'); DISPLAY("File: %s\n", inFileName); - if(!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)){ + if (!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)) { DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n\n", inFileName); return 1; } - else{ + else { fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); int error = getFileInfo(info, inFileName); if(error==1){ From 4495e9a82616a5953bb209dd7692afca99fbd3e8 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:02:54 -0700 Subject: [PATCH 182/400] allow analysis even if file does not have zst extension --- programs/fileio.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 4f92e16e8..e6671308c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -914,8 +914,8 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead); if (ZSTD_isError(headerSize)) { - fclose(srcFile); DISPLAY("Error: could not determine frame header size\n"); + fclose(srcFile); return 1; } @@ -1037,25 +1037,20 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ DISPLAYOUT("Check: XXH64\n"); } } + + DISPLAYOUT("\n"); } int FIO_listFile(const char* inFileName, int displayLevel){ - const char* const suffixPtr = strrchr(inFileName, '.'); DISPLAY("File: %s\n", inFileName); - if (!suffixPtr || strcmp(suffixPtr, ZSTD_EXTENSION)) { - DISPLAYLEVEL(1, "file %s was not compressed with zstd -- ignoring\n\n", inFileName); + fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); + int error = getFileInfo(info, inFileName); + if (error == 1) { + DISPLAY("An error occurred with getting file info\n"); return 1; } - else { - fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); - int error = getFileInfo(info, inFileName); - if(error==1){ - DISPLAY("An error occurred with getting file info\n"); - exit(1); - } - displayInfo(inFileName, info, displayLevel); - } - DISPLAY("\n"); + displayInfo(inFileName, info, displayLevel); + free(info); return 0; } From 9437cc74980e7f5168eb485d31fd64f054f945cd Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:07:54 -0700 Subject: [PATCH 183/400] added --list command --- programs/zstdcli.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 6de33ce09..c71e80bdd 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -149,6 +149,7 @@ static int usage_advanced(const char* programName) #endif #endif DISPLAY( " -M# : Set a memory usage limit for decompression \n"); + DISPLAY( "--list : list information about a zstd compressed file \n"); DISPLAY( "-- : All arguments after \"--\" are treated as files \n"); #ifndef ZSTD_NODICT DISPLAY( "\n"); @@ -402,6 +403,7 @@ int main(int argCount, const char* argv[]) if (argument[1]=='-') { /* long commands (--long-word) */ if (!strcmp(argument, "--")) { nextArgumentsAreFiles=1; continue; } /* only file names allowed from now on */ + if (!strcmp(argument, "--list")) { operation=zom_list; continue; } if (!strcmp(argument, "--compress")) { operation=zom_compress; continue; } if (!strcmp(argument, "--decompress")) { operation=zom_decompress; continue; } if (!strcmp(argument, "--uncompress")) { operation=zom_decompress; continue; } From 96cabf72330f1b466407059a5f0981a24571fac1 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:25:20 -0700 Subject: [PATCH 184/400] cleaned up if statements --- programs/fileio.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index e6671308c..523b6174e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -893,7 +893,6 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); if (numBytesRead < ZSTD_frameHeaderSize_min) { if(feof(srcFile)){ - DISPLAY("ran out of files\n"); break; } else{ @@ -1000,29 +999,19 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ double const compressedSizeMB = (double)info->compressedSize/(1 MB); double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); + const char* checkString = (info->usesCheck ? "XXH64" : "None"); if(displayLevel<=2){ - if(info->usesCheck && info->canComputeDecompSize){ + if (info->canComputeDecompSize) { DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB %7.2f MB %5.3f XXH64 %s\n", + DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %s %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, - compressedSizeMB/decompressedSizeMB, inFileName); + compressedSizeMB/decompressedSizeMB, checkString, inFileName); } - else if(!info->usesCheck){ - DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB %7.2f MB %5.3f %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, - compressedSizeMB/decompressedSizeMB, inFileName); - } - else if(!info->canComputeDecompSize){ - DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB XXH64 %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); - } - else{ - DISPLAYOUT("Skippable Non-Skippable Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB %s\n", - info->numSkippableFrames, info->numActualFrames, compressedSizeMB, inFileName); + else { + DISPLAYOUT("Skippable Non-Skippable Compressed Check Filename\n"); + DISPLAYOUT("%9d %13d %7.2f MB %s %s\n", + info->numSkippableFrames, info->numActualFrames, compressedSizeMB, checkString, inFileName); } } else{ From 8b3ff7c9bcb91bd15e994e6fda151b1fda0a7f0a Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:35:37 -0700 Subject: [PATCH 185/400] changed info to static allocation --- programs/fileio.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 523b6174e..aff1edd41 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1000,7 +1000,6 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ double const compressedSizeMB = (double)info->compressedSize/(1 MB); double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); const char* checkString = (info->usesCheck ? "XXH64" : "None"); - if(displayLevel<=2){ if (info->canComputeDecompSize) { DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); @@ -1031,15 +1030,14 @@ void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ } int FIO_listFile(const char* inFileName, int displayLevel){ - DISPLAY("File: %s\n", inFileName); - fileInfo_t* info = (fileInfo_t*)malloc(sizeof(fileInfo_t)); - int error = getFileInfo(info, inFileName); + DISPLAYOUT("File: %s\n", inFileName); + fileInfo_t info; + int const error = getFileInfo(&info, inFileName); if (error == 1) { DISPLAY("An error occurred with getting file info\n"); return 1; } - displayInfo(inFileName, info, displayLevel); - free(info); + displayInfo(inFileName, &info, displayLevel); return 0; } From e7f02fc58ad25c55ff78b0fea9cb5ad40978f0c0 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:53:02 -0700 Subject: [PATCH 186/400] closed file at end of function, created another variable to keep exit points simpler --- programs/fileio.c | 75 +++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index aff1edd41..09ef1791d 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -887,6 +887,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ info->numActualFrames = 0; info->numSkippableFrames = 0; info->canComputeDecompSize = 1; + int detectError = 0; /* begin analyzing frame */ for( ; ; ){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; @@ -897,8 +898,8 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } else{ DISPLAY("Error: did not reach end of file but ran out of frames\n"); - fclose(srcFile); - return 1; + detectError = 1; + break; } } U32 const magicNumber = MEM_readLE32(headerBuffer); @@ -906,7 +907,6 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead); if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { info->canComputeDecompSize = 0; - DISPLAY("could not compute decompressed size\n"); } else { info->decompressedSize += frameContentSize; @@ -914,34 +914,24 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead); if (ZSTD_isError(headerSize)) { DISPLAY("Error: could not determine frame header size\n"); - fclose(srcFile); - return 1; + detectError = 1; + break; } { - /* go back to the beginning of the frame */ - int const ret = fseek(srcFile, -numBytesRead, SEEK_CUR); + /* move to the end of the frame header */ + int const ret = fseek(srcFile, headerSize-numBytesRead, SEEK_CUR); if (ret != 0) { - DISPLAY("Error: could not rewind to beginning of frame\n"); - fclose(srcFile); - return 1; - } - } - - { - /* skip frame header */ - int const ret = fseek(srcFile, headerSize, SEEK_CUR); - if (ret != 0) { - DISPLAY("Error: could not skip header\n"); - fclose(srcFile); - return 1; + DISPLAY("Error: could not move to end of frame header\n"); + detectError = 1; + break; } } /* skip the rest of the blocks in the frame */ { int lastBlock = 0; - int readBytes = 0; + size_t readBytes = 0; do{ BYTE blockHeaderBuffer[3]; U32 blockHeader; @@ -949,44 +939,59 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); if (readBytes != 3) { DISPLAY("There was a problem reading the block header\n"); - fclose(srcFile); - return 1; + detectError = 1; + break; } blockHeader = MEM_readLE24(blockHeaderBuffer); lastBlock = blockHeader & 1; blockSize = (blockHeader - (blockHeader & 7)) >> 3; - fseek(srcFile, blockSize, SEEK_CUR); - }while (lastBlock != 1); + { + int const ret = fseek(srcFile, blockSize, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not skip to end of block\n"); + detectError = 1; + break; + } + } + } while (lastBlock != 1); + + if (detectError) { + break; + } } { /* check if checksum is used */ - BYTE frameHeaderDescriptor = headerBuffer[4]; - int contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; + BYTE const frameHeaderDescriptor = headerBuffer[4]; + int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; if (contentChecksumFlag) { info->usesCheck = 1; } if (contentChecksumFlag) { - fseek(srcFile, 4, SEEK_CUR); + int const ret = fseek(srcFile, 4, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not skip past checksum\n"); + detectError = 1; + break; + } } } info->numActualFrames++; } else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { BYTE frameSizeBuffer[4]; - long frameSize; size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); - info->numSkippableFrames++; if (readBytes != 4) { DISPLAY("There was an error reading skippable frame size"); - exit(1); + detectError = 1; + break; } - frameSize = MEM_readLE32(frameSizeBuffer); + long const frameSize = MEM_readLE32(frameSizeBuffer); { int const ret = fseek(srcFile, frameSize, SEEK_CUR); if (ret != 0) { DISPLAY("Error: could not find end of skippable frame\n"); - fclose(srcFile); - return 1; + detectError = 1; + break; } } fseek(srcFile, frameSize, SEEK_CUR); @@ -994,7 +999,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } } fclose(srcFile); - return 0; + return detectError; } void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ double const compressedSizeMB = (double)info->compressedSize/(1 MB); From b766211e10fd3e148d38e0c1c24043c65a817002 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 15:55:49 -0700 Subject: [PATCH 187/400] made another function static --- programs/fileio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 09ef1791d..23c8badc6 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -954,7 +954,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } } } while (lastBlock != 1); - + if (detectError) { break; } @@ -1001,7 +1001,8 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ fclose(srcFile); return detectError; } -void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ + +static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ double const compressedSizeMB = (double)info->compressedSize/(1 MB); double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); const char* checkString = (info->usesCheck ? "XXH64" : "None"); From 54e0b6c66b78b0f9035ec06e959428cd200289c1 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 16:01:52 -0700 Subject: [PATCH 188/400] got rid of imlpicit precision loss --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 23c8badc6..e76f93791 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -920,7 +920,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ { /* move to the end of the frame header */ - int const ret = fseek(srcFile, headerSize-numBytesRead, SEEK_CUR); + int const ret = fseek(srcFile, (long)(headerSize-numBytesRead), SEEK_CUR); if (ret != 0) { DISPLAY("Error: could not move to end of frame header\n"); detectError = 1; From e49afae2ab6f720333fb47fda66333c53f6d736d Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 16:03:40 -0700 Subject: [PATCH 189/400] changed implicit precision loss again --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index e76f93791..5a1bef7a8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -920,7 +920,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ { /* move to the end of the frame header */ - int const ret = fseek(srcFile, (long)(headerSize-numBytesRead), SEEK_CUR); + int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR); if (ret != 0) { DISPLAY("Error: could not move to end of frame header\n"); detectError = 1; From 0757eae6ff55c6dd09ff3320ad232804ea2ae86f Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 16:12:04 -0700 Subject: [PATCH 190/400] rearranging code to allow for consts --- programs/fileio.c | 158 +++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 5a1bef7a8..cf329ddef 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -877,6 +877,7 @@ typedef struct { * if successful, returns 0, otherwise returns 1 */ static int getFileInfo(fileInfo_t* info, const char* inFileName){ + int detectError = 0; FILE* const srcFile = FIO_openSrcFile(inFileName); if (srcFile == NULL) { DISPLAY("Error: could not open source file %s\n", inFileName); @@ -887,7 +888,6 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ info->numActualFrames = 0; info->numSkippableFrames = 0; info->canComputeDecompSize = 1; - int detectError = 0; /* begin analyzing frame */ for( ; ; ){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; @@ -902,100 +902,100 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ break; } } - U32 const magicNumber = MEM_readLE32(headerBuffer); - if (magicNumber == ZSTD_MAGICNUMBER) { - U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead); - if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { - info->canComputeDecompSize = 0; - } - else { - info->decompressedSize += frameContentSize; - } - size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead); - if (ZSTD_isError(headerSize)) { - DISPLAY("Error: could not determine frame header size\n"); - detectError = 1; - break; - } - - { - /* move to the end of the frame header */ - int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR); - if (ret != 0) { - DISPLAY("Error: could not move to end of frame header\n"); - detectError = 1; - break; + { + U32 const magicNumber = MEM_readLE32(headerBuffer); + if (magicNumber == ZSTD_MAGICNUMBER) { + U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead); + if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { + info->canComputeDecompSize = 0; } - } - - /* skip the rest of the blocks in the frame */ - { - int lastBlock = 0; - size_t readBytes = 0; - do{ - BYTE blockHeaderBuffer[3]; - U32 blockHeader; - int blockSize; - readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); - if (readBytes != 3) { - DISPLAY("There was a problem reading the block header\n"); + else { + info->decompressedSize += frameContentSize; + } + { + /* move to the end of the frame header */ + size_t const headerSize = ZSTD_frameHeaderSize(headerBuffer, numBytesRead); + if (ZSTD_isError(headerSize)) { + DISPLAY("Error: could not determine frame header size\n"); detectError = 1; break; } - blockHeader = MEM_readLE24(blockHeaderBuffer); - lastBlock = blockHeader & 1; - blockSize = (blockHeader - (blockHeader & 7)) >> 3; - { - int const ret = fseek(srcFile, blockSize, SEEK_CUR); + int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not move to end of frame header\n"); + detectError = 1; + break; + } + } + + /* skip the rest of the blocks in the frame */ + { + int lastBlock = 0; + size_t readBytes = 0; + do{ + BYTE blockHeaderBuffer[3]; + U32 blockHeader; + int blockSize; + readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); + if (readBytes != 3) { + DISPLAY("There was a problem reading the block header\n"); + detectError = 1; + break; + } + blockHeader = MEM_readLE24(blockHeaderBuffer); + lastBlock = blockHeader & 1; + blockSize = (blockHeader - (blockHeader & 7)) >> 3; + { + int const ret = fseek(srcFile, blockSize, SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not skip to end of block\n"); + detectError = 1; + break; + } + } + } while (lastBlock != 1); + + if (detectError) { + break; + } + } + { + /* check if checksum is used */ + BYTE const frameHeaderDescriptor = headerBuffer[4]; + int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; + if (contentChecksumFlag) { + info->usesCheck = 1; + } + if (contentChecksumFlag) { + int const ret = fseek(srcFile, 4, SEEK_CUR); if (ret != 0) { - DISPLAY("Error: could not skip to end of block\n"); + DISPLAY("Error: could not skip past checksum\n"); detectError = 1; break; } } - } while (lastBlock != 1); - - if (detectError) { + } + info->numActualFrames++; + } + else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { + BYTE frameSizeBuffer[4]; + size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); + if (readBytes != 4) { + DISPLAY("There was an error reading skippable frame size"); + detectError = 1; break; } - } - { - /* check if checksum is used */ - BYTE const frameHeaderDescriptor = headerBuffer[4]; - int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; - if (contentChecksumFlag) { - info->usesCheck = 1; - } - if (contentChecksumFlag) { - int const ret = fseek(srcFile, 4, SEEK_CUR); + { + long const frameSize = MEM_readLE32(frameSizeBuffer); + int const ret = fseek(srcFile, frameSize, SEEK_CUR); if (ret != 0) { - DISPLAY("Error: could not skip past checksum\n"); + DISPLAY("Error: could not find end of skippable frame\n"); detectError = 1; break; } } + info->numSkippableFrames++; } - info->numActualFrames++; - } - else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { - BYTE frameSizeBuffer[4]; - size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); - if (readBytes != 4) { - DISPLAY("There was an error reading skippable frame size"); - detectError = 1; - break; - } - long const frameSize = MEM_readLE32(frameSizeBuffer); - { - int const ret = fseek(srcFile, frameSize, SEEK_CUR); - if (ret != 0) { - DISPLAY("Error: could not find end of skippable frame\n"); - detectError = 1; - break; - } - } - fseek(srcFile, frameSize, SEEK_CUR); - info->numSkippableFrames++; } } fclose(srcFile); @@ -1036,8 +1036,8 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev } int FIO_listFile(const char* inFileName, int displayLevel){ - DISPLAYOUT("File: %s\n", inFileName); fileInfo_t info; + DISPLAYOUT("File: %s\n", inFileName); int const error = getFileInfo(&info, inFileName); if (error == 1) { DISPLAY("An error occurred with getting file info\n"); From acaefb531bb0549cb11fac143ad349ccf40efc99 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 16:27:38 -0700 Subject: [PATCH 191/400] refactoring brackets to allow for const values --- programs/fileio.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index cf329ddef..bb3f13d8e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -920,11 +920,13 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ detectError = 1; break; } - int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR); - if (ret != 0) { - DISPLAY("Error: could not move to end of frame header\n"); - detectError = 1; - break; + { + int const ret = fseek(srcFile, ((long)headerSize)-((long)numBytesRead), SEEK_CUR); + if (ret != 0) { + DISPLAY("Error: could not move to end of frame header\n"); + detectError = 1; + break; + } } } @@ -1038,10 +1040,12 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev int FIO_listFile(const char* inFileName, int displayLevel){ fileInfo_t info; DISPLAYOUT("File: %s\n", inFileName); - int const error = getFileInfo(&info, inFileName); - if (error == 1) { - DISPLAY("An error occurred with getting file info\n"); - return 1; + { + int const error = getFileInfo(&info, inFileName); + if (error == 1) { + DISPLAY("An error occurred with getting file info\n"); + return 1; + } } displayInfo(inFileName, &info, displayLevel); return 0; From ddd1ab710c58f8fc8613ede1e2217bc5fadc360c Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 16:53:03 -0700 Subject: [PATCH 192/400] added tests in playTest.sh --- tests/playTests.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index e69574588..6b794f6d4 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -537,6 +537,29 @@ fi rm tmp* +$ECHO "\n**** zstd --list/-l single frame tests ****" +./datagen > tmp1 +./datagen > tmp2 +./datagen > tmp3 +./datagen > tmp4 +$ZSTD tmp* +$ZSTD -l tmp* +$ZSTD -lv tmp* +$ZSTD --list tmp* +$ZSTD --list -v tmp* + +$ECHO "\n**** zstd --list/-l multiple frame tests ****" +cat tmp1.zst tmp2.zst > tmp12.zst +cat tmp3.zst tmp4.zst > tmp34.zst +cat tmp12.zst tmp34.zst > tmp1234.zst +cat tmp12.zst tmp4.zst > tmp124.zst +$ZSTD -l tmp* +$ZSTD -lv tmp* +$ZSTD --list tmp* +$ZSTD --list -v tmp* + +rm tmp* + if [ "$1" != "--test-large-data" ]; then $ECHO "Skipping large data tests" exit 0 From 60a2e55e2e2c7ffeb978d944a31696f2b7c5bcc1 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 17:00:59 -0700 Subject: [PATCH 193/400] added case for when file is not compressed with zstd (incorrect magic number) --- programs/fileio.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index bb3f13d8e..908e0edb6 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -874,7 +874,7 @@ typedef struct { /* * Reads information from file, stores in *info - * if successful, returns 0, otherwise returns 1 + * if successful, returns 0, returns 1 for frame analysis error, returns 2 for file not compressed with zstd */ static int getFileInfo(fileInfo_t* info, const char* inFileName){ int detectError = 0; @@ -998,6 +998,10 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } info->numSkippableFrames++; } + else { + detectError = 2; + break; + } } } fclose(srcFile); @@ -1043,8 +1047,12 @@ int FIO_listFile(const char* inFileName, int displayLevel){ { int const error = getFileInfo(&info, inFileName); if (error == 1) { + /* display error, but provide output */ DISPLAY("An error occurred with getting file info\n"); - return 1; + } + else if (error == 2) { + DISPLAYOUT("File %s not compressed with zstd\n\n", inFileName); + return 0; } } displayInfo(inFileName, &info, displayLevel); From b316691f9126711a2a68f7e0661194afd2b3fdf8 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 17:03:59 -0700 Subject: [PATCH 194/400] added const --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 908e0edb6..d807cffc1 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -981,7 +981,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } else if (magicNumber == ZSTD_MAGIC_SKIPPABLE_START) { BYTE frameSizeBuffer[4]; - size_t readBytes = fread(frameSizeBuffer, 1, 4, srcFile); + size_t const readBytes = fread(frameSizeBuffer, 1, 4, srcFile); if (readBytes != 4) { DISPLAY("There was an error reading skippable frame size"); detectError = 1; From d3b34e4a2516418c4589812fc2e98f6f9bd461d8 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 17:12:41 -0700 Subject: [PATCH 195/400] changed spacing on if statements --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index d807cffc1..8db61a6fc 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -893,7 +893,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); if (numBytesRead < ZSTD_frameHeaderSize_min) { - if(feof(srcFile)){ + if (feof(srcFile)) { break; } else{ @@ -1012,7 +1012,7 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev double const compressedSizeMB = (double)info->compressedSize/(1 MB); double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); const char* checkString = (info->usesCheck ? "XXH64" : "None"); - if(displayLevel<=2){ + if (displayLevel <= 2) { if (info->canComputeDecompSize) { DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %s %s\n", From 0d7c4d766ab9358b58e193b579578b6442e2f8fd Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 17:30:18 -0700 Subject: [PATCH 196/400] initialized info manually to avoid error --- programs/fileio.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 8db61a6fc..5ab3c5be0 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -884,10 +884,6 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ return 1; } info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName); - info->decompressedSize = 0; - info->numActualFrames = 0; - info->numSkippableFrames = 0; - info->canComputeDecompSize = 1; /* begin analyzing frame */ for( ; ; ){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; @@ -1014,10 +1010,11 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev const char* checkString = (info->usesCheck ? "XXH64" : "None"); if (displayLevel <= 2) { if (info->canComputeDecompSize) { + double const ratio = (info->decompressedSize == 0) ? 0.0 : compressedSizeMB/decompressedSizeMB; DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %s %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, - compressedSizeMB/decompressedSizeMB, checkString, inFileName); + ratio, checkString, inFileName); } else { DISPLAYOUT("Skippable Non-Skippable Compressed Check Filename\n"); @@ -1043,6 +1040,14 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev int FIO_listFile(const char* inFileName, int displayLevel){ fileInfo_t info; + + /* initialize info to avoid warnings */ + info.numActualFrames = 0; + info.numSkippableFrames = 0; + info.decompressedSize = 0; + info.canComputeDecompSize = 1; + info.compressedSize = 0; + info.usesCheck = 0; DISPLAYOUT("File: %s\n", inFileName); { int const error = getFileInfo(&info, inFileName); From b3e62446c67ff0b76eaf37be717f4c5a9c880260 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 17:46:49 -0700 Subject: [PATCH 197/400] added in correct error return from main in zstdcli.c --- programs/fileio.c | 6 +++--- programs/zstdcli.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 5ab3c5be0..2f51b95cf 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1057,11 +1057,11 @@ int FIO_listFile(const char* inFileName, int displayLevel){ } else if (error == 2) { DISPLAYOUT("File %s not compressed with zstd\n\n", inFileName); - return 0; + return 1; } + displayInfo(inFileName, &info, displayLevel); + return error; } - displayInfo(inFileName, &info, displayLevel); - return 0; } int FIO_compressMultipleFilenames(const char** inFileNamesTable, unsigned nbFiles, diff --git a/programs/zstdcli.c b/programs/zstdcli.c index c71e80bdd..a55640351 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -675,7 +675,7 @@ int main(int argCount, const char* argv[]) } } #endif - if(operation==zom_list){ + if (operation == zom_list) { g_displayOut = stdout; if(filenameIdx==0){ DISPLAY("No files given\n"); @@ -686,12 +686,13 @@ int main(int argCount, const char* argv[]) DISPLAY("===========================================\n"); DISPLAY("Number of files listed: %d\n", filenameIdx); { + int error = 0; unsigned u; for(u=0; u Date: Thu, 15 Jun 2017 18:03:34 -0700 Subject: [PATCH 198/400] added protection : MT incompatible with Static allocation --- lib/compress/zstd_compress.c | 2 ++ lib/zstd.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index db672da04..8377b37e5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -339,6 +339,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v if (value > 1) return ERROR(compressionParameter_unsupported); #endif if ((value>1) && (cctx->nbThreads != value)) { + if (cctx->staticSize) /* MT not compatible with static alloc */ + return ERROR(compressionParameter_unsupported); ZSTDMT_freeCCtx(cctx->mtctx); cctx->nbThreads = value; cctx->mtctx = ZSTDMT_createCCtx(value); diff --git a/lib/zstd.h b/lib/zstd.h index 357af9194..eb72fc4e5 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -68,7 +68,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< to be used when checking d #define ZSTD_QUOTE(str) #str #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) -ZSTDLIB_API const char* ZSTD_versionString(void); +ZSTDLIB_API const char* ZSTD_versionString(void); /* v1.3.0 */ /*************************************** @@ -424,6 +424,7 @@ typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; v /* use this constant to defer to stdlib's functions */ static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL}; + /*************************************** * Frame size functions ***************************************/ From 2f30433cd797a64f6c81b1c2f090214a4607f9bb Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 18:06:32 -0700 Subject: [PATCH 199/400] fixing general style --- tests/decodecorpus.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 96799f8bc..9565d33d7 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1324,13 +1324,13 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const const size_t headerSize = dictSize/4; const size_t dictContentSize = dictSize - dictSize/4; ZSTD_DCtx* dctx = ZSTD_createDCtx(); - if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { + if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); return 1; } { /* use 3/4 of dictionary for content, save rest for header/entropy tables */ - if(dictContentSize < 128 || dictSize < 256){ + if (dictContentSize < 128 || dictSize < 256) { DISPLAY("Error: dictionary size is too small\n"); return 1; } @@ -1352,7 +1352,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const size_t* curr = sampleSizes; size_t totalSize = 0; unsigned numReps = 1; - while(numSamples < 200){ + while (numSamples < 200) { size_t randSize = RAND(&seed) % dictContentSize; unsigned counter = numReps; numSamples += numReps; @@ -1568,7 +1568,7 @@ int main(int argc, char** argv) argument++; if (strcmp(argument, "content-size") == 0) { opts.contentSize = 1; - } else if(strcmp(argument, "train-dict") == 0){ + } else if (strcmp(argument, "train-dict") == 0) { argument += 11; dictSize = readInt(&argument); genDict = 1; @@ -1607,11 +1607,9 @@ int main(int argc, char** argv) return generateFile(seed, path, origPath); } else if (genDict == 0){ return generateCorpus(seed, numFiles, path, origPath); - } else if (numFiles == 0){ - /* should generate a single file with a dictionary */ - return generateCorpusWithDict(seed, 1, path, origPath, dictSize); - } else{ - /* should generate multiple files with a dictionary */ + } else { + /* should generate files with a dictionary */ + numFiles = (numFiles == 0) ? 1 : numFiles; return generateCorpusWithDict(seed, numFiles, path, origPath, dictSize); } From 4a0e4c856c3da6be24030fe706cc31ae8a65d383 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Thu, 15 Jun 2017 18:08:22 -0700 Subject: [PATCH 200/400] fixing more spacing on loops --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 2f51b95cf..df492a9ef 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -885,7 +885,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName); /* begin analyzing frame */ - for( ; ; ){ + for ( ; ; ) { BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); if (numBytesRead < ZSTD_frameHeaderSize_min) { @@ -930,7 +930,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ { int lastBlock = 0; size_t readBytes = 0; - do{ + do { BYTE blockHeaderBuffer[3]; U32 blockHeader; int blockSize; From cc9f9b7f4c3c5e00f78b6c7ca9498297ece121ce Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 15 Jun 2017 18:17:10 -0700 Subject: [PATCH 201/400] protection : ZSTD_CONTENTSIZE_UNKNOWN automatically disables contentSizeFlag --- lib/compress/zstd_compress.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 8377b37e5..1d4f4f5a1 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -542,8 +542,6 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, ZSTD_compResetPolicy_e const crp, ZSTD_buffered_policy_e const zbuff) { - DEBUGLOG(5, "ZSTD_resetCCtx_internal : wlog=%u / old=%u", - params.cParams.windowLog, zc->appliedParams.cParams.windowLog); assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); if (crp == ZSTDcrp_continue) { @@ -612,10 +610,11 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, /* init params */ zc->appliedParams = params; - zc->blockSize = blockSize; - DEBUGLOG(5, "blockSize = %uK", (U32)blockSize>>10); zc->frameContentSize = frameContentSize; zc->consumedSrcSize = 0; + if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) + zc->appliedParams.fParams.contentSizeFlag = 0; + zc->blockSize = blockSize; XXH64_reset(&zc->xxhState, 0); zc->stage = ZSTDcs_init; From bd18c885a38d7cd93fe610c7e647e280198ada50 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 10:17:50 -0700 Subject: [PATCH 202/400] added ZSTD_CCtx_reset --- lib/compress/zstd_compress.c | 11 +++++++++-- lib/zstd.h | 5 +++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 1d4f4f5a1..1be0e97b3 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -399,14 +399,14 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s } /* Not ready yet ! */ -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) +size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize) { (void)cctx; (void)prefix; (void)prefixSize; /* to be done later */ if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); return ERROR(compressionParameter_unsupported); } -ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) +size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) { if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); cctx->cdict = cdict; @@ -414,6 +414,13 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) } +void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) +{ + cctx->streamStage = zcss_init; + cctx->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + cctx->cdict = NULL; +} + /** ZSTD_checkParams() : ensure param values remain within authorized range. @return : 0, or an error code if one value is beyond authorized range */ diff --git a/lib/zstd.h b/lib/zstd.h index eb72fc4e5..a19543814 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -819,10 +819,11 @@ ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, /*! ZSTD_CCtx_reset() : * Return a CCtx to clean state. * Useful after an error, or to interrupt an ongoing compression job and start a new one. - * It's possible to modify compression parameters after a reset. * Any internal data not yet flushed is cancelled. + * Dictionary (if any) is dropped, next compression starts with srcSize==unknown by default. + * It's possible to modify compression parameters after a reset. */ -ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx); /* Not ready yet ! */ +ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx); /* Not ready yet ! */ /*! ZSTD_compress_generic_simpleArgs() : From 559ee82e901020f7fe98b1beec402298a57f8623 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 11:58:21 -0700 Subject: [PATCH 203/400] fixed : calling ZSTD_compress_generic() to end-flush a stream in multiple steps --- lib/common/error_private.c | 3 ++- lib/common/zstd_errors.h | 10 +++++++--- lib/compress/zstd_compress.c | 32 ++++++++++++++++++-------------- lib/compress/zstdmt_compress.c | 25 +++++++++++++++---------- lib/zstd.h | 4 ++-- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/lib/common/error_private.c b/lib/common/error_private.c index 6bc86da7a..2d752cd23 100644 --- a/lib/common/error_private.c +++ b/lib/common/error_private.c @@ -24,7 +24,8 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter"; case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode"; case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding"; - case PREFIX(compressionParameter_unsupported): return "Compression parameter is out of bound"; + case PREFIX(compressionParameter_unsupported): return "Compression parameter is not supported"; + case PREFIX(compressionParameter_outOfBound): return "Compression parameter is out of bound"; case PREFIX(init_missing): return "Context should be init first"; case PREFIX(memory_allocation): return "Allocation error : not enough memory"; case PREFIX(stage_wrong): return "Operation not authorized at current processing stage"; diff --git a/lib/common/zstd_errors.h b/lib/common/zstd_errors.h index e067acf6e..19f1597aa 100644 --- a/lib/common/zstd_errors.h +++ b/lib/common/zstd_errors.h @@ -35,8 +35,11 @@ extern "C" { #endif /*-**************************************** -* error codes list -******************************************/ + * error codes list + * note : this API is still considered unstable + * it should not be used with a dynamic library + * only static linking is allowed + ******************************************/ typedef enum { ZSTD_error_no_error, ZSTD_error_GENERIC, @@ -47,6 +50,7 @@ typedef enum { ZSTD_error_frameParameter_unsupportedBy32bits, ZSTD_error_frameParameter_windowTooLarge, ZSTD_error_compressionParameter_unsupported, + ZSTD_error_compressionParameter_outOfBound, ZSTD_error_init_missing, ZSTD_error_memory_allocation, ZSTD_error_stage_wrong, @@ -67,7 +71,7 @@ typedef enum { /*! ZSTD_getErrorCode() : convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, - which can be used to compare directly with enum list published into "error_public.h" */ + which can be used to compare with enum list published above */ ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult); ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 1be0e97b3..dfaa1854f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -241,7 +241,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v { # define CLAMPCHECK(val,min,max) { \ if ((valmax)) { \ - return ERROR(compressionParameter_unsupported); \ + return ERROR(compressionParameter_outOfBound); \ } } if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); @@ -342,19 +342,20 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v if (cctx->staticSize) /* MT not compatible with static alloc */ return ERROR(compressionParameter_unsupported); ZSTDMT_freeCCtx(cctx->mtctx); - cctx->nbThreads = value; + cctx->nbThreads = 1; cctx->mtctx = ZSTDMT_createCCtx(value); if (cctx->mtctx == NULL) return ERROR(memory_allocation); - } - cctx->nbThreads = 1; + cctx->nbThreads = value; + } else + cctx->nbThreads = 1; return 0; - case ZSTDMT_p_jobSize: + case ZSTD_p_jobSize: if (cctx->nbThreads <= 1) return ERROR(compressionParameter_unsupported); assert(cctx->mtctx != NULL); return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_sectionSize, value); - case ZSTDMT_p_overlapSizeLog: + case ZSTD_p_overlapSizeLog: if (cctx->nbThreads <= 1) return ERROR(compressionParameter_unsupported); assert(cctx->mtctx != NULL); return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value); @@ -3648,8 +3649,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, && (zcs->inBuffPos == zcs->inToCompress) ) { /* empty */ someMoreWork = 0; break; - } - } + } + } /* compress current block (note : this stage cannot be stopped in the middle) */ DEBUGLOG(5, "stream compression stage (flushMode==%u)", flushMode); { void* cDst; @@ -3658,7 +3659,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, size_t oSize = oend-op; unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend); if (oSize >= ZSTD_compressBound(iSize)) - cDst = op; /* compress directly into output buffer (skip flush stage) */ + cDst = op; /* compress into output buffer, to skip flush stage */ else cDst = zcs->outBuff, oSize = zcs->outBuffSize; cSize = lastBlock ? @@ -3667,7 +3668,6 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ZSTD_compressContinue(zcs, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize); if (ZSTD_isError(cSize)) return cSize; - DEBUGLOG(5, "cSize = %u (lastBlock:%u)", (U32)cSize, lastBlock); zcs->frameEnded = lastBlock; /* prepare next block */ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize; @@ -3681,7 +3681,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (cDst == op) { /* no need to flush */ op += cSize; if (zcs->frameEnded) { - DEBUGLOG(5, "Frame directly completed"); + DEBUGLOG(5, "Frame completed directly in outBuffer"); someMoreWork = 0; zcs->streamStage = zcss_init; } @@ -3707,7 +3707,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, } zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0; if (zcs->frameEnded) { - DEBUGLOG(5, "Frame completed"); + DEBUGLOG(5, "Frame completed on flush"); someMoreWork = 0; zcs->streamStage = zcss_init; break; @@ -3781,15 +3781,19 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { + DEBUGLOG(5, "calling ZSTDMT_compressStream_generic(%i,...)", endOp); size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); + DEBUGLOG(5, "ZSTDMT result : %u", (U32)flushMin); if (ZSTD_isError(flushMin)) cctx->streamStage = zcss_init; + if (endOp == ZSTD_e_end && flushMin==0) + cctx->streamStage = zcss_init; /* compression completed */ return flushMin; } #endif - DEBUGLOG(5, "starting ZSTD_compressStream_generic"); + DEBUGLOG(5, "calling ZSTD_compressStream_generic(%i,...)", endOp); CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); - DEBUGLOG(5, "completing ZSTD_compress_generic"); + DEBUGLOG(5, "completed ZSTD_compress_generic"); return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */ } diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 098412824..a4b4f5160 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -704,7 +704,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi zcs->inBuff.filled); DEBUGLOG(5, "new inBuff pre-filled"); zcs->dictSize = newDictSize; - } else { + } else { /* if (endFrame==1) */ zcs->inBuff.buffer = g_nullBuffer; zcs->inBuff.filled = 0; zcs->dictSize = 0; @@ -768,7 +768,7 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi zcs->jobs[wJobID].jobScanned = 1; } { size_t const toWrite = MIN(job.cSize - job.dstFlushed, output->size - output->pos); - DEBUGLOG(4, "Flushing %u bytes from job %u ", (U32)toWrite, zcs->doneJobID); + DEBUGLOG(5, "Flushing %u bytes from job %u ", (U32)toWrite, zcs->doneJobID); memcpy((char*)output->dst + output->pos, (const char*)job.dstBuff.start + job.dstFlushed, toWrite); output->pos += toWrite; job.dstFlushed += toWrite; @@ -808,11 +808,11 @@ size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBu if ( (zcs->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { /* avoid overwriting job round buffer */ - CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0) ); + CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0 /* blockToFlush */) ); } /* check for data to flush */ - CHECK_F( ZSTDMT_flushNextJob(zcs, output, (zcs->inBuff.filled == zcs->inBuffSize)) ); /* block if it wasn't possible to create new job due to saturation */ + CHECK_F( ZSTDMT_flushNextJob(zcs, output, (zcs->inBuff.filled == zcs->inBuffSize) /* blockToFlush */) ); /* block if it wasn't possible to create new job due to saturation */ /* recommended next input size : fill current input buffer */ return zcs->inBuffSize - zcs->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */ @@ -823,16 +823,20 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp { size_t const srcSize = zcs->inBuff.filled - zcs->dictSize; - if (srcSize) DEBUGLOG(4, "flushing : %u bytes left to compress", (U32)srcSize); + if (srcSize) + DEBUGLOG(5, "flushing : %u bytes left to compress", (U32)srcSize); if ( ((srcSize > 0) || (endFrame && !zcs->frameEnded)) && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { + DEBUGLOG(5, "create new job with %u bytes to compress", (U32)srcSize); + DEBUGLOG(5, "end order : %u", endFrame); CHECK_F( ZSTDMT_createCompressionJob(zcs, srcSize, endFrame) ); + DEBUGLOG(5, "resulting zcs->frameEnded : %u", zcs->frameEnded); } /* check if there is any data available to flush */ DEBUGLOG(5, "zcs->doneJobID : %u ; zcs->nextJobID : %u", - zcs->doneJobID, zcs->nextJobID); - return ZSTDMT_flushNextJob(zcs, output, 1); + zcs->doneJobID, zcs->nextJobID); + return ZSTDMT_flushNextJob(zcs, output, 1 /*blockToFlush */); } @@ -840,14 +844,14 @@ size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) { if (zcs->nbThreads==1) return ZSTD_flushStream(zcs->cctxPool->cctx[0], output); - return ZSTDMT_flushStream_internal(zcs, output, 0); + return ZSTDMT_flushStream_internal(zcs, output, 0 /* endFrame */); } size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) { if (zcs->nbThreads==1) return ZSTD_endStream(zcs->cctxPool->cctx[0], output); - return ZSTDMT_flushStream_internal(zcs, output, 1); + return ZSTDMT_flushStream_internal(zcs, output, 1 /* endFrame */); } size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, @@ -855,7 +859,8 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, ZSTD_inBuffer* input, ZSTD_EndDirective endOp) { - CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); + if (input->pos < input->size) /* exclude final flushes */ + CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); switch(endOp) { case ZSTD_e_flush: diff --git a/lib/zstd.h b/lib/zstd.h index a19543814..1e73b5277 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -702,11 +702,11 @@ typedef enum { * More threads improve speed, but also increase memory usage. * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled. * Special: value 0 means "do not change nbThreads" */ - ZSTDMT_p_jobSize, /* Size of a compression job. Each compression job is completed in parallel. + ZSTD_p_jobSize, /* Size of a compression job. Each compression job is completed in parallel. * 0 means default, which is dynamically determined based on compression parameters. * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest * The minimum size is automatically and transparently enforced */ - ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. + ZSTD_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */ /* advanced parameters - may not remain available after API update */ From 33873f0e743376b0554b1e58526e37d2d63c09b6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 12:04:21 -0700 Subject: [PATCH 204/400] fixed : new advanced AIP : setting nbThreads to the same value > 1 --- lib/compress/zstd_compress.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index dfaa1854f..a482a7f7f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -335,6 +335,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_nbThreads: if (value==0) return 0; + DEBUGLOG(5, " setting nbThreads : %u", value); #ifndef ZSTD_MULTITHREAD if (value > 1) return ERROR(compressionParameter_unsupported); #endif @@ -345,9 +346,8 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v cctx->nbThreads = 1; cctx->mtctx = ZSTDMT_createCCtx(value); if (cctx->mtctx == NULL) return ERROR(memory_allocation); - cctx->nbThreads = value; - } else - cctx->nbThreads = 1; + } + cctx->nbThreads = value; return 0; case ZSTD_p_jobSize: @@ -356,6 +356,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_sectionSize, value); case ZSTD_p_overlapSizeLog: + DEBUGLOG(5, " setting overlap with nbThreads == %u", cctx->nbThreads); if (cctx->nbThreads <= 1) return ERROR(compressionParameter_unsupported); assert(cctx->mtctx != NULL); return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value); From 9e73f2f3203482fac5f9ed163513d6205818926f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 12:24:01 -0700 Subject: [PATCH 205/400] fix : correctly reset pledgedSrcSize to unknown status when starting a new compression with an existing context --- lib/compress/zstd_compress.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index a482a7f7f..5334f04f5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -309,6 +309,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v #endif case ZSTD_p_contentSizeFlag : + DEBUGLOG(2, "set content size flag = %u", (value>0)); /* Content size written in frame header _when known_ (default:1) */ cctx->requestedParams.fParams.contentSizeFlag = value>0; return 0; @@ -371,6 +372,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) { + DEBUGLOG(2, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize); if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); cctx->frameContentSize = pledgedSrcSize; return 0; @@ -3198,9 +3200,12 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); if (ZSTD_isError(endResult)) return endResult; if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ - if (cctx->frameContentSize != cctx->consumedSrcSize) + DEBUGLOG(2, "end of frame : controlling src size"); + if (cctx->frameContentSize != cctx->consumedSrcSize) { + DEBUGLOG(2, "error : pledgedSrcSize = %u, while realSrcSize = %u", + (U32)cctx->frameContentSize, (U32)cctx->consumedSrcSize); return ERROR(srcSize_wrong); - } + } } return cSize + endResult; } @@ -3685,6 +3690,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, DEBUGLOG(5, "Frame completed directly in outBuffer"); someMoreWork = 0; zcs->streamStage = zcss_init; + zcs->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; } break; } @@ -3711,6 +3717,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, DEBUGLOG(5, "Frame completed on flush"); someMoreWork = 0; zcs->streamStage = zcss_init; + zcs->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; break; } zcs->streamStage = zcss_load; @@ -3786,8 +3793,10 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); DEBUGLOG(5, "ZSTDMT result : %u", (U32)flushMin); if (ZSTD_isError(flushMin)) cctx->streamStage = zcss_init; - if (endOp == ZSTD_e_end && flushMin==0) + if (endOp == ZSTD_e_end && flushMin==0) { cctx->streamStage = zcss_init; /* compression completed */ + cctx->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + } return flushMin; } #endif From 2cf7755da7d87956b02833f49d069cf955710d2e Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 12:34:41 -0700 Subject: [PATCH 206/400] fix : pledgedSrcSize correctly reset to unknown in "continue" mode --- lib/compress/zstd_compress.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 5334f04f5..c79ce3951 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -309,7 +309,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v #endif case ZSTD_p_contentSizeFlag : - DEBUGLOG(2, "set content size flag = %u", (value>0)); + DEBUGLOG(5, "set content size flag = %u", (value>0)); /* Content size written in frame header _when known_ (default:1) */ cctx->requestedParams.fParams.contentSizeFlag = value>0; return 0; @@ -372,7 +372,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize) { - DEBUGLOG(2, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize); + DEBUGLOG(5, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize); if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); cctx->frameContentSize = pledgedSrcSize; return 0; @@ -529,9 +529,14 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1, static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize) { U32 const end = (U32)(cctx->nextSrc - cctx->base); + DEBUGLOG(5, "continue mode"); cctx->appliedParams = params; cctx->frameContentSize = frameContentSize; cctx->consumedSrcSize = 0; + if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) + cctx->appliedParams.fParams.contentSizeFlag = 0; + DEBUGLOG(5, "content size : %u ; flag : %u", + (U32)frameContentSize, cctx->appliedParams.fParams.contentSizeFlag); cctx->lowLimit = end; cctx->dictLimit = end; cctx->nextToUpdate = end+1; @@ -625,6 +630,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->consumedSrcSize = 0; if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) zc->appliedParams.fParams.contentSizeFlag = 0; + DEBUGLOG(5, "content size : %u ; flag : %u", + (U32)frameContentSize, zc->appliedParams.fParams.contentSizeFlag); zc->blockSize = blockSize; XXH64_reset(&zc->xxhState, 0); @@ -3200,9 +3207,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize); if (ZSTD_isError(endResult)) return endResult; if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ - DEBUGLOG(2, "end of frame : controlling src size"); + DEBUGLOG(5, "end of frame : controlling src size"); if (cctx->frameContentSize != cctx->consumedSrcSize) { - DEBUGLOG(2, "error : pledgedSrcSize = %u, while realSrcSize = %u", + DEBUGLOG(5, "error : pledgedSrcSize = %u, while realSrcSize = %u", (U32)cctx->frameContentSize, (U32)cctx->consumedSrcSize); return ERROR(srcSize_wrong); } } @@ -3382,9 +3389,9 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize, + cctxSize; ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace; void* ptr; - DEBUGLOG(2, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7); + DEBUGLOG(5, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7); if ((size_t)workspace & 7) return NULL; /* 8-aligned */ - DEBUGLOG(2, "(workspaceSize < neededSize) : (%u < %u) => %u", + DEBUGLOG(5, "(workspaceSize < neededSize) : (%u < %u) => %u", (U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize)); if (workspaceSize < neededSize) return NULL; From a0ba849fe6b8914ee8042714739ee33dad6b653c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 13:29:17 -0700 Subject: [PATCH 207/400] changed frameContentSize field to pledgedSrcSizePlusOne pledgedSrcSize is proper : it's a promise, not yet fulfilled. It will be controlled at the end. PlusOne is meant to have 0 (default) == unknown --- lib/compress/zstd_compress.c | 45 ++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c79ce3951..97d19ba2f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -98,7 +98,7 @@ struct ZSTD_CCtx_s { void* workSpace; size_t workSpaceSize; size_t blockSize; - U64 frameContentSize; + U64 pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */ U64 consumedSrcSize; XXH64_state_t xxhState; ZSTD_customMem customMem; @@ -152,6 +152,8 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) if (!cctx) return NULL; cctx->customMem = customMem; cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT; + ZSTD_STATIC_ASSERT(zcss_init==0); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==-(1ULL)); return cctx; } @@ -233,7 +235,7 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx) { if (cctx->compressionLevel==ZSTD_CLEVEL_CUSTOM) return; cctx->requestedParams.cParams = ZSTD_getCParams(cctx->compressionLevel, - cctx->frameContentSize, 0); + cctx->pledgedSrcSizePlusOne-1, 0); cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM; } @@ -374,7 +376,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo { DEBUGLOG(5, " setting pledgedSrcSize to %u", (U32)pledgedSrcSize); if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); - cctx->frameContentSize = pledgedSrcSize; + cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; return 0; } @@ -421,7 +423,7 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) { cctx->streamStage = zcss_init; - cctx->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + cctx->pledgedSrcSizePlusOne = 0; cctx->cdict = NULL; } @@ -531,7 +533,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra U32 const end = (U32)(cctx->nextSrc - cctx->base); DEBUGLOG(5, "continue mode"); cctx->appliedParams = params; - cctx->frameContentSize = frameContentSize; + cctx->pledgedSrcSizePlusOne = frameContentSize+1; cctx->consumedSrcSize = 0; if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) cctx->appliedParams.fParams.contentSizeFlag = 0; @@ -554,7 +556,7 @@ typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; /*! ZSTD_resetCCtx_internal() : note : `params` are assumed fully validated at this stage */ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, - ZSTD_parameters params, U64 frameContentSize, + ZSTD_parameters params, U64 pledgedSrcSize, ZSTD_compResetPolicy_e const crp, ZSTD_buffered_policy_e const zbuff) { @@ -565,7 +567,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, DEBUGLOG(5, "ZSTD_equivalentParams()==1"); zc->fseCTables_ready = 0; zc->hufCTable_repeatMode = HUF_repeat_none; - return ZSTD_continueCCtx(zc, params, frameContentSize); + return ZSTD_continueCCtx(zc, params, pledgedSrcSize); } } { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog); @@ -626,9 +628,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, /* init params */ zc->appliedParams = params; - zc->frameContentSize = frameContentSize; + zc->pledgedSrcSizePlusOne = pledgedSrcSize+1; zc->consumedSrcSize = 0; - if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) + if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) zc->appliedParams.fParams.contentSizeFlag = 0; DEBUGLOG(5, "content size : %u ; flag : %u", (U32)frameContentSize, zc->appliedParams.fParams.contentSizeFlag); @@ -2873,7 +2875,8 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */ if (frame && (cctx->stage==ZSTDcs_init)) { - fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, cctx->frameContentSize, cctx->dictID); + fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, + cctx->pledgedSrcSizePlusOne-1, cctx->dictID); if (ZSTD_isError(fhSize)) return fhSize; dstCapacity -= fhSize; dst = (char*)dst + fhSize; @@ -3208,7 +3211,7 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, if (ZSTD_isError(endResult)) return endResult; if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */ DEBUGLOG(5, "end of frame : controlling src size"); - if (cctx->frameContentSize != cctx->consumedSrcSize) { + if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) { DEBUGLOG(5, "error : pledgedSrcSize = %u, while realSrcSize = %u", (U32)cctx->frameContentSize, (U32)cctx->consumedSrcSize); return ERROR(srcSize_wrong); @@ -3697,7 +3700,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, DEBUGLOG(5, "Frame completed directly in outBuffer"); someMoreWork = 0; zcs->streamStage = zcss_init; - zcs->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + zcs->pledgedSrcSizePlusOne = 0; } break; } @@ -3724,7 +3727,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, DEBUGLOG(5, "Frame completed on flush"); someMoreWork = 0; zcs->streamStage = zcss_init; - zcs->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + zcs->pledgedSrcSizePlusOne = 0; break; } zcs->streamStage = zcss_load; @@ -3782,27 +3785,29 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, ZSTD_parameters params = cctx->requestedParams; if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM) params.cParams = ZSTD_getCParams(cctx->compressionLevel, - cctx->frameContentSize, 0 /* dictSize */); + cctx->pledgedSrcSizePlusOne+1, 0 /* dictSize */); #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { - CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->frameContentSize) ); + CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) ); cctx->streamStage = zcss_load; } else #endif { - CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->frameContentSize) ); + CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->pledgedSrcSizePlusOne+1) ); } } #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { - DEBUGLOG(5, "calling ZSTDMT_compressStream_generic(%i,...)", endOp); size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); DEBUGLOG(5, "ZSTDMT result : %u", (U32)flushMin); - if (ZSTD_isError(flushMin)) cctx->streamStage = zcss_init; - if (endOp == ZSTD_e_end && flushMin==0) { + if (ZSTD_isError(flushMin)) { + cctx->streamStage = zcss_init; + cctx->pledgedSrcSizePlusOne = 0; + } + if (endOp == ZSTD_e_end && flushMin == 0) { cctx->streamStage = zcss_init; /* compression completed */ - cctx->frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; + cctx->pledgedSrcSizePlusOne = 0; } return flushMin; } From b26728c9c8c01b9546a37f9e3a2bdfadcf142fce Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 14:00:46 -0700 Subject: [PATCH 208/400] added ZSTD_startNewCompression() --- lib/compress/zstd_compress.c | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 97d19ba2f..ad3736ced 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -419,11 +419,17 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict) return ERROR(compressionParameter_unsupported); } - -void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) +static void ZSTD_startNewCompression(ZSTD_CCtx* cctx) { cctx->streamStage = zcss_init; cctx->pledgedSrcSizePlusOne = 0; +} + +/*! ZSTD_CCtx_reset() : + * Also dumps dictionary */ +void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) +{ + ZSTD_startNewCompression(cctx); cctx->cdict = NULL; } @@ -528,17 +534,17 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1, /*! ZSTD_continueCCtx() : reuse CCtx without reset (note : requires no dictionary) */ -static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize) +static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 pledgedSrcSize) { U32 const end = (U32)(cctx->nextSrc - cctx->base); DEBUGLOG(5, "continue mode"); cctx->appliedParams = params; - cctx->pledgedSrcSizePlusOne = frameContentSize+1; + cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1; cctx->consumedSrcSize = 0; - if (frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) + if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) cctx->appliedParams.fParams.contentSizeFlag = 0; - DEBUGLOG(5, "content size : %u ; flag : %u", - (U32)frameContentSize, cctx->appliedParams.fParams.contentSizeFlag); + DEBUGLOG(5, "pledged content size : %u ; flag : %u", + (U32)pledgedSrcSize, cctx->appliedParams.fParams.contentSizeFlag); cctx->lowLimit = end; cctx->dictLimit = end; cctx->nextToUpdate = end+1; @@ -632,8 +638,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, zc->consumedSrcSize = 0; if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN) zc->appliedParams.fParams.contentSizeFlag = 0; - DEBUGLOG(5, "content size : %u ; flag : %u", - (U32)frameContentSize, zc->appliedParams.fParams.contentSizeFlag); + DEBUGLOG(5, "pledged content size : %u ; flag : %u", + (U32)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag); zc->blockSize = blockSize; XXH64_reset(&zc->xxhState, 0); @@ -3699,8 +3705,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (zcs->frameEnded) { DEBUGLOG(5, "Frame completed directly in outBuffer"); someMoreWork = 0; - zcs->streamStage = zcss_init; - zcs->pledgedSrcSizePlusOne = 0; + ZSTD_startNewCompression(zcs); } break; } @@ -3726,8 +3731,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, if (zcs->frameEnded) { DEBUGLOG(5, "Frame completed on flush"); someMoreWork = 0; - zcs->streamStage = zcss_init; - zcs->pledgedSrcSizePlusOne = 0; + ZSTD_startNewCompression(zcs); break; } zcs->streamStage = zcss_load; @@ -3801,13 +3805,9 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (cctx->nbThreads > 1) { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); DEBUGLOG(5, "ZSTDMT result : %u", (U32)flushMin); - if (ZSTD_isError(flushMin)) { - cctx->streamStage = zcss_init; - cctx->pledgedSrcSizePlusOne = 0; - } - if (endOp == ZSTD_e_end && flushMin == 0) { - cctx->streamStage = zcss_init; /* compression completed */ - cctx->pledgedSrcSizePlusOne = 0; + if ( ZSTD_isError(flushMin) + || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ + ZSTD_startNewCompression(cctx); } return flushMin; } From 944be54774f03a5aa82641c970fa5bdc66e39853 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 14:04:30 -0700 Subject: [PATCH 209/400] fixed attempt : minor Visual sign conversion warning --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index ad3736ced..8993e7d75 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -153,7 +153,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) cctx->customMem = customMem; cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT; ZSTD_STATIC_ASSERT(zcss_init==0); - ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==-(1ULL)); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(U64)(-(1ULL))); return cctx; } From d3de3d51a37d5587e62ad1030daa08c775be6749 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 16:51:33 -0700 Subject: [PATCH 210/400] fix attempt 2 : Visual sign conversion warning --- lib/compress/zstd_compress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 8993e7d75..937fd3107 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -153,7 +153,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem) cctx->customMem = customMem; cctx->compressionLevel = ZSTD_CLEVEL_DEFAULT; ZSTD_STATIC_ASSERT(zcss_init==0); - ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(U64)(-(1ULL))); + ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1)); return cctx; } From aee916e37c159b2fc4c8e273597d36e0d6307797 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 17:01:46 -0700 Subject: [PATCH 211/400] fixed +/-1 error for pledgedSrcSizePlusOne --- lib/compress/zstd_compress.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 937fd3107..6286c5aa6 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3219,7 +3219,7 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx, DEBUGLOG(5, "end of frame : controlling src size"); if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) { DEBUGLOG(5, "error : pledgedSrcSize = %u, while realSrcSize = %u", - (U32)cctx->frameContentSize, (U32)cctx->consumedSrcSize); + (U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize); return ERROR(srcSize_wrong); } } return cSize + endResult; @@ -3789,7 +3789,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, ZSTD_parameters params = cctx->requestedParams; if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM) params.cParams = ZSTD_getCParams(cctx->compressionLevel, - cctx->pledgedSrcSizePlusOne+1, 0 /* dictSize */); + cctx->pledgedSrcSizePlusOne-1, 0 /* dictSize */); #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { @@ -3798,7 +3798,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, } else #endif { - CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->pledgedSrcSizePlusOne+1) ); + CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->pledgedSrcSizePlusOne-1) ); } } #ifdef ZSTD_MULTITHREAD From 381e66cfbd3b59c34fb006e3ca3d70a709c6ca48 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 17:29:35 -0700 Subject: [PATCH 212/400] added ZSTD_clampCParams() now ZSTD_adjustCParams() is always successful, it always produces a valid CParams --- lib/compress/zstd_compress.c | 37 ++++++++++++++++++++++++++++------ lib/compress/zstdmt_compress.c | 4 ++-- lib/zstd.h | 4 ++-- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 6286c5aa6..f848c088e 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -433,8 +433,8 @@ void ZSTD_CCtx_reset(ZSTD_CCtx* cctx) cctx->cdict = NULL; } -/** ZSTD_checkParams() : - ensure param values remain within authorized range. +/** ZSTD_checkCParams() : + control CParam values remain within authorized range. @return : 0, or an error code if one value is beyond authorized range */ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) { @@ -448,6 +448,25 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) return 0; } +/** ZSTD_clampCParams() : + * make CParam values within valid range. + * @return : valid CParams */ +static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters cParams) +{ +# define CLAMP(val,min,max) { \ + if (valmax) val=max; \ + } + CLAMP(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); + CLAMP(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); + CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); + CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); + CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); + CLAMP(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); + if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra; + return cParams; +} + /** ZSTD_cycleLog() : * condition for correct operation : hashLog > 1 */ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) @@ -456,14 +475,15 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) return hashLog - btScale; } -/** ZSTD_adjustCParams() : +/** ZSTD_adjustCParams_internal() : optimize `cPar` for a given input (`srcSize` and `dictSize`). mostly downsizing to reduce memory consumption and initialization. Both `srcSize` and `dictSize` are optional (use 0 if unknown), but if both are 0, no optimization can be done. Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */ -ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) +ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) { + assert(ZSTD_checkCParams(cPar)==0); if (srcSize+dictSize == 0) return cPar; /* no size information available : no adjustment */ /* resize params, to use less memory when necessary */ @@ -483,6 +503,12 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u return cPar; } +ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize) +{ + cPar = ZSTD_clampCParams(cPar); + return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize); +} + size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams) { @@ -3989,8 +4015,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX; if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX; } - cp = ZSTD_adjustCParams(cp, srcSizeHint, dictSize); - return cp; + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); /* no need to ensure initial CParams validity */ } /*! ZSTD_getParams() : diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index a4b4f5160..42e31ca18 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -190,7 +190,7 @@ static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads, cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem); if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } - DEBUGLOG(1, "cctxPool created, with %u threads", nbThreads); + DEBUGLOG(3, "cctxPool created, with %u threads", nbThreads); return cctxPool; } @@ -458,7 +458,7 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, size_t frameStartPos = 0, dstBufferPos = 0; DEBUGLOG(3, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize); - DEBUGLOG(2, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); + DEBUGLOG(3, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); params.fParams.contentSizeFlag = 1; if (nbChunks==1) { /* fallback to single-thread mode */ diff --git a/lib/zstd.h b/lib/zstd.h index 1e73b5277..928abe240 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -589,8 +589,8 @@ ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long l ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params); /*! ZSTD_adjustCParams() : -* optimize params for a given `srcSize` and `dictSize`. -* both values are optional, select `0` if unknown. */ + * optimize params for a given `srcSize` and `dictSize`. + * both values are optional, select `0` if unknown. */ ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize); /*! ZSTD_compress_advanced() : From 01743a36e78950a4113dd12f7fd79ab5009c1a31 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 16 Jun 2017 17:56:41 -0700 Subject: [PATCH 213/400] fuzzer tests for new API --- NEWS | 2 + doc/zstd_manual.html | 9 +- tests/Makefile | 16 ++- tests/zstreamtest.c | 334 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 339 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index 9f1298126..3f9b4b220 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,11 @@ v1.3.0 cli : changed : `-t *` does no longer stop after a decompression error +API : added : ZSTD_versionString() API exp : new advanced API : ZSTD_compress_generic(), ZSTD_CCtx_setParameter() API exp : new : API for static or external allocation : ZSTD_initStatic?Ctx() API exp : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700) API exp : changed : strongest strategy renamed ZSTD_btultra +API exp : clarified presentation of memory estimation / measurement functions. new : contrib/seekable_format, demo and API, by Sean Purcell changed : contrib/linux-kernel, updated version and license, by Nick Terrell diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 523c49bb4..d108acaa4 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -581,11 +581,11 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference); * More threads improve speed, but also increase memory usage. * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled. * Special: value 0 means "do not change nbThreads" */ - ZSTDMT_p_jobSize,
    /* Size of a compression job. Each compression job is completed in parallel. + ZSTD_p_jobSize, /* Size of a compression job. Each compression job is completed in parallel. * 0 means default, which is dynamically determined based on compression parameters. * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest * The minimum size is automatically and transparently enforced */ - ZSTDMT_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. + ZSTD_p_overlapSizeLog, /* Size of previous input reloaded at the beginning of each job. * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */ /* advanced parameters - may not remain available after API update */ @@ -691,11 +691,12 @@ size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dic


    -
    size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    +
    void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
     

    Return a CCtx to clean state. Useful after an error, or to interrupt an ongoing compression job and start a new one. - It's possible to modify compression parameters after a reset. Any internal data not yet flushed is cancelled. + Dictionary (if any) is dropped, next compression starts with srcSize==unknown by default. + It's possible to modify compression parameters after a reset.


    diff --git a/tests/Makefile b/tests/Makefile index 0ee182fa8..c116404b8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -30,14 +30,14 @@ DEBUGFLAGS= -g -DZSTD_DEBUG=1 CPPFLAGS += -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) CFLAGS ?= -O3 -CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ +CFLAGS += -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ - -Wstrict-prototypes -Wundef -Wformat-security \ - -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ - -Wredundant-decls \ - $(DEBUGFLAGS) -CFLAGS += $(MOREFLAGS) -FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) + -Wstrict-prototypes -Wundef -Wformat-security \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls +CFLAGS += $(DEBUGFLAGS) +CFLAGS += $(MOREFLAGS) +FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c @@ -321,6 +321,8 @@ test-zbuff32: zbufftest32 test-zstream: zstreamtest $(QEMU_SYS) ./zstreamtest $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) + $(QEMU_SYS) ./zstreamtest --mt $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) + $(QEMU_SYS) ./zstreamtest --newapi $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) test-zstream32: zstreamtest32 $(QEMU_SYS) ./zstreamtest32 $(ZSTREAM_TESTTIME) $(FUZZER_FLAGS) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 17772856e..424d1cf63 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -25,6 +25,7 @@ #include /* fgets, sscanf */ #include /* clock_t, clock() */ #include /* strcmp */ +#include /* assert */ #include "mem.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_maxCLevel, ZSTD_customMem, ZSTD_getDictID_fromFrame */ #include "zstd.h" /* ZSTD_compressBound */ @@ -646,8 +647,22 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog) #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) -#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \ - DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); goto _output_error; } +#define CHECK(cond, ...) { \ + if (cond) { \ + DISPLAY("Error => "); \ + DISPLAY(__VA_ARGS__); \ + DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); \ + goto _output_error; \ +} } + +#define CHECK_Z(f) { \ + size_t const err = f; \ + if (ZSTD_isError(err)) { \ + DISPLAY("Error => %s : %s ", \ + #f, ZSTD_getErrorName(err)); \ + DISPLAY(" (seed %u, test nb %u) \n", seed, testNb); \ + goto _output_error; \ +} } static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests) { @@ -739,8 +754,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1; { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? 0 : maxTestSize; - size_t const resetError = ZSTD_resetCStream(zc, pledgedSrcSize); - CHECK(ZSTD_isError(resetError), "ZSTD_resetCStream error : %s", ZSTD_getErrorName(resetError)); + CHECK_Z( ZSTD_resetCStream(zc, pledgedSrcSize) ); } } else { U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; @@ -760,9 +774,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres ZSTD_parameters params = ZSTD_getParams(cLevel, pledgedSrcSize, dictSize); params.fParams.checksumFlag = FUZ_rand(&lseed) & 1; params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1; - { size_t const initError = ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize); - CHECK (ZSTD_isError(initError),"ZSTD_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); - } } } + CHECK_Z ( ZSTD_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize) ); + } } /* multi-segments compression test */ XXH64_reset(&xxhState, 0); @@ -1142,6 +1155,289 @@ _output_error: } +/* Tests for ZSTD_compressGeneric() API */ +static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests) +{ + static const U32 maxSrcLog = 24; + static const U32 maxSampleLog = 19; + size_t const srcBufferSize = (size_t)1<= testNb) { DISPLAYUPDATE(2, "\r%6u/%6u ", testNb, nbTests); } + else { DISPLAYUPDATE(2, "\r%6u ", testNb); } + FUZ_rand(&coreSeed); + lseed = coreSeed ^ prime32; + + /* states full reset (deliberately not synchronized) */ + /* some issues can only happen when reusing states */ + if ((FUZ_rand(&lseed) & 0xFF) == 131) { + DISPLAYLEVEL(5, "Creating new context \n"); + ZSTD_freeCCtx(zc); + zc = ZSTD_createCCtx(); + CHECK(zc==NULL, "allocation error"); + resetAllowed=0; + } + if ((FUZ_rand(&lseed) & 0xFF) == 132) { + ZSTD_freeDStream(zd); + zd = ZSTD_createDStream(); + CHECK(zd==NULL, "allocation error"); + ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ + } + + /* srcBuffer selection [0-4] */ + { U32 buffNb = FUZ_rand(&lseed) & 0x7F; + if (buffNb & 7) buffNb=2; /* most common : compressible (P) */ + else { + buffNb >>= 3; + if (buffNb & 7) { + const U32 tnb[2] = { 1, 3 }; /* barely/highly compressible */ + buffNb = tnb[buffNb >> 3]; + } else { + const U32 tnb[2] = { 0, 4 }; /* not compressible / sparse */ + buffNb = tnb[buffNb >> 3]; + } } + srcBuffer = cNoiseBuffer[buffNb]; + } + + /* compression init */ + if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */ + && oldTestLog /* at least one test happened */ && resetAllowed) { + maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2); + if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1; + CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) ); + { int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1; + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_compressionLevel, compressionLevel) ); + } + } else { + U32 const testLog = FUZ_rand(&lseed) % maxSrcLog; + U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog; + U32 const cLevel = (FUZ_rand(&lseed) % + (ZSTD_maxCLevel() - + (MAX(testLog, dictLog) / cLevelLimiter))) + + 1; + maxTestSize = FUZ_rLogLength(&lseed, testLog); + oldTestLog = testLog; + /* random dictionary selection */ + dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0; + { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize); + dict = srcBuffer + dictStart; + } + { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; + ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize); + + /* mess with compression parameters */ + cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1; + cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1; + cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1; + cParams.searchLog += (FUZ_rand(&lseed) & 3) - 1; + cParams.searchLength += (FUZ_rand(&lseed) & 3) - 1; + cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((FUZ_rand(&lseed) & 127) * 128))); + cParams = ZSTD_adjustCParams(cParams, 0, 0); + + /* to do : check everything works properly when only some parameters are set and others are not */ + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_hashLog, cParams.hashLog) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_chainLog, cParams.chainLog) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_searchLog, cParams.searchLog) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); + + CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); + + /* to do : check that cParams are blocked after loading non-NULL dictionary */ + + /* mess with frame parameters */ + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_contentSizeFlag, pledgedSrcSize>0) ); + CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) ); /* <== to test : must work also when pledgedSrcSize not set ! */ + DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize); + + /* multi-threading parameters */ + { U32 const nbThreads = (FUZ_rand(&lseed) & 3) + 1; + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbThreads, nbThreads) ); + if (nbThreads > 1) { + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_jobSize, FUZ_rand(&lseed) % (2*maxTestSize+1)) ); + } } } } + + /* multi-segments compression test */ + XXH64_reset(&xxhState, 0); + { ZSTD_outBuffer outBuff = { cBuffer, cBufferSize, 0 } ; + U32 n; + for (n=0, cSize=0, totalTestSize=0 ; totalTestSize < maxTestSize ; n++) { + /* compress random chunks into randomly sized dst buffers */ + { size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize); + size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize); + size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize); + ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 }; + outBuff.size = outBuff.pos + dstBuffSize; + + CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_continue) ); + DISPLAYLEVEL(5, "compress consumed %u bytes (total : %u) \n", + (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos)); + + XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); + memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); + totalTestSize += inBuff.pos; + } + + /* random flush operation, to mess around */ + if ((FUZ_rand(&lseed) & 15) == 0) { + ZSTD_inBuffer inBuff = { NULL, 0, 0 }; + size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); + outBuff.size = outBuff.pos + adjustedDstSize; + DISPLAYLEVEL(5, "Flushing into dst buffer of size %u \n", (U32)adjustedDstSize); + CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_flush) ); + } } + + /* final frame epilogue */ + { size_t remainingToFlush = (size_t)(-1); + while (remainingToFlush) { + ZSTD_inBuffer inBuff = { NULL, 0, 0 }; + size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); + outBuff.size = outBuff.pos + adjustedDstSize; + DISPLAYLEVEL(5, "End-flush into dst buffer of size %u \n", (U32)adjustedDstSize); + remainingToFlush = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end); + CHECK(ZSTD_isError(remainingToFlush), "ZSTD_compress_generic w/ ZSTD_e_end error : %s", ZSTD_getErrorName(remainingToFlush)); + } } + crcOrig = XXH64_digest(&xxhState); + cSize = outBuff.pos; + DISPLAYLEVEL(5, "Frame completed : %u bytes \n", (U32)cSize); + } + + /* multi - fragments decompression test */ + if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) { + CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed"); + } else { + ZSTD_initDStream_usingDict(zd, dict, dictSize); + } + { size_t decompressionResult = 1; + ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 }; + ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 }; + for (totalGenSize = 0 ; decompressionResult ; ) { + size_t const readCSrcSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize); + inBuff.size = inBuff.pos + readCSrcSize; + outBuff.size = inBuff.pos + dstBuffSize; + DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes \n", (U32)readCSrcSize); + decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff); + CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult)); + DISPLAYLEVEL(5, "inBuff.pos = %u \n", (U32)readCSrcSize); + } + CHECK (outBuff.pos != totalTestSize, "decompressed data : wrong size (%u != %u)", (U32)outBuff.pos, (U32)totalTestSize); + CHECK (inBuff.pos != cSize, "compressed data should be fully read (%u != %u)", (U32)inBuff.pos, (U32)cSize); + { U64 const crcDest = XXH64(dstBuffer, totalTestSize, 0); + if (crcDest!=crcOrig) findDiff(copyBuffer, dstBuffer, totalTestSize); + CHECK (crcDest!=crcOrig, "decompressed data corrupted"); + } } + + /*===== noisy/erroneous src decompression test =====*/ + + /* add some noise */ + { U32 const nbNoiseChunks = (FUZ_rand(&lseed) & 7) + 2; + U32 nn; for (nn=0; nn Date: Fri, 16 Jun 2017 18:16:27 -0700 Subject: [PATCH 214/400] removed macro CLAMP from decodecorpus never used, and would duplicate with CLAMP from zstd_compress.c --- tests/decodecorpus.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index f7b3c854f..940e3d8a1 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -73,8 +73,6 @@ static clock_t clockSpan(clock_t cStart) /*-******************************************************* * Random function *********************************************************/ -#define CLAMP(x, a, b) ((x) < (a) ? (a) : ((x) > (b) ? (b) : (x))) - static unsigned RAND(unsigned* src) { #define RAND_rotl32(x,r) ((x << r) | (x >> (32 - r))) From 92bafda406935a276080534a762f4ed9b50dc638 Mon Sep 17 00:00:00 2001 From: Yuri Date: Sat, 17 Jun 2017 00:23:41 -0700 Subject: [PATCH 215/400] INSTALL_DATA instead of INSTALL_LIB for libzstd.a INSTALL_LIB can be passed -s flag to strip symbols. Static libraries should not be stripped, only dynamic ones should be stripped. --- lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Makefile b/lib/Makefile index d0c3c8264..5845cf170 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -149,7 +149,7 @@ install: libzstd.a libzstd libzstd.pc @$(INSTALL) -d -m 755 $(DESTDIR)$(PKGCONFIGDIR)/ $(DESTDIR)$(INCLUDEDIR)/ @$(INSTALL_DATA) libzstd.pc $(DESTDIR)$(PKGCONFIGDIR)/ @echo Installing libraries - @$(INSTALL_LIB) libzstd.a $(DESTDIR)$(LIBDIR) + @$(INSTALL_DATA) libzstd.a $(DESTDIR)$(LIBDIR) @$(INSTALL_LIB) libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR) @ln -sf libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT_MAJOR) @ln -sf libzstd.$(SHARED_EXT_VER) $(DESTDIR)$(LIBDIR)/libzstd.$(SHARED_EXT) From 8dee0ec99e2259e863afaa14ecf5f723e6518cba Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Jun 2017 23:25:15 -0700 Subject: [PATCH 216/400] new api fuzzer tests : compression parameters are randomly set --- tests/zstreamtest.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 424d1cf63..e087dd722 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1197,7 +1197,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed); /* highly compressible */ RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed); /* sparse content */ memset(copyBuffer, 0x65, copyBufferSize); /* make copyBuffer considered initialized */ - ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ + ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ /* catch up testNb */ for (testNb=1; testNb < startTest; testNb++) @@ -1285,13 +1285,12 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((FUZ_rand(&lseed) & 127) * 128))); cParams = ZSTD_adjustCParams(cParams, 0, 0); - /* to do : check everything works properly when only some parameters are set and others are not */ - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_hashLog, cParams.hashLog) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_chainLog, cParams.chainLog) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_searchLog, cParams.searchLog) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_hashLog, cParams.hashLog) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_chainLog, cParams.chainLog) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_searchLog, cParams.searchLog) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); @@ -1416,7 +1415,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double /* No forward progress possible */ if (outBuff.pos < outBuff.size && inBuff.pos == cSize) break; } } } } - DISPLAY("\r%u fuzzer tests completed \n", testNb); + DISPLAY("\r%u fuzzer tests completed \n", testNb-1); _cleanup: ZSTD_freeCCtx(zc); From ea3630a88997b88f9f17c6fdf637ed15e44b69d8 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Jun 2017 23:31:55 -0700 Subject: [PATCH 217/400] new api fuzzer set : dictionary is randomly set --- tests/zstreamtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index e087dd722..0785aecb4 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1292,6 +1292,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); + if (FUZ_rand(&lseed) & 1) { dict=NULL; dictSize=0; } CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); /* to do : check that cParams are blocked after loading non-NULL dictionary */ From f5deae8a672754f0a1b0785c9fbec78fb9deca76 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 18 Jun 2017 23:41:38 -0700 Subject: [PATCH 218/400] new api fuzzer tests : frame parameters are randonly set --- tests/zstreamtest.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 0785aecb4..d5b50fd5c 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1282,7 +1282,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1; cParams.searchLog += (FUZ_rand(&lseed) & 3) - 1; cParams.searchLength += (FUZ_rand(&lseed) & 3) - 1; - cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((FUZ_rand(&lseed) & 127) * 128))); + cParams.targetLength = (U32)(cParams.targetLength * (0.5 + ((double)(FUZ_rand(&lseed) & 127) / 128))); cParams = ZSTD_adjustCParams(cParams, 0, 0); if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog) ); @@ -1293,15 +1293,15 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); if (FUZ_rand(&lseed) & 1) { dict=NULL; dictSize=0; } - CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); + CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); /* unconditionally set, to be sync with decoder (could be improved) */ /* to do : check that cParams are blocked after loading non-NULL dictionary */ /* mess with frame parameters */ - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_contentSizeFlag, pledgedSrcSize>0) ); - CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) ); /* <== to test : must work also when pledgedSrcSize not set ! */ + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_dictIDFlag, FUZ_rand(&lseed) & 1) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_contentSizeFlag, FUZ_rand(&lseed) & 1) ); + if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setPledgedSrcSize(zc, pledgedSrcSize) ); DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize); /* multi-threading parameters */ From 09ac51b56be02deea1782aa9e0fda908feb3956b Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 19 Jun 2017 09:24:38 -0700 Subject: [PATCH 219/400] small style changes --- tests/decodecorpus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 9565d33d7..4f8e89a2b 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1342,7 +1342,6 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const RAND_buffer(&seed, (void*)dictContent, dictContentSize); { size_t dictWriteSize = 0; - /* create random samples */ unsigned numSamples = 0; BYTE* samples; @@ -1361,10 +1360,11 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const totalSize += *curr; curr++; } + DISPLAY("random size: %zu\n", randSize); numReps *= 2; } samples = malloc(totalSize); - + DISPLAY("%zu\n", totalSize); /* reset pointer and counter */ curr = sampleSizes; i = 0; @@ -1372,7 +1372,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const /* take substring from dictionary content */ size_t pos = 0; BYTE* endDict = dictContent + dictContentSize; - while(i++ < numSamples){ + while (i++ < numSamples) { size_t currSize = *(curr++); BYTE* startSubstring = endDict - currSize; memcpy(samples + pos, (void*)startSubstring, currSize); @@ -1441,7 +1441,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, fullDict, dictSize); - if(ZSTD_isError(returnValue)){ + if (ZSTD_isError(returnValue)) { DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue)); } From 55b9b28dad3b3aa98bfa81def73039e1cf38472e Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 19 Jun 2017 09:55:55 -0700 Subject: [PATCH 220/400] made style changes, added description in man file --- programs/fileio.c | 7 +++---- programs/zstd.1.md | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index df492a9ef..f46986d0a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -929,12 +929,11 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ /* skip the rest of the blocks in the frame */ { int lastBlock = 0; - size_t readBytes = 0; do { BYTE blockHeaderBuffer[3]; U32 blockHeader; int blockSize; - readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); + size_t readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); if (readBytes != 3) { DISPLAY("There was a problem reading the block header\n"); detectError = 1; @@ -984,8 +983,8 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ break; } { - long const frameSize = MEM_readLE32(frameSizeBuffer); - int const ret = fseek(srcFile, frameSize, SEEK_CUR); + U32 const frameSize = MEM_readLE32(frameSizeBuffer); + int const ret = fseek(srcFile, (long)frameSize, SEEK_CUR); if (ret != 0) { DISPLAY("Error: could not find end of skippable frame\n"); detectError = 1; diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 2f5a6747e..a5ae27cb7 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -93,6 +93,10 @@ the last one takes effect. * `--train FILEs`: Use FILEs as a training set to create a dictionary. The training set should contain a lot of small files (> 100). +* `-l`, `--list`: + Display information related to a zstd compressed file, such as size, ratio, and checksum. + Some of these fields may not be available. + This command can be augmented with the `-v` modifier. ### Operation modifiers From ed1d0391272137b5a53b3e2c32ac4a19787d8116 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Jun 2017 11:07:33 -0700 Subject: [PATCH 221/400] newapi fuzzer tests : random flush orders in main loop --- tests/zstreamtest.c | 64 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index d5b50fd5c..09aaae54d 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -729,8 +729,16 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres /* states full reset (deliberately not synchronized) */ /* some issues can only happen when reusing states */ - if ((FUZ_rand(&lseed) & 0xFF) == 131) { ZSTD_freeCStream(zc); zc = ZSTD_createCStream(); resetAllowed=0; } - if ((FUZ_rand(&lseed) & 0xFF) == 132) { ZSTD_freeDStream(zd); zd = ZSTD_createDStream(); ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ } + if ((FUZ_rand(&lseed) & 0xFF) == 131) { + ZSTD_freeCStream(zc); + zc = ZSTD_createCStream(); + resetAllowed=0; + } + if ((FUZ_rand(&lseed) & 0xFF) == 132) { + ZSTD_freeDStream(zd); + zd = ZSTD_createDStream(); + ZSTD_initDStream_usingDict(zd, NULL, 0); /* ensure at least one init */ + } /* srcBuffer selection [0-4] */ { U32 buffNb = FUZ_rand(&lseed) & 0x7F; @@ -791,8 +799,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 }; outBuff.size = outBuff.pos + dstBuffSize; - { size_t const compressionError = ZSTD_compressStream(zc, &outBuff, &inBuff); - CHECK (ZSTD_isError(compressionError), "compression error : %s", ZSTD_getErrorName(compressionError)); } + CHECK_Z( ZSTD_compressStream(zc, &outBuff, &inBuff) ); XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); @@ -804,9 +811,8 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); outBuff.size = outBuff.pos + adjustedDstSize; - { size_t const flushError = ZSTD_flushStream(zc, &outBuff); - CHECK (ZSTD_isError(flushError), "flush error : %s", ZSTD_getErrorName(flushError)); - } } } + CHECK_Z( ZSTD_flushStream(zc, &outBuff) ); + } } /* final frame epilogue */ { size_t remainingToFlush = (size_t)(-1); @@ -1308,8 +1314,9 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double { U32 const nbThreads = (FUZ_rand(&lseed) & 3) + 1; CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbThreads, nbThreads) ); if (nbThreads > 1) { + U32 const jobLog = FUZ_rand(&lseed) % (testLog+1); CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_overlapSizeLog, FUZ_rand(&lseed) % 10) ); - CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_jobSize, FUZ_rand(&lseed) % (2*maxTestSize+1)) ); + CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_jobSize, (U32)FUZ_rLogLength(&lseed, jobLog)) ); } } } } /* multi-segments compression test */ @@ -1318,32 +1325,23 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double U32 n; for (n=0, cSize=0, totalTestSize=0 ; totalTestSize < maxTestSize ; n++) { /* compress random chunks into randomly sized dst buffers */ - { size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog); - size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize); - size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize); - size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); - size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize); - ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 }; - outBuff.size = outBuff.pos + dstBuffSize; + size_t const randomSrcSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const srcSize = MIN(maxTestSize-totalTestSize, randomSrcSize); + size_t const srcStart = FUZ_rand(&lseed) % (srcBufferSize - srcSize); + size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); + size_t const dstBuffSize = MIN(cBufferSize - cSize, randomDstSize); + ZSTD_EndDirective const flush = (FUZ_rand(&lseed) & 15) ? ZSTD_e_continue : ZSTD_e_flush; + ZSTD_inBuffer inBuff = { srcBuffer+srcStart, srcSize, 0 }; + outBuff.size = outBuff.pos + dstBuffSize; - CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_continue) ); - DISPLAYLEVEL(5, "compress consumed %u bytes (total : %u) \n", - (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos)); + CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, flush) ); + DISPLAYLEVEL(5, "compress consumed %u bytes (total : %u) \n", + (U32)inBuff.pos, (U32)(totalTestSize + inBuff.pos)); - XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); - memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); - totalTestSize += inBuff.pos; - } - - /* random flush operation, to mess around */ - if ((FUZ_rand(&lseed) & 15) == 0) { - ZSTD_inBuffer inBuff = { NULL, 0, 0 }; - size_t const randomDstSize = FUZ_randomLength(&lseed, maxSampleLog); - size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize); - outBuff.size = outBuff.pos + adjustedDstSize; - DISPLAYLEVEL(5, "Flushing into dst buffer of size %u \n", (U32)adjustedDstSize); - CHECK_Z( ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_flush) ); - } } + XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos); + memcpy(copyBuffer+totalTestSize, srcBuffer+srcStart, inBuff.pos); + totalTestSize += inBuff.pos; + } /* final frame epilogue */ { size_t remainingToFlush = (size_t)(-1); @@ -1413,7 +1411,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double inBuff.size = inBuff.pos + adjustedCSrcSize; { size_t const decompressError = ZSTD_decompressStream(zd, &outBuff, &inBuff); if (ZSTD_isError(decompressError)) break; /* error correctly detected */ - /* No forward progress possible */ + /* Good so far, but no more progress possible */ if (outBuff.pos < outBuff.size && inBuff.pos == cSize) break; } } } } DISPLAY("\r%u fuzzer tests completed \n", testNb-1); From 33467add60a9ef1c3c0e0e937b03e78159c25f1c Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 19 Jun 2017 11:27:50 -0700 Subject: [PATCH 222/400] made changes so that HUF_writeCTable no longer fails --- tests/decodecorpus.c | 50 +++++++++++++------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 4f8e89a2b..00eaa9dab 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1342,42 +1342,22 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const RAND_buffer(&seed, (void*)dictContent, dictContentSize); { size_t dictWriteSize = 0; - /* create random samples */ - unsigned numSamples = 0; - BYTE* samples; - unsigned i = 0; - size_t* sampleSizes = malloc(255*sizeof(size_t)); + + /* create samples */ + unsigned numSamples = 4; + BYTE* samples = malloc(5000*sizeof(BYTE)); + size_t* sampleSizes = malloc(numSamples*sizeof(size_t)); { - size_t* curr = sampleSizes; - size_t totalSize = 0; - unsigned numReps = 1; - while (numSamples < 200) { - size_t randSize = RAND(&seed) % dictContentSize; - unsigned counter = numReps; - numSamples += numReps; - while(counter-- > 0){ - *curr = randSize; - totalSize += *curr; - curr++; - } - DISPLAY("random size: %zu\n", randSize); - numReps *= 2; - } - samples = malloc(totalSize); - DISPLAY("%zu\n", totalSize); - /* reset pointer and counter */ - curr = sampleSizes; - i = 0; - { - /* take substring from dictionary content */ - size_t pos = 0; - BYTE* endDict = dictContent + dictContentSize; - while (i++ < numSamples) { - size_t currSize = *(curr++); - BYTE* startSubstring = endDict - currSize; - memcpy(samples + pos, (void*)startSubstring, currSize); - pos += currSize; + unsigned i = 1; + size_t currSize = 1; + BYTE* curr = samples; + while (i <= 4) { + *(sampleSizes + i - 1) = currSize; + for (int j = 0; j < currSize; j++) { + *(curr++) = (BYTE)i; } + i++; + currSize *= 16; } } DISPLAY("==================done with generation====================\n"); @@ -1386,7 +1366,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const ZDICT_params_t zdictParams; memset(&zdictParams, 0, sizeof(zdictParams)); zdictParams.dictID = dictID; - zdictParams.notificationLevel = 1; + zdictParams.notificationLevel = 5; DISPLAY("===================zdict params================\n"); /* finalize dictionary with random samples */ dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, From da4ddc1f76f7c89cf0715de7d4543bab72b261dc Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Mon, 19 Jun 2017 11:40:45 -0700 Subject: [PATCH 223/400] fixed decompression so that it uses compressed version --- tests/decodecorpus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 00eaa9dab..8c94154df 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1353,7 +1353,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const BYTE* curr = samples; while (i <= 4) { *(sampleSizes + i - 1) = currSize; - for (int j = 0; j < currSize; j++) { + for (size_t j = 0; j < currSize; j++) { *(curr++) = (BYTE)i; } i++; @@ -1416,9 +1416,9 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const } /* if asked, supply the decompressed version */ - + DISPLAY("Attempting to decompress using the dictionary\n"); returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE, - fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, + fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, fullDict, dictSize); if (ZSTD_isError(returnValue)) { From d7a3bffba909eb5c0ebe79d3f1e457c1ec7d2da9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Jun 2017 11:53:01 -0700 Subject: [PATCH 224/400] new api : setting compression parameters is refused if a dictionary is already loaded --- lib/compress/zstd_compress.c | 11 +++++++++++ lib/zstd.h | 7 ++++--- tests/zstreamtest.c | 23 ++++++++++++++++------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f848c088e..3620e13d8 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -253,11 +253,15 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_compressionLevel : if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel(); /* cap max compression level */ if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); cctx->compressionLevel = value; return 0; case ZSTD_p_windowLog : + DEBUGLOG(5, "setting ZSTD_p_windowLog = %u (cdict:%u)", + value, (cctx->cdict!=NULL)); if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.windowLog = value; @@ -265,6 +269,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_hashLog : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.hashLog = value; @@ -272,6 +277,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_chainLog : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.chainLog = value; @@ -279,6 +285,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_searchLog : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.searchLog = value; @@ -286,6 +293,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_minMatch : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.searchLength = value; @@ -293,6 +301,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_targetLength : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.targetLength = value; @@ -300,6 +309,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v case ZSTD_p_compressionStrategy : if (value == 0) return 0; /* special value : 0 means "don't change anything" */ + if (cctx->cdict) return ERROR(stage_wrong); CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra); ZSTD_cLevelToCParams(cctx); cctx->requestedParams.cParams.strategy = (ZSTD_strategy)value; @@ -384,6 +394,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s { if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */ + DEBUGLOG(5, "load dictionary of size %u", (U32)dictSize); ZSTD_freeCDict(cctx->cdictLocal); /* in case one already exists */ if (dict==NULL || dictSize==0) { /* no dictionary mode */ cctx->cdictLocal = NULL; diff --git a/lib/zstd.h b/lib/zstd.h index 928abe240..b204b9a7b 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -528,8 +528,9 @@ ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem); * If it needs more memory than available, it will simply error out. * Note 2 : there is no corresponding "free" function. * Since workspace was allocated externally, it must be freed externally too. - * Limitation : currently not compatible with internal CDict creation, such as - * ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict(). + * Limitation 1 : currently not compatible with internal CDict creation, such as + * ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict(). + * Limitation 2 : currently not compatible with multi-threading */ ZSTDLIB_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize); @@ -746,7 +747,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo * It's also a CPU-heavy operation, with non-negligible impact on latency. * Note 3 : Dictionary will be used for all future compression jobs. * To return to "no-dictionary" situation, load a NULL dictionary */ -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); /* Not ready yet ! */ +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize); /*! ZSTD_CCtx_refPrefix() : * Reference a prefix (content-only dictionary) to bootstrap next compression job. diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 09aaae54d..57993fcbb 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1161,7 +1161,7 @@ _output_error: } -/* Tests for ZSTD_compressGeneric() API */ +/* Tests for ZSTD_compress_generic() API */ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests) { static const U32 maxSrcLog = 24; @@ -1181,7 +1181,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double ZSTD_DStream* zd = ZSTD_createDStream(); /* will be reset sometimes */ ZSTD_DStream* const zd_noise = ZSTD_createDStream(); clock_t const startClock = clock(); - const BYTE* dict=NULL; /* can keep same dict on 2 consecutive tests */ + const BYTE* dict = NULL; /* can keep same dict on 2 consecutive tests */ size_t dictSize = 0; U32 oldTestLog = 0; int const cLevelLimiter = bigTests ? 3 : 2; @@ -1278,11 +1278,13 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double dictSize = ((FUZ_rand(&lseed)&63)==1) ? FUZ_rLogLength(&lseed, dictLog) : 0; { size_t const dictStart = FUZ_rand(&lseed) % (srcBufferSize - dictSize); dict = srcBuffer + dictStart; + if (!dictSize) dict=NULL; } { U64 const pledgedSrcSize = (FUZ_rand(&lseed) & 3) ? ZSTD_CONTENTSIZE_UNKNOWN : maxTestSize; ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize); /* mess with compression parameters */ + CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) ); /* always cancel previous dict, to make user it's possible to pass compression parameters */ cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1; cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1; cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1; @@ -1298,10 +1300,15 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_minMatch, cParams.searchLength) ); if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) ); - if (FUZ_rand(&lseed) & 1) { dict=NULL; dictSize=0; } - CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); /* unconditionally set, to be sync with decoder (could be improved) */ + /* unconditionally set, to be sync with decoder */ + CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); - /* to do : check that cParams are blocked after loading non-NULL dictionary */ + if (dict && dictSize) { + /* test that compression parameters are correctly rejected after setting a dictionary */ + DISPLAYLEVEL(5, "setting windowLog while dict!=NULL \n"); + size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1) ; + CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed"); + } /* mess with frame parameters */ if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_checksumFlag, FUZ_rand(&lseed) & 1) ); @@ -1352,7 +1359,9 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double outBuff.size = outBuff.pos + adjustedDstSize; DISPLAYLEVEL(5, "End-flush into dst buffer of size %u \n", (U32)adjustedDstSize); remainingToFlush = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end); - CHECK(ZSTD_isError(remainingToFlush), "ZSTD_compress_generic w/ ZSTD_e_end error : %s", ZSTD_getErrorName(remainingToFlush)); + CHECK(ZSTD_isError(remainingToFlush), + "ZSTD_compress_generic w/ ZSTD_e_end error : %s", + ZSTD_getErrorName(remainingToFlush) ); } } crcOrig = XXH64_digest(&xxhState); cSize = outBuff.pos; @@ -1471,7 +1480,7 @@ int main(int argc, const char** argv) e_api selected_api = simple_api; const char* const programName = argv[0]; ZSTD_customMem const customMem = { allocFunction, freeFunction, NULL }; - ZSTD_customMem const customNULL = { NULL, NULL, NULL }; + ZSTD_customMem const customNULL = ZSTD_defaultCMem; /* Check command line */ for(argNb=1; argNb Date: Mon, 19 Jun 2017 11:53:42 -0700 Subject: [PATCH 225/400] minor declaration statement warning fix --- tests/zstreamtest.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 57993fcbb..95b3add0b 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1305,7 +1305,6 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double if (dict && dictSize) { /* test that compression parameters are correctly rejected after setting a dictionary */ - DISPLAYLEVEL(5, "setting windowLog while dict!=NULL \n"); size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1) ; CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed"); } From c7dcf0f37937b5af99730072ec048f94506b5648 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Jun 2017 12:03:25 -0700 Subject: [PATCH 226/400] updated manual --- doc/zstd_manual.html | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index d108acaa4..907366032 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -437,8 +437,9 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference); If it needs more memory than available, it will simply error out. Note 2 : there is no corresponding "free" function. Since workspace was allocated externally, it must be freed externally too. - Limitation : currently not compatible with internal CDict creation, such as - ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict(). + Limitation 1 : currently not compatible with internal CDict creation, such as + ZSTD_CCtx_loadDictionary() or ZSTD_initCStream_usingDict(). + Limitation 2 : currently not compatible with multi-threading


    @@ -496,8 +497,8 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);


    ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
    -

    optimize params for a given `srcSize` and `dictSize`. - both values are optional, select `0` if unknown. +

    optimize params for a given `srcSize` and `dictSize`. + both values are optional, select `0` if unknown.


    size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
    @@ -611,7 +612,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
                this value is overriden by srcSize instead. 
     


    -
    size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);   /* Not ready yet ! */
    +
    size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
     

    Create an internal CDict from dict buffer. Decompression will have to use same buffer. @result : 0, or an error code (which can be tested with ZSTD_isError()). From 9ad11bea4e83f008919218581488420b539a1a05 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 19 Jun 2017 12:24:14 -0700 Subject: [PATCH 227/400] [linux] Fix decompression memory allocation --- contrib/linux-kernel/lib/zstd/decompress.c | 34 +++++++++++-------- contrib/linux-kernel/test/UserlandTest.cpp | 15 +++++++-- contrib/linux-kernel/zstd.diff | 38 +++++++++++++--------- 3 files changed, 55 insertions(+), 32 deletions(-) diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c index def10ea4d..ec673d7e6 100644 --- a/contrib/linux-kernel/lib/zstd/decompress.c +++ b/contrib/linux-kernel/lib/zstd/decompress.c @@ -2212,6 +2212,20 @@ ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, size_t wor zds->ddict = zds->ddictLocal; zds->legacyVersion = 0; zds->hostageByte = 0; + + { + size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); + size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; + + zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem); + zds->inBuffSize = blockSize; + zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem); + zds->outBuffSize = neededOutSize; + if (zds->inBuff == NULL || zds->outBuff == NULL) { + ZSTD_freeDStream(zds); + return NULL; + } + } return zds; } @@ -2333,25 +2347,17 @@ size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inB if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); - /* Adapt buffer sizes to frame header instructions */ + /* Buffers are preallocated, but double check */ { - size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); - size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2; - zds->blockSize = blockSize; + size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); + size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; if (zds->inBuffSize < blockSize) { - ZSTD_free(zds->inBuff, zds->customMem); - zds->inBuffSize = blockSize; - zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem); - if (zds->inBuff == NULL) - return ERROR(memory_allocation); + return ERROR(GENERIC); } if (zds->outBuffSize < neededOutSize) { - ZSTD_free(zds->outBuff, zds->customMem); - zds->outBuffSize = neededOutSize; - zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem); - if (zds->outBuff == NULL) - return ERROR(memory_allocation); + return ERROR(GENERIC); } + zds->blockSize = blockSize; } zds->stage = zdss_read; } diff --git a/contrib/linux-kernel/test/UserlandTest.cpp b/contrib/linux-kernel/test/UserlandTest.cpp index 73b30be4c..03058382f 100644 --- a/contrib/linux-kernel/test/UserlandTest.cpp +++ b/contrib/linux-kernel/test/UserlandTest.cpp @@ -280,9 +280,9 @@ TEST(Block, ContentSize) { TEST(Block, CCtxLevelIncrease) { std::string c; - auto cctx = createCCtx(6); + auto cctx = createCCtx(22); auto dctx = createDCtx(); - for (int level = 1; level <= 6; ++level) { + for (int level = 1; level <= 22; ++level) { auto compressed = compress(*cctx, kData, level); auto const decompressed = decompress(*dctx, compressed, kData.size()); EXPECT_EQ(kData, decompressed); @@ -478,6 +478,17 @@ TEST(Stream, Flush) { EXPECT_EQ(kData, decompressed); } +TEST(Stream, DStreamLevelIncrease) { + auto zds = createDStream(); + for (int level = 1; level <= 22; ++level) { + auto zcs = createCStream(level); + auto compressed = compress(*zcs, kData); + ZSTD_resetDStream(zds.get()); + auto const decompressed = decompress(*zds, compressed, kData.size()); + EXPECT_EQ(kData, decompressed); + } +} + #define TEST_SYMBOL(symbol) \ do { \ extern void *__##symbol; \ diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff index 285961ab2..1fa64ff86 100644 --- a/contrib/linux-kernel/zstd.diff +++ b/contrib/linux-kernel/zstd.diff @@ -5068,10 +5068,10 @@ index 0000000..42236a3 +MODULE_DESCRIPTION("Zstd Compressor"); diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c new file mode 100644 -index 0000000..def10ea +index 0000000..ec673d7 --- /dev/null +++ b/lib/zstd/decompress.c -@@ -0,0 +1,2508 @@ +@@ -0,0 +1,2514 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. @@ -7286,6 +7286,20 @@ index 0000000..def10ea + zds->ddict = zds->ddictLocal; + zds->legacyVersion = 0; + zds->hostageByte = 0; ++ ++ { ++ size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); ++ size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; ++ ++ zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem); ++ zds->inBuffSize = blockSize; ++ zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem); ++ zds->outBuffSize = neededOutSize; ++ if (zds->inBuff == NULL || zds->outBuff == NULL) { ++ ZSTD_freeDStream(zds); ++ return NULL; ++ } ++ } + return zds; +} + @@ -7407,25 +7421,17 @@ index 0000000..def10ea + if (zds->fParams.windowSize > zds->maxWindowSize) + return ERROR(frameParameter_windowTooLarge); + -+ /* Adapt buffer sizes to frame header instructions */ ++ /* Buffers are preallocated, but double check */ + { -+ size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); -+ size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2; -+ zds->blockSize = blockSize; ++ size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); ++ size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2; + if (zds->inBuffSize < blockSize) { -+ ZSTD_free(zds->inBuff, zds->customMem); -+ zds->inBuffSize = blockSize; -+ zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem); -+ if (zds->inBuff == NULL) -+ return ERROR(memory_allocation); ++ return ERROR(GENERIC); + } + if (zds->outBuffSize < neededOutSize) { -+ ZSTD_free(zds->outBuff, zds->customMem); -+ zds->outBuffSize = neededOutSize; -+ zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem); -+ if (zds->outBuff == NULL) -+ return ERROR(memory_allocation); ++ return ERROR(GENERIC); + } ++ zds->blockSize = blockSize; + } + zds->stage = zdss_read; + } From bf99150be30b19009592414d763e82570ff53df3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 19 Jun 2017 12:56:25 -0700 Subject: [PATCH 228/400] update new api presentation in zstd.h and manual --- doc/zstd_manual.html | 395 +++++++++++++++-------------- lib/compress/zstd_compress.c | 6 +- lib/zstd.h | 465 ++++++++++++++++++----------------- 3 files changed, 431 insertions(+), 435 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 907366032..cf51daa85 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -516,204 +516,6 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);

    Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters


    -

    New experimental advanced parameters API


    -
    typedef enum {
    -    /* compression parameters */
    -    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    -                              * Default level is 3.
    -                              * Special: value 0 means "do not change cLevel". */
    -    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    -                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    -                              * default value : set through compressionLevel.
    -                              * Special: value 0 means "do not change windowLog". */
    -    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    -                              * Resulting table size is (1 << (hashLog+2)).
    -                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    -                              * Larger tables improve compression ratio of strategies <= dFast,
    -                              * and improve speed of strategies > dFast.
    -                              * Special: value 0 means "do not change hashLog". */
    -    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    -                              * Resulting table size is (1 << (chainLog+2)).
    -                              * Larger tables result in better and slower compression.
    -                              * This parameter is useless when using "fast" strategy.
    -                              * Special: value 0 means "do not change chainLog". */
    -    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    -                              * More attempts result in better and slower compression.
    -                              * This parameter is useless when using "fast" and "dFast" strategies.
    -                              * Special: value 0 means "do not change searchLog". */
    -    ZSTD_p_minMatch,         /* Minimum size of searched matches (note : repCode matches can be smaller).
    -                              * Larger values make faster compression and decompression, but decrease ratio.
    -                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    -                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    -                              * Note that currently, for all strategies > fast, effective maximum is 6.
    -                              * Special: value 0 means "do not change minMatchLength". */
    -    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    -                              * Length of Match considered "good enough" to stop search.
    -                              * Larger values make compression stronger and slower.
    -                              * Special: value 0 means "do not change targetLength". */
    -    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    -                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
    -                              * The higher the value of selected strategy, the more complex it is,
    -                              * resulting in stronger and slower compression.
    -                              * Special: value 0 means "do not change strategy". */
    -#if 0
    -    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    -                              * Can be set to a more precise value than windowLog.
    -                              * Will be transparently reduced to closest possible inferior value
    -                              * (see Zstandard compression format) */
    -                             /* Not ready yet ! */
    -#endif
    -
    -    /* frame parameters */
    -    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    -    ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
    -    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    -
    -    /* dictionary parameters */
    -    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    -                              * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its user (CDict) */
    -                             /* Not ready yet ! */
    -    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    -                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    -
    -    /* multi-threading parameters */
    -    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    -                              * More threads improve speed, but also increase memory usage.
    -                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    -                              * Special: value 0 means "do not change nbThreads" */
    -    ZSTD_p_jobSize,          /* Size of a compression job. Each compression job is completed in parallel.
    -                              * 0 means default, which is dynamically determined based on compression parameters.
    -                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    -                              * The minimum size is automatically and transparently enforced */
    -    ZSTD_p_overlapSizeLog,   /* Size of previous input reloaded at the beginning of each job.
    -                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    -
    -    /* advanced parameters - may not remain available after API update */
    -    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    -                              * even when referencing into Dictionary content
    -                              * default : 0 when using a CDict, 1 when using a Prefix */
    -} ZSTD_cParameter;
    -

    -
    size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    -

    Set one compression parameter, selected by enum ZSTD_cParameter. - Note : when `value` is an enum, cast it to unsigned for proper type checking. - @result : 0, or an error code (which can be tested with ZSTD_isError()). -


    - -
    size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    -

    Total input data size to be compressed into a single frame. - This value will be controlled at the end, and result in error if not respected. - @result : 0, or an error code (which can be tested with ZSTD_isError()). - Note 1 : 0 means zero, empty. - In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. - Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for all new compression jobs. - Note 2 : If all data is provided and consumed in a single round, - this value is overriden by srcSize instead. -


    - -
    size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
    -

    Create an internal CDict from dict buffer. - Decompression will have to use same buffer. - @result : 0, or an error code (which can be tested with ZSTD_isError()). - Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, - meaning "return to no-dictionary mode". - Note 1 : Dictionary content will be copied internally, - except if ZSTD_p_refDictContent is set. - Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. - For this reason, compression parameters cannot be changed anymore after loading a prefix. - It's also a CPU-heavy operation, with non-negligible impact on latency. - Note 3 : Dictionary will be used for all future compression jobs. - To return to "no-dictionary" situation, load a NULL dictionary -


    - -
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    -

    Reference a prefix (content-only dictionary) to bootstrap next compression job. - Decompression will have to use same prefix. - @result : 0, or an error code (which can be tested with ZSTD_isError()). - Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode". - Note 1 : Prefix buffer is referenced. It must outlive compression job. - Note 3 : Prefix is only used once. Tables are discarded at end of compression job. - If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict. - Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters. - For this reason, compression parameters cannot be changed anymore after loading a prefix. - It's also a CPU-heavy operation, with non-negligible impact on latency. -


    - -
    ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    -size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    -size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    -

    Create a CDict object which is still mutable after creation. - It's the only one case allowing usage of ZSTD_CDict_setParameter(). - Once all compression parameters are selected, - it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). - Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). - After loading the dictionary, no more change is possible. - The only remaining operation is to free CDict object. - Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx. - -


    - -
    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
    -

    Add a prepared dictionary to cctx, to be used for next compression jobs. - Note that compression parameters will be enforced from within CDict. - Currently, they supercede any compression parameter previously set within CCtx. - The dictionary will remain valid for future compression jobs using same cctx. - @result : 0, or an error code (which can be tested with ZSTD_isError()). - Special : adding a NULL CDict means "return to no-dictionary mode". - Note 1 : Currently, only one dictionary can be managed. - Adding a new dictionary effectively "discards" any previous one. - Note 2 : CDict is just referenced, its lifetime must outlive CCtx. - -


    - -
    typedef enum {
    -    ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
    -    ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    -    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    -} ZSTD_EndDirective;
    -

    -
    size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    -                              ZSTD_outBuffer* output,
    -                              ZSTD_inBuffer* input,
    -                              ZSTD_EndDirective endOp);
    -

    Behave about the same as ZSTD_compressStream. To note : - - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter() - - Compression parameters cannot be changed once compression is started. - - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize - - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. - - @return provides the amount of data ready to flush within internal buffers - or an error code, which can be tested using ZSTD_isError(). - if @return != 0, flush is not fully completed, and must be called again to empty internal buffers. - - after a ZSTD_e_end directive, if internal buffer is not fully flushed, - only ZSTD_e_end and ZSTD_e_flush operations are allowed. - It is necessary to fully flush internal buffers - before changing compression parameters or start a new compression job. - -


    - -
    void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    -

    Return a CCtx to clean state. - Useful after an error, or to interrupt an ongoing compression job and start a new one. - Any internal data not yet flushed is cancelled. - Dictionary (if any) is dropped, next compression starts with srcSize==unknown by default. - It's possible to modify compression parameters after a reset. - -


    - -
    size_t ZSTD_compress_generic_simpleArgs (
    -                ZSTD_CCtx* cctx,
    -                void* dst, size_t dstCapacity, size_t* dstPos,
    -          const void* src, size_t srcSize, size_t* srcPos,
    -                ZSTD_EndDirective endOp);
    -

    Same as ZSTD_compress_generic(), - but using only simple integral types as arguments. - Argument list is less expressive than ZSTD_{in,out}Buffer, - but can be helpful for binders to dynamic languages - which have troubles handling structures containing memory pointers. - -


    -

    Advanced decompression functions

    
     
     
    unsigned ZSTD_isFrame(const void* buffer, size_t size);
    @@ -931,6 +733,203 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
     

    typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
     

    +

    New advanced API (experimental, and compression only)


    +
    typedef enum {
    +    /* compression parameters */
    +    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    +                              * Default level is ZSTD_CLEVEL_DEFAULT==3.
    +                              * Special: value 0 means "do not change cLevel". */
    +    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    +                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    +                              * default value : set through compressionLevel.
    +                              * Special: value 0 means "do not change windowLog". */
    +    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    +                              * Resulting table size is (1 << (hashLog+2)).
    +                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    +                              * Larger tables improve compression ratio of strategies <= dFast,
    +                              * and improve speed of strategies > dFast.
    +                              * Special: value 0 means "do not change hashLog". */
    +    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    +                              * Resulting table size is (1 << (chainLog+2)).
    +                              * Larger tables result in better and slower compression.
    +                              * This parameter is useless when using "fast" strategy.
    +                              * Special: value 0 means "do not change chainLog". */
    +    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    +                              * More attempts result in better and slower compression.
    +                              * This parameter is useless when using "fast" and "dFast" strategies.
    +                              * Special: value 0 means "do not change searchLog". */
    +    ZSTD_p_minMatch,         /* Minimum size of searched matches (note : repCode matches can be smaller).
    +                              * Larger values make faster compression and decompression, but decrease ratio.
    +                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    +                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    +                              * Note that currently, for all strategies > fast, effective maximum is 6.
    +                              * Special: value 0 means "do not change minMatchLength". */
    +    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    +                              * Length of Match considered "good enough" to stop search.
    +                              * Larger values make compression stronger and slower.
    +                              * Special: value 0 means "do not change targetLength". */
    +    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    +                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
    +                              * The higher the value of selected strategy, the more complex it is,
    +                              * resulting in stronger and slower compression.
    +                              * Special: value 0 means "do not change strategy". */
    +#if 0
    +    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    +                              * Can be set to a more precise value than windowLog.
    +                              * Will be transparently reduced to closest possible inferior value
    +                              * (see Zstandard compression format) */
    +                             /* Not ready yet ! */
    +#endif
    +
    +    /* frame parameters */
    +    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    +    ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
    +    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    +
    +    /* dictionary parameters */
    +    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    +                              * This avoids duplicating dictionary content.
    +                              * But it also requires that dictionary buffer outlives its user (CDict) */
    +                             /* Not ready yet ! */
    +    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    +                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    +
    +    /* multi-threading parameters */
    +    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    +                              * More threads improve speed, but also increase memory usage.
    +                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    +                              * Special: value 0 means "do not change nbThreads" */
    +    ZSTD_p_jobSize,          /* Size of a compression job. Each compression job is completed in parallel.
    +                              * 0 means default, which is dynamically determined based on compression parameters.
    +                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    +                              * The minimum size is automatically and transparently enforced */
    +    ZSTD_p_overlapSizeLog,   /* Size of previous input reloaded at the beginning of each job.
    +                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    +
    +    /* advanced parameters - may not remain available after API update */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    +                              * even when referencing into Dictionary content
    +                              * default : 0 when using a CDict, 1 when using a Prefix */
    +} ZSTD_cParameter;
    +

    +
    size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    +

    Set one compression parameter, selected by enum ZSTD_cParameter. + Note : when `value` is an enum, cast it to unsigned for proper type checking. + @result : 0, or an error code (which can be tested with ZSTD_isError()). +


    + +
    size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    +

    Total input data size to be compressed as a single frame. + This value will be controlled at the end, and result in error if not respected. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : 0 means zero, empty. + In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN. + Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for new compression jobs. + Note 2 : If all data is provided and consumed in a single round, + this value is overriden by srcSize instead. +


    + +
    size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
    +

    Create an internal CDict from dict buffer. + Decompression will have to use same buffer. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, + meaning "return to no-dictionary mode". + Note 1 : Dictionary content will be copied internally, + except if ZSTD_p_refDictContent is set. + Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. + For this reason, compression parameters cannot be changed anymore after loading a prefix. + It's also a CPU-heavy operation, with non-negligible impact on latency. + Note 3 : Dictionary will be used for all future compression jobs. + To return to "no-dictionary" situation, load a NULL dictionary +


    + +
    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
    +

    Ref a prepared dictionary, to be used for all next compression jobs. + Note that compression parameters are enforced from within CDict, + and supercede any compression parameter previously set within CCtx. + The dictionary will remain valid for future compression jobs using same CCtx. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : adding a NULL CDict means "return to no-dictionary mode". + Note 1 : Currently, only one dictionary can be managed. + Adding a new dictionary effectively "discards" any previous one. + Note 2 : CDict is just referenced, its lifetime must outlive CCtx. + +


    + +
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +

    Reference a prefix (content-only dictionary) to bootstrap next compression job. + Decompression will have to use same prefix. + Prefix is only used once. Tables are discarded at end of compression job. + If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode". + Note 1 : Prefix buffer is referenced. It must outlive compression job. + Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters. + It's a CPU-heavy operation, with non-negligible impact on latency. +


    + +
    typedef enum {
    +    ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
    +    ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +} ZSTD_EndDirective;
    +

    +
    size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                              ZSTD_outBuffer* output,
    +                              ZSTD_inBuffer* input,
    +                              ZSTD_EndDirective endOp);
    +

    Behave about the same as ZSTD_compressStream. To note : + - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter() + - Compression parameters cannot be changed once compression is started. + - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize + - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. + - @return provides the minimum amount of data still to flush from internal buffers + or an error code, which can be tested using ZSTD_isError(). + if @return != 0, flush is not fully completed, and must be called again to empty internal buffers. + - after a ZSTD_e_end directive, if internal buffer is not fully flushed, + only ZSTD_e_end and ZSTD_e_flush operations are allowed. + It is necessary to fully flush internal buffers + before starting a new compression job, or changing compression parameters. + +


    + +
    void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    +

    Return a CCtx to clean state. + Useful after an error, or to interrupt an ongoing compression job and start a new one. + Any internal data not yet flushed is cancelled. + Dictionary (if any) is dropped. + It's possible to modify compression parameters after a reset. + +


    + +
    size_t ZSTD_compress_generic_simpleArgs (
    +                ZSTD_CCtx* cctx,
    +                void* dst, size_t dstCapacity, size_t* dstPos,
    +          const void* src, size_t srcSize, size_t* srcPos,
    +                ZSTD_EndDirective endOp);
    +

    Same as ZSTD_compress_generic(), + but using only integral types as arguments. + Argument list is larger and less expressive than ZSTD_{in,out}Buffer, + but can be helpful for binders from dynamic languages + which have troubles handling structures containing memory pointers. + +


    + +
    ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    +size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    +size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    +

    Create a CDict object which is still mutable after creation. + It's the only one case allowing usage of ZSTD_CDict_setParameter(). + Once all compression parameters are selected, + it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). + Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). + After loading the dictionary, no more change is possible. + The only remaining operation is to free CDict object. + Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx. + +


    +

    Block functions

         Block functions produce and decode raw zstd blocks, without frame metadata.
         Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 3620e13d8..49d29dce4 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -15,6 +15,7 @@
     #  define ZSTD_CLEVEL_DEFAULT 3
     #endif
     
    +
     /*-*************************************
     *  Dependencies
     ***************************************/
    @@ -4021,11 +4022,6 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
         if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* 0 == default; no negative compressionLevel yet */
         if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
         cp = ZSTD_defaultCParameters[tableID][compressionLevel];
    -    if (MEM_32bits()) {   /* auto-correction, for 32-bits mode */
    -        if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
    -        if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
    -        if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
    -    }
         return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);   /* no need to ensure initial CParams validity */
     }
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index b204b9a7b..a60c91335 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -610,238 +610,6 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
                                 const ZSTD_CDict* cdict, ZSTD_frameParameters fParams);
     
     
    -/*===   New experimental advanced parameters API   ===*/
    -
    -/* notes on API design :
    - *   In this proposal, parameters are pushed one by one into an existing CCtx,
    - *   and then applied on all following compression jobs.
    - *   When no parameter is ever provided, CCtx is created with compression level 3.
    - *
    - *   Another approach could be to load parameters into an intermediate _opaque_ object.
    - *   The object would then be loaded into CCtx (like ZSTD_compress_advanced())
    - *   This approach would be compatible with ZSTD_createCDict_advanced().
    - *   But it's more cumbersome for CCtx, as it requires to manage an additional object.
    - *
    - *   Below proposal push parameters directly into CCtx.
    - *   It's a bit more complex for CDict, as advanced version now requires 3 steps.
    - *   (basic CDict API remains the same).
    - *   See API details below
    - */
    -
    -/* notes on naming convention :
    - *   Initially, the API favored names like ZSTD_setCCtxParameter() .
    - *   In this proposal, convention is changed towards ZSTD_CCtx_setParameter() .
    - *   The main idea is that it identifies more clearly the target object type.
    - *   It feels clearer when considering other potential variants :
    - *   ZSTD_CDict_setParameter() (rather than ZSTD_setCDictParameter())
    - *   ZSTD_DCtx_setParameter()  (rather than ZSTD_setDCtxParameter() )
    - *   The left variant looks clearer.
    - */
    -
    -typedef enum {
    -    /* compression parameters */
    -    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    -                              * Default level is 3.
    -                              * Special: value 0 means "do not change cLevel". */
    -    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    -                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    -                              * default value : set through compressionLevel.
    -                              * Special: value 0 means "do not change windowLog". */
    -    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    -                              * Resulting table size is (1 << (hashLog+2)).
    -                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    -                              * Larger tables improve compression ratio of strategies <= dFast,
    -                              * and improve speed of strategies > dFast.
    -                              * Special: value 0 means "do not change hashLog". */
    -    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    -                              * Resulting table size is (1 << (chainLog+2)).
    -                              * Larger tables result in better and slower compression.
    -                              * This parameter is useless when using "fast" strategy.
    -                              * Special: value 0 means "do not change chainLog". */
    -    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    -                              * More attempts result in better and slower compression.
    -                              * This parameter is useless when using "fast" and "dFast" strategies.
    -                              * Special: value 0 means "do not change searchLog". */
    -    ZSTD_p_minMatch,         /* Minimum size of searched matches (note : repCode matches can be smaller).
    -                              * Larger values make faster compression and decompression, but decrease ratio.
    -                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    -                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    -                              * Note that currently, for all strategies > fast, effective maximum is 6.
    -                              * Special: value 0 means "do not change minMatchLength". */
    -    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    -                              * Length of Match considered "good enough" to stop search.
    -                              * Larger values make compression stronger and slower.
    -                              * Special: value 0 means "do not change targetLength". */
    -    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    -                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
    -                              * The higher the value of selected strategy, the more complex it is,
    -                              * resulting in stronger and slower compression.
    -                              * Special: value 0 means "do not change strategy". */
    -#if 0
    -    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    -                              * Can be set to a more precise value than windowLog.
    -                              * Will be transparently reduced to closest possible inferior value
    -                              * (see Zstandard compression format) */
    -                             /* Not ready yet ! */
    -#endif
    -
    -    /* frame parameters */
    -    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    -    ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
    -    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    -
    -    /* dictionary parameters */
    -    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    -                              * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its user (CDict) */
    -                             /* Not ready yet ! */
    -    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    -                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    -
    -    /* multi-threading parameters */
    -    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    -                              * More threads improve speed, but also increase memory usage.
    -                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    -                              * Special: value 0 means "do not change nbThreads" */
    -    ZSTD_p_jobSize,          /* Size of a compression job. Each compression job is completed in parallel.
    -                              * 0 means default, which is dynamically determined based on compression parameters.
    -                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    -                              * The minimum size is automatically and transparently enforced */
    -    ZSTD_p_overlapSizeLog,   /* Size of previous input reloaded at the beginning of each job.
    -                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    -
    -    /* advanced parameters - may not remain available after API update */
    -    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    -                              * even when referencing into Dictionary content
    -                              * default : 0 when using a CDict, 1 when using a Prefix */
    -} ZSTD_cParameter;
    -
    -
    -/*! ZSTD_CCtx_setParameter() :
    - *  Set one compression parameter, selected by enum ZSTD_cParameter.
    - *  Note : when `value` is an enum, cast it to unsigned for proper type checking.
    - *  @result : 0, or an error code (which can be tested with ZSTD_isError()). */
    -ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    -
    -/*! ZSTD_CCtx_setPledgedSrcSize() :
    - *  Total input data size to be compressed into a single frame.
    - *  This value will be controlled at the end, and result in error if not respected.
    - * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    - *  Note 1 : 0 means zero, empty.
    - *           In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN.
    - *           Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for all new compression jobs.
    - *  Note 2 : If all data is provided and consumed in a single round,
    - *           this value is overriden by srcSize instead. */
    -ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    -
    -/*! ZSTD_CCtx_loadDictionary() :
    - *  Create an internal CDict from dict buffer.
    - *  Decompression will have to use same buffer.
    - * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    - *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix,
    - *            meaning "return to no-dictionary mode".
    - *  Note 1 : Dictionary content will be copied internally,
    - *           except if ZSTD_p_refDictContent is set.
    - *  Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
    - *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    - *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    - *  Note 3 : Dictionary will be used for all future compression jobs.
    - *           To return to "no-dictionary" situation, load a NULL dictionary */
    -ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
    -
    -/*! ZSTD_CCtx_refPrefix() :
    - *  Reference a prefix (content-only dictionary) to bootstrap next compression job.
    - *  Decompression will have to use same prefix.
    - * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    - *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode".
    - *  Note 1 : Prefix buffer is referenced. It must outlive compression job.
    - *  Note 3 : Prefix is only used once. Tables are discarded at end of compression job.
    - *           If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict.
    - *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
    - *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    - *           It's also a CPU-heavy operation, with non-negligible impact on latency. */
    -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    -
    -
    -/*! ZSTD_CDict_createEmpty() :
    - *  Create a CDict object which is still mutable after creation.
    - *  It's the only one case allowing usage of ZSTD_CDict_setParameter().
    - *  Once all compression parameters are selected,
    - *  it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary().
    - *  Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set).
    - *  After loading the dictionary, no more change is possible.
    - *  The only remaining operation is to free CDict object.
    - *  Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx.
    - */
    -ZSTDLIB_API ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    -ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    -ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    -
    -/*! ZSTD_CCtx_refCDict() :
    - *  Add a prepared dictionary to cctx, to be used for next compression jobs.
    - *  Note that compression parameters will be enforced from within CDict.
    - *  Currently, they supercede any compression parameter previously set within CCtx.
    - *  The dictionary will remain valid for future compression jobs using same cctx.
    - * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    - *  Special : adding a NULL CDict means "return to no-dictionary mode".
    - *  Note 1 : Currently, only one dictionary can be managed.
    - *           Adding a new dictionary effectively "discards" any previous one.
    - *  Note 2 : CDict is just referenced, its lifetime must outlive CCtx.
    - */
    -ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
    -
    -
    -
    -typedef enum {
    -    ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
    -    ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    -    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    -} ZSTD_EndDirective;
    -
    -/*! ZSTD_compressStream_generic() :
    - *  Behave about the same as ZSTD_compressStream. To note :
    - *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter()
    - *  - Compression parameters cannot be changed once compression is started.
    - *  - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize
    - *  - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit.
    - *  - @return provides the amount of data ready to flush within internal buffers
    - *            or an error code, which can be tested using ZSTD_isError().
    - *            if @return != 0, flush is not fully completed, and must be called again to empty internal buffers.
    - *  - after a ZSTD_e_end directive, if internal buffer is not fully flushed,
    - *            only ZSTD_e_end and ZSTD_e_flush operations are allowed.
    - *            It is necessary to fully flush internal buffers
    - *            before changing compression parameters or start a new compression job.
    - */
    -ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    -                                          ZSTD_outBuffer* output,
    -                                          ZSTD_inBuffer* input,
    -                                          ZSTD_EndDirective endOp);
    -
    -/*! ZSTD_CCtx_reset() :
    - *  Return a CCtx to clean state.
    - *  Useful after an error, or to interrupt an ongoing compression job and start a new one.
    - *  Any internal data not yet flushed is cancelled.
    - *  Dictionary (if any) is dropped, next compression starts with srcSize==unknown by default.
    - *  It's possible to modify compression parameters after a reset.
    - */
    -ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    -
    -
    -/*! ZSTD_compress_generic_simpleArgs() :
    - *  Same as ZSTD_compress_generic(),
    - *  but using only simple integral types as arguments.
    - *  Argument list is less expressive than ZSTD_{in,out}Buffer,
    - *  but can be helpful for binders to dynamic languages
    - *  which have troubles handling structures containing memory pointers.
    - */
    -size_t ZSTD_compress_generic_simpleArgs (
    -                            ZSTD_CCtx* cctx,
    -                            void* dst, size_t dstCapacity, size_t* dstPos,
    -                      const void* src, size_t srcSize, size_t* srcPos,
    -                            ZSTD_EndDirective endOp);
    -
    -
    -
     /*--- Advanced decompression functions ---*/
     
     /*! ZSTD_isFrame() :
    @@ -1081,6 +849,239 @@ ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t ds
     typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
     ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
     
    +
    +
    +/*===   New advanced API (experimental, and compression only)  ===*/
    +
    +/* notes on API design :
    + *   In this proposal, parameters are pushed one by one into an existing CCtx,
    + *   and then applied on all subsequent compression jobs.
    + *   When no parameter is ever provided, CCtx is created with compression level ZSTD_CLEVEL_DEFAULT.
    + *
    + *   This API is intended to replace all others experimental API.
    + *   It can basically do all other use cases, and even new ones.
    + *   It stands a good chance to become "stable",
    + *   after a reasonable testing period.
    + */
    +
    +/* note on naming convention :
    + *   Initially, the API favored names like ZSTD_setCCtxParameter() .
    + *   In this proposal, convention is changed towards ZSTD_CCtx_setParameter() .
    + *   The main idea is that it identifies more clearly the target object type.
    + *   It feels clearer when considering other potential variants :
    + *   ZSTD_CDict_setParameter() (rather than ZSTD_setCDictParameter())
    + *   ZSTD_DCtx_setParameter()  (rather than ZSTD_setDCtxParameter() )
    + *   The left variant feels clearer.
    + */
    +
    +typedef enum {
    +    /* compression parameters */
    +    ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    +                              * Default level is ZSTD_CLEVEL_DEFAULT==3.
    +                              * Special: value 0 means "do not change cLevel". */
    +    ZSTD_p_windowLog,        /* Maximum allowed back-reference distance, expressed as power of 2.
    +                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
    +                              * default value : set through compressionLevel.
    +                              * Special: value 0 means "do not change windowLog". */
    +    ZSTD_p_hashLog,          /* Size of the probe table, as a power of 2.
    +                              * Resulting table size is (1 << (hashLog+2)).
    +                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
    +                              * Larger tables improve compression ratio of strategies <= dFast,
    +                              * and improve speed of strategies > dFast.
    +                              * Special: value 0 means "do not change hashLog". */
    +    ZSTD_p_chainLog,         /* Size of the full-search table, as a power of 2.
    +                              * Resulting table size is (1 << (chainLog+2)).
    +                              * Larger tables result in better and slower compression.
    +                              * This parameter is useless when using "fast" strategy.
    +                              * Special: value 0 means "do not change chainLog". */
    +    ZSTD_p_searchLog,        /* Number of search attempts, as a power of 2.
    +                              * More attempts result in better and slower compression.
    +                              * This parameter is useless when using "fast" and "dFast" strategies.
    +                              * Special: value 0 means "do not change searchLog". */
    +    ZSTD_p_minMatch,         /* Minimum size of searched matches (note : repCode matches can be smaller).
    +                              * Larger values make faster compression and decompression, but decrease ratio.
    +                              * Must be clamped between ZSTD_SEARCHLENGTH_MIN and ZSTD_SEARCHLENGTH_MAX.
    +                              * Note that currently, for all strategies < btopt, effective minimum is 4.
    +                              * Note that currently, for all strategies > fast, effective maximum is 6.
    +                              * Special: value 0 means "do not change minMatchLength". */
    +    ZSTD_p_targetLength,     /* Only useful for strategies >= btopt.
    +                              * Length of Match considered "good enough" to stop search.
    +                              * Larger values make compression stronger and slower.
    +                              * Special: value 0 means "do not change targetLength". */
    +    ZSTD_p_compressionStrategy, /* See ZSTD_strategy enum definition.
    +                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility.
    +                              * The higher the value of selected strategy, the more complex it is,
    +                              * resulting in stronger and slower compression.
    +                              * Special: value 0 means "do not change strategy". */
    +#if 0
    +    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    +                              * Can be set to a more precise value than windowLog.
    +                              * Will be transparently reduced to closest possible inferior value
    +                              * (see Zstandard compression format) */
    +                             /* Not ready yet ! */
    +#endif
    +
    +    /* frame parameters */
    +    ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
    +    ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
    +    ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
    +
    +    /* dictionary parameters */
    +    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    +                              * This avoids duplicating dictionary content.
    +                              * But it also requires that dictionary buffer outlives its user (CDict) */
    +                             /* Not ready yet ! */
    +    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    +                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    +
    +    /* multi-threading parameters */
    +    ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    +                              * More threads improve speed, but also increase memory usage.
    +                              * Can only receive a value > 1 if ZSTD_MULTITHREAD is enabled.
    +                              * Special: value 0 means "do not change nbThreads" */
    +    ZSTD_p_jobSize,          /* Size of a compression job. Each compression job is completed in parallel.
    +                              * 0 means default, which is dynamically determined based on compression parameters.
    +                              * Job size must be a minimum of overlapSize, or 1 KB, whichever is largest
    +                              * The minimum size is automatically and transparently enforced */
    +    ZSTD_p_overlapSizeLog,   /* Size of previous input reloaded at the beginning of each job.
    +                              * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
    +
    +    /* advanced parameters - may not remain available after API update */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    +                              * even when referencing into Dictionary content
    +                              * default : 0 when using a CDict, 1 when using a Prefix */
    +} ZSTD_cParameter;
    +
    +
    +/*! ZSTD_CCtx_setParameter() :
    + *  Set one compression parameter, selected by enum ZSTD_cParameter.
    + *  Note : when `value` is an enum, cast it to unsigned for proper type checking.
    + *  @result : 0, or an error code (which can be tested with ZSTD_isError()). */
    +ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    +
    +/*! ZSTD_CCtx_setPledgedSrcSize() :
    + *  Total input data size to be compressed as a single frame.
    + *  This value will be controlled at the end, and result in error if not respected.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Note 1 : 0 means zero, empty.
    + *           In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN.
    + *           Note that ZSTD_CONTENTSIZE_UNKNOWN is default value for new compression jobs.
    + *  Note 2 : If all data is provided and consumed in a single round,
    + *           this value is overriden by srcSize instead. */
    +ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
    +
    +/*! ZSTD_CCtx_loadDictionary() :
    + *  Create an internal CDict from dict buffer.
    + *  Decompression will have to use same buffer.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix,
    + *            meaning "return to no-dictionary mode".
    + *  Note 1 : Dictionary content will be copied internally,
    + *           except if ZSTD_p_refDictContent is set.
    + *  Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
    + *           For this reason, compression parameters cannot be changed anymore after loading a prefix.
    + *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    + *  Note 3 : Dictionary will be used for all future compression jobs.
    + *           To return to "no-dictionary" situation, load a NULL dictionary */
    +ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
    +
    +/*! ZSTD_CCtx_refCDict() :
    + *  Ref a prepared dictionary, to be used for all next compression jobs.
    + *  Note that compression parameters are enforced from within CDict,
    + *  and supercede any compression parameter previously set within CCtx.
    + *  The dictionary will remain valid for future compression jobs using same CCtx.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : adding a NULL CDict means "return to no-dictionary mode".
    + *  Note 1 : Currently, only one dictionary can be managed.
    + *           Adding a new dictionary effectively "discards" any previous one.
    + *  Note 2 : CDict is just referenced, its lifetime must outlive CCtx.
    + */
    +ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
    +
    +/*! ZSTD_CCtx_refPrefix() :
    + *  Reference a prefix (content-only dictionary) to bootstrap next compression job.
    + *  Decompression will have to use same prefix.
    + *  Prefix is only used once. Tables are discarded at end of compression job.
    + *  If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode".
    + *  Note 1 : Prefix buffer is referenced. It must outlive compression job.
    + *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
    + *           It's a CPU-heavy operation, with non-negligible impact on latency. */
    +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +
    +
    +
    +typedef enum {
    +    ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
    +    ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    +    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +} ZSTD_EndDirective;
    +
    +/*! ZSTD_compressStream_generic() :
    + *  Behave about the same as ZSTD_compressStream. To note :
    + *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter()
    + *  - Compression parameters cannot be changed once compression is started.
    + *  - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize
    + *  - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit.
    + *  - @return provides the minimum amount of data still to flush from internal buffers
    + *            or an error code, which can be tested using ZSTD_isError().
    + *            if @return != 0, flush is not fully completed, and must be called again to empty internal buffers.
    + *  - after a ZSTD_e_end directive, if internal buffer is not fully flushed,
    + *            only ZSTD_e_end and ZSTD_e_flush operations are allowed.
    + *            It is necessary to fully flush internal buffers
    + *            before starting a new compression job, or changing compression parameters.
    + */
    +ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    +                                          ZSTD_outBuffer* output,
    +                                          ZSTD_inBuffer* input,
    +                                          ZSTD_EndDirective endOp);
    +
    +/*! ZSTD_CCtx_reset() :
    + *  Return a CCtx to clean state.
    + *  Useful after an error, or to interrupt an ongoing compression job and start a new one.
    + *  Any internal data not yet flushed is cancelled.
    + *  Dictionary (if any) is dropped.
    + *  It's possible to modify compression parameters after a reset.
    + */
    +ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    +
    +
    +/*! ZSTD_compress_generic_simpleArgs() :
    + *  Same as ZSTD_compress_generic(),
    + *  but using only integral types as arguments.
    + *  Argument list is larger and less expressive than ZSTD_{in,out}Buffer,
    + *  but can be helpful for binders from dynamic languages
    + *  which have troubles handling structures containing memory pointers.
    + */
    +size_t ZSTD_compress_generic_simpleArgs (
    +                            ZSTD_CCtx* cctx,
    +                            void* dst, size_t dstCapacity, size_t* dstPos,
    +                      const void* src, size_t srcSize, size_t* srcPos,
    +                            ZSTD_EndDirective endOp);
    +
    +
    +/* note : this part if completely experimental, not ready yet.
    + * Main idea is : if ZSTD_parameters is not a good fit for stable API,
    + * there will be a need for something else.
    + * While initialising compression is now correctly covered,
    + * creating an advanced CDict still needs to be solved.
    + * Below is merely a plan of what it could look like */
    +/*! ZSTD_CDict_createEmpty() :
    + *  Create a CDict object which is still mutable after creation.
    + *  It's the only one case allowing usage of ZSTD_CDict_setParameter().
    + *  Once all compression parameters are selected,
    + *  it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary().
    + *  Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set).
    + *  After loading the dictionary, no more change is possible.
    + *  The only remaining operation is to free CDict object.
    + *  Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx.
    + */
    +ZSTDLIB_API ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    +
    +
     /**
         Block functions
     
    
    From 8f4fa43fe8f9e5c5c1264c215d9a8ba35abcf429 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 13:21:50 -0700
    Subject: [PATCH 229/400] got files to decompress
    
    ---
     tests/decodecorpus.c | 16 ++++++++++++----
     1 file changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 8c94154df..98c84bcb4 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -671,7 +671,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                     if(genDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
                         /* we still need to be within the windowSize however */
    -                    const U32 lenPastStart = RAND(seed) % dictSize;
    +                    U32 const lenPastStart = RAND(seed) % dictSize;
                         offset = MIN(frame->header.windowSize, offset+lenPastStart);
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
    @@ -693,7 +693,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
     
             {   size_t j;
                 for (j = 0; j < matchLen; j++) {
    -                if((void*)(srcPtr-offset) < (void*)frame->srcStart){
    +                if ((void*)(srcPtr - offset) < (void*)frame->srcStart) {
                         /* copy from dictionary instead of literals */
                         *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-(BYTE*)frame->srcStart)));
                     }
    @@ -1330,7 +1330,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
         }
         {
             /* use 3/4 of dictionary for content, save rest for header/entropy tables */
    -        if (dictContentSize < 128 || dictSize < 256) {
    +        if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
                 DISPLAY("Error: dictionary size is too small\n");
                 return 1;
             }
    @@ -1399,7 +1399,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
     
             DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
     
    -        seed = generateFrame(seed, &fr, 1, dictSize, dictContent, dictID);
    +        seed = generateFrame(seed, &fr, 1, dictContentSize, dictContent, dictID);
     
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                 DISPLAY("Error: path too long\n");
    @@ -1421,6 +1421,14 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                                                    fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
                                                    fullDict, dictSize);
     
    +        {
    +            size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    +            for (size_t i = 0; i < checkDiff; i++) {
    +                if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    +                    DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                }
    +            }
    +        }
             if (ZSTD_isError(returnValue)) {
                 DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
             }
    
    From 1fc1a35dc472eb26bf6c28fe098994b8ec2539dc Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 14:02:27 -0700
    Subject: [PATCH 230/400] added calls to free to match calls to malloc, made
     some stylistic changes, added init function for new struct
    
    ---
     tests/decodecorpus.c | 49 ++++++++++++++++++++++++++++++++++++--------
     1 file changed, 41 insertions(+), 8 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 98c84bcb4..610df7cb4 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -233,6 +233,12 @@ typedef struct {
         cblockStats_t oldStats; /* so they can be rolled back if uncompressible */
     } frame_t;
     
    +typedef struct {
    +    int useDict;
    +    U32 dictID;
    +    size_t dictSize;
    +    BYTE* dictContent;
    +} dictOptions;
     /*-*******************************************************
     *  Generator Functions
     *********************************************************/
    @@ -1312,6 +1318,16 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path,
         return 0;
     }
     
    +static dictOptions initDictOptions(int useDict, U32 dictID, size_t dictSize, BYTE* dictContent){
    +    /* allocate space statically */
    +    dictOptions dictOp;
    +    memset((void*)(&dictOp), 0, sizeof(dictOp));
    +    dictOp.useDict = useDict;
    +    dictOp.dictID = dictID;
    +    dictOp.dictSize = dictSize;
    +    dictOp.dictContent = dictContent;
    +    return dictOp;
    +}
     static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path,
                                         const char* const origPath, const size_t dictSize)
     {
    @@ -1338,6 +1354,10 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
         /* Generate the dictionary randomly first */
         dictID = RAND(&seed);
         fullDict = malloc(dictSize);
    +    if (fullDict == NULL) {
    +        DISPLAY("Error: could not allocate space for full dictionary.\n");
    +        return 1;
    +    }
         dictContent = fullDict + headerSize;
         RAND_buffer(&seed, (void*)dictContent, dictContentSize);
         {
    @@ -1347,6 +1367,11 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             unsigned numSamples = 4;
             BYTE* samples = malloc(5000*sizeof(BYTE));
             size_t* sampleSizes = malloc(numSamples*sizeof(size_t));
    +        if (samples == NULL || sampleSizes == NULL) {
    +            DISPLAY("Error: could not generate samples for the dictionary.\n");
    +            free(fullDict);
    +            return 1;
    +        }
             {
                 unsigned i = 1;
                 size_t currSize = 1;
    @@ -1360,36 +1385,40 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                     currSize *= 16;
                 }
             }
    -        DISPLAY("==================done with generation====================\n");
             {
                 /* set dictionary params */
                 ZDICT_params_t zdictParams;
                 memset(&zdictParams, 0, sizeof(zdictParams));
                 zdictParams.dictID = dictID;
    -            zdictParams.notificationLevel = 5;
    -            DISPLAY("===================zdict params================\n");
    +            zdictParams.notificationLevel = 1;
                 /* finalize dictionary with random samples */
                 dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
                                             dictContent, dictContentSize,
                                             samples, sampleSizes, numSamples,
                                             zdictParams);
             }
    -
    +        free(samples);
    +        free(sampleSizes);
             if(dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)){
                 DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    +            free(fullDict);
                 return 1;
             }
    -        DISPLAY("=================done with finalize=================\n");
             /* write out dictionary */
             if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){
                 DISPLAY("Error: dictionary path too long\n");
    +            free(fullDict);
                 return 1;
             }
             outputBuffer(fullDict, dictSize, outPath);
         }
     
    -    DISPLAY("generating compressed files\n");
         decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE);
    +    if (decompressedPtr == NULL) {
    +        DISPLAY("Error: could not allocate memory for decompressed pointer\n");
    +        free(fullDict);
    +        return 1;
    +    }
     
         /* generate random compressed/decompressed files */
         for (fnum = 0; fnum < numFiles; fnum++) {
    @@ -1403,6 +1432,8 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
     
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                 DISPLAY("Error: path too long\n");
    +            free(fullDict);
    +            free(decompressedPtr);
                 return 1;
             }
             outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath);
    @@ -1410,13 +1441,14 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             if (origPath) {
                 if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) {
                     DISPLAY("Error: path too long\n");
    +                free(fullDict);
    +                free(decompressedPtr);
                     return 1;
                 }
                 outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath);
             }
     
             /* if asked, supply the decompressed version */
    -        DISPLAY("Attempting to decompress using the dictionary\n");
             returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
                                                    fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
                                                    fullDict, dictSize);
    @@ -1434,7 +1466,8 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             }
     
         }
    -    DISPLAY("end of function\n");
    +    free(decompressedPtr);
    +    free(fullDict);
         return 0;
     }
     
    
    From 34f4e5cab24c202226a523bc7a88f1c05234c61d Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 14:07:56 -0700
    Subject: [PATCH 231/400] changed if statement styling
    
    ---
     tests/decodecorpus.c | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 610df7cb4..ffaad4a17 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -674,7 +674,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                               MIN(frame->header.windowSize,
                                   (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) +
                              1;
    -                if(genDict && (RAND(seed) & 1)) {
    +                if (genDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
                         /* we still need to be within the windowSize however */
                         U32 const lenPastStart = RAND(seed) % dictSize;
    @@ -703,7 +703,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                         /* copy from dictionary instead of literals */
                         *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-(BYTE*)frame->srcStart)));
                     }
    -                else{
    +                else {
                         *srcPtr = *(srcPtr-offset);
                     }
                     srcPtr++;
    @@ -1399,13 +1399,13 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             }
             free(samples);
             free(sampleSizes);
    -        if(dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)){
    +        if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
                 DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
                 free(fullDict);
                 return 1;
             }
             /* write out dictionary */
    -        if(snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH){
    +        if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) {
                 DISPLAY("Error: dictionary path too long\n");
                 free(fullDict);
                 return 1;
    
    From 73ebb646d8b294a3126f4a141966fb178f6c1bbe Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 14:20:35 -0700
    Subject: [PATCH 232/400] small stylistic changes
    
    ---
     tests/decodecorpus.c | 6 ++----
     1 file changed, 2 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index ffaad4a17..86ec0e985 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1333,8 +1333,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
     {
         char outPath[MAX_PATH];
         BYTE* fullDict;
    -    U32 dictID;
    -    unsigned fnum;
    +    U32 const dictID = RAND(&seed);
         BYTE* decompressedPtr;
         BYTE* dictContent;
         const size_t headerSize = dictSize/4;
    @@ -1352,7 +1351,6 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             }
         }
         /* Generate the dictionary randomly first */
    -    dictID = RAND(&seed);
         fullDict = malloc(dictSize);
         if (fullDict == NULL) {
             DISPLAY("Error: could not allocate space for full dictionary.\n");
    @@ -1421,7 +1419,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
         }
     
         /* generate random compressed/decompressed files */
    -    for (fnum = 0; fnum < numFiles; fnum++) {
    +    for (unsigned fnum = 0; fnum < numFiles; fnum++) {
             frame_t fr;
             size_t returnValue;
     
    
    From 2a52d72712c3705006c7e182f2ffacd10e3bae24 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 14:21:35 -0700
    Subject: [PATCH 233/400] added comment to anotate decompressed error code
    
    ---
     tests/decodecorpus.c | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 86ec0e985..b26ebc214 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1452,6 +1452,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                                                    fullDict, dictSize);
     
             {
    +            /* print differences if any */
                 size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
                 for (size_t i = 0; i < checkDiff; i++) {
                     if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    
    From 55f9cd49428ee3d5cb294699d607641062ea8d09 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Mon, 19 Jun 2017 15:12:28 -0700
    Subject: [PATCH 234/400] [libzstd] Fix UBSAN failure
    
    ---
     lib/compress/zstd_compress.c | 8 ++++++--
     1 file changed, 6 insertions(+), 2 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 3ba1748f0..d5de46a49 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -2136,15 +2136,19 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
                 break;  /* nothing found : store previous solution */
             }
     
    +        /* NOTE:
    +         * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
    +         * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
    +         * overflows the pointer, which is undefined behavior.
    +         */
             /* catch up */
             if (offset) {
                 while ( (start > anchor)
                      && (start > base+offset-ZSTD_REP_MOVE)
    -                 && (start[-1] == start[-1-offset+ZSTD_REP_MOVE]) )  /* only search for offset within prefix */
    +                 && (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1]) )  /* only search for offset within prefix */
                     { start--; matchLength++; }
                 offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
             }
    -
             /* store sequence */
     _storeSequence:
             {   size_t const litLength = start - anchor;
    
    From fe234bf48b1d6e8b82aff99237bbea7e8ebf7137 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 19 Jun 2017 15:23:19 -0700
    Subject: [PATCH 235/400] fix attempts : fullbench for VS2008
    
    ---
     build/VS2008/fullbench/fullbench.vcproj | 54 +++++++++++++----------
     lib/zstd.h                              | 58 ++++++++++++-------------
     programs/bench.c                        | 15 +++----
     3 files changed, 67 insertions(+), 60 deletions(-)
    
    diff --git a/build/VS2008/fullbench/fullbench.vcproj b/build/VS2008/fullbench/fullbench.vcproj
    index 0734219b4..582a9ce93 100644
    --- a/build/VS2008/fullbench/fullbench.vcproj
    +++ b/build/VS2008/fullbench/fullbench.vcproj
    @@ -328,10 +328,6 @@
     			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
     			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
     			>
    -			
    -			
     			
    @@ -340,10 +336,6 @@
     				RelativePath="..\..\..\lib\common\error_private.c"
     				>
     			
    -			
    -			
     			
    @@ -352,18 +344,6 @@
     				RelativePath="..\..\..\lib\common\xxhash.c"
     				>
     			
    -			
    -			
    -			
    -			
    -			
    -			
     			
    @@ -372,16 +352,44 @@
     				RelativePath="..\..\..\lib\compress\zstd_compress.c"
     				>
     			
    +			
    +			
    +			
    +			
    +			
    +			
     			
     			
    +			
    +			
    +			
    +			
    +			
    +			
     		
     		
    +			
    +			
     			
    @@ -419,11 +427,11 @@
     				>
     			
     			
     			
     			
     			
     			
     			
     			
     			
     		
    diff --git a/lib/zstd.h b/lib/zstd.h
    index a60c91335..e0c880103 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -47,12 +47,12 @@ extern "C" {
         - a single step (described as Simple API)
         - a single step, reusing a context (described as Explicit memory management)
         - unbounded multiple steps (described as Streaming compression)
    -  The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
    +  The compression ratio achievable on small data can be highly improved using a dictionary in:
         - a single step (described as Simple dictionary API)
         - a single step, reusing a dictionary (described as Fast dictionary API)
     
       Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
    -  These APIs shall never be used with a dynamic library.
    +  Advanced experimental APIs shall never be used with a dynamic library.
       They are not "stable", their definition may change in the future. Only static linking is allowed.
     *********************************************************************************************************/
     
    @@ -62,13 +62,13 @@ extern "C" {
     #define ZSTD_VERSION_RELEASE  0
     
     #define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
    -ZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< to be used when checking dll version */
    +ZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< useful to check dll version */
     
     #define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
     #define ZSTD_QUOTE(str) #str
     #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
     #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
    -ZSTDLIB_API const char* ZSTD_versionString(void);   /* v1.3.0 */
    +ZSTDLIB_API const char* ZSTD_versionString(void);   /* >= v1.3.0 */
     
     
     /***************************************
    @@ -85,7 +85,7 @@ ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
     
     /*! ZSTD_decompress() :
      *  `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
    - *  `dstCapacity` is an upper bound of originalSize.
    + *  `dstCapacity` is an upper bound of originalSize to regenerate.
      *  If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
      *  @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
      *            or an errorCode if it fails (which can be tested using ZSTD_isError()). */
    @@ -163,9 +163,9 @@ ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx,
     *  Simple dictionary API
     ***************************/
     /*! ZSTD_compress_usingDict() :
    -*   Compression using a predefined Dictionary (see dictBuilder/zdict.h).
    -*   Note : This function loads the dictionary, resulting in significant startup delay.
    -*   Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
    + *  Compression using a predefined Dictionary (see dictBuilder/zdict.h).
    + *  Note : This function loads the dictionary, resulting in significant startup delay.
    + *  Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
     ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
                                                void* dst, size_t dstCapacity,
                                          const void* src, size_t srcSize,
    @@ -173,31 +173,31 @@ ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
                                                int compressionLevel);
     
     /*! ZSTD_decompress_usingDict() :
    -*   Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
    -*   Dictionary must be identical to the one used during compression.
    -*   Note : This function loads the dictionary, resulting in significant startup delay.
    -*   Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
    + *  Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
    + *  Dictionary must be identical to the one used during compression.
    + *  Note : This function loads the dictionary, resulting in significant startup delay.
    + *  Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
     ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
                                                  void* dst, size_t dstCapacity,
                                            const void* src, size_t srcSize,
                                            const void* dict,size_t dictSize);
     
     
    -/****************************
    -*  Fast dictionary API
    -****************************/
    +/**********************************
    + *  Bulk processing dictionary API
    + *********************************/
     typedef struct ZSTD_CDict_s ZSTD_CDict;
     
     /*! ZSTD_createCDict() :
    -*   When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
    -*   ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
    -*   ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only.
    -*   `dictBuffer` can be released after ZSTD_CDict creation, as its content is copied within CDict */
    + *  When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
    + *  ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
    + *  ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
    + *  `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict */
     ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
                                              int compressionLevel);
     
     /*! ZSTD_freeCDict() :
    -*   Function frees memory allocated by ZSTD_createCDict(). */
    + *  Function frees memory allocated by ZSTD_createCDict(). */
     ZSTDLIB_API size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
     
     /*! ZSTD_compress_usingCDict() :
    @@ -214,17 +214,17 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
     typedef struct ZSTD_DDict_s ZSTD_DDict;
     
     /*! ZSTD_createDDict() :
    -*   Create a digested dictionary, ready to start decompression operation without startup delay.
    -*   dictBuffer can be released after DDict creation, as its content is copied inside DDict */
    + *  Create a digested dictionary, ready to start decompression operation without startup delay.
    + *  dictBuffer can be released after DDict creation, as its content is copied inside DDict */
     ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
     
     /*! ZSTD_freeDDict() :
    -*   Function frees memory allocated with ZSTD_createDDict() */
    + *  Function frees memory allocated with ZSTD_createDDict() */
     ZSTDLIB_API size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
     
     /*! ZSTD_decompress_usingDDict() :
    -*   Decompression using a digested Dictionary.
    -*   Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
    + *  Decompression using a digested Dictionary.
    + *  Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
     ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
                                                   void* dst, size_t dstCapacity,
                                             const void* src, size_t srcSize,
    @@ -290,8 +290,8 @@ typedef struct ZSTD_outBuffer_s {
     *
     * *******************************************************************/
     
    -typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are effectively same object */
    -                                 /* Continue due distinghish them for compatibility with versions <= v1.2.0 */
    +typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are now effectively same object (>= v1.3.0) */
    +                                 /* But continue to distinguish them for compatibility with versions <= v1.2.0 */
     /*===== ZSTD_CStream management functions =====*/
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
     ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
    @@ -329,8 +329,8 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output
     *            The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
     * *******************************************************************************/
     
    -//typedef struct ZSTD_DStream_s ZSTD_DStream;
    -typedef ZSTD_DCtx ZSTD_DStream;
    +typedef ZSTD_DCtx ZSTD_DStream;  /**< DCtx and DStream are now effectively same object (>= v1.3.0) */
    +                                 /* But continue to distinguish them for compatibility with versions <= v1.2.0 */
     /*===== ZSTD_DStream management functions =====*/
     ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
     ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
    diff --git a/programs/bench.c b/programs/bench.c
    index 22b871952..1f1b00594 100644
    --- a/programs/bench.c
    +++ b/programs/bench.c
    @@ -86,14 +86,13 @@ static clock_t g_time = 0;
     #ifndef DEBUG
     #  define DEBUG 0
     #endif
    -#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
    -#define EXM_THROW(error, ...)                                             \
    -{                                                                         \
    -    DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__); \
    -    DISPLAYLEVEL(1, "Error %i : ", error);                                \
    -    DISPLAYLEVEL(1, __VA_ARGS__);                                         \
    -    DISPLAYLEVEL(1, " \n");                                               \
    -    exit(error);                                                          \
    +#define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
    +#define EXM_THROW(error, ...)  {                      \
    +    DEBUGOUTPUT("%s: %i: \n", __FILE__, __LINE__);    \
    +    DISPLAYLEVEL(1, "Error %i : ", error);            \
    +    DISPLAYLEVEL(1, __VA_ARGS__);                     \
    +    DISPLAYLEVEL(1, " \n");                           \
    +    exit(error);                                      \
     }
     
     
    
    From 695a0a34496f43e2fbd184c247a71bdf9711eb1b Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 19 Jun 2017 15:27:30 -0700
    Subject: [PATCH 236/400] fixed IA64 compilation error, by @mcmilk
    
    ---
     lib/decompress/zstd_decompress.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index bb3eed399..aeaa40c1f 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -53,7 +53,7 @@
     #  include "zstd_legacy.h"
     #endif
     
    -#if defined(_MSC_VER)
    +#if defined(_MSC_VER) && !defined(_M_IA64)  /* _mm_prefetch() is not defined for ia64 */
     #  include    /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
     #  define ZSTD_PREFETCH(ptr)   _mm_prefetch((const char*)ptr, _MM_HINT_T0)
     #elif defined(__GNUC__)
    
    From a48e129d4873c1741efe8e0dcfba0568e29aefba Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Mon, 19 Jun 2017 15:48:30 -0700
    Subject: [PATCH 237/400] [linux] Port libzstd UBSAN fix
    
    ---
     contrib/linux-kernel/lib/zstd/compress.c |  7 ++++++-
     contrib/linux-kernel/zstd.diff           | 11 ++++++++---
     2 files changed, 14 insertions(+), 4 deletions(-)
    
    diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c
    index 42236a3e1..1aff542b0 100644
    --- a/contrib/linux-kernel/lib/zstd/compress.c
    +++ b/contrib/linux-kernel/lib/zstd/compress.c
    @@ -1978,10 +1978,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx *ctx, const void *src, size_t src
     				break; /* nothing found : store previous solution */
     			}
     
    +		/* NOTE:
    +		 * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
    +		 * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
    +		 * overflows the pointer, which is undefined behavior.
    +		 */
     		/* catch up */
     		if (offset) {
     			while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) &&
    -			       (start[-1] == start[-1 - offset + ZSTD_REP_MOVE])) /* only search for offset within prefix */
    +			       (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1])) /* only search for offset within prefix */
     			{
     				start--;
     				matchLength++;
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/zstd.diff
    index 1fa64ff86..e83b56ed2 100644
    --- a/contrib/linux-kernel/zstd.diff
    +++ b/contrib/linux-kernel/zstd.diff
    @@ -1599,10 +1599,10 @@ index 0000000..a826b99
     +#endif /* BITSTREAM_H_MODULE */
     diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c
     new file mode 100644
    -index 0000000..42236a3
    +index 0000000..1aff542
     --- /dev/null
     +++ b/lib/zstd/compress.c
    -@@ -0,0 +1,3463 @@
    +@@ -0,0 +1,3468 @@
     +/**
     + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
     + * All rights reserved.
    @@ -3583,10 +3583,15 @@ index 0000000..42236a3
     +				break; /* nothing found : store previous solution */
     +			}
     +
    ++		/* NOTE:
    ++		 * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.
    ++		 * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which
    ++		 * overflows the pointer, which is undefined behavior.
    ++		 */
     +		/* catch up */
     +		if (offset) {
     +			while ((start > anchor) && (start > base + offset - ZSTD_REP_MOVE) &&
    -+			       (start[-1] == start[-1 - offset + ZSTD_REP_MOVE])) /* only search for offset within prefix */
    ++			       (start[-1] == (start-offset+ZSTD_REP_MOVE)[-1])) /* only search for offset within prefix */
     +			{
     +				start--;
     +				matchLength++;
    
    From 1ee4f6b36c1bb2290b470815226fce0a5023f0da Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 15:55:01 -0700
    Subject: [PATCH 238/400] cleaning up code
    
    ---
     tests/decodecorpus.c | 210 +++++++++++++++++++++++--------------------
     1 file changed, 114 insertions(+), 96 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index b26ebc214..10c8a153d 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1263,6 +1263,69 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
         return 0;
     }
     
    +/*_*******************************************************
    +*  Dictionary Helper Functions
    +*********************************************************/
    +/* returns 0 if successful, otherwise returns 1 upon error */
    +static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
    +    const size_t headerSize = dictSize/4;
    +    const size_t dictContentSize = dictSize - dictSize/4;
    +    BYTE* const dictContent = fullDict + headerSize;
    +
    +    /* use 3/4 of dictionary for content, save rest for header/entropy tables */
    +    if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
    +        DISPLAY("Error: dictionary size is too small\n");
    +        return 1;
    +    }
    +
    +    /* fill in dictionary content */
    +    RAND_buffer(&seed, (void*)dictContent, dictContentSize);
    +
    +    /* allocate space for samples */
    +    {
    +        size_t dictWriteSize = 0;
    +        unsigned const numSamples = 4;
    +        BYTE* const samples = malloc(5000*sizeof(BYTE));
    +        size_t* const sampleSizes = malloc(numSamples*sizeof(size_t));
    +        if (samples == NULL || sampleSizes == NULL) {
    +            DISPLAY("Error: could not generate samples for the dictionary.\n");
    +            return 1;
    +        }
    +
    +        /* generate samples */
    +        unsigned i = 1;
    +        size_t currSize = 1;
    +        BYTE* curr = samples;
    +        while (i <= 4) {
    +            *(sampleSizes + i - 1) = currSize;
    +            for (size_t j = 0; j < currSize; j++) {
    +                *(curr++) = (BYTE)i;
    +            }
    +            i++;
    +            currSize *= 16;
    +        }
    +
    +        /* set dictionary params */
    +        ZDICT_params_t zdictParams;
    +        memset(&zdictParams, 0, sizeof(zdictParams));
    +        zdictParams.dictID = dictID;
    +        zdictParams.notificationLevel = 1;
    +
    +        /* finalize dictionary with random samples */
    +        dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    +                                    dictContent, dictContentSize,
    +                                    samples, sampleSizes, numSamples,
    +                                    zdictParams);
    +        free(samples);
    +        free(sampleSizes);
    +        if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
    +            DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    +            return 1;
    +        }
    +    }
    +    return 0;
    +}
    +
     /*-*******************************************************
     *  File I/O
     *********************************************************/
    @@ -1328,146 +1391,101 @@ static dictOptions initDictOptions(int useDict, U32 dictID, size_t dictSize, BYT
         dictOp.dictContent = dictContent;
         return dictOp;
     }
    +
     static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path,
                                         const char* const origPath, const size_t dictSize)
     {
         char outPath[MAX_PATH];
         BYTE* fullDict;
         U32 const dictID = RAND(&seed);
    -    BYTE* decompressedPtr;
    -    BYTE* dictContent;
    -    const size_t headerSize = dictSize/4;
    -    const size_t dictContentSize = dictSize - dictSize/4;
    -    ZSTD_DCtx* dctx = ZSTD_createDCtx();
    +    int errorDetected = 0;
    +
         if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) {
             DISPLAY("Error: path too long\n");
             return 1;
         }
    -    {
    -        /* use 3/4 of dictionary for content, save rest for header/entropy tables */
    -        if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
    -            DISPLAY("Error: dictionary size is too small\n");
    -            return 1;
    -        }
    -    }
    -    /* Generate the dictionary randomly first */
    +
    +    /* allocate space for the dictionary */
         fullDict = malloc(dictSize);
         if (fullDict == NULL) {
             DISPLAY("Error: could not allocate space for full dictionary.\n");
             return 1;
         }
    -    dictContent = fullDict + headerSize;
    -    RAND_buffer(&seed, (void*)dictContent, dictContentSize);
    +
    +    /* randomly generate the dictionary */
         {
    -        size_t dictWriteSize = 0;
    -
    -        /* create samples */
    -        unsigned numSamples = 4;
    -        BYTE* samples = malloc(5000*sizeof(BYTE));
    -        size_t* sampleSizes = malloc(numSamples*sizeof(size_t));
    -        if (samples == NULL || sampleSizes == NULL) {
    -            DISPLAY("Error: could not generate samples for the dictionary.\n");
    -            free(fullDict);
    -            return 1;
    +        int ret = genRandomDict(dictID, seed, dictSize, fullDict);
    +        if (ret != 0) {
    +            errorDetected = ret;
    +            goto dictCleanup;
             }
    -        {
    -            unsigned i = 1;
    -            size_t currSize = 1;
    -            BYTE* curr = samples;
    -            while (i <= 4) {
    -                *(sampleSizes + i - 1) = currSize;
    -                for (size_t j = 0; j < currSize; j++) {
    -                    *(curr++) = (BYTE)i;
    -                }
    -                i++;
    -                currSize *= 16;
    -            }
    -        }
    -        {
    -            /* set dictionary params */
    -            ZDICT_params_t zdictParams;
    -            memset(&zdictParams, 0, sizeof(zdictParams));
    -            zdictParams.dictID = dictID;
    -            zdictParams.notificationLevel = 1;
    -            /* finalize dictionary with random samples */
    -            dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    -                                        dictContent, dictContentSize,
    -                                        samples, sampleSizes, numSamples,
    -                                        zdictParams);
    -        }
    -        free(samples);
    -        free(sampleSizes);
    -        if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
    -            DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    -            free(fullDict);
    -            return 1;
    -        }
    -        /* write out dictionary */
    -        if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) {
    -            DISPLAY("Error: dictionary path too long\n");
    -            free(fullDict);
    -            return 1;
    -        }
    -        outputBuffer(fullDict, dictSize, outPath);
         }
     
    -    decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE);
    -    if (decompressedPtr == NULL) {
    -        DISPLAY("Error: could not allocate memory for decompressed pointer\n");
    -        free(fullDict);
    -        return 1;
    +    /* write out dictionary */
    +    if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) {
    +        DISPLAY("Error: dictionary path too long\n");
    +        errorDetected = 1;
    +        goto dictCleanup;
         }
    +    outputBuffer(fullDict, dictSize, outPath);
     
         /* generate random compressed/decompressed files */
         for (unsigned fnum = 0; fnum < numFiles; fnum++) {
             frame_t fr;
    -        size_t returnValue;
    -
    -
             DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
    -
    -        seed = generateFrame(seed, &fr, 1, dictContentSize, dictContent, dictID);
    -
    +        {
    +            size_t dictContentSize = dictSize-dictSize/4;
    +            BYTE* const dictContent = fullDict+dictSize/4;
    +            seed = generateFrame(seed, &fr, 1, dictContentSize, dictContent, dictID);
    +        }
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                 DISPLAY("Error: path too long\n");
    -            free(fullDict);
    -            free(decompressedPtr);
    -            return 1;
    +            errorDetected = 1;
    +            goto dictCleanup;
             }
             outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath);
     
             if (origPath) {
                 if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) {
                     DISPLAY("Error: path too long\n");
    -                free(fullDict);
    -                free(decompressedPtr);
    -                return 1;
    +                errorDetected = 1;
    +                goto dictCleanup;
                 }
                 outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath);
             }
     
    -        /* if asked, supply the decompressed version */
    -        returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    -                                               fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    -                                               fullDict, dictSize);
    -
    +        /* check the output to make sure that decompressed versions match official zstd */
             {
    +            ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    +            BYTE* const decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE);
    +            if (decompressedPtr == NULL) {
    +                DISPLAY("Error: could not allocate memory for decompressed pointer\n");
    +                errorDetected = 1;
    +                goto dictCleanup;
    +            }
    +            size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    +                                                   fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    +                                                   fullDict, dictSize);
    +            if (ZSTD_isError(returnValue)) {
    +               DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
    +            }
    +
                 /* print differences if any */
    -            size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    -            for (size_t i = 0; i < checkDiff; i++) {
    -                if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    -                    DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +            {
    +                size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    +                for (size_t i = 0; i < checkDiff; i++) {
    +                    if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    +                        DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                    }
                     }
                 }
    +            free(decompressedPtr);
             }
    -        if (ZSTD_isError(returnValue)) {
    -            DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
    -        }
    -
         }
    -    free(decompressedPtr);
    +
    +dictCleanup:
         free(fullDict);
    -    return 0;
    +    return errorDetected;
     }
     
     
    
    From b91b810c64f3ccc244b0a5f6e2a067f88ee2c6d8 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:05:05 -0700
    Subject: [PATCH 239/400] made some small changes to dictInfo struct and
     initDictInfo
    
    ---
     tests/decodecorpus.c | 25 +++++++++++++------------
     1 file changed, 13 insertions(+), 12 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 10c8a153d..dba277128 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -237,8 +237,9 @@ typedef struct {
         int useDict;
         U32 dictID;
         size_t dictSize;
    +    BYTE* fullDict;
         BYTE* dictContent;
    -} dictOptions;
    +} dictInfo;
     /*-*******************************************************
     *  Generator Functions
     *********************************************************/
    @@ -1326,6 +1327,17 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
         return 0;
     }
     
    +static dictInfo initDictInfo(int useDict, size_t dictSize, BYTE* fullDict, U32 seed){
    +    /* allocate space statically */
    +    dictInfo dictOp;
    +    memset((void*)(&dictOp), 0, sizeof(dictOp));
    +    dictOp.useDict = useDict;
    +    dictOp.dictSize = dictSize;
    +    dictOp.fullDict = fullDict;
    +    dictOp.dictContent = fullDict + dictSize/4;
    +    if (useDict) dictOp.dictID = RAND(&seed);
    +    return dictOp;
    +}
     /*-*******************************************************
     *  File I/O
     *********************************************************/
    @@ -1381,17 +1393,6 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path,
         return 0;
     }
     
    -static dictOptions initDictOptions(int useDict, U32 dictID, size_t dictSize, BYTE* dictContent){
    -    /* allocate space statically */
    -    dictOptions dictOp;
    -    memset((void*)(&dictOp), 0, sizeof(dictOp));
    -    dictOp.useDict = useDict;
    -    dictOp.dictID = dictID;
    -    dictOp.dictSize = dictSize;
    -    dictOp.dictContent = dictContent;
    -    return dictOp;
    -}
    -
     static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const path,
                                         const char* const origPath, const size_t dictSize)
     {
    
    From 7ea025cc7df569b95770d23a273d2802ec3e8c7d Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:23:00 -0700
    Subject: [PATCH 240/400] added in struct to keep functions more orderly
    
    ---
     tests/decodecorpus.c | 216 ++++++++++++++++++++++---------------------
     1 file changed, 112 insertions(+), 104 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index dba277128..76949a6e7 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -236,8 +236,7 @@ typedef struct {
     typedef struct {
         int useDict;
         U32 dictID;
    -    size_t dictSize;
    -    BYTE* fullDict;
    +    size_t dictContentSize;
         BYTE* dictContent;
     } dictInfo;
     /*-*******************************************************
    @@ -249,7 +248,7 @@ struct {
     } opts; /* advanced options on generation */
     
     /* Generate and write a random frame header */
    -static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, U32 dictID)
    +static void writeFrameHeader(U32* seed, frame_t* frame, dictInfo info)
     {
         BYTE* const op = frame->data;
         size_t pos = 0;
    @@ -315,7 +314,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, U32 dictID)
         pos += 4;
     
         {
    -        int dictBits = genDict ? 3 : 0;
    +        int dictBits = info.useDict ? 3 : 0;
             BYTE const frameHeaderDescriptor =
                     (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2) | dictBits);
             op[pos++] = frameHeaderDescriptor;
    @@ -324,8 +323,8 @@ static void writeFrameHeader(U32* seed, frame_t* frame, int genDict, U32 dictID)
         if (!singleSegment) {
             op[pos++] = windowByte;
         }
    -    if(genDict) {
    -        MEM_writeLE32(op + pos, (U32) dictID);
    +    if(info.useDict) {
    +        MEM_writeLE32(op + pos, (U32) info.dictID);
             pos += 4;
         }
         if (contentSizeFlag) {
    @@ -618,7 +617,7 @@ static inline void initSeqStore(seqStore_t *seqStore) {
     
     /* Randomly generate sequence commands */
     static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
    -                                size_t contentSize, size_t literalsSize, int genDict, size_t dictSize, BYTE* dictContent)
    +                                size_t contentSize, size_t literalsSize, dictInfo info)
     {
         /* The total length of all the matches */
         size_t const remainingMatch = contentSize - literalsSize;
    @@ -675,10 +674,10 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                               MIN(frame->header.windowSize,
                                   (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) +
                              1;
    -                if (genDict && (RAND(seed) & 1)) {
    +                if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
                         /* we still need to be within the windowSize however */
    -                    U32 const lenPastStart = RAND(seed) % dictSize;
    +                    U32 const lenPastStart = RAND(seed) % info.dictContentSize;
                         offset = MIN(frame->header.windowSize, offset+lenPastStart);
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
    @@ -696,13 +695,13 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                         repIndex = MIN(2, offsetCode + 1);
                     }
                 }
    -        } while (((!genDict) && (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0);
    +        } while (((!info.useDict) && (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0);
     
             {   size_t j;
                 for (j = 0; j < matchLen; j++) {
                     if ((void*)(srcPtr - offset) < (void*)frame->srcStart) {
                         /* copy from dictionary instead of literals */
    -                    *srcPtr = *(dictContent + dictSize - (offset-(srcPtr-(BYTE*)frame->srcStart)));
    +                    *srcPtr = *(info.dictContent + info.dictContentSize - (offset-(srcPtr-(BYTE*)frame->srcStart)));
                     }
                     else {
                         *srcPtr = *(srcPtr-offset);
    @@ -956,7 +955,7 @@ static size_t writeSequences(U32* seed, frame_t* frame, seqStore_t* seqStorePtr,
     }
     
     static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize,
    -                                  size_t literalsSize, int genDict, size_t dictSize, BYTE* dictContent)
    +                                  size_t literalsSize, dictInfo info)
     {
         seqStore_t seqStore;
         size_t numSequences;
    @@ -965,14 +964,14 @@ static size_t writeSequencesBlock(U32* seed, frame_t* frame, size_t contentSize,
         initSeqStore(&seqStore);
     
         /* randomly generate sequences */
    -    numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize, genDict, dictSize, dictContent);
    +    numSequences = generateSequences(seed, frame, &seqStore, contentSize, literalsSize, info);
         /* write them out to the frame data */
         CHECKERR(writeSequences(seed, frame, &seqStore, numSequences));
     
         return numSequences;
     }
     
    -static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize, int genDict, size_t dictSize, BYTE* dictContent)
    +static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize, dictInfo info)
     {
         BYTE* const blockStart = (BYTE*)frame->data;
         size_t literalsSize;
    @@ -984,7 +983,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize
     
         DISPLAYLEVEL(4, "   literals size: %u\n", (U32)literalsSize);
     
    -    nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize, genDict, dictSize, dictContent);
    +    nbSeq = writeSequencesBlock(seed, frame, contentSize, literalsSize, info);
     
         DISPLAYLEVEL(4, "   number of sequences: %u\n", (U32)nbSeq);
     
    @@ -992,7 +991,7 @@ static size_t writeCompressedBlock(U32* seed, frame_t* frame, size_t contentSize
     }
     
     static void writeBlock(U32* seed, frame_t* frame, size_t contentSize,
    -                       int lastBlock, int genDict, size_t dictSize, BYTE* dictContent)
    +                       int lastBlock, dictInfo info)
     {
         int const blockTypeDesc = RAND(seed) % 8;
         size_t blockSize;
    @@ -1032,7 +1031,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize,
             frame->oldStats = frame->stats;
     
             frame->data = op;
    -        compressedSize = writeCompressedBlock(seed, frame, contentSize, genDict, dictSize, dictContent);
    +        compressedSize = writeCompressedBlock(seed, frame, contentSize, info);
             if (compressedSize > contentSize) {
                 blockType = 0;
                 memcpy(op, frame->src, contentSize);
    @@ -1058,7 +1057,7 @@ static void writeBlock(U32* seed, frame_t* frame, size_t contentSize,
         frame->data = op;
     }
     
    -static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize, BYTE* dictContent)
    +static void writeBlocks(U32* seed, frame_t* frame, dictInfo info)
     {
         size_t contentLeft = frame->header.contentSize;
         size_t const maxBlockSize = MIN(MAX_BLOCK_SIZE, frame->header.windowSize);
    @@ -1081,7 +1080,7 @@ static void writeBlocks(U32* seed, frame_t* frame, int genDict, size_t dictSize,
                 }
             }
     
    -        writeBlock(seed, frame, blockContentSize, lastBlock, genDict, dictSize, dictContent);
    +        writeBlock(seed, frame, blockContentSize, lastBlock, info);
     
             contentLeft -= blockContentSize;
             if (lastBlock) break;
    @@ -1146,19 +1145,92 @@ static void initFrame(frame_t* fr)
     }
     
     /* Return the final seed */
    -static U32 generateFrame(U32 seed, frame_t* fr, int genDict, size_t dictSize, BYTE* dictContent, U32 dictID)
    +static U32 generateFrame(U32 seed, frame_t* fr, dictInfo info)
     {
         /* generate a complete frame */
         DISPLAYLEVEL(1, "frame seed: %u\n", seed);
         initFrame(fr);
     
    -    writeFrameHeader(&seed, fr, genDict, dictID);
    -    writeBlocks(&seed, fr, genDict, dictSize, dictContent);
    +    writeFrameHeader(&seed, fr, info);
    +    writeBlocks(&seed, fr, info);
         writeChecksum(fr);
     
         return seed;
     }
     
    +/*_*******************************************************
    +*  Dictionary Helper Functions
    +*********************************************************/
    +/* returns 0 if successful, otherwise returns 1 upon error */
    +static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
    +    const size_t headerSize = dictSize/4;
    +    const size_t dictContentSize = dictSize - dictSize/4;
    +    BYTE* const dictContent = fullDict + headerSize;
    +
    +    /* use 3/4 of dictionary for content, save rest for header/entropy tables */
    +    if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
    +        DISPLAY("Error: dictionary size is too small\n");
    +        return 1;
    +    }
    +
    +    /* fill in dictionary content */
    +    RAND_buffer(&seed, (void*)dictContent, dictContentSize);
    +
    +    /* allocate space for samples */
    +    {
    +        size_t dictWriteSize = 0;
    +        unsigned const numSamples = 4;
    +        BYTE* const samples = malloc(5000*sizeof(BYTE));
    +        size_t* const sampleSizes = malloc(numSamples*sizeof(size_t));
    +        if (samples == NULL || sampleSizes == NULL) {
    +            DISPLAY("Error: could not generate samples for the dictionary.\n");
    +            return 1;
    +        }
    +
    +        /* generate samples */
    +        unsigned i = 1;
    +        size_t currSize = 1;
    +        BYTE* curr = samples;
    +        while (i <= 4) {
    +            *(sampleSizes + i - 1) = currSize;
    +            for (size_t j = 0; j < currSize; j++) {
    +                *(curr++) = (BYTE)i;
    +            }
    +            i++;
    +            currSize *= 16;
    +        }
    +
    +        /* set dictionary params */
    +        ZDICT_params_t zdictParams;
    +        memset(&zdictParams, 0, sizeof(zdictParams));
    +        zdictParams.dictID = dictID;
    +        zdictParams.notificationLevel = 1;
    +
    +        /* finalize dictionary with random samples */
    +        dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    +                                    dictContent, dictContentSize,
    +                                    samples, sampleSizes, numSamples,
    +                                    zdictParams);
    +        free(samples);
    +        free(sampleSizes);
    +        if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
    +            DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    +            return 1;
    +        }
    +    }
    +    return 0;
    +}
    +
    +static dictInfo initDictInfo(int useDict, size_t dictContentSize, BYTE* dictContent, U32 dictID){
    +    /* allocate space statically */
    +    dictInfo dictOp;
    +    memset((void*)(&dictOp), 0, sizeof(dictOp));
    +    dictOp.useDict = useDict;
    +    dictOp.dictContentSize = dictContentSize;
    +    dictOp.dictContent = dictContent;
    +    dictOp.dictID = dictID;
    +    return dictOp;
    +}
     
     /*-*******************************************************
     *  Test Mode
    @@ -1240,7 +1312,10 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
             else
                 DISPLAYUPDATE("\r%u           ", fnum);
     
    -        seed = generateFrame(seed, &fr, 0, 0, NULL, 0);
    +        {
    +            dictInfo const info = initDictInfo(0, 0, NULL, 0);
    +            generateFrame(seed, &fr, info);
    +        }
     
             {   size_t const r = testDecodeSimple(&fr);
                 if (ZSTD_isError(r)) {
    @@ -1264,80 +1339,6 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
         return 0;
     }
     
    -/*_*******************************************************
    -*  Dictionary Helper Functions
    -*********************************************************/
    -/* returns 0 if successful, otherwise returns 1 upon error */
    -static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
    -    const size_t headerSize = dictSize/4;
    -    const size_t dictContentSize = dictSize - dictSize/4;
    -    BYTE* const dictContent = fullDict + headerSize;
    -
    -    /* use 3/4 of dictionary for content, save rest for header/entropy tables */
    -    if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
    -        DISPLAY("Error: dictionary size is too small\n");
    -        return 1;
    -    }
    -
    -    /* fill in dictionary content */
    -    RAND_buffer(&seed, (void*)dictContent, dictContentSize);
    -
    -    /* allocate space for samples */
    -    {
    -        size_t dictWriteSize = 0;
    -        unsigned const numSamples = 4;
    -        BYTE* const samples = malloc(5000*sizeof(BYTE));
    -        size_t* const sampleSizes = malloc(numSamples*sizeof(size_t));
    -        if (samples == NULL || sampleSizes == NULL) {
    -            DISPLAY("Error: could not generate samples for the dictionary.\n");
    -            return 1;
    -        }
    -
    -        /* generate samples */
    -        unsigned i = 1;
    -        size_t currSize = 1;
    -        BYTE* curr = samples;
    -        while (i <= 4) {
    -            *(sampleSizes + i - 1) = currSize;
    -            for (size_t j = 0; j < currSize; j++) {
    -                *(curr++) = (BYTE)i;
    -            }
    -            i++;
    -            currSize *= 16;
    -        }
    -
    -        /* set dictionary params */
    -        ZDICT_params_t zdictParams;
    -        memset(&zdictParams, 0, sizeof(zdictParams));
    -        zdictParams.dictID = dictID;
    -        zdictParams.notificationLevel = 1;
    -
    -        /* finalize dictionary with random samples */
    -        dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    -                                    dictContent, dictContentSize,
    -                                    samples, sampleSizes, numSamples,
    -                                    zdictParams);
    -        free(samples);
    -        free(sampleSizes);
    -        if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
    -            DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    -            return 1;
    -        }
    -    }
    -    return 0;
    -}
    -
    -static dictInfo initDictInfo(int useDict, size_t dictSize, BYTE* fullDict, U32 seed){
    -    /* allocate space statically */
    -    dictInfo dictOp;
    -    memset((void*)(&dictOp), 0, sizeof(dictOp));
    -    dictOp.useDict = useDict;
    -    dictOp.dictSize = dictSize;
    -    dictOp.fullDict = fullDict;
    -    dictOp.dictContent = fullDict + dictSize/4;
    -    if (useDict) dictOp.dictID = RAND(&seed);
    -    return dictOp;
    -}
     /*-*******************************************************
     *  File I/O
     *********************************************************/
    @@ -1349,7 +1350,10 @@ static int generateFile(U32 seed, const char* const path,
     
         DISPLAY("seed: %u\n", seed);
     
    -    generateFrame(seed, &fr, 0, 0, NULL, 0);
    +    {
    +        dictInfo const info = initDictInfo(0, 0, NULL, 0);
    +        generateFrame(seed, &fr, info);
    +    }
     
         outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, path);
         if (origPath) {
    @@ -1371,7 +1375,10 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path,
     
             DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
     
    -        seed = generateFrame(seed, &fr, 0, 0, NULL, 0);
    +        {
    +            dictInfo const info = initDictInfo(0, 0, NULL, 0);
    +            generateFrame(seed, &fr, info);
    +        }
     
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                 DISPLAY("Error: path too long\n");
    @@ -1437,7 +1444,8 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
             {
                 size_t dictContentSize = dictSize-dictSize/4;
                 BYTE* const dictContent = fullDict+dictSize/4;
    -            seed = generateFrame(seed, &fr, 1, dictContentSize, dictContent, dictID);
    +            dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    +            seed = generateFrame(seed, &fr, info);
             }
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                 DISPLAY("Error: path too long\n");
    @@ -1545,7 +1553,7 @@ int main(int argc, char** argv)
         int testMode = 0;
         const char* path = NULL;
         const char* origPath = NULL;
    -    int genDict = 0;
    +    int useDict = 0;
         unsigned dictSize = (10 << 10); /* 10 kB default */
     
         int argNb;
    @@ -1610,7 +1618,7 @@ int main(int argc, char** argv)
                         } else if (strcmp(argument, "train-dict") == 0) {
                             argument += 11;
                             dictSize = readInt(&argument);
    -                        genDict = 1;
    +                        useDict = 1;
                         } else {
                             advancedUsage(argv[0]);
                             return 1;
    @@ -1642,9 +1650,9 @@ int main(int argc, char** argv)
             return 1;
         }
     
    -    if (numFiles == 0 && genDict == 0) {
    +    if (numFiles == 0 && useDict == 0) {
             return generateFile(seed, path, origPath);
    -    } else if (genDict == 0){
    +    } else if (useDict == 0){
             return generateCorpus(seed, numFiles, path, origPath);
         } else {
             /* should generate files with a dictionary */
    
    From f4f928595bbe0a976fee0ca7e2f0ddf3d10e7374 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:27:05 -0700
    Subject: [PATCH 241/400] changed scope to get rid of mixed code/variables
     warning
    
    ---
     tests/decodecorpus.c | 20 +++++++++++---------
     1 file changed, 11 insertions(+), 9 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 76949a6e7..c4264c9d2 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1188,16 +1188,18 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
             }
     
             /* generate samples */
    -        unsigned i = 1;
    -        size_t currSize = 1;
    -        BYTE* curr = samples;
    -        while (i <= 4) {
    -            *(sampleSizes + i - 1) = currSize;
    -            for (size_t j = 0; j < currSize; j++) {
    -                *(curr++) = (BYTE)i;
    +        {
    +            unsigned i = 1;
    +            size_t currSize = 1;
    +            BYTE* curr = samples;
    +            while (i <= 4) {
    +                *(sampleSizes + i - 1) = currSize;
    +                for (size_t j = 0; j < currSize; j++) {
    +                    *(curr++) = (BYTE)i;
    +                }
    +                i++;
    +                currSize *= 16;
                 }
    -            i++;
    -            currSize *= 16;
             }
     
             /* set dictionary params */
    
    From 365e265a8eb9ea6efd912a907f03e63f55a38f1a Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:28:40 -0700
    Subject: [PATCH 242/400] changed scope so that warning disappears
    
    ---
     tests/decodecorpus.c | 20 +++++++++++---------
     1 file changed, 11 insertions(+), 9 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index c4264c9d2..bd6d762e8 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1203,16 +1203,18 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
             }
     
             /* set dictionary params */
    -        ZDICT_params_t zdictParams;
    -        memset(&zdictParams, 0, sizeof(zdictParams));
    -        zdictParams.dictID = dictID;
    -        zdictParams.notificationLevel = 1;
    +        {
    +            ZDICT_params_t zdictParams;
    +            memset(&zdictParams, 0, sizeof(zdictParams));
    +            zdictParams.dictID = dictID;
    +            zdictParams.notificationLevel = 1;
     
    -        /* finalize dictionary with random samples */
    -        dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    -                                    dictContent, dictContentSize,
    -                                    samples, sampleSizes, numSamples,
    -                                    zdictParams);
    +            /* finalize dictionary with random samples */
    +            dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize,
    +                                        dictContent, dictContentSize,
    +                                        samples, sampleSizes, numSamples,
    +                                        zdictParams);
    +        }
             free(samples);
             free(sampleSizes);
             if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) {
    
    From 791352ad0e4f2e4aabefa224becda064191588af Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:32:38 -0700
    Subject: [PATCH 243/400] scope change
    
    ---
     tests/decodecorpus.c | 12 +++++++-----
     1 file changed, 7 insertions(+), 5 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index bd6d762e8..4c6e4b27f 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1476,11 +1476,13 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                     errorDetected = 1;
                     goto dictCleanup;
                 }
    -            size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    -                                                   fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    -                                                   fullDict, dictSize);
    -            if (ZSTD_isError(returnValue)) {
    -               DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
    +            {
    +                size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    +                                                       fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    +                                                       fullDict, dictSize);
    +                if (ZSTD_isError(returnValue)) {
    +                   DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
    +                }
                 }
     
                 /* print differences if any */
    
    From 147ef05f12b1b1f81039e548533e8723ec37eabe Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:38:51 -0700
    Subject: [PATCH 244/400] for loop declaration not allowed
    
    ---
     tests/decodecorpus.c | 85 +++++++++++++++++++++++---------------------
     1 file changed, 44 insertions(+), 41 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 4c6e4b27f..42360d2c4 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1442,59 +1442,62 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
         outputBuffer(fullDict, dictSize, outPath);
     
         /* generate random compressed/decompressed files */
    -    for (unsigned fnum = 0; fnum < numFiles; fnum++) {
    -        frame_t fr;
    -        DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
    -        {
    -            size_t dictContentSize = dictSize-dictSize/4;
    -            BYTE* const dictContent = fullDict+dictSize/4;
    -            dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    -            seed = generateFrame(seed, &fr, info);
    -        }
    -        if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
    -            DISPLAY("Error: path too long\n");
    -            errorDetected = 1;
    -            goto dictCleanup;
    -        }
    -        outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath);
    -
    -        if (origPath) {
    -            if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) {
    +    {
    +        unsigned fnum;
    +        for (fnum = 0; fnum < numFiles; fnum++) {
    +            frame_t fr;
    +            DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
    +            {
    +                size_t dictContentSize = dictSize-dictSize/4;
    +                BYTE* const dictContent = fullDict+dictSize/4;
    +                dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    +                seed = generateFrame(seed, &fr, info);
    +            }
    +            if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
                     DISPLAY("Error: path too long\n");
                     errorDetected = 1;
                     goto dictCleanup;
                 }
    -            outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath);
    -        }
    +            outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath);
     
    -        /* check the output to make sure that decompressed versions match official zstd */
    -        {
    -            ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    -            BYTE* const decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE);
    -            if (decompressedPtr == NULL) {
    -                DISPLAY("Error: could not allocate memory for decompressed pointer\n");
    -                errorDetected = 1;
    -                goto dictCleanup;
    -            }
    -            {
    -                size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    -                                                       fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    -                                                       fullDict, dictSize);
    -                if (ZSTD_isError(returnValue)) {
    -                   DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
    +            if (origPath) {
    +                if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) {
    +                    DISPLAY("Error: path too long\n");
    +                    errorDetected = 1;
    +                    goto dictCleanup;
                     }
    +                outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath);
                 }
     
    -            /* print differences if any */
    +            /* check the output to make sure that decompressed versions match official zstd */
                 {
    -                size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    -                for (size_t i = 0; i < checkDiff; i++) {
    -                    if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    -                        DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    +                BYTE* const decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE);
    +                if (decompressedPtr == NULL) {
    +                    DISPLAY("Error: could not allocate memory for decompressed pointer\n");
    +                    errorDetected = 1;
    +                    goto dictCleanup;
    +                }
    +                {
    +                    size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE,
    +                                                           fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    +                                                           fullDict, dictSize);
    +                    if (ZSTD_isError(returnValue)) {
    +                       DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue));
                         }
                     }
    +
    +                /* print differences if any */
    +                {
    +                    size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    +                    for (size_t i = 0; i < checkDiff; i++) {
    +                        if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    +                            DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                        }
    +                    }
    +                }
    +                free(decompressedPtr);
                 }
    -            free(decompressedPtr);
             }
         }
     
    
    From 7a263909897bef6aa6ab5c2c0617e7f3574596fc Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 16:39:57 -0700
    Subject: [PATCH 245/400] changing for loop declaration
    
    ---
     tests/decodecorpus.c | 9 ++++++---
     1 file changed, 6 insertions(+), 3 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 42360d2c4..08c2cc0a5 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1490,9 +1490,12 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                     /* print differences if any */
                     {
                         size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart;
    -                    for (size_t i = 0; i < checkDiff; i++) {
    -                        if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    -                            DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                    {
    +                        size_t i;
    +                        for (i = 0; i < checkDiff; i++) {
    +                            if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) {
    +                                DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i)));
    +                            }
                             }
                         }
                     }
    
    From 23098b53e81d3ad9a44c0cc54b14aebafefbf5fa Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:13:00 -0700
    Subject: [PATCH 246/400] wrote a test for dictionary corpus
    
    ---
     tests/decodecorpus.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 48 insertions(+)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 08c2cc0a5..d2bf565c9 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1297,6 +1297,54 @@ cleanup:
         return ret;
     }
     
    +static size_t testDecodeWithDict(U32 seed, size_t dictSize)
    +{
    +    U32 const dictID = RAND(&seed);
    +    int errorDetected = 0;
    +    BYTE* const fullDict = malloc(dictSize);
    +    if (fullDict == NULL) {
    +        return ERROR(GENERIC);
    +    }
    +
    +    {
    +        int ret = genRandomDict(dictID, seed, dictSize, fullDict);
    +        if (ret != 0) {
    +            errorDetected = ERROR(GENERIC);
    +            goto dictTestCleanup;
    +        }
    +    }
    +
    +    frame_t* fr;
    +    {
    +        size_t dictContentSize = dictSize-dictSize/4;
    +        BYTE* const dictContent = fullDict+dictSize/4;
    +        dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    +        seed = generateFrame(seed, &fr, info);
    +    }
    +
    +    {
    +        ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    +        {
    +            size_t const returnValue = ZSTD_decompress_usingDict(dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE,
    +                                                   fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    +                                                   fullDict, dictSize);
    +            if (ZSTD_isError(returnValue)) {
    +               errorDetected = ZSTD_getErrorName(returnValue);
    +               goto dictTestCleanup
    +            }
    +        }
    +
    +        if (memcmp(DECOMPRESSED_BUFFER, fr->srcStart, (BYTE*)fr->src - (BYTE*)fr->srcStart) != 0) {
    +            errorDetected = ERROR(corruption_detected);
    +            goto dictTestCleanup;
    +        }
    +    }
    +
    +dictTestCleanup:
    +    free(fullDict);
    +    return errorDetected;
    +}
    +
     static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS)
     {
         unsigned fnum;
    
    From bdec7b8ce7b131779d768f60776f6eb0dee8f54d Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:18:43 -0700
    Subject: [PATCH 247/400] fixed for loop declaration, fixed test case
    
    ---
     tests/decodecorpus.c | 17 ++++++++++-------
     1 file changed, 10 insertions(+), 7 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index d2bf565c9..14d3f2358 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1194,8 +1194,11 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
                 BYTE* curr = samples;
                 while (i <= 4) {
                     *(sampleSizes + i - 1) = currSize;
    -                for (size_t j = 0; j < currSize; j++) {
    -                    *(curr++) = (BYTE)i;
    +                {
    +                    size_t j;
    +                    for (j = 0; j < currSize; j++) {
    +                        *(curr++) = (BYTE)i;
    +                    }
                     }
                     i++;
                     currSize *= 16;
    @@ -1300,7 +1303,7 @@ cleanup:
     static size_t testDecodeWithDict(U32 seed, size_t dictSize)
     {
         U32 const dictID = RAND(&seed);
    -    int errorDetected = 0;
    +    size_t errorDetected = 0;
         BYTE* const fullDict = malloc(dictSize);
         if (fullDict == NULL) {
             return ERROR(GENERIC);
    @@ -1314,7 +1317,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
             }
         }
     
    -    frame_t* fr;
    +    frame_t fr;
         {
             size_t dictContentSize = dictSize-dictSize/4;
             BYTE* const dictContent = fullDict+dictSize/4;
    @@ -1329,12 +1332,12 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
                                                        fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
                                                        fullDict, dictSize);
                 if (ZSTD_isError(returnValue)) {
    -               errorDetected = ZSTD_getErrorName(returnValue);
    -               goto dictTestCleanup
    +               errorDetected = returnValue;
    +               goto dictTestCleanup;
                 }
             }
     
    -        if (memcmp(DECOMPRESSED_BUFFER, fr->srcStart, (BYTE*)fr->src - (BYTE*)fr->srcStart) != 0) {
    +        if (memcmp(DECOMPRESSED_BUFFER, fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart) != 0) {
                 errorDetected = ERROR(corruption_detected);
                 goto dictTestCleanup;
             }
    
    From fdbb07283a0ca801ba37eb0328e3dcb6ce045f93 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:29:15 -0700
    Subject: [PATCH 248/400] added test to runTestMode
    
    ---
     tests/decodecorpus.c | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 14d3f2358..8e2cefb4b 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1386,6 +1386,14 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
                     return 1;
                 }
             }
    +        {
    +            size_t const dictSize = RAND(&seed);
    +            size_t const r = testDecodeWithDict(seed, dictSize);
    +            if (ZSTD_isError(r)) {
    +                DISPLAY("Error in dictionary mode on test seed %u: %s\n", seed+fnum, ZSTD_getErrorName(r));
    +                return 1;
    +            }
    +        }
         }
     
         DISPLAY("\r%u tests completed: ", fnum);
    
    From ea2af1ffc429981214124572524790c82126493a Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:34:50 -0700
    Subject: [PATCH 249/400] changed dictionary to stay reasonable size during
     test
    
    ---
     tests/decodecorpus.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 8e2cefb4b..4b42c6d7c 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1387,7 +1387,8 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
                 }
             }
             {
    -            size_t const dictSize = RAND(&seed);
    +            /* don't create a dictionary that is too big */
    +            size_t const dictSize = RAND(&seed) % (10 << 20);
                 size_t const r = testDecodeWithDict(seed, dictSize);
                 if (ZSTD_isError(r)) {
                     DISPLAY("Error in dictionary mode on test seed %u: %s\n", seed+fnum, ZSTD_getErrorName(r));
    
    From 7d2b5613b4f067e36fd435e06ea4a476b736dc51 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:37:14 -0700
    Subject: [PATCH 250/400] adhere to min dict size
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 4b42c6d7c..f5cfd6288 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1388,7 +1388,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
             }
             {
                 /* don't create a dictionary that is too big */
    -            size_t const dictSize = RAND(&seed) % (10 << 20);
    +            size_t const dictSize = RAND(&seed) % (10 << 20) + ZDICT_DICTSIZE_MIN;
                 size_t const r = testDecodeWithDict(seed, dictSize);
                 if (ZSTD_isError(r)) {
                     DISPLAY("Error in dictionary mode on test seed %u: %s\n", seed+fnum, ZSTD_getErrorName(r));
    
    From 3a6856edcaaa8ce88b280fed06a91bc6789cab4b Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:43:16 -0700
    Subject: [PATCH 251/400] changed scope to avoid errors
    
    ---
     tests/decodecorpus.c | 41 +++++++++++++++++++++--------------------
     1 file changed, 21 insertions(+), 20 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index f5cfd6288..7d91a1c70 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1316,30 +1316,31 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
                 goto dictTestCleanup;
             }
         }
    -
    -    frame_t fr;
         {
    -        size_t dictContentSize = dictSize-dictSize/4;
    -        BYTE* const dictContent = fullDict+dictSize/4;
    -        dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    -        seed = generateFrame(seed, &fr, info);
    -    }
    -
    -    {
    -        ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    +        frame_t fr;
             {
    -            size_t const returnValue = ZSTD_decompress_usingDict(dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE,
    -                                                   fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    -                                                   fullDict, dictSize);
    -            if (ZSTD_isError(returnValue)) {
    -               errorDetected = returnValue;
    -               goto dictTestCleanup;
    -            }
    +            size_t dictContentSize = dictSize-dictSize/4;
    +            BYTE* const dictContent = fullDict+dictSize/4;
    +            dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
    +            seed = generateFrame(seed, &fr, info);
             }
     
    -        if (memcmp(DECOMPRESSED_BUFFER, fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart) != 0) {
    -            errorDetected = ERROR(corruption_detected);
    -            goto dictTestCleanup;
    +        {
    +            ZSTD_DCtx* const dctx = ZSTD_createDCtx();
    +            {
    +                size_t const returnValue = ZSTD_decompress_usingDict(dctx, DECOMPRESSED_BUFFER, MAX_DECOMPRESSED_SIZE,
    +                                                       fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart,
    +                                                       fullDict, dictSize);
    +                if (ZSTD_isError(returnValue)) {
    +                   errorDetected = returnValue;
    +                   goto dictTestCleanup;
    +                }
    +            }
    +
    +            if (memcmp(DECOMPRESSED_BUFFER, fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart) != 0) {
    +                errorDetected = ERROR(corruption_detected);
    +                goto dictTestCleanup;
    +            }
             }
         }
     
    
    From 008d44ad66dc09cbbd4cc2ad782559731aeee8d2 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 19 Jun 2017 17:45:43 -0700
    Subject: [PATCH 252/400] fix attempt : fullbench VS2008 project
    
    ---
     build/VS2008/fullbench/fullbench.vcproj | 8 ++++++++
     1 file changed, 8 insertions(+)
    
    diff --git a/build/VS2008/fullbench/fullbench.vcproj b/build/VS2008/fullbench/fullbench.vcproj
    index 582a9ce93..942934561 100644
    --- a/build/VS2008/fullbench/fullbench.vcproj
    +++ b/build/VS2008/fullbench/fullbench.vcproj
    @@ -348,6 +348,14 @@
     				RelativePath="..\..\..\lib\common\zstd_common.c"
     				>
     			
    +			
    +			
    +			
    +			
     			
    
    From 4a4f9ba2623e75e433a50fa2a6302848436c36db Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Mon, 19 Jun 2017 17:46:21 -0700
    Subject: [PATCH 253/400] const value that doesn't change
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 7d91a1c70..74252d562 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1319,7 +1319,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
         {
             frame_t fr;
             {
    -            size_t dictContentSize = dictSize-dictSize/4;
    +            size_t const dictContentSize = dictSize-dictSize/4;
                 BYTE* const dictContent = fullDict+dictSize/4;
                 dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
                 seed = generateFrame(seed, &fr, info);
    
    From c08e649e95deb7fdee73bc13e71ee067419d22bf Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 19 Jun 2017 18:25:35 -0700
    Subject: [PATCH 254/400] first implementation of bench.c with new API
     ZSTD_compress_generic()
    
    Doesn't speed optimize this buffer-to-buffer scenario yet.
    Still internally defers to streaming implementation.
    
    Also : fixed a long standing bug in ZSTDMT streaming API.
    ---
     doc/zstd_manual.html           | 50 ++++++++++++------------
     lib/compress/zstd_compress.c   |  5 ++-
     lib/compress/zstdmt_compress.c | 70 ++++++++++++++++++++--------------
     programs/bench.c               | 51 +++++++++++++++++++------
     4 files changed, 110 insertions(+), 66 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index cf51daa85..88e890793 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -13,7 +13,7 @@
     
  • Simple API
  • Explicit memory management
  • Simple dictionary API
  • -
  • Fast dictionary API
  • +
  • Bulk processing dictionary API
  • Streaming
  • Streaming compression - HowTo
  • Streaming decompression - HowTo
  • @@ -40,18 +40,18 @@ - a single step (described as Simple API) - a single step, reusing a context (described as Explicit memory management) - unbounded multiple steps (described as Streaming compression) - The compression ratio achievable on small data can be highly improved using compression with a dictionary in: + The compression ratio achievable on small data can be highly improved using a dictionary in: - a single step (described as Simple dictionary API) - a single step, reusing a dictionary (described as Fast dictionary API) Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h. - These APIs shall never be used with a dynamic library. + Advanced experimental APIs shall never be used with a dynamic library. They are not "stable", their definition may change in the future. Only static linking is allowed.

    Version

    
     
    -
    unsigned ZSTD_versionNumber(void);   /**< to be used when checking dll version */
    +
    unsigned ZSTD_versionNumber(void);   /**< useful to check dll version */
     

    Simple API

    
     
    @@ -67,7 +67,7 @@
     
    size_t ZSTD_decompress( void* dst, size_t dstCapacity,
                       const void* src, size_t compressedSize);
     

    `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames. - `dstCapacity` is an upper bound of originalSize. + `dstCapacity` is an upper bound of originalSize to regenerate. If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data. @return : the number of bytes decompressed into `dst` (<= `dstCapacity`), or an errorCode if it fails (which can be tested using ZSTD_isError()). @@ -140,33 +140,33 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); const void* src, size_t srcSize, const void* dict,size_t dictSize, int compressionLevel); -

    Compression using a predefined Dictionary (see dictBuilder/zdict.h). - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. +

    Compression using a predefined Dictionary (see dictBuilder/zdict.h). + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used.


    size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
                                      void* dst, size_t dstCapacity,
                                const void* src, size_t srcSize,
                                const void* dict,size_t dictSize);
    -

    Decompression using a predefined Dictionary (see dictBuilder/zdict.h). - Dictionary must be identical to the one used during compression. - Note : This function loads the dictionary, resulting in significant startup delay. - Note : When `dict == NULL || dictSize < 8` no dictionary is used. +

    Decompression using a predefined Dictionary (see dictBuilder/zdict.h). + Dictionary must be identical to the one used during compression. + Note : This function loads the dictionary, resulting in significant startup delay. + Note : When `dict == NULL || dictSize < 8` no dictionary is used.


    -

    Fast dictionary API

    
    +

    Bulk processing dictionary API

    
     
     
    ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
                                  int compressionLevel);
    -

    When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. - ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. - ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only. - `dictBuffer` can be released after ZSTD_CDict creation, as its content is copied within CDict +

    When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once. + ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay. + ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only. + `dictBuffer` can be released after ZSTD_CDict creation, since its content is copied within CDict


    size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);
    -

    Function frees memory allocated by ZSTD_createCDict(). +

    Function frees memory allocated by ZSTD_createCDict().


    size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
    @@ -180,20 +180,20 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
     


    ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
    -

    Create a digested dictionary, ready to start decompression operation without startup delay. - dictBuffer can be released after DDict creation, as its content is copied inside DDict +

    Create a digested dictionary, ready to start decompression operation without startup delay. + dictBuffer can be released after DDict creation, as its content is copied inside DDict


    size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);
    -

    Function frees memory allocated with ZSTD_createDDict() +

    Function frees memory allocated with ZSTD_createDDict()


    size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
                                       void* dst, size_t dstCapacity,
                                 const void* src, size_t srcSize,
                                 const ZSTD_DDict* ddict);
    -

    Decompression using a digested Dictionary. - Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. +

    Decompression using a digested Dictionary. + Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times.


    Streaming

    
    @@ -250,7 +250,7 @@ size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);
      
     
    -
    typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are effectively same object */
    +
    typedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are now effectively same object (>= v1.3.0) */
     

    ZSTD_CStream management functions

    ZSTD_CStream* ZSTD_createCStream(void);
     size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
    @@ -285,6 +285,8 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
      
     
    +
    typedef ZSTD_DCtx ZSTD_DStream;  /**< DCtx and DStream are now effectively same object (>= v1.3.0) */
    +

    ZSTD_DStream management functions

    ZSTD_DStream* ZSTD_createDStream(void);
     size_t ZSTD_freeDStream(ZSTD_DStream* zds);
     

    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 49d29dce4..f5ac75a95 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -571,7 +571,7 @@ static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1, } /*! ZSTD_continueCCtx() : - reuse CCtx without reset (note : requires no dictionary) */ + * reuse CCtx without reset (note : requires no dictionary) */ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 pledgedSrcSize) { U32 const end = (U32)(cctx->nextSrc - cctx->base); @@ -3831,6 +3831,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { + DEBUGLOG(4, "call ZSTDMT_initCStream_internal"); CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) ); cctx->streamStage = zcss_load; } else @@ -3842,7 +3843,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); - DEBUGLOG(5, "ZSTDMT result : %u", (U32)flushMin); + DEBUGLOG(4, "ZSTDMT_compressStream_generic : %u", (U32)flushMin); if ( ZSTD_isError(flushMin) || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */ ZSTD_startNewCompression(cctx); diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 42e31ca18..895d362fb 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -190,7 +190,7 @@ static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads, cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem); if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } - DEBUGLOG(3, "cctxPool created, with %u threads", nbThreads); + DEBUGLOG(4, "cctxPool created, with %u threads", nbThreads); return cctxPool; } @@ -261,11 +261,11 @@ void ZSTDMT_compressChunk(void* jobDescription) ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription; const void* const src = (const char*)job->srcStart + job->dictSize; buffer_t const dstBuff = job->dstBuff; - DEBUGLOG(3, "job (first:%u) (last:%u) : dictSize %u, srcSize %u", + DEBUGLOG(4, "job (first:%u) (last:%u) : dictSize %u, srcSize %u", job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize); if (job->cdict) { /* should only happen for first segment */ size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize); - DEBUGLOG(3, "using CDict"); + DEBUGLOG(5, "using CDict"); if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; } } else { /* srcStart points at reloaded section */ if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */ @@ -280,12 +280,12 @@ void ZSTDMT_compressChunk(void* jobDescription) ZSTD_invalidateRepCodes(job->cctx); } - DEBUGLOG(4, "Compressing : "); + DEBUGLOG(5, "Compressing : "); DEBUG_PRINTHEX(4, job->srcStart, 12); job->cSize = (job->lastChunk) ? ZSTD_compressEnd (job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize) : ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize); - DEBUGLOG(3, "compressed %u bytes into %u bytes (first:%u) (last:%u)", + DEBUGLOG(4, "compressed %u bytes into %u bytes (first:%u) (last:%u)", (unsigned)job->srcSize, (unsigned)job->cSize, job->firstChunk, job->lastChunk); DEBUGLOG(5, "dstBuff.size : %u ; => %s", (U32)dstBuff.size, ZSTD_getErrorName(job->cSize)); @@ -426,7 +426,7 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, mtctx->sectionSize = value; return 0; case ZSTDMT_p_overlapSectionLog : - DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value); + DEBUGLOG(5, "ZSTDMT_p_overlapSectionLog : %u", value); mtctx->overlapRLog = (value >= 9) ? 0 : 9 - value; return 0; default : @@ -457,8 +457,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */ size_t frameStartPos = 0, dstBufferPos = 0; - DEBUGLOG(3, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize); - DEBUGLOG(3, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); + DEBUGLOG(4, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize); + DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); params.fParams.contentSizeFlag = 1; if (nbChunks==1) { /* fallback to single-thread mode */ @@ -495,8 +495,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex; mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond; - DEBUGLOG(3, "posting job %u (%u bytes)", u, (U32)chunkSize); - DEBUG_PRINTHEX(3, mtctx->jobs[u].srcStart, 12); + DEBUGLOG(4, "posting job %u (%u bytes)", u, (U32)chunkSize); + DEBUG_PRINTHEX(5, mtctx->jobs[u].srcStart, 12); POOL_add(mtctx->factory, ZSTDMT_compressChunk, &mtctx->jobs[u]); frameStartPos += chunkSize; @@ -508,14 +508,14 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, { unsigned chunkID; size_t error = 0, dstPos = 0; for (chunkID=0; chunkIDjobCompleted_mutex); while (mtctx->jobs[chunkID].jobCompleted==0) { - DEBUGLOG(4, "waiting for jobCompleted signal from chunk %u", chunkID); + DEBUGLOG(5, "waiting for jobCompleted signal from chunk %u", chunkID); pthread_cond_wait(&mtctx->jobCompleted_cond, &mtctx->jobCompleted_mutex); } pthread_mutex_unlock(&mtctx->jobCompleted_mutex); - DEBUGLOG(3, "ready to write chunk %u ", chunkID); + DEBUGLOG(5, "ready to write chunk %u ", chunkID); ZSTDMT_releaseCCtx(mtctx->cctxPool, mtctx->jobs[chunkID].cctx); mtctx->jobs[chunkID].cctx = NULL; @@ -533,7 +533,7 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, dstPos += cSize ; } } - if (!error) DEBUGLOG(3, "compressed size : %u ", (U32)dstPos); + if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos); return error ? error : dstPos; } @@ -550,7 +550,7 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) unsigned const jobID = zcs->doneJobID & zcs->jobIDMask; PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex); while (zcs->jobs[jobID].jobCompleted==0) { - DEBUGLOG(4, "waiting for jobCompleted signal from chunk %u", zcs->doneJobID); /* we want to block when waiting for data to flush */ + DEBUGLOG(5, "waiting for jobCompleted signal from chunk %u", zcs->doneJobID); /* we want to block when waiting for data to flush */ pthread_cond_wait(&zcs->jobCompleted_cond, &zcs->jobCompleted_mutex); } pthread_mutex_unlock(&zcs->jobCompleted_mutex); @@ -593,12 +593,12 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, } zcs->targetDictSize = (zcs->overlapRLog>=9) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); - DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog); - DEBUGLOG(3, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); + DEBUGLOG(5, "overlapRLog : %u ", zcs->overlapRLog); + DEBUGLOG(5, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize); zcs->targetSectionSize = MAX(zcs->targetDictSize, zcs->targetSectionSize); - DEBUGLOG(3, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10)); + DEBUGLOG(5, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10)); zcs->marginSize = zcs->targetSectionSize >> 2; zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize; zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); @@ -628,7 +628,8 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx, ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict); if (cdict==NULL) return ERROR(GENERIC); /* method incompatible with NULL cdict */ params.fParams = fParams; - return ZSTDMT_initCStream_internal(mtctx, NULL, 0, cdict, params, pledgedSrcSize); + return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict, + params, pledgedSrcSize); } @@ -686,6 +687,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi /* get a new buffer for next input */ if (!endFrame) { size_t const newDictSize = MIN(srcSize + zcs->dictSize, zcs->targetDictSize); + DEBUGLOG(5, "ZSTDMT_createCompressionJob::endFrame = %u", endFrame); zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); if (zcs->inBuff.buffer.start == NULL) { /* not enough memory to allocate next input buffer */ zcs->jobs[jobID].jobCompleted = 1; @@ -694,9 +696,9 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi ZSTDMT_releaseAllJobResources(zcs); return ERROR(memory_allocation); } - DEBUGLOG(5, "inBuff filled to %u", (U32)zcs->inBuff.filled); + DEBUGLOG(5, "inBuff currently filled to %u", (U32)zcs->inBuff.filled); zcs->inBuff.filled -= srcSize + zcs->dictSize - newDictSize; - DEBUGLOG(5, "new job : filled to %u, with %u dict and %u src", + DEBUGLOG(5, "new job : inBuff filled to %u, with %u dict and %u src", (U32)zcs->inBuff.filled, (U32)newDictSize, (U32)(zcs->inBuff.filled - newDictSize)); memmove(zcs->inBuff.buffer.start, @@ -705,6 +707,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi DEBUGLOG(5, "new inBuff pre-filled"); zcs->dictSize = newDictSize; } else { /* if (endFrame==1) */ + DEBUGLOG(5, "ZSTDMT_createCompressionJob::endFrame = %u", endFrame); zcs->inBuff.buffer = g_nullBuffer; zcs->inBuff.filled = 0; zcs->dictSize = 0; @@ -714,7 +717,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsi zcs->params.fParams.checksumFlag = 0; } - DEBUGLOG(3, "posting job %u : %u bytes (end:%u) (note : doneJob = %u=>%u)", + DEBUGLOG(4, "posting job %u : %u bytes (end:%u) (note : doneJob = %u=>%u)", zcs->nextJobID, (U32)zcs->jobs[jobID].srcSize, zcs->jobs[jobID].lastChunk, @@ -757,7 +760,7 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi XXH64_update(&zcs->xxhState, (const char*)job.srcStart + job.dictSize, job.srcSize); if (zcs->frameEnded && (zcs->doneJobID+1 == zcs->nextJobID)) { /* write checksum at end of last section */ U32 const checksum = (U32)XXH64_digest(&zcs->xxhState); - DEBUGLOG(4, "writing checksum : %08X \n", checksum); + DEBUGLOG(5, "writing checksum : %08X \n", checksum); MEM_writeLE32((char*)job.dstBuff.start + job.cSize, checksum); job.cSize += 4; zcs->jobs[wJobID].cSize += 4; @@ -792,23 +795,25 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) { size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize; - if (zcs->frameEnded) - /* current frame being ended. Only flush is allowed. Restart with init */ + if (zcs->frameEnded) { + /* current frame being ended. Only flush is allowed. Or start new job with init */ + DEBUGLOG(5, "ZSTDMT_compressStream: zcs::frameEnded==1"); return ERROR(stage_wrong); + } if (zcs->nbThreads==1) { return ZSTD_compressStream(zcs->cctxPool->cctx[0], output, input); } /* fill input buffer */ { size_t const toLoad = MIN(input->size - input->pos, zcs->inBuffSize - zcs->inBuff.filled); - memcpy((char*)zcs->inBuff.buffer.start + zcs->inBuff.filled, input->src, toLoad); + memcpy((char*)zcs->inBuff.buffer.start + zcs->inBuff.filled, (const char*)input->src + input->pos, toLoad); input->pos += toLoad; zcs->inBuff.filled += toLoad; } if ( (zcs->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { /* avoid overwriting job round buffer */ - CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0 /* blockToFlush */) ); + CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0 /* endFrame */) ); } /* check for data to flush */ @@ -824,7 +829,8 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp size_t const srcSize = zcs->inBuff.filled - zcs->dictSize; if (srcSize) - DEBUGLOG(5, "flushing : %u bytes left to compress", (U32)srcSize); + DEBUGLOG(5, "ZSTDMT_flushStream_internal : %u bytes left to compress", + (U32)srcSize); if ( ((srcSize > 0) || (endFrame && !zcs->frameEnded)) && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { DEBUGLOG(5, "create new job with %u bytes to compress", (U32)srcSize); @@ -842,6 +848,7 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) { + DEBUGLOG(5, "ZSTDMT_flushStream"); if (zcs->nbThreads==1) return ZSTD_flushStream(zcs->cctxPool->cctx[0], output); return ZSTDMT_flushStream_internal(zcs, output, 0 /* endFrame */); @@ -849,6 +856,7 @@ size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) { + DEBUGLOG(5, "ZSTDMT_endStream"); if (zcs->nbThreads==1) return ZSTD_endStream(zcs->cctxPool->cctx[0], output); return ZSTDMT_flushStream_internal(zcs, output, 1 /* endFrame */); @@ -859,17 +867,21 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, ZSTD_inBuffer* input, ZSTD_EndDirective endOp) { + DEBUGLOG(5, "in: pos:%u / size:%u ; endOp=%u", + (U32)input->pos, (U32)input->size, (U32)endOp); if (input->pos < input->size) /* exclude final flushes */ CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); + if (input->pos < input->size) endOp = ZSTD_e_continue; switch(endOp) { case ZSTD_e_flush: return ZSTDMT_flushStream(mtctx, output); case ZSTD_e_end: + DEBUGLOG(5, "endOp:%u; calling ZSTDMT_endStream", (U32)endOp); return ZSTDMT_endStream(mtctx, output); case ZSTD_e_continue: return 1; default: - return ERROR(GENERIC); + return ERROR(GENERIC); /* invalid endDirective */ } } diff --git a/programs/bench.c b/programs/bench.c index 1f1b00594..6f09a56de 100644 --- a/programs/bench.c +++ b/programs/bench.c @@ -158,7 +158,6 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, const ZSTD_compressionParameters* comprParams) { size_t const blockSize = ((g_blockSize>=32 && !g_decodeOnly) ? g_blockSize : srcSize) + (!srcSize) /* avoid div by 0 */ ; - size_t const avgSize = MIN(blockSize, (srcSize / nbFiles)); U32 const maxNbBlocks = (U32) ((srcSize + (blockSize-1)) / blockSize) + nbFiles; blockParam_t* const blockTable = (blockParam_t*) malloc(maxNbBlocks * sizeof(blockParam_t)); size_t const maxCompressedSize = ZSTD_compressBound(srcSize) + (maxNbBlocks * 1024); /* add some room for safety */ @@ -261,42 +260,72 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize, UTIL_getTime(&clockStart); if (!cCompleted) { /* still some time to do compression tests */ - ZSTD_customMem const cmem = { NULL, NULL, NULL }; U64 const clockLoop = g_nbSeconds ? TIMELOOP_MICROSEC : 1; U32 nbLoops = 0; + ZSTD_CDict* cdict = NULL; +#ifdef ZSTD_NEWAPI + ZSTD_CCtx_setParameter(ctx, ZSTD_p_nbThreads, g_nbThreads); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionLevel, cLevel); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_windowLog, comprParams->windowLog); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_chainLog, comprParams->chainLog); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_searchLog, comprParams->searchLog); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_minMatch, comprParams->searchLength); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_targetLength, comprParams->targetLength); + ZSTD_CCtx_setParameter(ctx, ZSTD_p_compressionStrategy, comprParams->strategy); + ZSTD_CCtx_loadDictionary(ctx, dictBuffer, dictBufferSize); +#else + size_t const avgSize = MIN(blockSize, (srcSize / nbFiles)); ZSTD_parameters zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize); - ZSTD_CDict* cdict; + ZSTD_customMem const cmem = { NULL, NULL, NULL }; if (comprParams->windowLog) zparams.cParams.windowLog = comprParams->windowLog; if (comprParams->chainLog) zparams.cParams.chainLog = comprParams->chainLog; if (comprParams->hashLog) zparams.cParams.hashLog = comprParams->hashLog; if (comprParams->searchLog) zparams.cParams.searchLog = comprParams->searchLog; if (comprParams->searchLength) zparams.cParams.searchLength = comprParams->searchLength; if (comprParams->targetLength) zparams.cParams.targetLength = comprParams->targetLength; - if (comprParams->strategy) zparams.cParams.strategy = (ZSTD_strategy)(comprParams->strategy - 1); + if (comprParams->strategy) zparams.cParams.strategy = comprParams->strategy; cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1, zparams.cParams, cmem); if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure"); +#endif do { U32 blockNb; - size_t rSize; for (blockNb=0; blockNb5) { int n; for (n=-5; n<0; n++) DISPLAY("%02X ", ((const BYTE*)srcBuffer)[u+n]); From e7093ca18c5b9e61eeae33d253b3ce58267f0347 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 19 Jun 2017 19:09:15 -0700 Subject: [PATCH 255/400] [linux] Add libfuzzer targets --- contrib/linux-kernel/test/DecompressCrash.c | 85 ++++++++++ contrib/linux-kernel/test/Makefile | 13 ++ contrib/linux-kernel/test/RoundTripCrash.c | 162 ++++++++++++++++++++ 3 files changed, 260 insertions(+) create mode 100644 contrib/linux-kernel/test/DecompressCrash.c create mode 100644 contrib/linux-kernel/test/RoundTripCrash.c diff --git a/contrib/linux-kernel/test/DecompressCrash.c b/contrib/linux-kernel/test/DecompressCrash.c new file mode 100644 index 000000000..b5b673aad --- /dev/null +++ b/contrib/linux-kernel/test/DecompressCrash.c @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* + This program takes a file in input, + performs a zstd round-trip test (compression - decompress) + compares the result with original + and generates a crash (double free) on corruption detection. +*/ + +/*=========================================== +* Dependencies +*==========================================*/ +#include /* size_t */ +#include /* malloc, free, exit */ +#include /* fprintf */ +#include + +/*=========================================== +* Macros +*==========================================*/ +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) + +static ZSTD_DCtx *dctx = NULL; +void *dws = NULL; +static void* rBuff = NULL; +static size_t buffSize = 0; + +static void crash(int errorCode){ + /* abort if AFL/libfuzzer, exit otherwise */ + #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* could also use __AFL_COMPILER */ + abort(); + #else + exit(errorCode); + #endif +} + +static void decompressCheck(const void* srcBuff, size_t srcBuffSize) +{ + size_t const neededBuffSize = 20 * srcBuffSize; + + /* Allocate all buffers and contexts if not already allocated */ + if (neededBuffSize > buffSize) { + free(rBuff); + buffSize = 0; + + rBuff = malloc(neededBuffSize); + if (!rBuff) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + buffSize = neededBuffSize; + } + if (!dctx) { + size_t const workspaceSize = ZSTD_DCtxWorkspaceBound(); + dws = malloc(workspaceSize); + if (!dws) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + dctx = ZSTD_initDCtx(dws, workspaceSize); + if (!dctx) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + } + ZSTD_decompressDCtx(dctx, rBuff, buffSize, srcBuff, srcBuffSize); + +#ifndef SKIP_FREE + free(dws); dws = NULL; dctx = NULL; + free(rBuff); rBuff = NULL; + buffSize = 0; +#endif +} + +int LLVMFuzzerTestOneInput(const unsigned char *srcBuff, size_t srcBuffSize) { + decompressCheck(srcBuff, srcBuffSize); + return 0; +} diff --git a/contrib/linux-kernel/test/Makefile b/contrib/linux-kernel/test/Makefile index e33a256a4..892264f4c 100644 --- a/contrib/linux-kernel/test/Makefile +++ b/contrib/linux-kernel/test/Makefile @@ -12,12 +12,24 @@ CPPFLAGS += $(IFLAGS) ../lib/zstd/libzstd.a: $(OBJECTS) $(AR) $(ARFLAGS) $@ $^ +DecompressCrash: DecompressCrash.o $(OBJECTS) libFuzzer.a + $(CXX) $(TEST_CPPFLAGS) $(TEST_CXXFLAGS) $(LDFLAGS) $^ -o $@ + +RoundTripCrash: RoundTripCrash.o $(OBJECTS) ../lib/xxhash.o libFuzzer.a + $(CXX) $(TEST_CPPFLAGS) $(TEST_CXXFLAGS) $(LDFLAGS) $^ -o $@ + UserlandTest: UserlandTest.cpp ../lib/zstd/libzstd.a ../lib/xxhash.o $(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@ XXHashUserlandTest: XXHashUserlandTest.cpp ../lib/xxhash.o ../../../lib/common/xxhash.o $(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@ +# Install libfuzzer +libFuzzer.a: + @$(RM) -rf Fuzzer + @git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer + @./Fuzzer/build.sh + # Install googletest .PHONY: googletest googletest: @@ -28,3 +40,4 @@ googletest: clean: $(RM) -f *.{o,a} ../lib/zstd/*.{o,a} + $(RM) -f DecompressCrash RoundTripCrash UserlandTest XXHashUserlandTest diff --git a/contrib/linux-kernel/test/RoundTripCrash.c b/contrib/linux-kernel/test/RoundTripCrash.c new file mode 100644 index 000000000..44c67f3ab --- /dev/null +++ b/contrib/linux-kernel/test/RoundTripCrash.c @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/* + This program takes a file in input, + performs a zstd round-trip test (compression - decompress) + compares the result with original + and generates a crash (double free) on corruption detection. +*/ + +/*=========================================== +* Dependencies +*==========================================*/ +#include /* size_t */ +#include /* malloc, free, exit */ +#include /* fprintf */ +#include +#include + +/*=========================================== +* Macros +*==========================================*/ +#define MIN(a,b) ( (a) < (b) ? (a) : (b) ) + +static const int kMaxClevel = 22; + +static ZSTD_CCtx *cctx = NULL; +void *cws = NULL; +static ZSTD_DCtx *dctx = NULL; +void *dws = NULL; +static void* cBuff = NULL; +static void* rBuff = NULL; +static size_t buffSize = 0; + + +/** roundTripTest() : +* Compresses `srcBuff` into `compressedBuff`, +* then decompresses `compressedBuff` into `resultBuff`. +* Compression level used is derived from first content byte. +* @return : result of decompression, which should be == `srcSize` +* or an error code if either compression or decompression fails. +* Note : `compressedBuffCapacity` should be `>= ZSTD_compressBound(srcSize)` +* for compression to be guaranteed to work */ +static size_t roundTripTest(void* resultBuff, size_t resultBuffCapacity, + void* compressedBuff, size_t compressedBuffCapacity, + const void* srcBuff, size_t srcBuffSize) +{ + size_t const hashLength = MIN(128, srcBuffSize); + unsigned const h32 = xxh32(srcBuff, hashLength, 0); + int const cLevel = h32 % kMaxClevel; + ZSTD_parameters const params = ZSTD_getParams(cLevel, srcBuffSize, 0); + size_t const cSize = ZSTD_compressCCtx(cctx, compressedBuff, compressedBuffCapacity, srcBuff, srcBuffSize, params); + if (ZSTD_isError(cSize)) { + fprintf(stderr, "Compression error : %u \n", ZSTD_getErrorCode(cSize)); + return cSize; + } + return ZSTD_decompressDCtx(dctx, resultBuff, resultBuffCapacity, compressedBuff, cSize); +} + + +static size_t checkBuffers(const void* buff1, const void* buff2, size_t buffSize) +{ + const char* ip1 = (const char*)buff1; + const char* ip2 = (const char*)buff2; + size_t pos; + + for (pos=0; pos buffSize) { + free(cBuff); + free(rBuff); + buffSize = 0; + + cBuff = malloc(neededBuffSize); + rBuff = malloc(neededBuffSize); + if (!cBuff || !rBuff) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + buffSize = neededBuffSize; + } + if (!cctx) { + ZSTD_compressionParameters const params = ZSTD_getCParams(kMaxClevel, 0, 0); + size_t const workspaceSize = ZSTD_CCtxWorkspaceBound(params); + cws = malloc(workspaceSize); + if (!cws) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + cctx = ZSTD_initCCtx(cws, workspaceSize); + if (!cctx) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + } + if (!dctx) { + size_t const workspaceSize = ZSTD_DCtxWorkspaceBound(); + dws = malloc(workspaceSize); + if (!dws) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + dctx = ZSTD_initDCtx(dws, workspaceSize); + if (!dctx) { + fprintf(stderr, "not enough memory ! \n"); + crash(1); + } + } + + { size_t const result = roundTripTest(rBuff, buffSize, cBuff, buffSize, srcBuff, srcBuffSize); + if (ZSTD_isError(result)) { + fprintf(stderr, "roundTripTest error : %u \n", ZSTD_getErrorCode(result)); + crash(1); + } + if (result != srcBuffSize) { + fprintf(stderr, "Incorrect regenerated size : %u != %u\n", (unsigned)result, (unsigned)srcBuffSize); + crash(1); + } + if (checkBuffers(srcBuff, rBuff, srcBuffSize) != srcBuffSize) { + fprintf(stderr, "Silent decoding corruption !!!"); + crash(1); + } + } + +#ifndef SKIP_FREE + free(cws); cws = NULL; cctx = NULL; + free(dws); dws = NULL; dctx = NULL; + free(cBuff); cBuff = NULL; + free(rBuff); rBuff = NULL; + buffSize = 0; +#endif +} + +int LLVMFuzzerTestOneInput(const unsigned char *srcBuff, size_t srcBuffSize) { + roundTripCheck(srcBuff, srcBuffSize); + return 0; +} From 631d3664b0970d3d06e439bed6bb42bd63188f25 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 19 Jun 2017 19:09:41 -0700 Subject: [PATCH 256/400] [linux] Add xxhash and zstd in-kernel tests --- contrib/linux-kernel/xxhash_test.c | 191 +++++++++++++ contrib/linux-kernel/zstd_compress_test.c | 285 ++++++++++++++++++++ contrib/linux-kernel/zstd_decompress_test.c | 256 ++++++++++++++++++ 3 files changed, 732 insertions(+) create mode 100644 contrib/linux-kernel/xxhash_test.c create mode 100644 contrib/linux-kernel/zstd_compress_test.c create mode 100644 contrib/linux-kernel/zstd_decompress_test.c diff --git a/contrib/linux-kernel/xxhash_test.c b/contrib/linux-kernel/xxhash_test.c new file mode 100644 index 000000000..5c1101b6f --- /dev/null +++ b/contrib/linux-kernel/xxhash_test.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* DO_XXH should be 32 or 64 for xxh32 and xxh64 respectively */ +#define DO_XXH 0 +/* DO_CRC should be 0 or 1 */ +#define DO_CRC 0 +/* Buffer size */ +#define BUFFER_SIZE 4096 + +#include +#include +#include +#include + +#if DO_XXH +#include +#endif + +#if DO_CRC +#include +#endif + +/* Device name to pass to register_chrdev(). */ +#define DEVICE_NAME "xxhash_test" + +/* Dynamically allocated device major number */ +static int device_major; + +/* + * We reuse the same hash state, and thus can hash only one + * file at a time. + */ +static bool device_is_open; + +static uint64_t total_length; + + +#if (DO_XXH == 32) + +#define xxh_state xxh32_state +#define xxh_reset xxh32_reset +#define xxh_update xxh32_update +#define xxh_digest xxh32_digest +#define XXH_FORMAT "XXH32 = 0x%x" + +#elif (DO_XXH == 64) + +#define xxh_state xxh64_state +#define xxh_reset xxh64_reset +#define xxh_update xxh64_update +#define xxh_digest xxh64_digest +#define XXH_FORMAT "XXH64 = 0x%llx" + +#elif DO_XXH + +#error "Invalid value of DO_XXH" + +#endif + +#if DO_XXH + +/* XXH state */ +static struct xxh_state state; + +#endif /* DO_XXH */ + +#if DO_CRC + +static uint32_t crc; + +#endif /* DO_CRC */ + +/* + * Input buffer used to put data coming from userspace. + */ +static uint8_t buffer_in[BUFFER_SIZE]; + +static int xxhash_test_open(struct inode *i, struct file *f) +{ + if (device_is_open) + return -EBUSY; + + device_is_open = true; + + total_length = 0; +#if DO_XXH + xxh_reset(&state, 0); +#endif +#if DO_CRC + crc = 0xFFFFFFFF; +#endif + + printk(KERN_INFO DEVICE_NAME ": opened\n"); + return 0; +} + +static int xxhash_test_release(struct inode *i, struct file *f) +{ + device_is_open = false; + + printk(KERN_INFO DEVICE_NAME ": total_len = %llu\n", total_length); +#if DO_XXH + printk(KERN_INFO DEVICE_NAME ": " XXH_FORMAT "\n", xxh_digest(&state)); +#endif +#if DO_CRC + printk(KERN_INFO DEVICE_NAME ": CRC32 = 0x%08x\n", ~crc); +#endif + printk(KERN_INFO DEVICE_NAME ": closed\n"); + return 0; +} + +/* + * Hash the data given to us from userspace. + */ +static ssize_t xxhash_test_write(struct file *file, const char __user *buf, + size_t size, loff_t *pos) +{ + size_t remaining = size; + + while (remaining > 0) { +#if DO_XXH + int ret; +#endif + size_t const copy_size = min(remaining, sizeof(buffer_in)); + + if (copy_from_user(buffer_in, buf, copy_size)) + return -EFAULT; + buf += copy_size; + remaining -= copy_size; + total_length += copy_size; +#if DO_XXH + if ((ret = xxh_update(&state, buffer_in, copy_size))) { + printk(KERN_INFO DEVICE_NAME ": xxh failure."); + return ret; + } +#endif +#if DO_CRC + crc = crc32(crc, buffer_in, copy_size); +#endif + } + return size; +} +/* register the character device. */ +static int __init xxhash_test_init(void) +{ + static const struct file_operations fileops = { + .owner = THIS_MODULE, + .open = &xxhash_test_open, + .release = &xxhash_test_release, + .write = &xxhash_test_write + }; + + device_major = register_chrdev(0, DEVICE_NAME, &fileops); + if (device_major < 0) { + return device_major; + } + + printk(KERN_INFO DEVICE_NAME ": module loaded\n"); + printk(KERN_INFO DEVICE_NAME ": Create a device node with " + "'mknod " DEVICE_NAME " c %d 0' and write data " + "to it.\n", device_major); + return 0; +} + +static void __exit xxhash_test_exit(void) +{ + unregister_chrdev(device_major, DEVICE_NAME); + printk(KERN_INFO DEVICE_NAME ": module unloaded\n"); +} + +module_init(xxhash_test_init); +module_exit(xxhash_test_exit); + +MODULE_DESCRIPTION("XXHash tester"); +MODULE_VERSION("1.0"); + + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/contrib/linux-kernel/zstd_compress_test.c b/contrib/linux-kernel/zstd_compress_test.c new file mode 100644 index 000000000..bf856b796 --- /dev/null +++ b/contrib/linux-kernel/zstd_compress_test.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* Compression level or 0 to disable */ +#define DO_ZLIB 9 +/* Compression level or 0 to disable */ +#define DO_ZSTD 0 +/* Buffer size */ +#define BUFFER_SIZE 4096 + +#include +#include +#include +#include +#include + +#if DO_ZSTD +#include +#endif + +#if DO_ZLIB +#include +#endif + +/* Device name to pass to register_chrdev(). */ +#define DEVICE_NAME "zstd_compress_test" + +/* Dynamically allocated device major number */ +static int device_major; + +/* + * We reuse the same state, and thus can compress only one file at a time. + */ +static bool device_is_open; + + +static void *workspace = NULL; + +/* + * Input buffer used to put data coming from userspace. + */ +static uint8_t buffer_in[BUFFER_SIZE]; +static uint8_t buffer_out[BUFFER_SIZE]; + +static uint64_t uncompressed_len; +static uint64_t compressed_len; + +#if DO_ZSTD + +static ZSTD_CStream *state; + +static ZSTD_inBuffer input = { + .src = buffer_in, + .size = sizeof(buffer_in), + .pos = sizeof(buffer_in), +}; + +static ZSTD_outBuffer output = { + .dst = buffer_out, + .size = sizeof(buffer_out), + .pos = sizeof(buffer_out), +}; + +#endif /* DO_ZSTD */ + +#if DO_ZLIB + +static z_stream state = { + .next_in = buffer_in, + .avail_in = 0, + .total_in = 0, + + .next_out = buffer_out, + .avail_out = sizeof(buffer_out), + .total_out = 0, + + .msg = NULL, + .state = NULL, + .workspace = NULL, +}; + +#endif /* DO_ZLIB */ + +static int zstd_compress_test_open(struct inode *i, struct file *f) +{ + if (device_is_open) + return -EBUSY; + + device_is_open = true; + + uncompressed_len = compressed_len = 0; + +#if DO_ZSTD + if (ZSTD_isError(ZSTD_resetCStream(state, 0))) + return -EIO; +#endif + +#if DO_ZLIB + if (zlib_deflateReset(&state) != Z_OK) + return -EIO; +#endif + + printk(KERN_INFO DEVICE_NAME ": opened\n"); + return 0; +} + +static int zstd_compress_test_release(struct inode *i, struct file *f) +{ + device_is_open = false; + +#if DO_ZSTD + do { + size_t ret; + + output.pos = 0; + ret = ZSTD_endStream(state, &output); + if (ZSTD_isError(ret)) { + printk(KERN_INFO DEVICE_NAME ": zstd end error %u\n", ZSTD_getErrorCode(ret)); + return -EIO; + } + compressed_len += output.pos; + } while (output.pos != output.size); +#endif + +#if DO_ZLIB + for (;;) { + int ret; + + state.next_out = buffer_out; + state.avail_out = sizeof(buffer_out); + ret = zlib_deflate(&state, Z_FINISH); + compressed_len += sizeof(buffer_out) - state.avail_out; + if (ret == Z_STREAM_END) + break; + if (ret != Z_OK) { + printk(KERN_INFO DEVICE_NAME ": zlib end error %d: %s\n", ret, state.msg); + return -EIO; + } + } +#endif + + printk(KERN_INFO DEVICE_NAME ": uncompressed_len = %llu\n", uncompressed_len); + printk(KERN_INFO DEVICE_NAME ": compressed_len = %llu\n", compressed_len); + printk(KERN_INFO DEVICE_NAME ": closed\n"); + return 0; +} + +/* + * Hash the data given to us from userspace. + */ +static ssize_t zstd_compress_test_write(struct file *file, + const char __user *buf, size_t size, loff_t *pos) +{ + size_t remaining = size; + + while (remaining > 0) { + size_t const copy_size = min(remaining, sizeof(buffer_in)); + + if (copy_from_user(buffer_in, buf, copy_size)) + return -EFAULT; + buf += copy_size; + remaining -= copy_size; + uncompressed_len += copy_size; + +#if DO_ZSTD + input.pos = 0; + input.size = copy_size; + while (input.pos != input.size) { + size_t ret; + + output.pos = 0; + ret = ZSTD_compressStream(state, &output, &input); + if (ZSTD_isError(ret)) { + printk(KERN_INFO DEVICE_NAME ": zstd compress error %u\n", ZSTD_getErrorCode(ret)); + return -EIO; + } + compressed_len += output.pos; + } +#endif +#if DO_ZLIB + state.next_in = buffer_in; + state.avail_in = copy_size; + while (state.avail_in > 0) { + int ret; + + state.next_out = buffer_out; + state.avail_out = sizeof(buffer_out); + ret = zlib_deflate(&state, Z_NO_FLUSH); + compressed_len += sizeof(buffer_out) - state.avail_out; + if (ret != Z_OK) { + printk(KERN_INFO DEVICE_NAME ": zlib end error %d: %s\n", ret, state.msg); + return -EIO; + } + } +#endif + } + return size; +} +/* register the character device. */ +static int __init zstd_compress_test_init(void) +{ + static const struct file_operations fileops = { + .owner = THIS_MODULE, + .open = &zstd_compress_test_open, + .release = &zstd_compress_test_release, + .write = &zstd_compress_test_write + }; + size_t workspace_size = 0; +#if DO_ZSTD + ZSTD_parameters params; +#endif + + device_major = register_chrdev(0, DEVICE_NAME, &fileops); + if (device_major < 0) { + return device_major; + } + +#if DO_ZSTD + params = ZSTD_getParams(DO_ZSTD, 0, 0); + workspace_size = ZSTD_CStreamWorkspaceBound(params.cParams); + + if (!(workspace = vmalloc(workspace_size))) + goto fail; + if (!(state = ZSTD_initCStream(params, 0, workspace, workspace_size))) + goto fail; +#endif + +#if DO_ZLIB + workspace_size = zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL); + + if (!(workspace = vmalloc(workspace_size))) + goto fail; + state.workspace = workspace; + if (zlib_deflateInit(&state, DO_ZLIB) != Z_OK) + goto fail; +#endif + + printk(KERN_INFO DEVICE_NAME ": module loaded\n"); + printk(KERN_INFO DEVICE_NAME ": compression requires %zu bytes of memory\n", workspace_size); + printk(KERN_INFO DEVICE_NAME ": Create a device node with " + "'mknod " DEVICE_NAME " c %d 0' and write data " + "to it.\n", device_major); + return 0; + +fail: + printk(KERN_INFO DEVICE_NAME ": failed to load module\n"); + if (workspace) { + vfree(workspace); + workspace = NULL; + } + return -ENOMEM; +} + +static void __exit zstd_compress_test_exit(void) +{ + unregister_chrdev(device_major, DEVICE_NAME); +#if DO_ZLIB + zlib_deflateEnd(&state); +#endif + if (workspace) { + vfree(workspace); + workspace = NULL; + } + printk(KERN_INFO DEVICE_NAME ": module unloaded\n"); +} + +module_init(zstd_compress_test_init); +module_exit(zstd_compress_test_exit); + +MODULE_DESCRIPTION("Zstd compression tester"); +MODULE_VERSION("1.0"); + +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/contrib/linux-kernel/zstd_decompress_test.c b/contrib/linux-kernel/zstd_decompress_test.c new file mode 100644 index 000000000..4905a5ac5 --- /dev/null +++ b/contrib/linux-kernel/zstd_decompress_test.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. This program is dual-licensed; you may select + * either version 2 of the GNU General Public License ("GPL") or BSD license + * ("BSD"). + */ + +/* Compression level or 0 to disable */ +#define DO_ZLIB 1 +/* Compression level or 0 to disable */ +#define DO_ZSTD 0 +/* Buffer size */ +#define BUFFER_SIZE 4096 + +#include +#include +#include +#include +#include + +#if DO_ZSTD +#include +#endif + +#if DO_ZLIB +#include +#endif + +/* Device name to pass to register_chrdev(). */ +#define DEVICE_NAME "zstd_decompress_test" + +/* Dynamically allocated device major number */ +static int device_major; + +/* + * We reuse the same state, and thus can compress only one file at a time. + */ +static bool device_is_open; + + +static void *workspace = NULL; + +/* + * Input buffer used to put data coming from userspace. + */ +static uint8_t buffer_in[BUFFER_SIZE]; +static uint8_t buffer_out[BUFFER_SIZE]; + +static uint64_t uncompressed_len; +static uint64_t compressed_len; + +#if DO_ZSTD + +static ZSTD_DStream *state; + +static ZSTD_inBuffer input = { + .src = buffer_in, + .size = sizeof(buffer_in), + .pos = sizeof(buffer_in), +}; + +static ZSTD_outBuffer output = { + .dst = buffer_out, + .size = sizeof(buffer_out), + .pos = sizeof(buffer_out), +}; + +#endif /* DO_ZSTD */ + +#if DO_ZLIB + +static z_stream state = { + .next_in = buffer_in, + .avail_in = 0, + .total_in = 0, + + .next_out = buffer_out, + .avail_out = sizeof(buffer_out), + .total_out = 0, + + .msg = NULL, + .state = NULL, + .workspace = NULL, +}; + +#endif /* DO_ZLIB */ + +static int zstd_decompress_test_open(struct inode *i, struct file *f) +{ + if (device_is_open) + return -EBUSY; + + device_is_open = true; + + uncompressed_len = compressed_len = 0; + +#if DO_ZSTD + if (ZSTD_isError(ZSTD_resetDStream(state))) + return -EIO; +#endif + +#if DO_ZLIB + if (zlib_inflateReset(&state) != Z_OK) + return -EIO; +#endif + + printk(KERN_INFO DEVICE_NAME ": opened\n"); + return 0; +} + +static int zstd_decompress_test_release(struct inode *i, struct file *f) +{ + device_is_open = false; + + printk(KERN_INFO DEVICE_NAME ": uncompressed_len = %llu\n", uncompressed_len); + printk(KERN_INFO DEVICE_NAME ": compressed_len = %llu\n", compressed_len); + printk(KERN_INFO DEVICE_NAME ": closed\n"); + return 0; +} + +/* + * Hash the data given to us from userspace. + */ +static ssize_t zstd_decompress_test_write(struct file *file, + const char __user *buf, size_t size, loff_t *pos) +{ + size_t remaining = size; + + while (remaining > 0) { + size_t const copy_size = min(remaining, sizeof(buffer_in)); + + if (copy_from_user(buffer_in, buf, copy_size)) + return -EFAULT; + buf += copy_size; + remaining -= copy_size; + compressed_len += copy_size; + +#if DO_ZSTD + input.pos = 0; + input.size = copy_size; + while (input.pos != input.size) { + size_t ret; + + output.pos = 0; + ret = ZSTD_decompressStream(state, &output, &input); + if (ZSTD_isError(ret)) { + printk(KERN_INFO DEVICE_NAME ": zstd decompress error %u\n", ZSTD_getErrorCode(ret)); + return -EIO; + } + uncompressed_len += output.pos; + } +#endif +#if DO_ZLIB + state.next_in = buffer_in; + state.avail_in = copy_size; + while (state.avail_in > 0) { + int ret; + + state.next_out = buffer_out; + state.avail_out = sizeof(buffer_out); + ret = zlib_inflate(&state, Z_NO_FLUSH); + uncompressed_len += sizeof(buffer_out) - state.avail_out; + if (ret != Z_OK && ret != Z_STREAM_END) { + printk(KERN_INFO DEVICE_NAME ": zlib decompress error %d: %s\n", ret, state.msg); + return -EIO; + } + } +#endif + } + return size; +} +/* register the character device. */ +static int __init zstd_decompress_test_init(void) +{ + static const struct file_operations fileops = { + .owner = THIS_MODULE, + .open = &zstd_decompress_test_open, + .release = &zstd_decompress_test_release, + .write = &zstd_decompress_test_write + }; + size_t workspace_size = 0; +#if DO_ZSTD + ZSTD_parameters params; + size_t max_window_size; +#endif + + device_major = register_chrdev(0, DEVICE_NAME, &fileops); + if (device_major < 0) { + return device_major; + } + +#if DO_ZSTD + params = ZSTD_getParams(DO_ZSTD, 0, 0); + max_window_size = (size_t)1 << params.cParams.windowLog; + workspace_size = ZSTD_DStreamWorkspaceBound(max_window_size); + + if (!(workspace = vmalloc(workspace_size))) + goto fail; + if (!(state = ZSTD_initDStream(max_window_size, workspace, workspace_size))) + goto fail; +#endif + +#if DO_ZLIB + workspace_size = zlib_inflate_workspacesize(); + + if (!(workspace = vmalloc(workspace_size))) + goto fail; + state.workspace = workspace; + if (zlib_inflateInit(&state) != Z_OK) + goto fail; +#endif + + printk(KERN_INFO DEVICE_NAME ": module loaded\n"); + printk(KERN_INFO DEVICE_NAME ": decompression requires %zu bytes of memory\n", workspace_size); + printk(KERN_INFO DEVICE_NAME ": Create a device node with " + "'mknod " DEVICE_NAME " c %d 0' and write data " + "to it.\n", device_major); + return 0; + +fail: + printk(KERN_INFO DEVICE_NAME ": failed to load module\n"); + if (workspace) { + vfree(workspace); + workspace = NULL; + } + return -ENOMEM; +} + +static void __exit zstd_decompress_test_exit(void) +{ + unregister_chrdev(device_major, DEVICE_NAME); +#if DO_ZLIB + zlib_deflateEnd(&state); +#endif + if (workspace) { + vfree(workspace); + workspace = NULL; + } + printk(KERN_INFO DEVICE_NAME ": module unloaded\n"); +} + +module_init(zstd_decompress_test_init); +module_exit(zstd_decompress_test_exit); + +MODULE_DESCRIPTION("Zstd decompression tester"); +MODULE_VERSION("1.0"); + +MODULE_LICENSE("Dual BSD/GPL"); From cb2dbe64349ceb134ebd29a7852aed64393748a1 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 09:35:21 -0700 Subject: [PATCH 257/400] changed fileInfo initialization, updated error code --- programs/fileio.c | 18 ++++++------------ programs/zstdcli.c | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index f46986d0a..780ddbf13 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -867,7 +867,7 @@ typedef struct { int numActualFrames; int numSkippableFrames; unsigned long long decompressedSize; - int canComputeDecompSize; + int decompUnavailable; unsigned long long compressedSize; int usesCheck; } fileInfo_t; @@ -903,7 +903,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ if (magicNumber == ZSTD_MAGICNUMBER) { U64 const frameContentSize = ZSTD_getFrameContentSize(headerBuffer, numBytesRead); if (frameContentSize == ZSTD_CONTENTSIZE_ERROR || frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN) { - info->canComputeDecompSize = 0; + info->decompUnavailable = 1; } else { info->decompressedSize += frameContentSize; @@ -1008,7 +1008,7 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); const char* checkString = (info->usesCheck ? "XXH64" : "None"); if (displayLevel <= 2) { - if (info->canComputeDecompSize) { + if (!info->decompUnavailable) { double const ratio = (info->decompressedSize == 0) ? 0.0 : compressedSizeMB/decompressedSizeMB; DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %s %s\n", @@ -1025,7 +1025,7 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev DISPLAYOUT("# Zstandard Frames: %d\n", info->numActualFrames); DISPLAYOUT("# Skippable Frames: %d\n", info->numSkippableFrames); DISPLAYOUT("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize); - if (info->canComputeDecompSize) { + if (!info->decompUnavailable) { DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAYOUT("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } @@ -1038,15 +1038,9 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev } int FIO_listFile(const char* inFileName, int displayLevel){ - fileInfo_t info; - /* initialize info to avoid warnings */ - info.numActualFrames = 0; - info.numSkippableFrames = 0; - info.decompressedSize = 0; - info.canComputeDecompSize = 1; - info.compressedSize = 0; - info.usesCheck = 0; + fileInfo_t info; + memset(&info, 0, sizeof(info)); DISPLAYOUT("File: %s\n", inFileName); { int const error = getFileInfo(&info, inFileName); diff --git a/programs/zstdcli.c b/programs/zstdcli.c index a55640351..2b0419b0c 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -688,8 +688,8 @@ int main(int argCount, const char* argv[]) { int error = 0; unsigned u; - for(u=0; u Date: Tue, 20 Jun 2017 09:50:28 -0700 Subject: [PATCH 258/400] changed computation for readability --- tests/decodecorpus.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 74252d562..fd983136f 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -323,7 +323,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame, dictInfo info) if (!singleSegment) { op[pos++] = windowByte; } - if(info.useDict) { + if (info.useDict) { MEM_writeLE32(op + pos, (U32) info.dictID); pos += 4; } @@ -697,11 +697,14 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, } } while (((!info.useDict) && (offset > (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) || offset == 0); - { size_t j; + { + size_t j; + BYTE* const dictEnd = info.dictContent + info.dictContentSize; for (j = 0; j < matchLen; j++) { if ((void*)(srcPtr - offset) < (void*)frame->srcStart) { /* copy from dictionary instead of literals */ - *srcPtr = *(info.dictContent + info.dictContentSize - (offset-(srcPtr-(BYTE*)frame->srcStart))); + size_t dictOffset = offset - (srcPtr - (BYTE*)frame->srcStart); + *srcPtr = *(dictEnd - dictOffset); } else { *srcPtr = *(srcPtr-offset); From b8237c6c66fe5da4a345c41623549d3ecd8dc323 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:12:13 -0700 Subject: [PATCH 259/400] refactoring for readability --- tests/decodecorpus.c | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index fd983136f..5577b5948 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1166,61 +1166,60 @@ static U32 generateFrame(U32 seed, frame_t* fr, dictInfo info) *********************************************************/ /* returns 0 if successful, otherwise returns 1 upon error */ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){ - const size_t headerSize = dictSize/4; - const size_t dictContentSize = dictSize - dictSize/4; - BYTE* const dictContent = fullDict + headerSize; - - /* use 3/4 of dictionary for content, save rest for header/entropy tables */ - if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) { - DISPLAY("Error: dictionary size is too small\n"); + /* allocate space for samples */ + unsigned const numSamples = 4; + BYTE* const samples = malloc(5000*sizeof(BYTE)); + size_t* const sampleSizes = malloc(numSamples*sizeof(size_t)); + if (samples == NULL || sampleSizes == NULL) { + DISPLAY("Error: could not allocate space for samples.\n"); return 1; } - /* fill in dictionary content */ - RAND_buffer(&seed, (void*)dictContent, dictContentSize); - - /* allocate space for samples */ + /* generate samples */ { + unsigned i = 1; + size_t currSize = 1; + BYTE* curr = samples; + while (i <= 4) { + *(sampleSizes + i - 1) = currSize; + { + size_t j; + for (j = 0; j < currSize; j++) { + *(curr++) = (BYTE)i; + } + } + i++; + currSize *= 16; + } + } + + + { + /* create variables */ size_t dictWriteSize = 0; - unsigned const numSamples = 4; - BYTE* const samples = malloc(5000*sizeof(BYTE)); - size_t* const sampleSizes = malloc(numSamples*sizeof(size_t)); - if (samples == NULL || sampleSizes == NULL) { - DISPLAY("Error: could not generate samples for the dictionary.\n"); + ZDICT_params_t zdictParams; + size_t const headerSize = dictSize/4; + size_t const dictContentSize = dictSize - dictSize/4; + BYTE* const dictContent = fullDict + headerSize; + if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) { + DISPLAY("Error: dictionary size is too small\n"); return 1; } - /* generate samples */ - { - unsigned i = 1; - size_t currSize = 1; - BYTE* curr = samples; - while (i <= 4) { - *(sampleSizes + i - 1) = currSize; - { - size_t j; - for (j = 0; j < currSize; j++) { - *(curr++) = (BYTE)i; - } - } - i++; - currSize *= 16; - } - } + /* init dictionary params */ + memset(&zdictParams, 0, sizeof(zdictParams)); + zdictParams.dictID = dictID; + zdictParams.notificationLevel = 1; - /* set dictionary params */ - { - ZDICT_params_t zdictParams; - memset(&zdictParams, 0, sizeof(zdictParams)); - zdictParams.dictID = dictID; - zdictParams.notificationLevel = 1; + /* fill in dictionary content */ + RAND_buffer(&seed, (void*)dictContent, dictContentSize); + + /* finalize dictionary with random samples */ + dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, + dictContent, dictContentSize, + samples, sampleSizes, numSamples, + zdictParams); - /* finalize dictionary with random samples */ - dictWriteSize = ZDICT_finalizeDictionary(fullDict, dictSize, - dictContent, dictContentSize, - samples, sampleSizes, numSamples, - zdictParams); - } free(samples); free(sampleSizes); if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) { @@ -1228,6 +1227,7 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){ return 1; } } + return 0; } From 551fb7ca056e8b8325ff3768fcb46e885a39c1ea Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:14:03 -0700 Subject: [PATCH 260/400] changed error condition --- tests/decodecorpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 5577b5948..c0770fefc 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1222,7 +1222,7 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){ free(samples); free(sampleSizes); - if (dictWriteSize != dictSize && ZDICT_isError(dictWriteSize)) { + if (ZDICT_isError(dictWriteSize)) { DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize)); return 1; } From ff5589c091baf46f987f56ce726bd761cabbabd7 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:17:38 -0700 Subject: [PATCH 261/400] added comments for clarity --- tests/decodecorpus.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index c0770fefc..074ac5931 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1305,6 +1305,7 @@ cleanup: static size_t testDecodeWithDict(U32 seed, size_t dictSize) { + /* create variables */ U32 const dictID = RAND(&seed); size_t errorDetected = 0; BYTE* const fullDict = malloc(dictSize); @@ -1312,6 +1313,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize) return ERROR(GENERIC); } + /* generate random dictionary */ { int ret = genRandomDict(dictID, seed, dictSize, fullDict); if (ret != 0) { @@ -1319,8 +1321,12 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize) goto dictTestCleanup; } } + + { frame_t fr; + + /* generate frame */ { size_t const dictContentSize = dictSize-dictSize/4; BYTE* const dictContent = fullDict+dictSize/4; @@ -1328,6 +1334,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize) seed = generateFrame(seed, &fr, info); } + /* manually decompress and check difference */ { ZSTD_DCtx* const dctx = ZSTD_createDCtx(); { From 15102069a1b6af495b15c9f35cd7261d2f78fd71 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:25:16 -0700 Subject: [PATCH 262/400] removed testing code from generation code --- tests/decodecorpus.c | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 074ac5931..8c048f478 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1519,7 +1519,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const frame_t fr; DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); { - size_t dictContentSize = dictSize-dictSize/4; + size_t const dictContentSize = dictSize-dictSize/4; BYTE* const dictContent = fullDict+dictSize/4; dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID); seed = generateFrame(seed, &fr, info); @@ -1539,39 +1539,6 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const } outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath); } - - /* check the output to make sure that decompressed versions match official zstd */ - { - ZSTD_DCtx* const dctx = ZSTD_createDCtx(); - BYTE* const decompressedPtr = malloc(MAX_DECOMPRESSED_SIZE); - if (decompressedPtr == NULL) { - DISPLAY("Error: could not allocate memory for decompressed pointer\n"); - errorDetected = 1; - goto dictCleanup; - } - { - size_t const returnValue = ZSTD_decompress_usingDict(dctx, decompressedPtr, MAX_DECOMPRESSED_SIZE, - fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, - fullDict, dictSize); - if (ZSTD_isError(returnValue)) { - DISPLAY("Error: %s\n", ZSTD_getErrorName(returnValue)); - } - } - - /* print differences if any */ - { - size_t checkDiff = (BYTE*)fr.src - (BYTE*)fr.srcStart; - { - size_t i; - for (i = 0; i < checkDiff; i++) { - if (*((BYTE*)(fr.srcStart + i)) != *((BYTE*)(decompressedPtr + i))) { - DISPLAY("i: %zu, fr: %u, decomp: %u\n", i, *((BYTE*)(fr.srcStart + i)), *((BYTE*)(decompressedPtr + i))); - } - } - } - } - free(decompressedPtr); - } } } From 36e14b196373097b6ad813db6b500f83f43384a9 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:34:34 -0700 Subject: [PATCH 263/400] added description to advanced usage, changed to use-dict --- tests/decodecorpus.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 8c048f478..0e6630cd1 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1592,6 +1592,7 @@ static void advancedUsage(const char* programName) DISPLAY( "\n"); DISPLAY( "Advanced arguments :\n"); DISPLAY( " --content-size : always include the content size in the frame header\n"); + DISPLAY( " --use-dict # : include a dictionary used to decompress the corpus\n"); } int main(int argc, char** argv) @@ -1665,8 +1666,8 @@ int main(int argc, char** argv) argument++; if (strcmp(argument, "content-size") == 0) { opts.contentSize = 1; - } else if (strcmp(argument, "train-dict") == 0) { - argument += 11; + } else if (strcmp(argument, "use-dict") == 0) { + argument += 9; dictSize = readInt(&argument); useDict = 1; } else { From 6a99de2dd8842fadd5869f41c2f25a558c80f3bd Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 10:45:06 -0700 Subject: [PATCH 264/400] change test to list info on .zst files --- tests/playTests.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 6b794f6d4..07d63e300 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -543,20 +543,20 @@ $ECHO "\n**** zstd --list/-l single frame tests ****" ./datagen > tmp3 ./datagen > tmp4 $ZSTD tmp* -$ZSTD -l tmp* -$ZSTD -lv tmp* -$ZSTD --list tmp* -$ZSTD --list -v tmp* +$ZSTD -l *.zst +$ZSTD -lv *.zst +$ZSTD --list *.zst +$ZSTD --list -v *.zst $ECHO "\n**** zstd --list/-l multiple frame tests ****" cat tmp1.zst tmp2.zst > tmp12.zst cat tmp3.zst tmp4.zst > tmp34.zst cat tmp12.zst tmp34.zst > tmp1234.zst cat tmp12.zst tmp4.zst > tmp124.zst -$ZSTD -l tmp* -$ZSTD -lv tmp* -$ZSTD --list tmp* -$ZSTD --list -v tmp* +$ZSTD -l *.zst +$ZSTD -lv *.zst +$ZSTD --list *.zst +$ZSTD --list -v *.zst rm tmp* From 0034129270e6d48d2b02336bb57043cb77366787 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:07:38 -0700 Subject: [PATCH 265/400] made changes to accommodate single file use case --- tests/decodecorpus.c | 45 ++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 0e6630cd1..09710c379 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1505,17 +1505,22 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const } /* write out dictionary */ - if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { - DISPLAY("Error: dictionary path too long\n"); - errorDetected = 1; - goto dictCleanup; + if (numFiles != 0) { + if (snprintf(outPath, MAX_PATH, "%s/dictionary", path) + 1 > MAX_PATH) { + DISPLAY("Error: dictionary path too long\n"); + errorDetected = 1; + goto dictCleanup; + } + outputBuffer(fullDict, dictSize, outPath); + } + else { + outputBuffer(fullDict, dictSize, "dictionary"); } - outputBuffer(fullDict, dictSize, outPath); /* generate random compressed/decompressed files */ { unsigned fnum; - for (fnum = 0; fnum < numFiles; fnum++) { + for (fnum = 0; fnum < MAX(numFiles, 1); fnum++) { frame_t fr; DISPLAYUPDATE("\r%u/%u ", fnum, numFiles); { @@ -1524,20 +1529,29 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID); seed = generateFrame(seed, &fr, info); } - if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { - DISPLAY("Error: path too long\n"); - errorDetected = 1; - goto dictCleanup; - } - outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath); - if (origPath) { - if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) { + if (numFiles != 0) { + if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) { DISPLAY("Error: path too long\n"); errorDetected = 1; goto dictCleanup; } - outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath); + outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, outPath); + + if (origPath) { + if (snprintf(outPath, MAX_PATH, "%s/z%06u", origPath, fnum) + 1 > MAX_PATH) { + DISPLAY("Error: path too long\n"); + errorDetected = 1; + goto dictCleanup; + } + outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, outPath); + } + } + else { + outputBuffer(fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, path); + if (origPath) { + outputBuffer(fr.srcStart, (BYTE*)fr.src - (BYTE*)fr.srcStart, origPath); + } } } } @@ -1707,7 +1721,6 @@ int main(int argc, char** argv) return generateCorpus(seed, numFiles, path, origPath); } else { /* should generate files with a dictionary */ - numFiles = (numFiles == 0) ? 1 : numFiles; return generateCorpusWithDict(seed, numFiles, path, origPath, dictSize); } From 1e0d125e7640b5f71b9facfefe321c8459a8c63d Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:15:26 -0700 Subject: [PATCH 266/400] const value --- tests/decodecorpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 09710c379..0c674014b 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -314,7 +314,7 @@ static void writeFrameHeader(U32* seed, frame_t* frame, dictInfo info) pos += 4; { - int dictBits = info.useDict ? 3 : 0; + int const dictBits = info.useDict ? 3 : 0; BYTE const frameHeaderDescriptor = (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2) | dictBits); op[pos++] = frameHeaderDescriptor; From 43ffcdde4044b2f95d86dea50aeb7228c089b189 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:27:39 -0700 Subject: [PATCH 267/400] const dictOffset --- tests/decodecorpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 0c674014b..f61d43884 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -703,7 +703,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore, for (j = 0; j < matchLen; j++) { if ((void*)(srcPtr - offset) < (void*)frame->srcStart) { /* copy from dictionary instead of literals */ - size_t dictOffset = offset - (srcPtr - (BYTE*)frame->srcStart); + size_t const dictOffset = offset - (srcPtr - (BYTE*)frame->srcStart); *srcPtr = *(dictEnd - dictOffset); } else { From bed0dc95bcf01417f0c75dc4403ba750566c034c Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:47:24 -0700 Subject: [PATCH 268/400] changed displayInfo alignment and const --- programs/fileio.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 780ddbf13..f49273271 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1006,18 +1006,18 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){ double const compressedSizeMB = (double)info->compressedSize/(1 MB); double const decompressedSizeMB = (double)info->decompressedSize/(1 MB); - const char* checkString = (info->usesCheck ? "XXH64" : "None"); + const char* const checkString = (info->usesCheck ? "XXH64" : "None"); if (displayLevel <= 2) { if (!info->decompUnavailable) { double const ratio = (info->decompressedSize == 0) ? 0.0 : compressedSizeMB/decompressedSizeMB; DISPLAYOUT("Skippable Non-Skippable Compressed Uncompressed Ratio Check Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %s %s\n", + DISPLAYOUT("%9d %13d %7.2f MB %9.2f MB %5.3f %5s %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB, ratio, checkString, inFileName); } else { DISPLAYOUT("Skippable Non-Skippable Compressed Check Filename\n"); - DISPLAYOUT("%9d %13d %7.2f MB %s %s\n", + DISPLAYOUT("%9d %13d %7.2f MB %5s %s\n", info->numSkippableFrames, info->numActualFrames, compressedSizeMB, checkString, inFileName); } } @@ -1029,12 +1029,9 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize); DISPLAYOUT("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB); } - if (info->usesCheck) { - DISPLAYOUT("Check: XXH64\n"); - } + DISPLAYOUT("Check: %s\n", checkString); + DISPLAYOUT("\n"); } - - DISPLAYOUT("\n"); } int FIO_listFile(const char* inFileName, int displayLevel){ @@ -1049,7 +1046,10 @@ int FIO_listFile(const char* inFileName, int displayLevel){ DISPLAY("An error occurred with getting file info\n"); } else if (error == 2) { - DISPLAYOUT("File %s not compressed with zstd\n\n", inFileName); + DISPLAYOUT("File %s not compressed with zstd\n", inFileName); + if (displayLevel > 2) { + DISPLAYOUT("\n"); + } return 1; } displayInfo(inFileName, &info, displayLevel); From b07d0af2baa2197a12e30af855c1ea2cbdb4f58e Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:54:44 -0700 Subject: [PATCH 269/400] added additional tests for error detection --- tests/playTests.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index 07d63e300..0fa6a7219 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -558,6 +558,12 @@ $ZSTD -lv *.zst $ZSTD --list *.zst $ZSTD --list -v *.zst +$ECHO "\n**** zstd --list/-l error detection tests ****" +!$ZSTD -l tmp1 tmp1.zst +!$ZSTD --list tmp* +!$ZSTD -lv tmp1* +!$ZSTD --list -v tmp2 tmp23.zst + rm tmp* if [ "$1" != "--test-large-data" ]; then From cea55a9217530b1b2888836c334194c960c77523 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:56:11 -0700 Subject: [PATCH 270/400] size_t const value --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index f49273271..342325465 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -933,7 +933,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ BYTE blockHeaderBuffer[3]; U32 blockHeader; int blockSize; - size_t readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); + size_t const readBytes = fread(blockHeaderBuffer, 1, 3, srcFile); if (readBytes != 3) { DISPLAY("There was a problem reading the block header\n"); detectError = 1; From 72e0ac9929b97f2711d08f9155c1211f7aed634c Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:58:27 -0700 Subject: [PATCH 271/400] minor update to logic --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 342325465..533b2250a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -941,7 +941,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } blockHeader = MEM_readLE24(blockHeaderBuffer); lastBlock = blockHeader & 1; - blockSize = (blockHeader - (blockHeader & 7)) >> 3; + blockSize = blockHeader >> 3; { int const ret = fseek(srcFile, blockSize, SEEK_CUR); if (ret != 0) { From c594507871efe3d89a6cfe26d69444e7c13f2a31 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 11:59:45 -0700 Subject: [PATCH 272/400] removed double if statements for same condition --- programs/fileio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 533b2250a..3964f0f97 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -960,11 +960,9 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ /* check if checksum is used */ BYTE const frameHeaderDescriptor = headerBuffer[4]; int const contentChecksumFlag = (frameHeaderDescriptor & (1 << 2)) >> 2; - if (contentChecksumFlag) { - info->usesCheck = 1; - } if (contentChecksumFlag) { int const ret = fseek(srcFile, 4, SEEK_CUR); + info->usesCheck = 1; if (ret != 0) { DISPLAY("Error: could not skip past checksum\n"); detectError = 1; From ff8f83bd47d3e10152be2f622cfedf7c905c9881 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 12:17:32 -0700 Subject: [PATCH 273/400] fixed fuzzer test --- tests/fuzzer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fuzzer.c b/tests/fuzzer.c index ee0aff08c..96336423c 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -420,6 +420,7 @@ static int basicUnitTests(U32 seed, double compressibility) size_t const r = ZSTD_decompress_usingDDict(dctx, decodedBuffer, CNBuffSize, compressedBuffer, cSize, ddict); if (r != CNBuffSize - dictSize) goto _output_error; } + free(ddictBuffer); DISPLAYLEVEL(4, "OK (size of static DDict : %u) \n", (U32)ddictBufferSize); } From bda57754a2bed5845c583906f6def2486988e1fd Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 12:43:10 -0700 Subject: [PATCH 274/400] moved signifcant operations to fileio.c --- programs/fileio.c | 22 +++++++++++++++++++++- programs/fileio.h | 2 +- programs/zstdcli.c | 19 ++----------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 3964f0f97..059823952 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1032,7 +1032,8 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev } } -int FIO_listFile(const char* inFileName, int displayLevel){ + +static int FIO_listFile(const char* inFileName, int displayLevel){ /* initialize info to avoid warnings */ fileInfo_t info; memset(&info, 0, sizeof(info)); @@ -1055,6 +1056,25 @@ int FIO_listFile(const char* inFileName, int displayLevel){ } } +int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int displayLevel){ + if (numFiles == 0) { + DISPLAYOUT("No files given\n"); + return 0; + } + DISPLAYOUT("===========================================\n"); + DISPLAYOUT("Printing information about compressed files\n"); + DISPLAYOUT("===========================================\n"); + DISPLAYOUT("Number of files listed: %u\n", numFiles); + { + int error = 0; + unsigned u; + for (u=0; u Date: Tue, 20 Jun 2017 13:26:25 -0700 Subject: [PATCH 275/400] added progress metric to display --- programs/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 059823952..93ec3f181 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1033,11 +1033,11 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev } -static int FIO_listFile(const char* inFileName, int displayLevel){ +static int FIO_listFile(const char* inFileName, int displayLevel, unsigned fileNo, unsigned numFiles){ /* initialize info to avoid warnings */ fileInfo_t info; memset(&info, 0, sizeof(info)); - DISPLAYOUT("File: %s\n", inFileName); + DISPLAYOUT("%s (%u/%u):\n", inFileName, fileNo, numFiles); { int const error = getFileInfo(&info, inFileName); if (error == 1) { @@ -1069,7 +1069,7 @@ int FIO_listMultipleFiles(unsigned numFiles, const char** filenameTable, int dis int error = 0; unsigned u; for (u=0; u Date: Tue, 20 Jun 2017 13:44:05 -0700 Subject: [PATCH 276/400] changed to use LONG_SEEK --- programs/fileio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 93ec3f181..37ec7f815 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -982,7 +982,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ } { U32 const frameSize = MEM_readLE32(frameSizeBuffer); - int const ret = fseek(srcFile, (long)frameSize, SEEK_CUR); + int const ret = LONG_SEEK(srcFile, frameSize, SEEK_CUR); if (ret != 0) { DISPLAY("Error: could not find end of skippable frame\n"); detectError = 1; From 076560290346c3f83137c6f10f3d5a33efc234aa Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 14:04:46 -0700 Subject: [PATCH 277/400] fixed error where extremely small files were not being detected as not compressed with zstd --- programs/fileio.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 37ec7f815..bf65ba528 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -889,10 +889,15 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); if (numBytesRead < ZSTD_frameHeaderSize_min) { - if (feof(srcFile)) { + if (feof(srcFile) && numBytesRead == 0) { break; } - else{ + else if (feof(srcFile)) { + DISPLAY("Error: reached end of file with incomplete frame\n"); + detectError = 2; + break; + } + else { DISPLAY("Error: did not reach end of file but ran out of frames\n"); detectError = 1; break; From b44ab82f7ad9c13d0f77d1fb279e4851a3eb47d4 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 14:11:49 -0700 Subject: [PATCH 278/400] ensure new ZSTD_strategy starts at value 1 --- lib/compress/zstd_compress.c | 11 +++++++---- lib/compress/zstdmt_compress.h | 13 +++++++------ programs/zstd.1.md | 4 ++-- programs/zstdcli.c | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f5ac75a95..1df1a4895 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2753,23 +2753,26 @@ static void ZSTD_compressBlock_btultra_extDict(ZSTD_CCtx* ctx, const void* src, } +/* ZSTD_selectBlockCompressor() : + * assumption : strat is a valid strategy */ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize); - static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict) { static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = { - { NULL, + { ZSTD_compressBlock_fast /* default for 0 */, ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btultra }, - { NULL, + { ZSTD_compressBlock_fast_extDict /* default for 0 */, ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btultra_extDict } }; ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1); + assert((U32)strat >= (U32)ZSTD_fast); + assert((U32)strat <= (U32)ZSTD_btultra); - return blockCompressor[extDict][(U32)strat]; + return blockCompressor[extDict!=0][(U32)strat]; } diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h index 8b0ca824f..d36914de5 100644 --- a/lib/compress/zstdmt_compress.h +++ b/lib/compress/zstdmt_compress.h @@ -15,13 +15,15 @@ #endif -/* Note : All prototypes defined in this file must be considered experimental. - * There is no guarantee of API continuity on any of these prototypes */ +/* Note : All prototypes defined in this file are labelled experimental. + * No guarantee of API continuity is provided on any of them. + * In fact, the expectation is that these prototypes will be replaced + * by ZSTD_compress_generic() API in the near future */ /* === Dependencies === */ -#include /* size_t */ +#include /* size_t */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */ -#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */ +#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */ /* === Memory management === */ @@ -32,7 +34,6 @@ ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx); ZSTDLIB_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx); -ZSTDLIB_API size_t ZSTDMT_estimateCCtxSize(ZSTD_compressionParameters cParams, unsigned nbThreads); /* not ready yet */ /* === Simple buffer-to-butter one-pass function === */ @@ -87,7 +88,7 @@ ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter /*! ZSTDMT_compressStream_generic() : * Combines ZSTDMT_compressStream() with ZSTDMT_flushStream() or ZSTDMT_endStream() - * depending on flush directive + * depending on flush directive. * @return : minimum amount of data still to be flushed * 0 if fully flushed * or an error code */ diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 4e731ddba..63830586e 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -251,8 +251,8 @@ The list of available _options_: Specify a strategy used by a match finder. There are 8 strategies numbered from 0 to 7, from faster to stronger: - 0=ZSTD\_fast, 1=ZSTD\_dfast, 2=ZSTD\_greedy, 3=ZSTD\_lazy, - 4=ZSTD\_lazy2, 5=ZSTD\_btlazy2, 6=ZSTD\_btopt, 7=ZSTD\_btultra. + 1=ZSTD\_fast, 2=ZSTD\_dfast, 3=ZSTD\_greedy, 4=ZSTD\_lazy, + 5=ZSTD\_lazy2, 6=ZSTD\_btlazy2, 7=ZSTD\_btopt, 8=ZSTD\_btultra. - `windowLog`=_wlog_, `wlog`=_wlog_: Specify the maximum number of bits for a match distance. diff --git a/programs/zstdcli.c b/programs/zstdcli.c index 32fef9993..f9f6fb56f 100644 --- a/programs/zstdcli.c +++ b/programs/zstdcli.c @@ -298,7 +298,7 @@ static unsigned parseCompressionParameters(const char* stringPtr, ZSTD_compressi if (longCommandWArg(&stringPtr, "searchLog=") || longCommandWArg(&stringPtr, "slog=")) { params->searchLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } if (longCommandWArg(&stringPtr, "searchLength=") || longCommandWArg(&stringPtr, "slen=")) { params->searchLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } if (longCommandWArg(&stringPtr, "targetLength=") || longCommandWArg(&stringPtr, "tlen=")) { params->targetLength = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } - if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(1 + readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } + if (longCommandWArg(&stringPtr, "strategy=") || longCommandWArg(&stringPtr, "strat=")) { params->strategy = (ZSTD_strategy)(readU32FromChar(&stringPtr)); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } if (longCommandWArg(&stringPtr, "overlapLog=") || longCommandWArg(&stringPtr, "ovlog=")) { g_overlapLog = readU32FromChar(&stringPtr); if (stringPtr[0]==',') { stringPtr++; continue; } else break; } return 0; } From 58c19b42026e80e4a09e4f2473045c66e2a87066 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 14:14:53 -0700 Subject: [PATCH 279/400] spacing matters for test scripts --- tests/playTests.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 0fa6a7219..7792a5690 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -559,10 +559,10 @@ $ZSTD --list *.zst $ZSTD --list -v *.zst $ECHO "\n**** zstd --list/-l error detection tests ****" -!$ZSTD -l tmp1 tmp1.zst -!$ZSTD --list tmp* -!$ZSTD -lv tmp1* -!$ZSTD --list -v tmp2 tmp23.zst +! $ZSTD -l tmp1 tmp1.zst +! $ZSTD --list tmp* +! $ZSTD -lv tmp1* +! $ZSTD --list -v tmp2 tmp23.zst rm tmp* From 78b823455441adc67abe4f608e1dfa5dddfbb820 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 14:26:48 -0700 Subject: [PATCH 280/400] fixed comments, following suggestion by @terrelln --- lib/zstd.h | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/lib/zstd.h b/lib/zstd.h index e0c880103..bbfb92d55 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -422,7 +422,7 @@ typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size); typedef void (*ZSTD_freeFunction) (void* opaque, void* address); typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem; /* use this constant to defer to stdlib's functions */ -static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL}; +static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL }; /*************************************** @@ -881,7 +881,6 @@ typedef enum { * Special: value 0 means "do not change cLevel". */ ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. - * default value : set through compressionLevel. * Special: value 0 means "do not change windowLog". */ ZSTD_p_hashLog, /* Size of the probe table, as a power of 2. * Resulting table size is (1 << (hashLog+2)). @@ -974,12 +973,12 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo * Create an internal CDict from dict buffer. * Decompression will have to use same buffer. * @result : 0, or an error code (which can be tested with ZSTD_isError()). - * Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, + * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, * meaning "return to no-dictionary mode". * Note 1 : Dictionary content will be copied internally, * except if ZSTD_p_refDictContent is set. * Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. - * For this reason, compression parameters cannot be changed anymore after loading a prefix. + * For this reason, compression parameters cannot be changed anymore after loading a dictionary. * It's also a CPU-heavy operation, with non-negligible impact on latency. * Note 3 : Dictionary will be used for all future compression jobs. * To return to "no-dictionary" situation, load a NULL dictionary */ @@ -1018,17 +1017,17 @@ typedef enum { ZSTD_e_end /* flush any remaining data and ends current frame. Any future compression starts a new frame. */ } ZSTD_EndDirective; -/*! ZSTD_compressStream_generic() : +/*! ZSTD_compress_generic() : * Behave about the same as ZSTD_compressStream. To note : - * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter() + * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter() * - Compression parameters cannot be changed once compression is started. * - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize * - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. * - @return provides the minimum amount of data still to flush from internal buffers * or an error code, which can be tested using ZSTD_isError(). - * if @return != 0, flush is not fully completed, and must be called again to empty internal buffers. + * if @return != 0, flush is not fully completed, there is some data left within internal buffers. * - after a ZSTD_e_end directive, if internal buffer is not fully flushed, - * only ZSTD_e_end and ZSTD_e_flush operations are allowed. + * only ZSTD_e_end or ZSTD_e_flush operations are allowed. * It is necessary to fully flush internal buffers * before starting a new compression job, or changing compression parameters. */ @@ -1061,26 +1060,6 @@ size_t ZSTD_compress_generic_simpleArgs ( ZSTD_EndDirective endOp); -/* note : this part if completely experimental, not ready yet. - * Main idea is : if ZSTD_parameters is not a good fit for stable API, - * there will be a need for something else. - * While initialising compression is now correctly covered, - * creating an advanced CDict still needs to be solved. - * Below is merely a plan of what it could look like */ -/*! ZSTD_CDict_createEmpty() : - * Create a CDict object which is still mutable after creation. - * It's the only one case allowing usage of ZSTD_CDict_setParameter(). - * Once all compression parameters are selected, - * it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). - * Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). - * After loading the dictionary, no more change is possible. - * The only remaining operation is to free CDict object. - * Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx. - */ -ZSTDLIB_API ZSTD_CDict* ZSTD_CDict_createEmpty(void); /* Not ready yet ! */ -ZSTDLIB_API size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value); /* Not ready yet ! */ -ZSTDLIB_API size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize); /* Not ready yet ! */ - /** Block functions From a73c2a444aa13ef1d2932ae13f565fea71382fa5 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 14:33:08 -0700 Subject: [PATCH 281/400] added tests with null files, changed condition to check that the file is more than 0 bytes --- programs/fileio.c | 2 +- tests/playTests.sh | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index bf65ba528..a5db88a4c 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -889,7 +889,7 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; size_t const numBytesRead = fread(headerBuffer, 1, sizeof(headerBuffer), srcFile); if (numBytesRead < ZSTD_frameHeaderSize_min) { - if (feof(srcFile) && numBytesRead == 0) { + if (feof(srcFile) && numBytesRead == 0 && info->compressedSize > 0) { break; } else if (feof(srcFile)) { diff --git a/tests/playTests.sh b/tests/playTests.sh index 7792a5690..21f79c715 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -564,6 +564,14 @@ $ECHO "\n**** zstd --list/-l error detection tests ****" ! $ZSTD -lv tmp1* ! $ZSTD --list -v tmp2 tmp23.zst +$ECHO "\n**** zstd --list/-l test with null files ****" +./datagen -g0 > tmp5 +$ZSTD tmp5 +! $ZSTD -l tmp5* +! $ZSTD -lv tmp5* +! $ZSTD --list tmp5* +! $ZSTD --list -v tmp5* + rm tmp* if [ "$1" != "--test-large-data" ]; then From ceb4f65620d936f1a80953a3e9c6a128fd05be32 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 15:31:54 -0700 Subject: [PATCH 282/400] allocate statically so we don't have to deal with freeing --- tests/decodecorpus.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index f61d43884..dd2bc562d 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1168,24 +1168,20 @@ static U32 generateFrame(U32 seed, frame_t* fr, dictInfo info) static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){ /* allocate space for samples */ unsigned const numSamples = 4; - BYTE* const samples = malloc(5000*sizeof(BYTE)); - size_t* const sampleSizes = malloc(numSamples*sizeof(size_t)); - if (samples == NULL || sampleSizes == NULL) { - DISPLAY("Error: could not allocate space for samples.\n"); - return 1; - } + BYTE samples[5000]; + size_t sampleSizes[4]; /* generate samples */ { unsigned i = 1; + unsigned j = 0; size_t currSize = 1; - BYTE* curr = samples; while (i <= 4) { - *(sampleSizes + i - 1) = currSize; + sampleSizes[i - 1] = currSize; { - size_t j; - for (j = 0; j < currSize; j++) { - *(curr++) = (BYTE)i; + size_t k; + for (k = 0; k < currSize; k++) { + samples[j++] = (BYTE)i; } } i++; @@ -1220,8 +1216,6 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){ samples, sampleSizes, numSamples, zdictParams); - free(samples); - free(sampleSizes); if (ZDICT_isError(dictWriteSize)) { DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize)); return 1; From 69bc4fab25bec6231f3528f24a969d5e598da7c6 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 15:37:14 -0700 Subject: [PATCH 283/400] free the context object once done with decompression --- tests/decodecorpus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index dd2bc562d..59b2af78a 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1345,6 +1345,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize) errorDetected = ERROR(corruption_detected); goto dictTestCleanup; } + ZSTD_freeDCtx(dctx); } } From acf0df678cf060c11c11821f330dfabb4130a08a Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 15:41:43 -0700 Subject: [PATCH 284/400] fixed strange spacing --- tests/decodecorpus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c index 59b2af78a..2eed515fe 100644 --- a/tests/decodecorpus.c +++ b/tests/decodecorpus.c @@ -1336,8 +1336,8 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize) fr.dataStart, (BYTE*)fr.data - (BYTE*)fr.dataStart, fullDict, dictSize); if (ZSTD_isError(returnValue)) { - errorDetected = returnValue; - goto dictTestCleanup; + errorDetected = returnValue; + goto dictTestCleanup; } } From c3bce24ef4c86f780e94e047f1cbc4ec1963f4ed Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 16:09:11 -0700 Subject: [PATCH 285/400] fixed potential dangling pointer, detected by @terrelln --- lib/common/zstd_internal.h | 1 - lib/compress/zstd_compress.c | 16 ++++++++-------- lib/decompress/zstd_decompress.c | 13 +++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 77f6e5672..611c74f81 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -263,7 +263,6 @@ typedef struct { const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); -int ZSTD_isSkipFrame(ZSTD_DCtx* dctx); /* custom memory allocation functions */ void* ZSTD_malloc(size_t size, ZSTD_customMem customMem); diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 1df1a4895..7c4b526e2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -240,13 +240,13 @@ static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx) cctx->compressionLevel = ZSTD_CLEVEL_CUSTOM; } +#define CLAMPCHECK(val,min,max) { \ + if (((val)<(min)) | ((val)>(max))) { \ + return ERROR(compressionParameter_outOfBound); \ +} } + size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value) { -# define CLAMPCHECK(val,min,max) { \ - if ((valmax)) { \ - return ERROR(compressionParameter_outOfBound); \ - } } - if (cctx->streamStage != zcss_init) return ERROR(stage_wrong); switch(param) @@ -3155,7 +3155,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, } /*! ZSTD_compressBegin_internal() : -* @return : 0, or an error code */ + * @return : 0, or an error code */ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, const ZSTD_CDict* cdict, @@ -3347,10 +3347,10 @@ static size_t ZSTD_initCDict_internal( cdict->dictContent = dictBuffer; } else { void* const internalBuffer = ZSTD_malloc(dictSize, cdict->refContext->customMem); - if (!internalBuffer) return ERROR(memory_allocation); - memcpy(internalBuffer, dictBuffer, dictSize); cdict->dictBuffer = internalBuffer; cdict->dictContent = internalBuffer; + if (!internalBuffer) return ERROR(memory_allocation); + memcpy(internalBuffer, dictBuffer, dictSize); } cdict->dictContentSize = dictSize; diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index aeaa40c1f..98372f94c 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1688,21 +1688,22 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { } } -int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */ +static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /** ZSTD_decompressContinue() : -* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) -* or an error code, which can be tested using ZSTD_isError() */ + * srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress()) + * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity) + * or an error code, which can be tested using ZSTD_isError() */ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { /* Sanity check */ - if (srcSize != dctx->expected) return ERROR(srcSize_wrong); + if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* unauthorized */ if (dstCapacity) ZSTD_checkContinuity(dctx, dst); switch (dctx->stage) { case ZSTDds_getFrameHeaderSize : - if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* impossible */ + if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* unauthorized */ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix); dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */ @@ -1747,7 +1748,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c dctx->stage = ZSTDds_getFrameHeaderSize; } } else { - dctx->expected = 3; /* go directly to next header */ + dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */ dctx->stage = ZSTDds_decodeBlockHeader; } return 0; From 466f92eaa643271ec1b537bc11e47bda5c96c121 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 16:25:29 -0700 Subject: [PATCH 286/400] removed one useless streaming compression stage, detected by @terrelln --- lib/compress/zstd_compress.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 7c4b526e2..e48bc41bd 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -68,7 +68,7 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr) /*-************************************* * Context memory management ***************************************/ -typedef enum { zcss_init=0, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage; +typedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage; struct ZSTD_CDict_s { void* dictBuffer; @@ -3371,7 +3371,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u DEBUGLOG(5, "ZSTD_createCDict_advanced"); if (!customMem.customAlloc ^ !customMem.customFree) return NULL; - { ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem); + { ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem); ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem); if (!cdict || !cctx) { @@ -3588,15 +3588,16 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, return ERROR(memory_allocation); } ZSTD_freeCDict(zcs->cdictLocal); - zcs->cdict = NULL; zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem); - if (zcs->cdictLocal == NULL) return ERROR(memory_allocation); zcs->cdict = zcs->cdictLocal; + if (zcs->cdictLocal == NULL) return ERROR(memory_allocation); } else { if (cdict) { ZSTD_parameters const cdictParams = ZSTD_getParamsFromCDict(cdict); params.cParams = cdictParams.cParams; /* cParams are enforced from cdict */ } + ZSTD_freeCDict(zcs->cdictLocal); + zcs->cdictLocal = NULL; zcs->cdict = cdict; } @@ -3779,9 +3780,6 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, break; } - case zcss_final: - someMoreWork = 0; break; /* useless */ - default: /* impossible */ assert(0); } From db3606e24989be34395559c42862f4130e5e45f3 Mon Sep 17 00:00:00 2001 From: Paul Cruz Date: Tue, 20 Jun 2017 17:43:36 -0700 Subject: [PATCH 287/400] added test for files with no frame content size --- tests/playTests.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index 21f79c715..4eb794b54 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -572,6 +572,14 @@ $ZSTD tmp5 ! $ZSTD --list tmp5* ! $ZSTD --list -v tmp5* +$ECHO "\n**** zstd --list/-l test with no frame content size ****" +echo -n '' > tmp6 +$ZSTD tmp6 +$ZSTD -l tmp6.zst +$ZSTD -lv tmp6.zst +$ZSTD --list tmp6.zst +$ZSTD --list -v tmp6.zst + rm tmp* if [ "$1" != "--test-large-data" ]; then From e51d51bdf7d77b66ea4beb87a52097633147b2a9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 20 Jun 2017 17:44:55 -0700 Subject: [PATCH 288/400] fixed memcpy() overlap --- lib/compress/zstd_compress.c | 5 ++--- lib/decompress/zstd_decompress.c | 11 +++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e48bc41bd..4f1a0bcc4 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -4017,14 +4017,13 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV * Size values are optional, provide 0 if not known or unused */ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) { - ZSTD_compressionParameters cp; size_t const addedSize = srcSizeHint ? 0 : 500; U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : (U64)-1; U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */ if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; - cp = ZSTD_defaultCParameters[tableID][compressionLevel]; - return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); /* no need to ensure initial CParams validity */ + { ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel]; + return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); } } /*! ZSTD_getParams() : diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 98372f94c..51fa244ce 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2306,14 +2306,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB break; } } - /* Consume header */ + /* Consume header (see ZSTDds_decodeFrameHeader) */ CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict)); - { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds); /* == ZSTD_frameHeaderSize_prefix */ - CHECK_F(ZSTD_decompressContinue(zds, NULL, 0, zds->headerBuffer, h1Size)); - { size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds); - CHECK_F(ZSTD_decompressContinue(zds, NULL, 0, zds->headerBuffer+h1Size, h2Size)); - } } + CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize)); + zds->expected = ZSTD_blockHeaderSize; + zds->stage = ZSTDds_decodeBlockHeader; + /* control buffer memory usage */ zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); From 7bd1a2900e8e2713cdc9801a9ff81563f39aec9c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 21 Jun 2017 11:50:33 -0700 Subject: [PATCH 289/400] added ZSTD_dictMode_e to control dictionary loading mode --- doc/zstd_manual.html | 47 +++++------ lib/common/zstd_internal.h | 3 +- lib/compress/zstd_compress.c | 125 ++++++++++++++++++++---------- lib/compress/zstdmt_compress.c | 5 +- lib/zstd.h | 29 ++++--- programs/bench.c | 2 +- tests/fuzzer.c | 71 +++++++++++------ tests/zstreamtest.c | 2 +- zlibWrapper/examples/zwrapbench.c | 4 +- 9 files changed, 177 insertions(+), 111 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 88e890793..63704e67e 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -341,7 +341,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB typedef void (*ZSTD_freeFunction) (void* opaque, void* address); typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
    /* use this constant to defer to stdlib's functions */ -static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL}; +static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL };

    Frame size functions

    
     
    @@ -461,14 +461,18 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
       It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict 
     


    -
    ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
    +
    typedef enum { ZSTD_dm_auto=0, ZSTD_dm_rawContent, ZSTD_dm_fullDict } ZSTD_dictMode_e;
    +

    +
    ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
    +                                      unsigned byReference, ZSTD_dictMode_e dictMode,
                                           ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
     

    Create a ZSTD_CDict using external alloc and free, and customized compression parameters


    ZSTD_CDict* ZSTD_initStaticCDict(
                     void* workspace, size_t workspaceSize,
    -          const void* dict, size_t dictSize, unsigned byReference,
    +          const void* dict, size_t dictSize,
    +                unsigned byReference, ZSTD_dictMode_e dictMode,
                     ZSTD_compressionParameters cParams);
     

    Generate a digested dictionary in provided memory area. workspace: The memory area to emplace the dictionary into. @@ -743,7 +747,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); * Special: value 0 means "do not change cLevel". */ ZSTD_p_windowLog, /* Maximum allowed back-reference distance, expressed as power of 2. * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX. - * default value : set through compressionLevel. * Special: value 0 means "do not change windowLog". */ ZSTD_p_hashLog, /* Size of the probe table, as a power of 2. * Resulting table size is (1 << (hashLog+2)). @@ -791,10 +794,10 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); /* dictionary parameters */ ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0). * This avoids duplicating dictionary content. - * But it also requires that dictionary buffer outlives its user (CDict) */ - /* Not ready yet ! */ - ZSTD_p_rawContentDict, /* load dictionary in "content-only" mode (no header analysis) (default:0) */ - /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */ + * But it also requires that dictionary buffer outlives its users */ + /* Not ready yet ! <=================================== */ + ZSTD_p_dictMode, /* Select how dictionary must be interpreted. Value must be from type ZSTD_dictMode_e. + * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */ /* multi-threading parameters */ ZSTD_p_nbThreads=400, /* Select how many threads a compression job can spawn (default:1) @@ -810,7 +813,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); /* advanced parameters - may not remain available after API update */ ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize, - * even when referencing into Dictionary content + * even when referencing into Dictionary content. * default : 0 when using a CDict, 1 when using a Prefix */ } ZSTD_cParameter;


    @@ -835,12 +838,12 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);

    Create an internal CDict from dict buffer. Decompression will have to use same buffer. @result : 0, or an error code (which can be tested with ZSTD_isError()). - Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, + Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, meaning "return to no-dictionary mode". Note 1 : Dictionary content will be copied internally, except if ZSTD_p_refDictContent is set. Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters. - For this reason, compression parameters cannot be changed anymore after loading a prefix. + For this reason, compression parameters cannot be changed anymore after loading a dictionary. It's also a CPU-heavy operation, with non-negligible impact on latency. Note 3 : Dictionary will be used for all future compression jobs. To return to "no-dictionary" situation, load a NULL dictionary @@ -859,7 +862,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);


    -
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! <===================================== */
     

    Reference a prefix (content-only dictionary) to bootstrap next compression job. Decompression will have to use same prefix. Prefix is only used once. Tables are discarded at end of compression job. @@ -882,15 +885,15 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); ZSTD_inBuffer* input, ZSTD_EndDirective endOp);

    Behave about the same as ZSTD_compressStream. To note : - - Compression parameters are pushed into CCtx before starting compression, using ZSTD_setCCtxParameter() + - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter() - Compression parameters cannot be changed once compression is started. - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. - @return provides the minimum amount of data still to flush from internal buffers or an error code, which can be tested using ZSTD_isError(). - if @return != 0, flush is not fully completed, and must be called again to empty internal buffers. + if @return != 0, flush is not fully completed, there is some data left within internal buffers. - after a ZSTD_e_end directive, if internal buffer is not fully flushed, - only ZSTD_e_end and ZSTD_e_flush operations are allowed. + only ZSTD_e_end or ZSTD_e_flush operations are allowed. It is necessary to fully flush internal buffers before starting a new compression job, or changing compression parameters. @@ -918,20 +921,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);


    -
    ZSTD_CDict* ZSTD_CDict_createEmpty(void);   /* Not ready yet ! */
    -size_t ZSTD_CDict_setParameter(ZSTD_CDict* cdict, ZSTD_cParameter param, unsigned value);  /* Not ready yet ! */
    -size_t ZSTD_CDict_loadDictionary(ZSTD_CDict* cdict, const void* dict, size_t dictSize);    /* Not ready yet ! */
    -

    Create a CDict object which is still mutable after creation. - It's the only one case allowing usage of ZSTD_CDict_setParameter(). - Once all compression parameters are selected, - it's possible to load the target dictionary, using ZSTD_CDict_loadDictionary(). - Dictionary content will be copied internally (except if ZSTD_p_refDictContent is set). - After loading the dictionary, no more change is possible. - The only remaining operation is to free CDict object. - Note : An unfinished CDict behaves the same as a NULL CDict if referenced into a CCtx. - -


    -

    Block functions

         Block functions produce and decode raw zstd blocks, without frame metadata.
         Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index 611c74f81..4e216d728 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -305,6 +305,7 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
     
     
     typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
    +#if 0
     /*! ZSTD_compressBegin_internal() :
      *  innermost initialization function. Private use only.
      *  expects params to be valid.
    @@ -315,7 +316,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
                                  const ZSTD_CDict* cdict,
                                        ZSTD_parameters params, U64 pledgedSrcSize,
                                        ZSTD_buffered_policy_e zbuff);
    -
    +#endif
     
     /*! ZSTD_initCStream_internal() :
      *  Private use only. Init streaming operation.
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 4f1a0bcc4..59ac3f35d 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -88,7 +88,7 @@ struct ZSTD_CCtx_s {
         U32   hashLog3;         /* dispatch table : larger == faster, more memory */
         U32   loadedDictEnd;    /* index of end of dictionary */
         U32   forceWindow;      /* force back-references to respect limit of 1<staticSize = workspaceSize;
         cctx->workSpace = (void*)(cctx+1);
         cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
     
         /* entropy space (never moves) */
    -    /* note : this code should be shared with resetCCtx, instead of copied */
    +    /* note : this code should be shared with resetCCtx, rather than copy/pasted */
         {   void* ptr = cctx->workSpace;
             cctx->hufCTable = (HUF_CElt*)ptr;
             ptr = (char*)cctx->hufCTable + hufCTable_size;
    @@ -203,6 +203,10 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
     size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
     {
         if (cctx==NULL) return 0;   /* support sizeof on NULL */
    +    DEBUGLOG(5, "sizeof(*cctx) : %u", (U32)sizeof(*cctx));
    +    DEBUGLOG(5, "workSpaceSize : %u", (U32)cctx->workSpaceSize);
    +    DEBUGLOG(5, "streaming buffers : %u", (U32)(cctx->outBuffSize + cctx->inBuffSize));
    +    DEBUGLOG(5, "inner MTCTX : %u", (U32)ZSTDMT_sizeof_CCtx(cctx->mtctx));
         return sizeof(*cctx) + cctx->workSpaceSize
                + ZSTD_sizeof_CDict(cctx->cdictLocal)
                + cctx->outBuffSize + cctx->inBuffSize
    @@ -225,7 +229,9 @@ size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned
         switch(param)
         {
         case ZSTD_p_forceWindow : cctx->forceWindow = value>0; cctx->loadedDictEnd = 0; return 0;
    -    case ZSTD_p_forceRawDict : cctx->forceRawDict = value>0; return 0;
    +    ZSTD_STATIC_ASSERT(ZSTD_dm_auto==0);
    +    ZSTD_STATIC_ASSERT(ZSTD_dm_rawContent==1);
    +    case ZSTD_p_forceRawDict : cctx->dictMode = (ZSTD_dictMode_e)(value>0); return 0;
         default: return ERROR(parameter_unknown);
         }
     }
    @@ -340,6 +346,14 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
         case ZSTD_p_refDictContent :   /* to be done later */
             return ERROR(compressionParameter_unsupported);
     
    +    case ZSTD_p_dictMode :
    +        /* restrict dictionary mode, to "rawContent" or "fullDict" only */
    +        ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
    +        if (value > (unsigned)ZSTD_dm_fullDict)
    +            return ERROR(compressionParameter_outOfBound);
    +        cctx->dictMode = (ZSTD_dictMode_e)value;
    +        return 0;
    +
         case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
                                        * even when referencing into Dictionary content
                                        * default : 0 when using a CDict, 1 when using a Prefix */
    @@ -375,10 +389,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
             assert(cctx->mtctx != NULL);
             return ZSTDMT_setMTCtxParameter(cctx->mtctx, ZSTDMT_p_overlapSectionLog, value);
     
    -    case ZSTD_p_rawContentDict :  /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    -        cctx->forceRawDict = value>0;
    -        return 0;
    -
         default: return ERROR(parameter_unknown);
         }
     }
    @@ -407,7 +417,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
                     ZSTD_getCParams(cctx->compressionLevel, 0, dictSize);
             cctx->cdictLocal = ZSTD_createCDict_advanced(
                                     dict, dictSize,
    -                                0 /* byReference */,
    +                                0 /* byReference */, cctx->dictMode,
                                     cParams, cctx->customMem);
             cctx->cdict = cctx->cdictLocal;
             if (cctx->cdictLocal == NULL)
    @@ -543,6 +553,8 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
         size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btultra)) ? optBudget : 0;
         size_t const neededSpace = entropySpace + tableSpace + tokenSpace + optSpace;
     
    +    DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)sizeof(ZSTD_CCtx));
    +    DEBUGLOG(5, "estimate workSpace : %u", (U32)neededSpace);
         return sizeof(ZSTD_CCtx) + neededSpace;
     }
     
    @@ -625,8 +637,8 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
                                     0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
             size_t const h3Size = ((size_t)1) << hashLog3;
             size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
    -        size_t const buffOutSize = ZSTD_compressBound(blockSize)+1;
    -        size_t const buffInSize = ((size_t)1 << params.cParams.windowLog) + blockSize;
    +        size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
    +        size_t const buffInSize = (zbuff==ZSTDb_buffered) ? ((size_t)1 << params.cParams.windowLog) + blockSize : 0;
             void* ptr;
     
             /* Check if workSpace is large enough, alloc a new one if needed */
    @@ -638,8 +650,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
                 size_t const optSpace = ( (params.cParams.strategy == ZSTD_btopt)
                                         || (params.cParams.strategy == ZSTD_btultra)) ?
                                         optPotentialSpace : 0;
    -            size_t const bufferSpace = (zbuff==ZSTDb_buffered) ?
    -                                        buffInSize + buffOutSize : 0;
    +            size_t const bufferSpace = buffInSize + buffOutSize;
                 size_t const neededSpace = entropySpace + optSpace + tableSpace
                                          + tokenSpace + bufferSpace;
     
    @@ -3142,22 +3153,33 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
     
     /** ZSTD_compress_insertDictionary() :
     *   @return : 0, or an error code */
    -static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
    +static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
    +                                       const void* dict, size_t dictSize,
    +                                             ZSTD_dictMode_e dictMode)
     {
         if ((dict==NULL) || (dictSize<=8)) return 0;
     
    -    /* dict as pure content */
    -    if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
    +    /* dict restricted modes */
    +    if (dictMode==ZSTD_dm_rawContent)
             return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
     
    -    /* dict as zstd dictionary */
    +    if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) {
    +        if (dictMode == ZSTD_dm_auto)
    +            return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
    +        if (dictMode == ZSTD_dm_fullDict)
    +            return ERROR(dictionary_wrong);
    +        assert(0);   /* impossible */
    +    }
    +
    +    /* dict as full zstd dictionary */
         return ZSTD_loadZstdDictionary(cctx, dict, dictSize);
     }
     
     /*! ZSTD_compressBegin_internal() :
      * @return : 0, or an error code */
    -size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
    +static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
                                  const void* dict, size_t dictSize,
    +                             ZSTD_dictMode_e dictMode,
                                  const ZSTD_CDict* cdict,
                                        ZSTD_parameters params, U64 pledgedSrcSize,
                                        ZSTD_buffered_policy_e zbuff)
    @@ -3172,7 +3194,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
     
         CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
                                         ZSTDcrp_continue, zbuff));
    -    return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
    +    return ZSTD_compress_insertDictionary(cctx, dict, dictSize, dictMode);
     }
     
     
    @@ -3184,7 +3206,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
     {
         /* compression parameters verification and optimization */
         CHECK_F(ZSTD_checkCParams(params.cParams));
    -    return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
    +    return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
                                         params, pledgedSrcSize, ZSTDb_not_buffered);
     }
     
    @@ -3192,7 +3214,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
     size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
     {
         ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
    -    return ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
    +    return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
                                            params, 0, ZSTDb_not_buffered);
     }
     
    @@ -3273,8 +3295,8 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
                              const void* dict,size_t dictSize,
                                    ZSTD_parameters params)
     {
    -    CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, NULL,
    -                                        params, srcSize, ZSTDb_not_buffered));
    +    CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dm_auto, NULL,
    +                                         params, srcSize, ZSTDb_not_buffered) );
         return ZSTD_compressEnd(cctx, dst,  dstCapacity, src, srcSize);
     }
     
    @@ -3319,6 +3341,8 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
      *  Estimate amount of memory that will be needed to create a dictionary with following arguments */
     size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference)
     {
    +    DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
    +    DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize(cParams));
         return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize(cParams)
                + (byReference ? 0 : dictSize);
     }
    @@ -3326,6 +3350,8 @@ size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSiz
     size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
     {
         if (cdict==NULL) return 0;   /* support sizeof on NULL */
    +    DEBUGLOG(5, "sizeof(*cdict) : %u", (U32)sizeof(*cdict));
    +    DEBUGLOG(5, "ZSTD_sizeof_CCtx : %u", (U32)ZSTD_sizeof_CCtx(cdict->refContext));
         return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
     }
     
    @@ -3339,7 +3365,8 @@ static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_
     
     static size_t ZSTD_initCDict_internal(
                         ZSTD_CDict* cdict,
    -              const void* dictBuffer, size_t dictSize, unsigned byReference,
    +              const void* dictBuffer, size_t dictSize,
    +                    unsigned byReference, ZSTD_dictMode_e dictMode,
                         ZSTD_compressionParameters cParams)
     {
         if ((byReference) || (!dictBuffer) || (!dictSize)) {
    @@ -3357,15 +3384,18 @@ static size_t ZSTD_initCDict_internal(
         {   ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */,
                         0 /* checksumFlag */, 0 /* noDictIDFlag */ };  /* dummy */
             ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
    -        CHECK_F( ZSTD_compressBegin_advanced(cdict->refContext,
    -                                            cdict->dictContent, dictSize,
    -                                            params, 0 /* srcSize */) );
    +        CHECK_F( ZSTD_compressBegin_internal(cdict->refContext,
    +                                        cdict->dictContent, dictSize, dictMode,
    +                                        NULL,
    +                                        params, ZSTD_CONTENTSIZE_UNKNOWN,
    +                                        ZSTDb_not_buffered) );
         }
     
         return 0;
     }
     
    -ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
    +ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
    +                                      unsigned byReference, ZSTD_dictMode_e dictMode,
                                           ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
     {
         DEBUGLOG(5, "ZSTD_createCDict_advanced");
    @@ -3382,7 +3412,8 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
             cdict->refContext = cctx;
     
             if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
    -                                        dictBuffer, dictSize, byReference,
    +                                        dictBuffer, dictSize,
    +                                        byReference, dictMode,
                                             cParams) )) {
                 ZSTD_freeCDict(cdict);
                 return NULL;
    @@ -3394,16 +3425,18 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, u
     
     ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
     {
    -    ZSTD_customMem const allocator = { NULL, NULL, NULL };
         ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
    -    return ZSTD_createCDict_advanced(dict, dictSize, 0, cParams, allocator);
    +    return ZSTD_createCDict_advanced(dict, dictSize,
    +                                     0 /* byReference */, ZSTD_dm_auto,
    +                                     cParams, ZSTD_defaultCMem);
     }
     
     ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
     {
    -    ZSTD_customMem const allocator = { NULL, NULL, NULL };
         ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
    -    return ZSTD_createCDict_advanced(dict, dictSize, 1, cParams, allocator);
    +    return ZSTD_createCDict_advanced(dict, dictSize,
    +                                     1 /* byReference */, ZSTD_dm_auto,
    +                                     cParams, ZSTD_defaultCMem);
     }
     
     size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
    @@ -3431,7 +3464,8 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
      *         Since workspace was allocated externally, it must be freed externally.
      */
     ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
    -                           const void* dict, size_t dictSize, unsigned byReference,
    +                           const void* dict, size_t dictSize,
    +                                 unsigned byReference, ZSTD_dictMode_e dictMode,
                                      ZSTD_compressionParameters cParams)
     {
         size_t const cctxSize = ZSTD_estimateCCtxSize(cParams);
    @@ -3455,8 +3489,9 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
         cdict->refContext = ZSTD_initStaticCCtx(ptr, cctxSize);
     
         if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
    -                                        dict, dictSize, 1 /* by Reference */,
    -                                        cParams) ))
    +                                              dict, dictSize,
    +                                              1 /* byReference */, dictMode,
    +                                              cParams) ))
             return NULL;
     
         return cdict;
    @@ -3476,8 +3511,11 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
         {   ZSTD_parameters params = cdict->refContext->appliedParams;
             params.fParams = fParams;
             DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced");
    -        return ZSTD_compressBegin_internal(cctx, NULL, 0, cdict,
    -                                params, pledgedSrcSize, ZSTDb_not_buffered);
    +        return ZSTD_compressBegin_internal(cctx,
    +                                           NULL, 0, ZSTD_dm_auto,
    +                                           cdict,
    +                                           params, pledgedSrcSize,
    +                                           ZSTDb_not_buffered);
         }
     }
     
    @@ -3552,8 +3590,11 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
     {
         DEBUGLOG(5, "ZSTD_resetCStream_internal");
     
    -    CHECK_F(ZSTD_compressBegin_internal(zcs, NULL, 0, zcs->cdict,
    -                                    params, pledgedSrcSize, ZSTDb_buffered));
    +    CHECK_F( ZSTD_compressBegin_internal(zcs,
    +                                        NULL, 0, ZSTD_dm_auto,
    +                                        zcs->cdict,
    +                                        params, pledgedSrcSize,
    +                                        ZSTDb_buffered) );
     
         zcs->inToCompress = 0;
         zcs->inBuffPos = 0;
    @@ -3588,7 +3629,9 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
                 return ERROR(memory_allocation);
             }
             ZSTD_freeCDict(zcs->cdictLocal);
    -        zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem);
    +        zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    +                                                    0 /* byReference */, ZSTD_dm_auto,
    +                                                    params.cParams, zcs->customMem);
             zcs->cdict = zcs->cdictLocal;
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
         } else {
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 895d362fb..499c531c7 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -584,8 +584,9 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
         if (dict) {
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdict = NULL;
    -        zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* byRef */,
    -                                                params.cParams, zcs->cMem);
    +        zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    +                                                    0 /* byRef */, ZSTD_dm_auto,
    +                                                    params.cParams, zcs->cMem);
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
             zcs->cdict = zcs->cdictLocal;
         } else {
    diff --git a/lib/zstd.h b/lib/zstd.h
    index bbfb92d55..30972cd0b 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -552,9 +552,12 @@ ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter par
      *  It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */
     ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
     
    +
    +typedef enum { ZSTD_dm_auto=0, ZSTD_dm_rawContent, ZSTD_dm_fullDict } ZSTD_dictMode_e;
     /*! ZSTD_createCDict_advanced() :
      *  Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
    -ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
    +ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
    +                                                  unsigned byReference, ZSTD_dictMode_e dictMode,
                                                       ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
     
     /*! ZSTD_initStaticCDict_advanced() :
    @@ -572,7 +575,8 @@ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictS
      */
     ZSTDLIB_API ZSTD_CDict* ZSTD_initStaticCDict(
                                 void* workspace, size_t workspaceSize,
    -                      const void* dict, size_t dictSize, unsigned byReference,
    +                      const void* dict, size_t dictSize,
    +                            unsigned byReference, ZSTD_dictMode_e dictMode,
                                 ZSTD_compressionParameters cParams);
     
     /*! ZSTD_getCParams() :
    @@ -867,13 +871,16 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
     /* note on naming convention :
      *   Initially, the API favored names like ZSTD_setCCtxParameter() .
      *   In this proposal, convention is changed towards ZSTD_CCtx_setParameter() .
    - *   The main idea is that it identifies more clearly the target object type.
    - *   It feels clearer when considering other potential variants :
    + *   The main driver is that it identifies more clearly the target object type.
    + *   It feels clearer in light of potential variants :
      *   ZSTD_CDict_setParameter() (rather than ZSTD_setCDictParameter())
      *   ZSTD_DCtx_setParameter()  (rather than ZSTD_setDCtxParameter() )
    - *   The left variant feels clearer.
    + *   Left variant feels easier to distinguish.
      */
     
    +/* note on enum design :
    + * All enum will be manually set to explicit values before reaching "stable API" status */
    +
     typedef enum {
         /* compression parameters */
         ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    @@ -928,10 +935,10 @@ typedef enum {
         /* dictionary parameters */
         ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
                                   * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its user (CDict) */
    -                             /* Not ready yet ! */
    -    ZSTD_p_rawContentDict,   /* load dictionary in "content-only" mode (no header analysis) (default:0) */
    -                             /* question : should there be an option to load dictionary only in zstd format, rejecting others with an error code ? */
    +                              * But it also requires that dictionary buffer outlives its users */
    +                             /* Not ready yet ! <=================================== */
    +    ZSTD_p_dictMode,         /* Select how dictionary must be interpreted. Value must be from type ZSTD_dictMode_e.
    +                              * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
     
         /* multi-threading parameters */
         ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    @@ -947,7 +954,7 @@ typedef enum {
     
         /* advanced parameters - may not remain available after API update */
         ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    -                              * even when referencing into Dictionary content
    +                              * even when referencing into Dictionary content.
                                   * default : 0 when using a CDict, 1 when using a Prefix */
     } ZSTD_cParameter;
     
    @@ -1007,7 +1014,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
      *  Note 1 : Prefix buffer is referenced. It must outlive compression job.
      *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
      *           It's a CPU-heavy operation, with non-negligible impact on latency. */
    -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! */
    +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! <===================================== */
     
     
     
    diff --git a/programs/bench.c b/programs/bench.c
    index 6f09a56de..f9493e3b0 100644
    --- a/programs/bench.c
    +++ b/programs/bench.c
    @@ -284,7 +284,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                         if (comprParams->searchLength) zparams.cParams.searchLength = comprParams->searchLength;
                         if (comprParams->targetLength) zparams.cParams.targetLength = comprParams->targetLength;
                         if (comprParams->strategy) zparams.cParams.strategy = comprParams->strategy;
    -                    cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1, zparams.cParams, cmem);
    +                    cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1 /*byRef*/, ZSTD_dm_auto, zparams.cParams, cmem);
                         if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure");
     #endif
                         do {
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 96336423c..a3a56d9d8 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -502,15 +502,16 @@ static int basicUnitTests(U32 seed, double compressibility)
     
             DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++);
             {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    -            size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize, 1);
    +            size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize, 1 /*byReference*/);
                 DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize);
             }
     
    -        DISPLAYLEVEL(4, "test%3i : compress with preprocessed dictionary : ", testNb++);
    +        DISPLAYLEVEL(4, "test%3i : compress with CDict ", testNb++);
             {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    -            ZSTD_customMem const customMem = { NULL, NULL, NULL };
                 ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize,
    -                                    1 /* by Referece */, cParams, customMem);
    +                                            1 /* byReference */, ZSTD_dm_auto,
    +                                            cParams, ZSTD_defaultCMem);
    +            DISPLAYLEVEL(4, "(size : %u) : ", (U32)ZSTD_sizeof_CDict(cdict));
                 cSize = ZSTD_compress_usingCDict(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
                                                      CNBuffer, CNBuffSize, cdict);
                 ZSTD_freeCDict(cdict);
    @@ -538,7 +539,8 @@ static int basicUnitTests(U32 seed, double compressibility)
                 void* const cdictBuffer = malloc(cdictSize);
                 if (cdictBuffer==NULL) goto _output_error;
                 {   ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize,
    -                                            dictBuffer, dictSize, 0 /* by Reference */,
    +                                            dictBuffer, dictSize,
    +                                            0 /* by Reference */, ZSTD_dm_auto,
                                                 cParams);
                     if (cdict == NULL) {
                         DISPLAY("ZSTD_initStaticCDict failed ");
    @@ -558,8 +560,7 @@ static int basicUnitTests(U32 seed, double compressibility)
             DISPLAYLEVEL(4, "test%3i : ZSTD_compress_usingCDict_advanced, no contentSize, no dictID : ", testNb++);
             {   ZSTD_frameParameters const fParams = { 0 /* frameSize */, 1 /* checksum */, 1 /* noDictID*/ };
                 ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    -            ZSTD_customMem const customMem = { NULL, NULL, NULL };
    -            ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1, cParams, customMem);
    +            ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1 /*byRef*/, ZSTD_dm_auto, cParams, ZSTD_defaultCMem);
                 cSize = ZSTD_compress_usingCDict_advanced(cctx, compressedBuffer, ZSTD_compressBound(CNBuffSize),
                                                      CNBuffer, CNBuffSize, cdict, fParams);
                 ZSTD_freeCDict(cdict);
    @@ -608,6 +609,22 @@ static int basicUnitTests(U32 seed, double compressibility)
             }
             DISPLAYLEVEL(4, "OK \n");
     
    +        DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a good dictionary : ", testNb++);
    +        {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    +            ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictSize, 1 /*byRef*/, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
    +            if (cdict==NULL) goto _output_error;
    +            ZSTD_freeCDict(cdict);
    +        }
    +        DISPLAYLEVEL(4, "OK \n");
    +
    +        DISPLAYLEVEL(4, "test%3i : Building cdict w/ ZSTD_dm_fullDict on a rawContent (must fail) : ", testNb++);
    +        {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    +            ZSTD_CDict* const cdict = ZSTD_createCDict_advanced((const char*)dictBuffer+1, dictSize-1, 1 /*byRef*/, ZSTD_dm_fullDict, cParams, ZSTD_defaultCMem);
    +            if (cdict!=NULL) goto _output_error;
    +            ZSTD_freeCDict(cdict);
    +        }
    +        DISPLAYLEVEL(4, "OK \n");
    +
             ZSTD_freeCCtx(cctx);
             free(dictBuffer);
             free(samplesSizes);
    @@ -686,9 +703,7 @@ static int basicUnitTests(U32 seed, double compressibility)
             size_t const wrongSrcSize = (srcSize + 1000);
             ZSTD_parameters params = ZSTD_getParams(1, wrongSrcSize, 0);
             params.fParams.contentSizeFlag = 1;
    -        {   size_t const result = ZSTD_compressBegin_advanced(cctx, NULL, 0, params, wrongSrcSize);
    -            if (ZSTD_isError(result)) goto _output_error;
    -        }
    +        CHECK( ZSTD_compressBegin_advanced(cctx, NULL, 0, params, wrongSrcSize) );
             {   size_t const result = ZSTD_compressEnd(cctx, decodedBuffer, CNBuffSize, CNBuffer, srcSize);
                 if (!ZSTD_isError(result)) goto _output_error;
                 if (ZSTD_getErrorCode(result) != ZSTD_error_srcSize_wrong) goto _output_error;
    @@ -870,8 +885,23 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)
     }
     
     #undef CHECK
    -#define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
    -                         DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb); goto _output_error; }
    +#define CHECK(cond, ...) {                                    \
    +    if (cond) {                                               \
    +        DISPLAY("Error => ");                                 \
    +        DISPLAY(__VA_ARGS__);                                 \
    +        DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb);  \
    +        goto _output_error;                                   \
    +}   }
    +
    +#define CHECK_Z(f) {                                          \
    +    size_t const err = f;                                     \
    +    if (ZSTD_isError(err)) {                                  \
    +        DISPLAY("Error => %s : %s ",                          \
    +                #f, ZSTD_getErrorName(err));                  \
    +        DISPLAY(" (seed %u, test nb %u)  \n", seed, testNb);  \
    +        goto _output_error;                                   \
    +}   }
    +
     
     static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxDurationS, double compressibility, int bigTests)
     {
    @@ -984,8 +1014,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
     
             /* frame header decompression test */
             {   ZSTD_frameHeader dParams;
    -            size_t const check = ZSTD_getFrameHeader(&dParams, cBuffer, cSize);
    -            CHECK(ZSTD_isError(check), "Frame Parameters extraction failed");
    +            CHECK_Z( ZSTD_getFrameHeader(&dParams, cBuffer, cSize) );
                 CHECK(dParams.frameContentSize != sampleSize, "Frame content size incorrect");
             }
     
    @@ -1072,20 +1101,17 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
                 dict = srcBuffer + (FUZ_rand(&lseed) % (srcBufferSize - dictSize));
     
                 if (FUZ_rand(&lseed) & 0xF) {
    -                size_t const errorCode = ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel);
    -                CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode));
    +                CHECK_Z ( ZSTD_compressBegin_usingDict(refCtx, dict, dictSize, cLevel) );
                 } else {
                     ZSTD_compressionParameters const cPar = ZSTD_getCParams(cLevel, 0, dictSize);
                     ZSTD_frameParameters const fPar = { FUZ_rand(&lseed)&1 /* contentSizeFlag */,
                                                         !(FUZ_rand(&lseed)&3) /* contentChecksumFlag*/,
                                                         0 /*NodictID*/ };   /* note : since dictionary is fake, dictIDflag has no impact */
                     ZSTD_parameters const p = FUZ_makeParams(cPar, fPar);
    -                size_t const errorCode = ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0);
    -                CHECK (ZSTD_isError(errorCode), "ZSTD_compressBegin_advanced error : %s", ZSTD_getErrorName(errorCode));
    +                CHECK_Z ( ZSTD_compressBegin_advanced(refCtx, dict, dictSize, p, 0) );
                 }
    -            {   size_t const errorCode = ZSTD_copyCCtx(ctx, refCtx, 0);
    -                CHECK (ZSTD_isError(errorCode), "ZSTD_copyCCtx error : %s", ZSTD_getErrorName(errorCode));
    -        }   }
    +            CHECK_Z( ZSTD_copyCCtx(ctx, refCtx, 0) );
    +        }
             ZSTD_setCCtxParameter(ctx, ZSTD_p_forceWindow, FUZ_rand(&lseed) & 1);
     
             {   U32 const nbChunks = (FUZ_rand(&lseed) & 127) + 2;
    @@ -1117,8 +1143,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, U32 const maxD
     
             /* streaming decompression test */
             if (dictSize<8) dictSize=0, dict=NULL;   /* disable dictionary */
    -        { size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
    -          CHECK (ZSTD_isError(errorCode), "ZSTD_decompressBegin_usingDict error : %s", ZSTD_getErrorName(errorCode)); }
    +        CHECK_Z( ZSTD_decompressBegin_usingDict(dctx, dict, dictSize) );
             totalCSize = 0;
             totalGenSize = 0;
             while (totalCSize < cSize) {
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 95b3add0b..7229f7031 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -486,7 +486,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         DISPLAYLEVEL(3, "test%3i : ZSTD_initCStream_usingCDict_advanced with masked dictID : ", testNb++);
         {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictionary.filled);
             ZSTD_frameParameters const fParams = { 1 /* contentSize */, 1 /* checksum */, 1 /* noDictID */};
    -        ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, 1 /* byReference */, cParams, customMem);
    +        ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictionary.start, dictionary.filled, 1 /* byReference */, ZSTD_dm_auto, cParams, customMem);
             size_t const initError = ZSTD_initCStream_usingCDict_advanced(zc, cdict, fParams, CNBufferSize);
             if (ZSTD_isError(initError)) goto _output_error;
             cSize = 0;
    diff --git a/zlibWrapper/examples/zwrapbench.c b/zlibWrapper/examples/zwrapbench.c
    index a57ed51ec..1fc2117f6 100644
    --- a/zlibWrapper/examples/zwrapbench.c
    +++ b/zlibWrapper/examples/zwrapbench.c
    @@ -90,7 +90,7 @@ static clock_t g_time = 0;
     #ifndef DEBUG
     #  define DEBUG 0
     #endif
    -#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
    +#define DEBUGOUTPUT(...) { if (DEBUG) DISPLAY(__VA_ARGS__); }
     #define EXM_THROW(error, ...)                                             \
     {                                                                         \
         DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \
    @@ -236,7 +236,7 @@ static int BMK_benchMem(z_const void* srcBuffer, size_t srcSize,
                     if (compressor == BMK_ZSTD) {
                         ZSTD_parameters const zparams = ZSTD_getParams(cLevel, avgSize, dictBufferSize);
                         ZSTD_customMem const cmem = { NULL, NULL, NULL };
    -                    ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1, zparams.cParams, cmem);
    +                    ZSTD_CDict* const cdict = ZSTD_createCDict_advanced(dictBuffer, dictBufferSize, 1 /*byRef*/, ZSTD_dm_auto, zparams.cParams, cmem);
                         if (cdict==NULL) EXM_THROW(1, "ZSTD_createCDict_advanced() allocation failure");
     
                         do {
    
    From c16748b1370906db470be6ab2b366b5a5e8e6f96 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 12:09:53 -0700
    Subject: [PATCH 290/400] added test cases for new command --list
    
    ---
     tests/playTests.sh | 17 ++++++++++-------
     1 file changed, 10 insertions(+), 7 deletions(-)
    
    diff --git a/tests/playTests.sh b/tests/playTests.sh
    index 4eb794b54..fa82ae9e7 100755
    --- a/tests/playTests.sh
    +++ b/tests/playTests.sh
    @@ -567,21 +567,24 @@ $ECHO "\n**** zstd --list/-l error detection tests ****"
     $ECHO "\n**** zstd --list/-l test with null files ****"
     ./datagen -g0 > tmp5
     $ZSTD tmp5
    +$ZSTD -l tmp5.zst
     ! $ZSTD -l tmp5*
    +$ZSTD -lv tmp5.zst
     ! $ZSTD -lv tmp5*
    -! $ZSTD --list tmp5*
    -! $ZSTD --list -v tmp5*
     
    -$ECHO "\n**** zstd --list/-l test with no frame content size ****"
    -echo -n '' > tmp6
    -$ZSTD tmp6
    +$ECHO "\n**** zstd --list/-l test with no content size field ****"
    +./datagen -g1MB | $ZSTD > tmp6.zst
     $ZSTD -l tmp6.zst
     $ZSTD -lv tmp6.zst
    -$ZSTD --list tmp6.zst
    -$ZSTD --list -v tmp6.zst
    +
    +$ECHO "\n**** zstd --list/-l test with no checksum ****"
    +$ZSTD -f --no-check tmp1
    +$ZSTD -l tmp1.zst
    +$ZSTD -lv tmp1.zst
     
     rm tmp*
     
    +
     if [ "$1" != "--test-large-data" ]; then
         $ECHO "Skipping large data tests"
         exit 0
    
    From 83095970e699c2430dc2266f2472e1393aaf0822 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 12:26:40 -0700
    Subject: [PATCH 291/400] free cdictLocal faster, suggested by @terrelln
    
    ---
     lib/compress/zstdmt_compress.c | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 499c531c7..f07143c1a 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -583,13 +583,14 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
         zcs->frameContentSize = pledgedSrcSize;
         if (dict) {
             ZSTD_freeCDict(zcs->cdictLocal);
    -        zcs->cdict = NULL;
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
                                                         0 /* byRef */, ZSTD_dm_auto,
                                                         params.cParams, zcs->cMem);
    -        if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
             zcs->cdict = zcs->cdictLocal;
    +        if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
         } else {
    +        ZSTD_freeCDict(zcs->cdictLocal);
    +        zcs->cdictLocal = NULL;
             zcs->cdict = cdict;
         }
     
    @@ -627,7 +628,7 @@ size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
                                          unsigned long long pledgedSrcSize)
     {
         ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
    -    if (cdict==NULL) return ERROR(GENERIC);   /* method incompatible with NULL cdict */
    +    if (cdict==NULL) return ERROR(dictionary_wrong);   /* method incompatible with NULL cdict */
         params.fParams = fParams;
         return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, cdict,
                                             params, pledgedSrcSize);
    
    From 74a725da69a939e4938082e676abde3e4009141a Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 12:27:20 -0700
    Subject: [PATCH 292/400] reversed calculation of ratio
    
    ---
     programs/fileio.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/programs/fileio.c b/programs/fileio.c
    index a5db88a4c..a0510f62d 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -1009,10 +1009,10 @@ static int getFileInfo(fileInfo_t* info, const char* inFileName){
     static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLevel){
         double const compressedSizeMB = (double)info->compressedSize/(1 MB);
         double const decompressedSizeMB = (double)info->decompressedSize/(1 MB);
    +    double const ratio = (info->compressedSize == 0) ? 0 : ((double)info->decompressedSize)/info->compressedSize;
         const char* const checkString = (info->usesCheck ? "XXH64" : "None");
         if (displayLevel <= 2) {
             if (!info->decompUnavailable) {
    -            double const ratio = (info->decompressedSize == 0) ? 0.0 : compressedSizeMB/decompressedSizeMB;
                 DISPLAYOUT("Skippable  Non-Skippable  Compressed  Uncompressed  Ratio  Check  Filename\n");
                 DISPLAYOUT("%9d  %13d  %7.2f MB  %9.2f MB  %5.3f  %5s  %s\n",
                         info->numSkippableFrames, info->numActualFrames, compressedSizeMB, decompressedSizeMB,
    @@ -1030,7 +1030,7 @@ static void displayInfo(const char* inFileName, fileInfo_t* info, int displayLev
             DISPLAYOUT("Compressed Size: %.2f MB (%llu B)\n", compressedSizeMB, info->compressedSize);
             if (!info->decompUnavailable) {
                 DISPLAYOUT("Decompressed Size: %.2f MB (%llu B)\n", decompressedSizeMB, info->decompressedSize);
    -            DISPLAYOUT("Ratio: %.4f\n", compressedSizeMB/decompressedSizeMB);
    +            DISPLAYOUT("Ratio: %.4f\n", ratio);
             }
             DISPLAYOUT("Check: %s\n", checkString);
             DISPLAYOUT("\n");
    
    From 6f5fe71041d23271fc2409add38250c915b8c4ca Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 12:37:23 -0700
    Subject: [PATCH 293/400] added error check for when file could not be opened
    
    ---
     programs/fileio.c | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/programs/fileio.c b/programs/fileio.c
    index a0510f62d..634a888c1 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -875,13 +875,14 @@ typedef struct {
     /*
      * Reads information from file, stores in *info
      * if successful, returns 0, returns 1 for frame analysis error, returns 2 for file not compressed with zstd
    + * returns 3 for cases in which file could not be opened.
      */
     static int getFileInfo(fileInfo_t* info, const char* inFileName){
         int detectError = 0;
         FILE* const srcFile = FIO_openSrcFile(inFileName);
         if (srcFile == NULL) {
             DISPLAY("Error: could not open source file %s\n", inFileName);
    -        return 1;
    +        return 3;
         }
         info->compressedSize = (unsigned long long)UTIL_getFileSize(inFileName);
         /* begin analyzing frame */
    @@ -1056,6 +1057,10 @@ static int FIO_listFile(const char* inFileName, int displayLevel, unsigned fileN
                 }
                 return 1;
             }
    +        else if (error == 3) {
    +            /* error occurred with opening the file */
    +            return 1;
    +        }
             displayInfo(inFileName, &info, displayLevel);
             return error;
         }
    
    From 5be0f5544e46182168ce83a06b968f63eeabda30 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 12:41:10 -0700
    Subject: [PATCH 294/400] added newline to align output
    
    ---
     programs/fileio.c | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/programs/fileio.c b/programs/fileio.c
    index 634a888c1..0bcd1f87f 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -1059,6 +1059,9 @@ static int FIO_listFile(const char* inFileName, int displayLevel, unsigned fileN
             }
             else if (error == 3) {
                 /* error occurred with opening the file */
    +            if (displayLevel > 2) {
    +                DISPLAYOUT("\n");
    +            }
                 return 1;
             }
             displayInfo(inFileName, &info, displayLevel);
    
    From 1e4129b27b2dfa840b6396c5f8b6222ac404bcd8 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 13:26:10 -0700
    Subject: [PATCH 295/400] fixed dangling pointer risk, detected by @terrelln
    
    ---
     lib/decompress/zstd_decompress.c | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 51fa244ce..4dd78e0e5 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -223,6 +223,7 @@ ZSTD_DCtx* ZSTD_createDCtx(void)
     size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
     {
         if (dctx==NULL) return 0;   /* support free on NULL */
    +    if (dctx->staticSize) return ERROR(memory_allocation);   /* not compatible with static DCtx */
         {   ZSTD_customMem const cMem = dctx->customMem;
             ZSTD_freeDDict(dctx->ddictLocal);
             dctx->ddictLocal = NULL;
    @@ -237,7 +238,7 @@ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
         }
     }
     
    -/* no longer appropriate */
    +/* no longer useful */
     void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
     {
         size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);
    @@ -1981,10 +1982,10 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_
             ddict->dictContent = dict;
         } else {
             void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);
    -        if (!internalBuffer) return ERROR(memory_allocation);
    -        memcpy(internalBuffer, dict, dictSize);
             ddict->dictBuffer = internalBuffer;
             ddict->dictContent = internalBuffer;
    +        if (!internalBuffer) return ERROR(memory_allocation);
    +        memcpy(internalBuffer, dict, dictSize);
         }
         ddict->dictSize = dictSize;
         ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */
    @@ -2353,7 +2354,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                         break;
                     }
                     if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
    -                    const int isSkipFrame = ZSTD_isSkipFrame(zds);
    +                    int const isSkipFrame = ZSTD_isSkipFrame(zds);
                         size_t const decodedSize = ZSTD_decompressContinue(zds,
                             zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
                             ip, neededInSize);
    
    From 204b6b7ef6f5afe0cd67700012debc9ce981b0c2 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 15:13:00 -0700
    Subject: [PATCH 296/400] fixed streaming buffered allocation with CDict
     compression
    
    ---
     lib/compress/zstd_compress.c   | 41 +++++++++++++++++++++++-----------
     lib/compress/zstdmt_compress.c |  3 +++
     2 files changed, 31 insertions(+), 13 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 59ac3f35d..06d022090 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -775,15 +775,14 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
     static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
                                 const ZSTD_CCtx* srcCCtx,
                                 ZSTD_frameParameters fParams,
    -                            unsigned long long pledgedSrcSize)
    +                            unsigned long long pledgedSrcSize,
    +                            ZSTD_buffered_policy_e zbuff)
     {
         DEBUGLOG(5, "ZSTD_copyCCtx_internal");
         if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
     
         memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
    -    {   ZSTD_buffered_policy_e const zbuff = srcCCtx->inBuffSize ?
    -                        ZSTDb_buffered : ZSTDb_not_buffered;
    -        ZSTD_parameters params = srcCCtx->appliedParams;
    +    {   ZSTD_parameters params = srcCCtx->appliedParams;
             params.fParams = fParams;
             ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
                                     ZSTDcrp_noMemset, zbuff);
    @@ -833,9 +832,11 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
     size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
     {
         ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
    +    ZSTD_buffered_policy_e const zbuff = (ZSTD_buffered_policy_e)(srcCCtx->inBuffSize>0);
    +    ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1);
         fParams.contentSizeFlag = pledgedSrcSize>0;
     
    -    return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, fParams, pledgedSrcSize);
    +    return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, fParams, pledgedSrcSize, zbuff);
     }
     
     
    @@ -3157,6 +3158,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
                                            const void* dict, size_t dictSize,
                                                  ZSTD_dictMode_e dictMode)
     {
    +    DEBUGLOG(5, "ZSTD_compress_insertDictionary");
         if ((dict==NULL) || (dictSize<=8)) return 0;
     
         /* dict restricted modes */
    @@ -3164,8 +3166,10 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx,
             return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
     
         if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) {
    -        if (dictMode == ZSTD_dm_auto)
    +        if (dictMode == ZSTD_dm_auto) {
    +            DEBUGLOG(5, "raw content dictionary detected");
                 return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
    +        }
             if (dictMode == ZSTD_dm_fullDict)
                 return ERROR(dictionary_wrong);
             assert(0);   /* impossible */
    @@ -3184,16 +3188,21 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
                                        ZSTD_parameters params, U64 pledgedSrcSize,
                                        ZSTD_buffered_policy_e zbuff)
     {
    +    DEBUGLOG(5, "ZSTD_compressBegin_internal");
    +    DEBUGLOG(5, "dict ? %s", dict ? "dict" : cdict ? "cdict" : "none");
    +    DEBUGLOG(5, "dictMode : %u", (U32)dictMode);
         /* params are supposed to be fully validated at this point */
         assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
     
    -    if (cdict && cdict->dictContentSize>0)
    +    if (cdict && cdict->dictContentSize>0) {
             return ZSTD_copyCCtx_internal(cctx, cdict->refContext,
    -                                      params.fParams, pledgedSrcSize);
    +                                      params.fParams, pledgedSrcSize,
    +                                      zbuff);
    +    }
     
    -    CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
    -                                    ZSTDcrp_continue, zbuff));
    +    CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
    +                                     ZSTDcrp_continue, zbuff) );
         return ZSTD_compress_insertDictionary(cctx, dict, dictSize, dictMode);
     }
     
    @@ -3369,6 +3378,7 @@ static size_t ZSTD_initCDict_internal(
                         unsigned byReference, ZSTD_dictMode_e dictMode,
                         ZSTD_compressionParameters cParams)
     {
    +    DEBUGLOG(5, "ZSTD_initCDict_internal, mode %u", (U32)dictMode);
         if ((byReference) || (!dictBuffer) || (!dictSize)) {
             cdict->dictBuffer = NULL;
             cdict->dictContent = dictBuffer;
    @@ -3398,7 +3408,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
                                           unsigned byReference, ZSTD_dictMode_e dictMode,
                                           ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
     {
    -    DEBUGLOG(5, "ZSTD_createCDict_advanced");
    +    DEBUGLOG(5, "ZSTD_createCDict_advanced, mode %u", (U32)dictMode);
         if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
     
         {   ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
    @@ -3616,22 +3626,27 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
         return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
     }
     
    +/*! ZSTD_initCStream_internal() :
    + *  Assumption 1 : params are valid
    + *  Assumption 2 : either dict, or cdict, is defined, not both */
     size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
                         const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
                         ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    +    DEBUGLOG(5, "ZSTD_initCStream_internal");
         assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
     
         if (dict && dictSize >= 8) {
    +        DEBUGLOG(5, "loading dictionary of size %u", (U32)dictSize);
             if (zcs->staticSize) {   /* static CCtx : never uses malloc */
                 /* incompatible with internal cdict creation */
                 return ERROR(memory_allocation);
             }
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    -                                                    0 /* byReference */, ZSTD_dm_auto,
    -                                                    params.cParams, zcs->customMem);
    +                                            0 /* byReference */, ZSTD_dm_auto,
    +                                            params.cParams, zcs->customMem);
             zcs->cdict = zcs->cdictLocal;
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
         } else {
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index f07143c1a..8a167ce1d 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -563,11 +563,13 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
                         const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
                         ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    +    DEBUGLOG(5, "ZSTDMT_initCStream_internal");
         /* params are supposed to be fully validated at this point */
         assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
         assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
     
         if (zcs->nbThreads==1) {
    +        DEBUGLOG(5, "single thread mode");
             return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0],
                                     dict, dictSize, cdict,
                                     params, pledgedSrcSize);
    @@ -619,6 +621,7 @@ size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,
                                     const void* dict, size_t dictSize,
                                     ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
    +    DEBUGLOG(5, "ZSTDMT_initCStream_advanced");
         return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, NULL, params, pledgedSrcSize);
     }
     
    
    From 991f9dfcde77df1de6e76af695128ae5368d77e5 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 15:16:13 -0700
    Subject: [PATCH 297/400] switched fileio.c to ZSTD_DEBUG trigger macro
    
    ---
     programs/fileio.c | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/programs/fileio.c b/programs/fileio.c
    index bbf52168a..d5340cc43 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -106,14 +106,14 @@ static clock_t g_time = 0;
     /*-*************************************
     *  Errors
     ***************************************/
    -#ifndef DEBUG
    -#  define DEBUG 0
    +#ifndef ZSTD_DEBUG
    +#  define ZSTD_DEBUG 0
     #endif
    -#define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__);
    +#define DEBUGLOG(l,...) if (l<=ZSTD_DEBUG) DISPLAY(__VA_ARGS__);
     #define EXM_THROW(error, ...)                                              \
     {                                                                          \
         DISPLAYLEVEL(1, "zstd: ");                                             \
    -    DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__);  \
    +    DEBUGLOG(1, "Error defined at %s, line %i : \n", __FILE__, __LINE__);  \
         DISPLAYLEVEL(1, "error %i : ", error);                                 \
         DISPLAYLEVEL(1, __VA_ARGS__);                                          \
         DISPLAYLEVEL(1, " \n");                                                \
    @@ -123,7 +123,7 @@ static clock_t g_time = 0;
     #define CHECK(f) {                                   \
         size_t const err = f;                            \
         if (ZSTD_isError(err)) {                         \
    -        DEBUGOUTPUT("%s \n", #f);                    \
    +        DEBUGLOG(1, "%s \n", #f);                    \
             EXM_THROW(11, "%s", ZSTD_getErrorName(err)); \
     }   }
     
    
    From b789860db075658c1fc7201e21dcc268aa6abb5a Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 21 Jun 2017 15:08:26 -0700
    Subject: [PATCH 298/400] [linux] Switch BtrFS compression level to 1
    
    ---
     contrib/linux-kernel/btrfs.diff      | 4 ++--
     contrib/linux-kernel/fs/btrfs/zstd.c | 2 +-
     2 files changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/contrib/linux-kernel/btrfs.diff b/contrib/linux-kernel/btrfs.diff
    index aa3ec1d98..f984a5383 100644
    --- a/contrib/linux-kernel/btrfs.diff
    +++ b/contrib/linux-kernel/btrfs.diff
    @@ -193,7 +193,7 @@ index 1f157fb..b0dec90 100644
      	BTRFS_FEAT_ATTR_PTR(raid56),
     diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
     new file mode 100644
    -index 0000000..45ea326
    +index 0000000..838741b
     --- /dev/null
     +++ b/fs/btrfs/zstd.c
     @@ -0,0 +1,433 @@
    @@ -231,7 +231,7 @@ index 0000000..45ea326
     +
     +static ZSTD_parameters zstd_get_btrfs_parameters(size_t src_len)
     +{
    -+	ZSTD_parameters params = ZSTD_getParams(3, src_len, 0);
    ++	ZSTD_parameters params = ZSTD_getParams(1, src_len, 0);
     +
     +	if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
     +		params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
    diff --git a/contrib/linux-kernel/fs/btrfs/zstd.c b/contrib/linux-kernel/fs/btrfs/zstd.c
    index 45ea3263c..838741b37 100644
    --- a/contrib/linux-kernel/fs/btrfs/zstd.c
    +++ b/contrib/linux-kernel/fs/btrfs/zstd.c
    @@ -32,7 +32,7 @@
     
     static ZSTD_parameters zstd_get_btrfs_parameters(size_t src_len)
     {
    -	ZSTD_parameters params = ZSTD_getParams(3, src_len, 0);
    +	ZSTD_parameters params = ZSTD_getParams(1, src_len, 0);
     
     	if (params.cParams.windowLog > ZSTD_BTRFS_MAX_WINDOWLOG)
     		params.cParams.windowLog = ZSTD_BTRFS_MAX_WINDOWLOG;
    
    From 34b0a0883a9d9402debded67e1299a838516d395 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 21 Jun 2017 15:10:18 -0700
    Subject: [PATCH 299/400] [linux] Rename diffs to patch names
    
    ---
     .../{xxhash.diff => 0001-lib-Add-xxhash-module.patch}             | 0
     .../linux-kernel/{zstd.diff => 0002-lib-Add-zstd-modules.patch}   | 0
     2 files changed, 0 insertions(+), 0 deletions(-)
     rename contrib/linux-kernel/{xxhash.diff => 0001-lib-Add-xxhash-module.patch} (100%)
     rename contrib/linux-kernel/{zstd.diff => 0002-lib-Add-zstd-modules.patch} (100%)
    
    diff --git a/contrib/linux-kernel/xxhash.diff b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    similarity index 100%
    rename from contrib/linux-kernel/xxhash.diff
    rename to contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    diff --git a/contrib/linux-kernel/zstd.diff b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    similarity index 100%
    rename from contrib/linux-kernel/zstd.diff
    rename to contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    
    From f3ad4062ba1c8d31d1d4ec9fa5756893ab5b3468 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 21 Jun 2017 15:19:54 -0700
    Subject: [PATCH 300/400] [linux] Add summaries to xxhash and zstd patches
    
    ---
     .../0001-lib-Add-xxhash-module.patch          |  94 ++++++++++-
     .../0002-lib-Add-zstd-modules.patch           | 158 +++++++++++++++++-
     2 files changed, 241 insertions(+), 11 deletions(-)
    
    diff --git a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    index 2aac5c0c6..c3ee41fd1 100644
    --- a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    +++ b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    @@ -1,3 +1,86 @@
    +From 36b990a005e68a30495e2b2981e30c5ce97a8591 Mon Sep 17 00:00:00 2001
    +From: Nick Terrell 
    +Date: Mon, 12 Jun 2017 12:13:48 -0700
    +Subject: [PATCH 1/4] lib: Add xxhash module
    +
    +Adds xxhash kernel module with xxh32 and xxh64 hashes. xxhash is an
    +extremely fast non-cryptographic hash algorithm for checksumming.
    +The zstd compression and decompression modules added in the next patch
    +require xxhash. I extracted it out from zstd since it is useful on its
    +own. I copied the code from the upstream XXHash source repository and
    +translated it into kernel style. I ran benchmarks and tests in the kernel
    +and tests in userland.
    +
    +I benchmarked xxhash as a special character device. I ran in four modes,
    +no-op, xxh32, xxh64, and crc32. The no-op mode simply copies the data to
    +kernel space and ignores it. The xxh32, xxh64, and crc32 modes compute
    +hashes on the copied data. I also ran it with four different buffer sizes.
    +The benchmark file is located in the upstream zstd source repository under
    +`contrib/linux-kernel/xxhash_test.c` [1].
    +
    +I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    +The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
    +16 GB of RAM, and a SSD. I benchmarked using the file `filesystem.squashfs`
    +from `ubuntu-16.10-desktop-amd64.iso`, which is 1,536,217,088 B large.
    +Run the following commands for the benchmark:
    +
    +    modprobe xxhash_test
    +    mknod xxhash_test c 245 0
    +    time cp filesystem.squashfs xxhash_test
    +
    +The time is reported by the time of the userland `cp`.
    +The GB/s is computed with
    +
    +    1,536,217,008 B / time(buffer size, hash)
    +
    +which includes the time to copy from userland.
    +The Normalized GB/s is computed with
    +
    +    1,536,217,088 B / (time(buffer size, hash) - time(buffer size, none)).
    +
    +
    +| Buffer Size (B) | Hash  | Time (s) | GB/s | Adjusted GB/s |
    +|-----------------|-------|----------|------|---------------|
    +|            1024 | none  |    0.408 | 3.77 |             - |
    +|            1024 | xxh32 |    0.649 | 2.37 |          6.37 |
    +|            1024 | xxh64 |    0.542 | 2.83 |         11.46 |
    +|            1024 | crc32 |    1.290 | 1.19 |          1.74 |
    +|            4096 | none  |    0.380 | 4.04 |             - |
    +|            4096 | xxh32 |    0.645 | 2.38 |          5.79 |
    +|            4096 | xxh64 |    0.500 | 3.07 |         12.80 |
    +|            4096 | crc32 |    1.168 | 1.32 |          1.95 |
    +|            8192 | none  |    0.351 | 4.38 |             - |
    +|            8192 | xxh32 |    0.614 | 2.50 |          5.84 |
    +|            8192 | xxh64 |    0.464 | 3.31 |         13.60 |
    +|            8192 | crc32 |    1.163 | 1.32 |          1.89 |
    +|           16384 | none  |    0.346 | 4.43 |             - |
    +|           16384 | xxh32 |    0.590 | 2.60 |          6.30 |
    +|           16384 | xxh64 |    0.466 | 3.30 |         12.80 |
    +|           16384 | crc32 |    1.183 | 1.30 |          1.84 |
    +
    +Tested in userland using the test-suite in the zstd repo under
    +`contrib/linux-kernel/test/XXHashUserlandTest.cpp` [2] by mocking the
    +kernel functions. A line in each branch of every function in `xxhash.c`
    +was commented out to ensure that the test-suite fails. Additionally
    +tested while testing zstd and with SMHasher [3].
    +
    +[1] https://phabricator.intern.facebook.com/P57526246
    +[2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/test/XXHashUserlandTest.cpp
    +[3] https://github.com/aappleby/smhasher
    +
    +zstd source repository: https://github.com/facebook/zstd
    +XXHash source repository: https://github.com/cyan4973/xxhash
    +
    +Signed-off-by: Nick Terrell 
    +---
    + include/linux/xxhash.h | 236 +++++++++++++++++++++++
    + lib/Kconfig            |   3 +
    + lib/Makefile           |   1 +
    + lib/xxhash.c           | 500 +++++++++++++++++++++++++++++++++++++++++++++++++
    + 4 files changed, 740 insertions(+)
    + create mode 100644 include/linux/xxhash.h
    + create mode 100644 lib/xxhash.c
    +
     diff --git a/include/linux/xxhash.h b/include/linux/xxhash.h
     new file mode 100644
     index 0000000..9e1f42c
    @@ -241,10 +324,10 @@ index 0000000..9e1f42c
     +
     +#endif /* XXHASH_H */
     diff --git a/lib/Kconfig b/lib/Kconfig
    -index 0c8b78a..b6009d7 100644
    +index 260a80e..9db178f 100644
     --- a/lib/Kconfig
     +++ b/lib/Kconfig
    -@@ -184,6 +184,9 @@ config CRC8
    +@@ -185,6 +185,9 @@ config CRC8
      	  when they need to do cyclic redundancy check according CRC8
      	  algorithm. Module will be called crc8.
      
    @@ -255,10 +338,10 @@ index 0c8b78a..b6009d7 100644
      	bool
      	depends on AUDIT && !AUDIT_ARCH
     diff --git a/lib/Makefile b/lib/Makefile
    -index 320ac46..e16f94a 100644
    +index 50144a3..5644bad 100644
     --- a/lib/Makefile
     +++ b/lib/Makefile
    -@@ -101,6 +101,7 @@ obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
    +@@ -93,6 +93,7 @@ obj-$(CONFIG_CRC32)	+= crc32.o
      obj-$(CONFIG_CRC7)	+= crc7.o
      obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
      obj-$(CONFIG_CRC8)	+= crc8.o
    @@ -772,3 +855,6 @@ index 0000000..dc94904
     +
     +MODULE_LICENSE("Dual BSD/GPL");
     +MODULE_DESCRIPTION("xxHash");
    +-- 
    +2.9.3
    +
    diff --git a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    index e83b56ed2..4ace675fc 100644
    --- a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    +++ b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    @@ -1,3 +1,145 @@
    +From 536a2c59c5bc58f526e69dd0a35b83d39508ae74 Mon Sep 17 00:00:00 2001
    +From: Nick Terrell 
    +Date: Wed, 21 Jun 2017 14:56:21 -0700
    +Subject: [PATCH 2/4] lib: Add zstd modules
    +
    +Add zstd compression and decompression kernel modules.
    +zstd offers a wide varity of compression speed and quality trade-offs.
    +It can compress at speeds approaching lz4, and quality approaching lzma.
    +zstd decompressions at speeds more than twice as fast as zlib, and
    +decompression speed remains roughly the same across all compression levels.
    +
    +The code was ported from the upstream zstd source repository. The
    +`linux/zstd.h` header was modified to match linux kernel style.
    +The cross-platform and allocation code was stripped out. Instead zstd
    +requires the caller to pass a preallocated workspace. The source files
    +were clang-formatted [1] to match the Linux Kernel style as much as
    +possible. Otherwise, the code was unmodified. We would like to avoid
    +as much further manual modification to the source code as possible, so it
    +will be easier to keep the kernel zstd up to date.
    +
    +I benchmarked zstd compression as a special character device. I ran zstd
    +and zlib compression at several levels, as well as performing no
    +compression, which measure the time spent copying the data to kernel space.
    +Data is passed to the compresser 4096 B at a time. The benchmark file is
    +located in the upstream zstd source repository under
    +`contrib/linux-kernel/zstd_compress_test.c` [2].
    +
    +I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    +The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
    +16 GB of RAM, and a SSD. I benchmarked using `silesia.tar` [3], which is
    +211,988,480 B large. Run the following commands for the benchmark:
    +
    +    sudo modprobe zstd_compress_test
    +    sudo mknod zstd_compress_test c 245 0
    +    sudo cp silesia.tar zstd_compress_test
    +
    +The time is reported by the time of the userland `cp`.
    +The MB/s is computed with
    +
    +    1,536,217,008 B / time(buffer size, hash)
    +
    +which includes the time to copy from userland.
    +The Adjusted MB/s is computed with
    +
    +    1,536,217,088 B / (time(buffer size, hash) - time(buffer size, none)).
    +
    +The memory reported is the amount of memory the compressor requests.
    +
    +| Method   | Size (B) | Time (s) | Ratio | MB/s    | Adj MB/s | Mem (MB) |
    +|----------|----------|----------|-------|---------|----------|----------|
    +| none     | 11988480 |    0.100 |     1 | 2119.88 |        - |        - |
    +| zstd -1  | 73645762 |    1.044 | 2.878 |  203.05 |   224.56 |     1.23 |
    +| zstd -3  | 66988878 |    1.761 | 3.165 |  120.38 |   127.63 |     2.47 |
    +| zstd -5  | 65001259 |    2.563 | 3.261 |   82.71 |    86.07 |     2.86 |
    +| zstd -10 | 60165346 |   13.242 | 3.523 |   16.01 |    16.13 |    13.22 |
    +| zstd -15 | 58009756 |   47.601 | 3.654 |    4.45 |     4.46 |    21.61 |
    +| zstd -19 | 54014593 |  102.835 | 3.925 |    2.06 |     2.06 |    60.15 |
    +| zlib -1  | 77260026 |    2.895 | 2.744 |   73.23 |    75.85 |     0.27 |
    +| zlib -3  | 72972206 |    4.116 | 2.905 |   51.50 |    52.79 |     0.27 |
    +| zlib -6  | 68190360 |    9.633 | 3.109 |   22.01 |    22.24 |     0.27 |
    +| zlib -9  | 67613382 |   22.554 | 3.135 |    9.40 |     9.44 |     0.27 |
    +
    +I benchmarked zstd decompression using the same method on the same machine.
    +The benchmark file is located in the upstream zstd repo under
    +`contrib/linux-kernel/zstd_decompress_test.c` [4]. The memory reported is
    +the amount of memory required to decompress data compressed with the given
    +compression level. If you know the maximum size of your input, you can
    +reduce the memory usage of decompression irrespective of the compression
    +level.
    +
    +| Method   | Time (s) | MB/s    | Adjusted MB/s | Memory (MB) |
    +|----------|----------|---------|---------------|-------------|
    +| none     |    0.025 | 8479.54 |             - |           - |
    +| zstd -1  |    0.358 |  592.15 |        636.60 |        0.84 |
    +| zstd -3  |    0.396 |  535.32 |        571.40 |        1.46 |
    +| zstd -5  |    0.396 |  535.32 |        571.40 |        1.46 |
    +| zstd -10 |    0.374 |  566.81 |        607.42 |        2.51 |
    +| zstd -15 |    0.379 |  559.34 |        598.84 |        4.61 |
    +| zstd -19 |    0.412 |  514.54 |        547.77 |        8.80 |
    +| zlib -1  |    0.940 |  225.52 |        231.68 |        0.04 |
    +| zlib -3  |    0.883 |  240.08 |        247.07 |        0.04 |
    +| zlib -6  |    0.844 |  251.17 |        258.84 |        0.04 |
    +| zlib -9  |    0.837 |  253.27 |        287.64 |        0.04 |
    +
    +Tested in userland using the test-suite in the zstd repo under
    +`contrib/linux-kernel/test/UserlandTest.cpp` [5] by mocking the kernel
    +functions. Fuzz tested using libfuzzer [6] with the fuzz harnesses under
    +`contrib/linux-kernel/test/{RoundTripCrash.c,DecompressCrash.c}` [7] [8]
    +with ASAN, UBSAN, and MSAN. Additionaly, it was tested while testing the
    +BtrFS and SquashFS patches coming next.
    +
    +[1] https://clang.llvm.org/docs/ClangFormat.html
    +[2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/zstd_compress_test.c
    +[3] http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia
    +[4] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/zstd_decompress_test.c
    +[5] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/test/UserlandTest.cpp
    +[6] http://llvm.org/docs/LibFuzzer.html
    +[7] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/test/RoundTripCrash.c
    +[8] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/test/DecompressCrash.c
    +
    +zstd source repository: https://github.com/facebook/zstd
    +
    +Signed-off-by: Nick Terrell 
    +---
    + include/linux/zstd.h      | 1157 +++++++++++++++
    + lib/Kconfig               |    8 +
    + lib/Makefile              |    2 +
    + lib/zstd/Makefile         |   18 +
    + lib/zstd/bitstream.h      |  374 +++++
    + lib/zstd/compress.c       | 3468 +++++++++++++++++++++++++++++++++++++++++++++
    + lib/zstd/decompress.c     | 2514 ++++++++++++++++++++++++++++++++
    + lib/zstd/entropy_common.c |  244 ++++
    + lib/zstd/error_private.h  |   53 +
    + lib/zstd/fse.h            |  584 ++++++++
    + lib/zstd/fse_compress.c   |  857 +++++++++++
    + lib/zstd/fse_decompress.c |  313 ++++
    + lib/zstd/huf.h            |  203 +++
    + lib/zstd/huf_compress.c   |  731 ++++++++++
    + lib/zstd/huf_decompress.c |  920 ++++++++++++
    + lib/zstd/mem.h            |  151 ++
    + lib/zstd/zstd_common.c    |   75 +
    + lib/zstd/zstd_internal.h  |  269 ++++
    + lib/zstd/zstd_opt.h       | 1014 +++++++++++++
    + 19 files changed, 12955 insertions(+)
    + create mode 100644 include/linux/zstd.h
    + create mode 100644 lib/zstd/Makefile
    + create mode 100644 lib/zstd/bitstream.h
    + create mode 100644 lib/zstd/compress.c
    + create mode 100644 lib/zstd/decompress.c
    + create mode 100644 lib/zstd/entropy_common.c
    + create mode 100644 lib/zstd/error_private.h
    + create mode 100644 lib/zstd/fse.h
    + create mode 100644 lib/zstd/fse_compress.c
    + create mode 100644 lib/zstd/fse_decompress.c
    + create mode 100644 lib/zstd/huf.h
    + create mode 100644 lib/zstd/huf_compress.c
    + create mode 100644 lib/zstd/huf_decompress.c
    + create mode 100644 lib/zstd/mem.h
    + create mode 100644 lib/zstd/zstd_common.c
    + create mode 100644 lib/zstd/zstd_internal.h
    + create mode 100644 lib/zstd/zstd_opt.h
    +
     diff --git a/include/linux/zstd.h b/include/linux/zstd.h
     new file mode 100644
     index 0000000..249575e
    @@ -1162,13 +1304,13 @@ index 0000000..249575e
     +
     +#endif  /* ZSTD_H */
     diff --git a/lib/Kconfig b/lib/Kconfig
    -index b6009d7..f00ddab 100644
    +index 9db178f..8deab4f 100644
     --- a/lib/Kconfig
     +++ b/lib/Kconfig
    -@@ -241,6 +241,14 @@ config LZ4HC_COMPRESS
    +@@ -242,6 +242,14 @@ config LZ4HC_COMPRESS
      config LZ4_DECOMPRESS
      	tristate
    - 
    +
     +config ZSTD_COMPRESS
     +	select XXHASH
     +	tristate
    @@ -1178,13 +1320,13 @@ index b6009d7..f00ddab 100644
     +	tristate
     +
      source "lib/xz/Kconfig"
    - 
    +
      #
     diff --git a/lib/Makefile b/lib/Makefile
    -index e16f94a..0cfd529 100644
    +index 5644bad..aa630d4 100644
     --- a/lib/Makefile
     +++ b/lib/Makefile
    -@@ -115,6 +115,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
    +@@ -107,6 +107,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
      obj-$(CONFIG_LZ4_COMPRESS) += lz4/
      obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/
      obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
    @@ -1192,7 +1334,7 @@ index e16f94a..0cfd529 100644
     +obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
      obj-$(CONFIG_XZ_DEC) += xz/
      obj-$(CONFIG_RAID6_PQ) += raid6/
    - 
    +
     diff --git a/lib/zstd/Makefile b/lib/zstd/Makefile
     new file mode 100644
     index 0000000..dd0a359
    @@ -13077,3 +13219,5 @@ index 0000000..55e1b4c
     +}
     +
     +#endif /* ZSTD_OPT_H_91842398743 */
    +--
    +2.9.3
    
    From 0a94fead41e13c7a40750c0d71fed9312c96c4a1 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 21 Jun 2017 15:21:25 -0700
    Subject: [PATCH 301/400] [linux] Rename last 2 diffs to patch names
    
    ---
     .../{btrfs.diff => 0003-btrfs-Add-zstd-support.patch}             | 0
     .../{squashfs.diff => 0004-squashfs-Add-zstd-support.patch}       | 0
     2 files changed, 0 insertions(+), 0 deletions(-)
     rename contrib/linux-kernel/{btrfs.diff => 0003-btrfs-Add-zstd-support.patch} (100%)
     rename contrib/linux-kernel/{squashfs.diff => 0004-squashfs-Add-zstd-support.patch} (100%)
    
    diff --git a/contrib/linux-kernel/btrfs.diff b/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch
    similarity index 100%
    rename from contrib/linux-kernel/btrfs.diff
    rename to contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch
    diff --git a/contrib/linux-kernel/squashfs.diff b/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch
    similarity index 100%
    rename from contrib/linux-kernel/squashfs.diff
    rename to contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch
    
    From dce789281ba41e8fdfebd35fa055117c51ace534 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 15:53:42 -0700
    Subject: [PATCH 302/400] fixed : decompression of skippable frames in
     streaming mode
    
    ---
     lib/decompress/zstd_decompress.c | 22 ++++++++---
     tests/zstreamtest.c              | 63 +++++++++++++++++---------------
     2 files changed, 50 insertions(+), 35 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 4dd78e0e5..c6695679d 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -2244,6 +2244,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
         char* op = ostart;
         U32 someMoreWork = 1;
     
    +    DEBUGLOG(5, "ZSTD_decompressStream");
    +    DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
     #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
         if (zds->legacyVersion) {
             /* legacy support is incompatible with static dctx */
    @@ -2308,12 +2310,20 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }   }
     
                 /* Consume header (see ZSTDds_decodeFrameHeader) */
    +            DEBUGLOG(5, "Consume header");
                 CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
    -            CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
    -            zds->expected = ZSTD_blockHeaderSize;
    -            zds->stage = ZSTDds_decodeBlockHeader;
    +
    +            if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {  /* skippable frame */
    +                zds->expected = MEM_readLE32(zds->headerBuffer + 4);
    +                zds->stage = ZSTDds_skipFrame;
    +            } else {
    +                CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
    +                zds->expected = ZSTD_blockHeaderSize;
    +                zds->stage = ZSTDds_decodeBlockHeader;
    +            }
     
                 /* control buffer memory usage */
    +            DEBUGLOG(5, "Control max buffer memory usage");
                 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
                 if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
     
    @@ -2328,8 +2338,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                         DEBUGLOG(5, "outBuff : from %u to %u",
                                     (U32)zds->outBuffSize, (U32)neededOutSize);
                         if (zds->staticSize) {  /* static DCtx */
    -                        DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
    -                        assert(zds->staticSize >= sizeof(ZSTD_DCtx));  /* already checked at init */
    +                        DEBUGLOG(5, "staticSize : %u", (U32)zds->staticSize);
    +                        assert(zds->staticSize >= sizeof(ZSTD_DCtx));  /* controlled at init */
                             if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx))
                                 return ERROR(memory_allocation);
                         } else {
    @@ -2347,7 +2357,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 /* pass-through */
     
             case zdss_read:
    +            DEBUGLOG(5, "stage zdss_read");
                 {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
    +                DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
                     if (neededInSize==0) {  /* end of frame */
                         zds->streamStage = zdss_init;
                         someMoreWork = 0;
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 7229f7031..e96e8891c 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -217,9 +217,9 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         }
     
         DISPLAYLEVEL(3, "test%3i : check actual CStream size : ", testNb++);
    -    { size_t const s = ZSTD_sizeof_CStream(zc);
    -      if (ZSTD_isError(s)) goto _output_error;
    -      DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
    +    {   size_t const s = ZSTD_sizeof_CStream(zc);
    +        if (ZSTD_isError(s)) goto _output_error;
    +        DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
         }
     
         /* Attempt bad compression parameters */
    @@ -234,15 +234,18 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* skippable frame test */
         DISPLAYLEVEL(3, "test%3i : decompress skippable frame : ", testNb++);
    -    ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize);
    +    if (ZSTD_isError( ZSTD_initDStream_usingDict(zd, CNBuffer, dictSize) ))
    +        goto _output_error;
         inBuff.src = compressedBuffer;
         inBuff.size = cSize;
         inBuff.pos = 0;
         outBuff.dst = decodedBuffer;
         outBuff.size = CNBufferSize;
         outBuff.pos = 0;
    -    { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
    -      if (r != 0) goto _output_error; }
    +    {   size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff);
    +        DISPLAYLEVEL(5, " ( ZSTD_decompressStream => %u ) ", (U32)r);
    +        if (r != 0) goto _output_error;
    +    }
         if (outBuff.pos != 0) goto _output_error;   /* skippable frame output len is 0 */
         DISPLAYLEVEL(3, "OK \n");
     
    @@ -732,12 +735,14 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
             if ((FUZ_rand(&lseed) & 0xFF) == 131) {
                 ZSTD_freeCStream(zc);
                 zc = ZSTD_createCStream();
    +            CHECK(zc==NULL, "ZSTD_createCStream : allocation error");
                 resetAllowed=0;
             }
             if ((FUZ_rand(&lseed) & 0xFF) == 132) {
                 ZSTD_freeDStream(zd);
                 zd = ZSTD_createDStream();
    -            ZSTD_initDStream_usingDict(zd, NULL, 0);  /* ensure at least one init */
    +            CHECK(zd==NULL, "ZSTD_createDStream : allocation error");
    +            CHECK_Z( ZSTD_initDStream_usingDict(zd, NULL, 0) );  /* ensure at least one init */
             }
     
             /* srcBuffer selection [0-4] */
    @@ -829,9 +834,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
     
             /* multi - fragments decompression test */
             if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
    -            CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed");
    +            CHECK_Z ( ZSTD_resetDStream(zd) );
             } else {
    -            ZSTD_initDStream_usingDict(zd, dict, dictSize);
    +            CHECK_Z ( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
             }
             {   size_t decompressionResult = 1;
                 ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
    @@ -866,7 +871,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
             }   }
     
             /* try decompression on noisy data */
    -        ZSTD_initDStream(zd_noise);   /* note : no dictionary */
    +        CHECK_Z( ZSTD_initDStream(zd_noise) );   /* note : no dictionary */
             {   ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
                 ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
                 while (outBuff.pos < dstBufferSize) {
    @@ -974,11 +979,13 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
                 DISPLAYLEVEL(5, "Creating new context with %u threads \n", nbThreads);
                 ZSTDMT_freeCCtx(zc);
                 zc = ZSTDMT_createCCtx(nbThreads);
    +            CHECK(zc==NULL, "ZSTDMT_createCCtx allocation error")
                 resetAllowed=0;
             }
             if ((FUZ_rand(&lseed) & 0xFF) == 132) {
                 ZSTD_freeDStream(zd);
                 zd = ZSTD_createDStream();
    +            CHECK(zd==NULL, "ZSTDMT_createCCtx allocation error")
                 ZSTD_initDStream_usingDict(zd, NULL, 0);  /* ensure at least one init */
             }
     
    @@ -1003,8 +1010,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
                 maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
                 if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
                 {   int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1;
    -                size_t const resetError = ZSTDMT_initCStream(zc, compressionLevel);
    -                CHECK(ZSTD_isError(resetError), "ZSTDMT_initCStream error : %s", ZSTD_getErrorName(resetError));
    +                CHECK_Z( ZSTDMT_initCStream(zc, compressionLevel) );
                 }
             } else {
                 U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
    @@ -1028,10 +1034,9 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
                     params.fParams.noDictIDFlag = FUZ_rand(&lseed) & 1;
                     params.fParams.contentSizeFlag = pledgedSrcSize>0;
                     DISPLAYLEVEL(5, "checksumFlag : %u \n", params.fParams.checksumFlag);
    -                { size_t const initError = ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize);
    -                  CHECK (ZSTD_isError(initError),"ZSTDMT_initCStream_advanced error : %s", ZSTD_getErrorName(initError)); }
    -                ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12);
    -                ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_sectionSize, FUZ_rand(&lseed) % (2*maxTestSize+1));
    +                CHECK_Z( ZSTDMT_initCStream_advanced(zc, dict, dictSize, params, pledgedSrcSize) );
    +                CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_overlapSectionLog, FUZ_rand(&lseed) % 12) );
    +                CHECK_Z( ZSTDMT_setMTCtxParameter(zc, ZSTDMT_p_sectionSize, FUZ_rand(&lseed) % (2*maxTestSize+1)) );
             }   }
     
             /* multi-segments compression test */
    @@ -1049,8 +1054,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
                         outBuff.size = outBuff.pos + dstBuffSize;
     
                         DISPLAYLEVEL(5, "Sending %u bytes to compress \n", (U32)srcSize);
    -                    { size_t const compressionError = ZSTDMT_compressStream(zc, &outBuff, &inBuff);
    -                      CHECK (ZSTD_isError(compressionError), "compression error : %s", ZSTD_getErrorName(compressionError)); }
    +                    CHECK_Z( ZSTDMT_compressStream(zc, &outBuff, &inBuff) );
                         DISPLAYLEVEL(5, "%u bytes read by ZSTDMT_compressStream \n", (U32)inBuff.pos);
     
                         XXH64_update(&xxhState, srcBuffer+srcStart, inBuff.pos);
    @@ -1064,9 +1068,8 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
                         size_t const adjustedDstSize = MIN(cBufferSize - cSize, randomDstSize);
                         outBuff.size = outBuff.pos + adjustedDstSize;
                         DISPLAYLEVEL(5, "Flushing into dst buffer of size %u \n", (U32)adjustedDstSize);
    -                    {   size_t const flushError = ZSTDMT_flushStream(zc, &outBuff);
    -                        CHECK (ZSTD_isError(flushError), "ZSTDMT_flushStream error : %s", ZSTD_getErrorName(flushError));
    -            }   }   }
    +                    CHECK_Z( ZSTDMT_flushStream(zc, &outBuff) );
    +            }   }
     
                 /* final frame epilogue */
                 {   size_t remainingToFlush = (size_t)(-1);
    @@ -1086,9 +1089,9 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
     
             /* multi - fragments decompression test */
             if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
    -            CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed");
    +            CHECK_Z( ZSTD_resetDStream(zd) );
             } else {
    -            ZSTD_initDStream_usingDict(zd, dict, dictSize);
    +            CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
             }
             {   size_t decompressionResult = 1;
                 ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
    @@ -1124,7 +1127,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
             }   }
     
             /* try decompression on noisy data */
    -        ZSTD_initDStream(zd_noise);   /* note : no dictionary */
    +        CHECK_Z( ZSTD_initDStream(zd_noise) );   /* note : no dictionary */
             {   ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
                 ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
                 while (outBuff.pos < dstBufferSize) {
    @@ -1203,7 +1206,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
         RDG_genBuffer(cNoiseBuffer[3], srcBufferSize, 0.95, 0., coreSeed);    /* highly compressible */
         RDG_genBuffer(cNoiseBuffer[4], srcBufferSize, 1.00, 0., coreSeed);    /* sparse content */
         memset(copyBuffer, 0x65, copyBufferSize);                             /* make copyBuffer considered initialized */
    -    ZSTD_initDStream_usingDict(zd, NULL, 0);   /* ensure at least one init */
    +    CHECK_Z( ZSTD_initDStream_usingDict(zd, NULL, 0) );   /* ensure at least one init */
     
         /* catch up testNb */
         for (testNb=1; testNb < startTest; testNb++)
    @@ -1231,13 +1234,13 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                 DISPLAYLEVEL(5, "Creating new context \n");
                 ZSTD_freeCCtx(zc);
                 zc = ZSTD_createCCtx();
    -            CHECK(zc==NULL, "allocation error");
    +            CHECK(zc==NULL, "ZSTD_createCCtx allocation error");
                 resetAllowed=0;
             }
             if ((FUZ_rand(&lseed) & 0xFF) == 132) {
                 ZSTD_freeDStream(zd);
                 zd = ZSTD_createDStream();
    -            CHECK(zd==NULL, "allocation error");
    +            CHECK(zd==NULL, "ZSTD_createDStream allocation error");
                 ZSTD_initDStream_usingDict(zd, NULL, 0);  /* ensure at least one init */
             }
     
    @@ -1369,9 +1372,9 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
     
             /* multi - fragments decompression test */
             if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
    -            CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed");
    +            CHECK_Z( ZSTD_resetDStream(zd) );
             } else {
    -            ZSTD_initDStream_usingDict(zd, dict, dictSize);
    +            CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
             }
             {   size_t decompressionResult = 1;
                 ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
    @@ -1407,7 +1410,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
             }   }
     
             /* try decompression on noisy data */
    -        ZSTD_initDStream(zd_noise);   /* note : no dictionary */
    +        CHECK_Z( ZSTD_initDStream(zd_noise) );   /* note : no dictionary */
             {   ZSTD_inBuffer  inBuff = { cBuffer, cSize, 0 };
                 ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };
                 while (outBuff.pos < dstBufferSize) {
    
    From 224e7a1053cc8c6e118c233105399768bb45b6ab Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 15:58:36 -0700
    Subject: [PATCH 303/400] added --list command contrib by @paulcruz74
    
    ---
     NEWS | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/NEWS b/NEWS
    index 3f9b4b220..db9df9634 100644
    --- a/NEWS
    +++ b/NEWS
    @@ -1,10 +1,11 @@
     v1.3.0
    -cli : changed : `-t *` does no longer stop after a decompression error
    +cli : new : `--list` command, by Paul Cruz
    +cli : changed : `-t *` continue processing list after a decompression error
     API : added : ZSTD_versionString()
     API exp : new advanced API : ZSTD_compress_generic(), ZSTD_CCtx_setParameter()
     API exp : new : API for static or external allocation : ZSTD_initStatic?Ctx()
     API exp : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700)
    -API exp : changed : strongest strategy renamed ZSTD_btultra
    +API exp : changed : strongest strategy renamed ZSTD_btultra, fastest strategy ZSTD_fast set to 1
     API exp : clarified presentation of memory estimation / measurement functions.
     new : contrib/seekable_format, demo and API, by Sean Purcell
     changed : contrib/linux-kernel, updated version and license, by Nick Terrell
    
    From ecb0f468662c5cdc5aa67ba0bfb59110d9466a1d Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 17:25:01 -0700
    Subject: [PATCH 304/400] add controls over streaming buffers
    
    ---
     lib/compress/zstd_compress.c | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 06d022090..6b662a9ee 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3743,7 +3743,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
         /* check expectations */
         DEBUGLOG(5, "ZSTD_compressStream_generic");
         assert(zcs->inBuff != NULL);
    +    assert(zcs->inBuffSize>0);
         assert(zcs->outBuff!= NULL);
    +    assert(zcs->outBuffSize>0);
         assert(output->pos <= output->size);
         assert(input->pos <= input->size);
     
    
    From ccae9ec8071adc973f9ec12db5bb4db927080090 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 17:43:21 -0700
    Subject: [PATCH 305/400] added comment addressing use of bits in frame header
     descriptor
    
    ---
     tests/decodecorpus.c | 7 +++++++
     1 file changed, 7 insertions(+)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 2eed515fe..526ddf15b 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -314,6 +314,13 @@ static void writeFrameHeader(U32* seed, frame_t* frame, dictInfo info)
         pos += 4;
     
         {
    +        /*
    +         * fcsCode: 2-bit flag specifying how many bytes used to represent Frame_Content_Size (bits 7-6)
    +         * singleSegment: 1-bit flag describing if data must be regenerated within a single continuous memory segment. (bit 5)
    +         * contentChecksumFlag: 1-bit flag that is set if frame includes checksum at the end -- set to 1 below (bit 2)
    +         * dictBits: 2-bit flag describing how many bytes Dictionary_ID uses -- set to 3 (bits 1-0)
    +         * For more information: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frame_header
    +         */
             int const dictBits = info.useDict ? 3 : 0;
             BYTE const frameHeaderDescriptor =
                     (BYTE) ((fcsCode << 6) | (singleSegment << 5) | (1 << 2) | dictBits);
    
    From 2ceaec1aad1d13f147126c63f1e94519feafbfe4 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 17:46:37 -0700
    Subject: [PATCH 306/400] got rid of unnecessary casting to void*
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 526ddf15b..282f959e6 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1235,7 +1235,7 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
     static dictInfo initDictInfo(int useDict, size_t dictContentSize, BYTE* dictContent, U32 dictID){
         /* allocate space statically */
         dictInfo dictOp;
    -    memset((void*)(&dictOp), 0, sizeof(dictOp));
    +    memset(&dictOp, 0, sizeof(dictOp));
         dictOp.useDict = useDict;
         dictOp.dictContentSize = dictContentSize;
         dictOp.dictContent = dictContent;
    
    From 04253e21bb0f20bc3985f8a850fd4866b090e9f0 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 17:48:01 -0700
    Subject: [PATCH 307/400] added const
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 282f959e6..1423ca1a2 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1316,7 +1316,7 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
     
         /* generate random dictionary */
         {
    -        int ret = genRandomDict(dictID, seed, dictSize, fullDict);
    +        int const ret = genRandomDict(dictID, seed, dictSize, fullDict);
             if (ret != 0) {
                 errorDetected = ERROR(GENERIC);
                 goto dictTestCleanup;
    
    From eeff2d0e3c15ea7de33450c6ad9da353e7d313e8 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 17:48:37 -0700
    Subject: [PATCH 308/400] added const x2
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 1423ca1a2..347bc1b50 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1499,7 +1499,7 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
     
         /* randomly generate the dictionary */
         {
    -        int ret = genRandomDict(dictID, seed, dictSize, fullDict);
    +        int const ret = genRandomDict(dictID, seed, dictSize, fullDict);
             if (ret != 0) {
                 errorDetected = ret;
                 goto dictCleanup;
    
    From bfc2f0008066c170fb825b59d4724884a34b19cf Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 17:57:14 -0700
    Subject: [PATCH 309/400] --no-big-tests for zstreamtest
    
    Apply --no-big-tests for tsan tests
    ---
     Makefile            |  3 ++-
     tests/zstreamtest.c | 29 ++++++++++++++++++-----------
     2 files changed, 20 insertions(+), 12 deletions(-)
    
    diff --git a/Makefile b/Makefile
    index d7a00e431..3cf1cb0b0 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -239,7 +239,8 @@ uasan-%: clean
     	LDFLAGS=-fuse-ld=gold MOREFLAGS="-Og -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined" $(MAKE) -C $(TESTDIR) $*
     
     tsan-%: clean
    -	LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread" $(MAKE) -C $(TESTDIR) $*
    +	LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests
    +
     apt-install:
     	sudo apt-get -yq --no-install-suggests --no-install-recommends --force-yes install $(APT_PACKAGES)
     
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index e96e8891c..29e48944a 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -689,7 +689,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    int const cLevelLimiter = bigTests ? 3 : 2;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    @@ -772,10 +772,11 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
             } else {
                 U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
                 U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog;
    -            U32 const cLevel = ( FUZ_rand(&lseed) %
    +            U32 const cLevelCandidate = ( FUZ_rand(&lseed) %
                                     (ZSTD_maxCLevel() -
    -                                (MAX(testLog, dictLog) / cLevelLimiter)))
    +                                (MAX(testLog, dictLog) / 3)))
                                      + 1;
    +            U32 const cLevel = MIN(cLevelCandidate, cLevelMax);
                 maxTestSize = FUZ_rLogLength(&lseed, testLog);
                 oldTestLog = testLog;
                 /* random dictionary selection */
    @@ -931,7 +932,8 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    int const cLevelLimiter = bigTests ? 3 : 2;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
    +    U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    @@ -975,7 +977,8 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
             /* states full reset (deliberately not synchronized) */
             /* some issues can only happen when reusing states */
             if ((FUZ_rand(&lseed) & 0xFF) == 131) {
    -            U32 const nbThreads = (FUZ_rand(&lseed) % 6) + 1;
    +            U32 const nbThreadsCandidate = (FUZ_rand(&lseed) % 6) + 1;
    +            U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
                 DISPLAYLEVEL(5, "Creating new context with %u threads \n", nbThreads);
                 ZSTDMT_freeCCtx(zc);
                 zc = ZSTDMT_createCCtx(nbThreads);
    @@ -1015,10 +1018,11 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
             } else {
                 U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
                 U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog;
    -            U32 const cLevel = (FUZ_rand(&lseed) %
    +            U32 const cLevelCandidate = (FUZ_rand(&lseed) %
                                    (ZSTD_maxCLevel() -
    -                               (MAX(testLog, dictLog) / cLevelLimiter))) +
    +                               (MAX(testLog, dictLog) / 3))) +
                                    1;
    +            U32 const cLevel = MIN(cLevelCandidate, cLevelMax);
                 maxTestSize = FUZ_rLogLength(&lseed, testLog);
                 oldTestLog = testLog;
                 /* random dictionary selection */
    @@ -1187,7 +1191,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
         const BYTE* dict = NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    int const cLevelLimiter = bigTests ? 3 : 2;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
    +    U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    @@ -1271,10 +1276,11 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
             } else {
                 U32 const testLog = FUZ_rand(&lseed) % maxSrcLog;
                 U32 const dictLog = FUZ_rand(&lseed) % maxSrcLog;
    -            U32 const cLevel = (FUZ_rand(&lseed) %
    +            U32 const cLevelCandidate = (FUZ_rand(&lseed) %
                                    (ZSTD_maxCLevel() -
    -                               (MAX(testLog, dictLog) / cLevelLimiter))) +
    +                               (MAX(testLog, dictLog) / 3))) +
                                    1;
    +            U32 const cLevel = MIN(cLevelCandidate, cLevelMax);
                 maxTestSize = FUZ_rLogLength(&lseed, testLog);
                 oldTestLog = testLog;
                 /* random dictionary selection */
    @@ -1320,7 +1326,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                     DISPLAYLEVEL(5, "pledgedSrcSize : %u \n", (U32)pledgedSrcSize);
     
                     /* multi-threading parameters */
    -                {   U32 const nbThreads = (FUZ_rand(&lseed) & 3) + 1;
    +                {   U32 const nbThreadsCandidate = (FUZ_rand(&lseed) & 4) + 1;
    +                    U32 const nbThreads = MIN(nbThreadsCandidate, nbThreadsMax);
                         CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_nbThreads, nbThreads) );
                         if (nbThreads > 1) {
                             U32 const jobLog = FUZ_rand(&lseed) % (testLog+1);
    
    From 32e36c2d9ac4d08633c2a432340d298251c87ad7 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 18:00:47 -0700
    Subject: [PATCH 310/400] removed requirement that offset be less than
     windowSize
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 347bc1b50..e2b098672 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -685,7 +685,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                         /* need to occasionally generate offsets that go past the start */
                         /* we still need to be within the windowSize however */
                         U32 const lenPastStart = RAND(seed) % info.dictContentSize;
    -                    offset = MIN(frame->header.windowSize, offset+lenPastStart);
    +                    offset = offset+lenPastStart;
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
                     repIndex = 2;
    
    From 52a13abf3fe9c6a1388e8e6fab9823345fa69642 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 18:13:52 -0700
    Subject: [PATCH 311/400] removed comment regarding windowSize requirement
    
    ---
     tests/decodecorpus.c | 1 -
     1 file changed, 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index e2b098672..64185a13b 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -683,7 +683,6 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                              1;
                     if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
    -                    /* we still need to be within the windowSize however */
                         U32 const lenPastStart = RAND(seed) % info.dictContentSize;
                         offset = offset+lenPastStart;
                     }
    
    From 4d3bdcf13054ffaab6e0298c720f1d48b5882a7a Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 18:20:02 -0700
    Subject: [PATCH 312/400] reduced CLevelMax for --no-big-tests
    
    ---
     tests/zstreamtest.c | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 29e48944a..8e58fc872 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -45,6 +45,7 @@
     #define GB *(1U<<30)
     
     static const U32 nbTestsDefault = 10000;
    +static const U32 g_cLevelMax_smallTests = 15;
     #define COMPRESSIBLE_NOISE_LENGTH (10 MB)
     #define FUZ_COMPRESSIBILITY_DEFAULT 50
     static const U32 prime32 = 2654435761U;
    @@ -689,7 +690,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    @@ -932,7 +933,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
         U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
    @@ -1191,7 +1192,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
         const BYTE* dict = NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : 17;
    +    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
         U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
    
    From 0b6eedeace6060ff431752eb8800b88c97c60071 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 18:24:19 -0700
    Subject: [PATCH 313/400] malloc samples instead of static allocation
    
    ---
     tests/decodecorpus.c | 16 ++++++++++++----
     1 file changed, 12 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 64185a13b..5608e7de0 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1173,9 +1173,14 @@ static U32 generateFrame(U32 seed, frame_t* fr, dictInfo info)
     /* returns 0 if successful, otherwise returns 1 upon error */
     static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
         /* allocate space for samples */
    +    int ret = 0;
         unsigned const numSamples = 4;
    -    BYTE samples[5000];
         size_t sampleSizes[4];
    +    BYTE* const samples = malloc(5000);
    +    if (samples == NULL) {
    +        DISPLAY("Error: could not allocate space for samples\n");
    +        return 1;
    +    }
     
         /* generate samples */
         {
    @@ -1205,7 +1210,8 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
             BYTE* const dictContent = fullDict + headerSize;
             if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
                 DISPLAY("Error: dictionary size is too small\n");
    -            return 1;
    +            ret = 1;
    +            goto exitGenRandomDict;
             }
     
             /* init dictionary params */
    @@ -1224,11 +1230,13 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
     
             if (ZDICT_isError(dictWriteSize)) {
                 DISPLAY("Could not finalize dictionary: %s\n", ZDICT_getErrorName(dictWriteSize));
    -            return 1;
    +            ret = 1;
             }
         }
     
    -    return 0;
    +exitGenRandomDict:
    +    free(samples);
    +    return ret;
     }
     
     static dictInfo initDictInfo(int useDict, size_t dictContentSize, BYTE* dictContent, U32 dictID){
    
    From 0950b3159ac8e065d5e8bb0e5f612e254d3ecadf Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 18:30:27 -0700
    Subject: [PATCH 314/400] more meaningful names for count variables
    
    ---
     tests/decodecorpus.c | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 5608e7de0..dfda93923 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1184,18 +1184,18 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
     
         /* generate samples */
         {
    -        unsigned i = 1;
    -        unsigned j = 0;
    +        unsigned literalValue = 1;
    +        unsigned samplesPos = 0;
             size_t currSize = 1;
    -        while (i <= 4) {
    -            sampleSizes[i - 1] = currSize;
    +        while (literalValue <= 4) {
    +            sampleSizes[literalValue - 1] = currSize;
                 {
                     size_t k;
                     for (k = 0; k < currSize; k++) {
    -                    samples[j++] = (BYTE)i;
    +                    samples[samplesPos++] = (BYTE)literalValue;
                     }
                 }
    -            i++;
    +            literalValue++;
                 currSize *= 16;
             }
         }
    
    From 49f8459d11765a0fe462bac69dec033bf3bd47fc Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 18:43:39 -0700
    Subject: [PATCH 315/400] fixed minor cast warning
    
    ---
     tests/zstreamtest.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 8e58fc872..3ab8d0537 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -690,7 +690,7 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
    +    U32 const cLevelMax = bigTests ? (U32)ZSTD_maxCLevel() : g_cLevelMax_smallTests;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    @@ -933,7 +933,7 @@ static int fuzzerTests_MT(U32 seed, U32 nbTests, unsigned startTest, double comp
         const BYTE* dict=NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
    +    U32 const cLevelMax = bigTests ? (U32)ZSTD_maxCLevel() : g_cLevelMax_smallTests;
         U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
    @@ -1192,7 +1192,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
         const BYTE* dict = NULL;   /* can keep same dict on 2 consecutive tests */
         size_t dictSize = 0;
         U32 oldTestLog = 0;
    -    U32 const cLevelMax = bigTests ? ZSTD_maxCLevel() : g_cLevelMax_smallTests;
    +    U32 const cLevelMax = bigTests ? (U32)ZSTD_maxCLevel() : g_cLevelMax_smallTests;
         U32 const nbThreadsMax = bigTests ? 5 : 2;
     
         /* allocations */
    
    From 04094f37e987cc509ee0a35a4cb5c930441d3576 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 21 Jun 2017 18:47:40 -0700
    Subject: [PATCH 316/400] fixed offset in this case os that it always goes past
     src start
    
    ---
     tests/decodecorpus.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index dfda93923..3e20b3ba5 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -683,8 +683,8 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                              1;
                     if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
    -                    U32 const lenPastStart = RAND(seed) % info.dictContentSize;
    -                    offset = offset+lenPastStart;
    +                    U32 const lenPastStart = RAND(seed) % info.dictContentSize + 1;
    +                    offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
                     repIndex = 2;
    
    From aff86be75ddbda0cea15950f7f7eab024e218966 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Wed, 21 Jun 2017 20:23:44 -0700
    Subject: [PATCH 317/400] [linux] Write all the patch summaries
    
    ---
     .../0001-lib-Add-xxhash-module.patch          |  12 +-
     .../0002-lib-Add-zstd-modules.patch           |  12 +-
     .../0003-btrfs-Add-zstd-support.patch         | 126 +++++++++++++++---
     .../0004-squashfs-Add-zstd-support.patch      |  70 +++++++++-
     .../linux-kernel/btrfs-extract-benchmark.sh   |  99 ++++++++++++++
     5 files changed, 279 insertions(+), 40 deletions(-)
     create mode 100755 contrib/linux-kernel/btrfs-extract-benchmark.sh
    
    diff --git a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    index c3ee41fd1..9a8f50a25 100644
    --- a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    +++ b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch
    @@ -1,6 +1,6 @@
    -From 36b990a005e68a30495e2b2981e30c5ce97a8591 Mon Sep 17 00:00:00 2001
    +From e75beb7c2e05550b2846e31ad8a0082c188504da Mon Sep 17 00:00:00 2001
     From: Nick Terrell 
    -Date: Mon, 12 Jun 2017 12:13:48 -0700
    +Date: Wed, 21 Jun 2017 17:27:42 -0700
     Subject: [PATCH 1/4] lib: Add xxhash module
     
     Adds xxhash kernel module with xxh32 and xxh64 hashes. xxhash is an
    @@ -324,10 +324,10 @@ index 0000000..9e1f42c
     +
     +#endif /* XXHASH_H */
     diff --git a/lib/Kconfig b/lib/Kconfig
    -index 260a80e..9db178f 100644
    +index 0c8b78a..b6009d7 100644
     --- a/lib/Kconfig
     +++ b/lib/Kconfig
    -@@ -185,6 +185,9 @@ config CRC8
    +@@ -184,6 +184,9 @@ config CRC8
      	  when they need to do cyclic redundancy check according CRC8
      	  algorithm. Module will be called crc8.
      
    @@ -338,10 +338,10 @@ index 260a80e..9db178f 100644
      	bool
      	depends on AUDIT && !AUDIT_ARCH
     diff --git a/lib/Makefile b/lib/Makefile
    -index 50144a3..5644bad 100644
    +index 0166fbc..1338226 100644
     --- a/lib/Makefile
     +++ b/lib/Makefile
    -@@ -93,6 +93,7 @@ obj-$(CONFIG_CRC32)	+= crc32.o
    +@@ -102,6 +102,7 @@ obj-$(CONFIG_CRC32_SELFTEST)	+= crc32test.o
      obj-$(CONFIG_CRC7)	+= crc7.o
      obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
      obj-$(CONFIG_CRC8)	+= crc8.o
    diff --git a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    index 4ace675fc..f94afe362 100644
    --- a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    +++ b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch
    @@ -1,6 +1,6 @@
    -From 536a2c59c5bc58f526e69dd0a35b83d39508ae74 Mon Sep 17 00:00:00 2001
    +From b52ae824ae6c0f7c7786380b34da9daaa54bfc26 Mon Sep 17 00:00:00 2001
     From: Nick Terrell 
    -Date: Wed, 21 Jun 2017 14:56:21 -0700
    +Date: Wed, 21 Jun 2017 17:31:24 -0700
     Subject: [PATCH 2/4] lib: Add zstd modules
     
     Add zstd compression and decompression kernel modules.
    @@ -1304,10 +1304,10 @@ index 0000000..249575e
     +
     +#endif  /* ZSTD_H */
     diff --git a/lib/Kconfig b/lib/Kconfig
    -index 9db178f..8deab4f 100644
    +index b6009d7..f00ddab 100644
     --- a/lib/Kconfig
     +++ b/lib/Kconfig
    -@@ -242,6 +242,14 @@ config LZ4HC_COMPRESS
    +@@ -241,6 +241,14 @@ config LZ4HC_COMPRESS
      config LZ4_DECOMPRESS
      	tristate
     
    @@ -1323,10 +1323,10 @@ index 9db178f..8deab4f 100644
     
      #
     diff --git a/lib/Makefile b/lib/Makefile
    -index 5644bad..aa630d4 100644
    +index 1338226..4fcef16 100644
     --- a/lib/Makefile
     +++ b/lib/Makefile
    -@@ -107,6 +107,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
    +@@ -116,6 +116,8 @@ obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
      obj-$(CONFIG_LZ4_COMPRESS) += lz4/
      obj-$(CONFIG_LZ4HC_COMPRESS) += lz4/
      obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
    diff --git a/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch b/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch
    index f984a5383..53d03d3ca 100644
    --- a/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch
    +++ b/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch
    @@ -1,3 +1,83 @@
    +From 599f8f2aaace3df939cb145368574a52268d82d0 Mon Sep 17 00:00:00 2001
    +From: Nick Terrell 
    +Date: Wed, 21 Jun 2017 17:31:39 -0700
    +Subject: [PATCH 3/4] btrfs: Add zstd support
    +
    +Add zstd compression and decompression support to BtrFS. zstd at its
    +fastest level compresses almost as well as zlib, while offering much
    +faster compression and decompression, approaching lzo speeds.
    +
    +I benchmarked btrfs with zstd compression against no compression, lzo
    +compression, and zlib compression. I benchmarked two scenarios. Copying
    +a set of files to btrfs, and then reading the files. Copying a tarball
    +to btrfs, extracting it to btrfs, and then reading the extracted files.
    +After every operation, I call `sync` and include the sync time.
    +Between every pair of operations I unmount and remount the filesystem
    +to avoid caching. The benchmark files can be found in the upstream
    +zstd source repository under
    +`contrib/linux-kernel/{btrfs-benchmark.sh,btrfs-extract-benchmark.sh}`
    +[1] [2].
    +
    +I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    +The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
    +16 GB of RAM, and a SSD.
    +
    +The first compression benchmark is copying 10 copies of the unzipped
    +Silesia corpus [3] into a BtrFS filesystem mounted with
    +`-o compress-force=Method`. The decompression benchmark times how long
    +it takes to `tar` all 10 copies into `/dev/null`. The compression ratio is
    +measured by comparing the output of `df` and `du`. See the benchmark file
    +[1] for details. I benchmarked multiple zstd compression levels, although
    +the patch uses zstd level 1.
    +
    +| Method  | Ratio | Compression MB/s | Decompression speed |
    +|---------|-------|------------------|---------------------|
    +| None    |  0.99 |              504 |                 686 |
    +| lzo     |  1.66 |              398 |                 442 |
    +| zlib    |  2.58 |               65 |                 241 |
    +| zstd 1  |  2.57 |              260 |                 383 |
    +| zstd 3  |  2.71 |              174 |                 408 |
    +| zstd 6  |  2.87 |               70 |                 398 |
    +| zstd 9  |  2.92 |               43 |                 406 |
    +| zstd 12 |  2.93 |               21 |                 408 |
    +| zstd 15 |  3.01 |               11 |                 354 |
    +
    +The next benchmark first copies `linux-4.11.6.tar` [4] to btrfs. Then it
    +measures the compression ratio, extracts the tar, and deletes the tar.
    +Then it measures the compression ratio again, and `tar`s the extracted
    +files into `/dev/null`. See the benchmark file [2] for details.
    +
    +| Method | Tar Ratio | Extract Ratio | Copy (s) | Extract (s)| Read (s) |
    +|--------|-----------|---------------|----------|------------|----------|
    +| None   |      0.97 |          0.78 |    0.981 |      5.501 |    8.807 |
    +| lzo    |      2.06 |          1.38 |    1.631 |      8.458 |    8.585 |
    +| zlib   |      3.40 |          1.86 |    7.750 |     21.544 |   11.744 |
    +| zstd 1 |      3.57 |          1.85 |    2.579 |     11.479 |    9.389 |
    +
    +[1] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/btrfs-benchmark.sh
    +[2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/btrfs-extract-benchmark.sh
    +[3] http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia
    +[4] https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.11.6.tar.xz
    +
    +zstd source repository: https://github.com/facebook/zstd
    +
    +Signed-off-by: Nick Terrell 
    +---
    + fs/btrfs/Kconfig           |   2 +
    + fs/btrfs/Makefile          |   2 +-
    + fs/btrfs/compression.c     |   1 +
    + fs/btrfs/compression.h     |   6 +-
    + fs/btrfs/ctree.h           |   1 +
    + fs/btrfs/disk-io.c         |   2 +
    + fs/btrfs/ioctl.c           |   6 +-
    + fs/btrfs/props.c           |   6 +
    + fs/btrfs/super.c           |  12 +-
    + fs/btrfs/sysfs.c           |   2 +
    + fs/btrfs/zstd.c            | 433 +++++++++++++++++++++++++++++++++++++++++++++
    + include/uapi/linux/btrfs.h |   8 +-
    + 12 files changed, 469 insertions(+), 12 deletions(-)
    + create mode 100644 fs/btrfs/zstd.c
    +
     diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig
     index 80e9c18..a26c63b 100644
     --- a/fs/btrfs/Kconfig
    @@ -25,7 +105,7 @@ index 128ce17..962a95a 100644
      	   reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \
      	   uuid-tree.o props.o hash.o free-space-tree.o
     diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
    -index c7721a6..66d4ced 100644
    +index 10e6b28..3beb0d0 100644
     --- a/fs/btrfs/compression.c
     +++ b/fs/btrfs/compression.c
     @@ -761,6 +761,7 @@ static struct {
    @@ -34,7 +114,7 @@ index c7721a6..66d4ced 100644
      	&btrfs_lzo_compress,
     +	&btrfs_zstd_compress,
      };
    - 
    +
      void __init btrfs_init_compress(void)
     diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
     index 39ec43a..d99fc21 100644
    @@ -50,20 +130,20 @@ index 39ec43a..d99fc21 100644
     +	BTRFS_COMPRESS_TYPES = 3,
     +	BTRFS_COMPRESS_LAST  = 4,
      };
    - 
    +
      struct btrfs_compress_op {
     @@ -92,5 +93,6 @@ struct btrfs_compress_op {
    - 
    +
      extern const struct btrfs_compress_op btrfs_zlib_compress;
      extern const struct btrfs_compress_op btrfs_lzo_compress;
     +extern const struct btrfs_compress_op btrfs_zstd_compress;
    - 
    +
      #endif
     diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
    -index 29b7fc2..878b23b9 100644
    +index 4f8f75d..61dd3dd 100644
     --- a/fs/btrfs/ctree.h
     +++ b/fs/btrfs/ctree.h
    -@@ -270,6 +270,7 @@ struct btrfs_super_block {
    +@@ -271,6 +271,7 @@ struct btrfs_super_block {
      	 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS |		\
      	 BTRFS_FEATURE_INCOMPAT_BIG_METADATA |		\
      	 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO |		\
    @@ -72,24 +152,24 @@ index 29b7fc2..878b23b9 100644
      	 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF |		\
      	 BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA |	\
     diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
    -index 08b74da..0c43e4e 100644
    +index 5f678dc..49c0e91 100644
     --- a/fs/btrfs/disk-io.c
     +++ b/fs/btrfs/disk-io.c
    -@@ -2853,6 +2853,8 @@ int open_ctree(struct super_block *sb,
    +@@ -2831,6 +2831,8 @@ int open_ctree(struct super_block *sb,
      	features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
      	if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
      		features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
    -+	else if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
    ++	else if (fs_info->compress_type == BTRFS_COMPRESS_ZSTD)
     +		features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD;
    - 
    +
      	if (features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
      		btrfs_info(fs_info, "has skinny extents");
     diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
    -index dabfc7a..d8ea727 100644
    +index e176375..f732cfd 100644
     --- a/fs/btrfs/ioctl.c
     +++ b/fs/btrfs/ioctl.c
     @@ -327,8 +327,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
    - 
    +
      		if (fs_info->compress_type == BTRFS_COMPRESS_LZO)
      			comp = "lzo";
     -		else
    @@ -101,13 +181,13 @@ index dabfc7a..d8ea727 100644
      				     comp, strlen(comp), 0);
      		if (ret)
     @@ -1463,6 +1465,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
    - 
    +
      	if (range->compress_type == BTRFS_COMPRESS_LZO) {
      		btrfs_set_fs_incompat(fs_info, COMPRESS_LZO);
     +	} else if (range->compress_type == BTRFS_COMPRESS_ZSTD) {
     +		btrfs_set_fs_incompat(fs_info, COMPRESS_ZSTD);
      	}
    - 
    +
      	ret = defrag_count;
     diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c
     index d6cb155..162105f 100644
    @@ -119,7 +199,7 @@ index d6cb155..162105f 100644
      		return 0;
     +	else if (!strncmp("zstd", value, len))
     +		return 0;
    - 
    +
      	return -EINVAL;
      }
     @@ -405,6 +407,8 @@ static int prop_compression_apply(struct inode *inode,
    @@ -130,7 +210,7 @@ index d6cb155..162105f 100644
     +		type = BTRFS_COMPRESS_ZSTD;
      	else
      		return -EINVAL;
    - 
    +
     @@ -422,6 +426,8 @@ static const char *prop_compression_extract(struct inode *inode)
      		return "zlib";
      	case BTRFS_COMPRESS_LZO:
    @@ -138,10 +218,10 @@ index d6cb155..162105f 100644
     +	case BTRFS_COMPRESS_ZSTD:
     +		return "zstd";
      	}
    - 
    +
      	return NULL;
     diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
    -index da687dc..b064456 100644
    +index 4f1cdd5..4f792d5 100644
     --- a/fs/btrfs/super.c
     +++ b/fs/btrfs/super.c
     @@ -513,6 +513,14 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
    @@ -159,7 +239,7 @@ index da687dc..b064456 100644
      			} else if (strncmp(args[0].from, "no", 2) == 0) {
      				compress_type = "no";
      				btrfs_clear_opt(info->mount_opt, COMPRESS);
    -@@ -1230,8 +1238,10 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
    +@@ -1240,8 +1248,10 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
      	if (btrfs_test_opt(info, COMPRESS)) {
      		if (info->compress_type == BTRFS_COMPRESS_ZLIB)
      			compress_type = "zlib";
    @@ -631,7 +711,7 @@ index 0000000..838741b
     +	.decompress = zstd_decompress,
     +};
     diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
    -index db4c253..f26c34f 100644
    +index a456e53..992c150 100644
     --- a/include/uapi/linux/btrfs.h
     +++ b/include/uapi/linux/btrfs.h
     @@ -255,13 +255,7 @@ struct btrfs_ioctl_fs_info_args {
    @@ -646,6 +726,8 @@ index db4c253..f26c34f 100644
     - */
     -#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZOv2	(1ULL << 4)
     +#define BTRFS_FEATURE_INCOMPAT_COMPRESS_ZSTD	(1ULL << 4)
    - 
    +
      /*
       * older kernels tried to do bigger metadata blocks, but the
    +--
    +2.9.3
    diff --git a/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch b/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch
    index b524819d2..e9c4b98c5 100644
    --- a/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch
    +++ b/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch
    @@ -1,11 +1,67 @@
    +From 5ff6a64abaea7b7f11d37cb0fdf08642316a3a90 Mon Sep 17 00:00:00 2001
    +From: Nick Terrell 
    +Date: Mon, 12 Jun 2017 12:18:23 -0700
    +Subject: [PATCH 4/4] squashfs: Add zstd support
    +
    +Add zstd compression and decompression support to SquashFS. zstd is a
    +great fit for SquashFS because it can compress at ratios approaching xz,
    +while decompressing twice as fast as zlib. For SquashFS in particular,
    +it can decompress as fast as lzo and lz4. It also has the flexibility
    +to turn down the compression ratio for faster compression times.
    +
    +The compression benchmark is run on the file tree from the SquashFS archive
    +found in ubuntu-16.10-desktop-amd64.iso [1]. It uses `mksquashfs` with the
    +default block size (128 KB) and and various compression algorithms/levels.
    +xz and zstd are also benchmarked with 256 KB blocks. The decompression
    +benchmark times how long it takes to `tar` the file tree into `/dev/null`.
    +See the benchmark file in the upstream zstd source repository located under
    +`contrib/linux-kernel/squashfs-benchmark.sh` [2] for details.
    +
    +I ran the benchmarks on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    +The VM is running on a MacBook Pro with a 3.1 GHz Intel Core i7 processor,
    +16 GB of RAM, and a SSD.
    +
    +| Method         | Ratio | Compression MB/s | Decompression MB/s |
    +|----------------|-------|------------------|--------------------|
    +| gzip           |  2.92 |               15 |                128 |
    +| lzo            |  2.64 |              9.5 |                217 |
    +| lz4            |  2.12 |               94 |                218 |
    +| xz             |  3.43 |              5.5 |                 35 |
    +| xz 256 KB      |  3.53 |              5.4 |                 40 |
    +| zstd 1         |  2.71 |               96 |                210 |
    +| zstd 5         |  2.93 |               69 |                198 |
    +| zstd 10        |  3.01 |               41 |                225 |
    +| zstd 15        |  3.13 |             11.4 |                224 |
    +| zstd 16 256 KB |  3.24 |              8.1 |                210 |
    +
    +This patch was written by Sean Purcell , but I will be
    +taking over the submission process.
    +
    +[1] http://releases.ubuntu.com/16.10/
    +[2] https://github.com/facebook/zstd/blob/dev/contrib/linux-kernel/squashfs-benchmark.sh
    +
    +zstd source repository: https://github.com/facebook/zstd
    +
    +Cc: Sean Purcell 
    +Signed-off-by: Nick Terrell 
    +---
    + fs/squashfs/Kconfig        |  14 +++++
    + fs/squashfs/Makefile       |   1 +
    + fs/squashfs/decompressor.c |   7 +++
    + fs/squashfs/decompressor.h |   4 ++
    + fs/squashfs/squashfs_fs.h  |   1 +
    + fs/squashfs/zstd_wrapper.c | 150 +++++++++++++++++++++++++++++++++++++++++++++
    + 6 files changed, 177 insertions(+)
    + create mode 100644 fs/squashfs/zstd_wrapper.c
    +
     diff --git a/fs/squashfs/Kconfig b/fs/squashfs/Kconfig
     index ffb093e..1adb334 100644
     --- a/fs/squashfs/Kconfig
     +++ b/fs/squashfs/Kconfig
     @@ -165,6 +165,20 @@ config SQUASHFS_XZ
    - 
    +
      	  If unsure, say N.
    - 
    +
     +config SQUASHFS_ZSTD
     +	bool "Include support for ZSTD compressed file systems"
     +	depends on SQUASHFS
    @@ -39,7 +95,7 @@ index d2bc136..8366398 100644
     @@ -65,6 +65,12 @@ static const struct squashfs_decompressor squashfs_zlib_comp_ops = {
      };
      #endif
    - 
    +
     +#ifndef CONFIG_SQUASHFS_ZSTD
     +static const struct squashfs_decompressor squashfs_zstd_comp_ops = {
     +	NULL, NULL, NULL, NULL, ZSTD_COMPRESSION, "zstd", 0
    @@ -56,7 +112,7 @@ index d2bc136..8366398 100644
     +	&squashfs_zstd_comp_ops,
      	&squashfs_unknown_comp_ops
      };
    - 
    +
     diff --git a/fs/squashfs/decompressor.h b/fs/squashfs/decompressor.h
     index a25713c..0f5a8e4 100644
     --- a/fs/squashfs/decompressor.h
    @@ -64,7 +120,7 @@ index a25713c..0f5a8e4 100644
     @@ -58,4 +58,8 @@ extern const struct squashfs_decompressor squashfs_lzo_comp_ops;
      extern const struct squashfs_decompressor squashfs_zlib_comp_ops;
      #endif
    - 
    +
     +#ifdef CONFIG_SQUASHFS_ZSTD
     +extern const struct squashfs_decompressor squashfs_zstd_comp_ops;
     +#endif
    @@ -79,7 +135,7 @@ index 506f4ba..24d12fd 100644
      #define XZ_COMPRESSION		4
      #define LZ4_COMPRESSION		5
     +#define ZSTD_COMPRESSION	6
    - 
    +
      struct squashfs_super_block {
      	__le32			s_magic;
     diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c
    @@ -238,3 +294,5 @@ index 0000000..8cb7c76
     +	.name = "zstd",
     +	.supported = 1
     +};
    +--
    +2.9.3
    diff --git a/contrib/linux-kernel/btrfs-extract-benchmark.sh b/contrib/linux-kernel/btrfs-extract-benchmark.sh
    new file mode 100755
    index 000000000..69721d093
    --- /dev/null
    +++ b/contrib/linux-kernel/btrfs-extract-benchmark.sh
    @@ -0,0 +1,99 @@
    +# !/bin/sh
    +set -e
    +
    +# Benchmarks run on a Ubuntu 14.04 VM with 2 cores and 4 GiB of RAM.
    +# The VM is running on a Macbook Pro with a 3.1 GHz Intel Core i7 processor and
    +# 16 GB of RAM and an SSD.
    +
    +# silesia is a directory that can be downloaded from
    +# http://mattmahoney.net/dc/silesia.html
    +# ls -l silesia/
    +# total 203M
    +# -rwxr-xr-x 1 terrelln 9.8M Apr 12  2002 dickens
    +# -rwxr-xr-x 1 terrelln  49M May 31  2002 mozilla
    +# -rwxr-xr-x 1 terrelln 9.6M Mar 20  2003 mr
    +# -rwxr-xr-x 1 terrelln  32M Apr  2  2002 nci
    +# -rwxr-xr-x 1 terrelln 5.9M Jul  4  2002 ooffice
    +# -rwxr-xr-x 1 terrelln 9.7M Apr 11  2002 osdb
    +# -rwxr-xr-x 1 terrelln 6.4M Apr  2  2002 reymont
    +# -rwxr-xr-x 1 terrelln  21M Mar 25  2002 samba
    +# -rwxr-xr-x 1 terrelln 7.0M Mar 24  2002 sao
    +# -rwxr-xr-x 1 terrelln  40M Mar 25  2002 webster
    +# -rwxr-xr-x 1 terrelln 8.1M Apr  4  2002 x-ray
    +# -rwxr-xr-x 1 terrelln 5.1M Nov 30  2000 xml
    +
    +# $HOME is on a ext4 filesystem
    +BENCHMARK_FILE="linux-4.11.6.tar"
    +BENCHMARK_DIR="$HOME/$BENCHMARK_FILE"
    +
    +# Normalize the environment
    +sudo umount /mnt/btrfs 2> /dev/null > /dev/null || true
    +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs
    +sudo rm -rf /mnt/btrfs/*
    +sync
    +sudo umount /mnt/btrfs
    +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs
    +
    +# Run the benchmark
    +echo "Copy"
    +time sh -c "sudo cp -r $BENCHMARK_DIR /mnt/btrfs/$BENCHMARK_FILE && sync"
    +
    +echo "Approximate tarred compression ratio"
    +printf "%d / %d\n"                                                             \
    +  $(df /mnt/btrfs --output=used -B 1 | tail -n 1)                              \
    +  $(sudo du /mnt/btrfs -b -d 0 | tr '\t' '\n' | head -n 1);
    +
    +# Unmount and remount to avoid any caching
    +sudo umount /mnt/btrfs
    +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs
    +
    +echo "Extract"
    +time sh -c "sudo tar -C /mnt/btrfs -xf /mnt/btrfs/$BENCHMARK_FILE && sync"
    +
    +# Remove the tarball, leaving only the extracted data
    +sudo rm /mnt/btrfs/$BENCHMARK_FILE
    +# Unmount and remount to avoid any caching
    +sudo umount /mnt/btrfs
    +sudo mount -t btrfs $@ /dev/sda3 /mnt/btrfs
    +
    +echo "Approximate extracted compression ratio"
    +printf "%d / %d\n"                                                             \
    +  $(df /mnt/btrfs --output=used -B 1 | tail -n 1)                              \
    +  $(sudo du /mnt/btrfs -b -d 0 | tr '\t' '\n' | head -n 1);
    +
    +echo "Read"
    +time sudo tar -c /mnt/btrfs 2> /dev/null | wc -c > /dev/null
    +
    +sudo rm -rf /mnt/btrfs/*
    +sudo umount /mnt/btrfs
    +
    +# Run for each of -o compress-force={none, lzo, zlib, zstd} 5 times and take the
    +# min time and ratio.
    +
    +# none
    +# copy: 0.981 s
    +# extract: 5.501 s
    +# read: 8.807 s
    +# tarball ratio: 0.97
    +# extracted ratio: 0.78
    +
    +# lzo
    +# copy: 1.631 s
    +# extract: 8.458 s
    +# read: 8.585 s
    +# tarball ratio: 2.06
    +# extracted ratio: 1.38
    +
    +# zlib
    +# copy: 7.750 s
    +# extract: 21.544 s
    +# read: 11.744 s
    +# tarball ratio : 3.40
    +# extracted ratio: 1.86
    +
    +# zstd 1
    +# copy: 2.579 s
    +# extract: 11.479 s
    +# read: 9.389 s
    +# tarball ratio : 3.57
    +# extracted ratio: 1.85
    
    From f99c2c1a229b1a64c77e7e7fd4f15e3d8686aa37 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 21 Jun 2017 23:35:58 -0700
    Subject: [PATCH 318/400] reduced --no-big-tests even more
    
    to pass tests on qemu-aarch64
    ---
     tests/zstreamtest.c | 10 +++++-----
     1 file changed, 5 insertions(+), 5 deletions(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 3ab8d0537..c972956c3 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -45,7 +45,7 @@
     #define GB *(1U<<30)
     
     static const U32 nbTestsDefault = 10000;
    -static const U32 g_cLevelMax_smallTests = 15;
    +static const U32 g_cLevelMax_smallTests = 10;
     #define COMPRESSIBLE_NOISE_LENGTH (10 MB)
     #define FUZ_COMPRESSIBILITY_DEFAULT 50
     static const U32 prime32 = 2654435761U;
    @@ -670,7 +670,7 @@ static size_t FUZ_randomLength(U32* seed, U32 maxLog)
     
     static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibility, int bigTests)
     {
    -    static const U32 maxSrcLog = 24;
    +    U32 const maxSrcLog = bigTests ? 24 : 22;
         static const U32 maxSampleLog = 19;
         size_t const srcBufferSize = (size_t)1<
    Date: Thu, 22 Jun 2017 10:04:14 -0700
    Subject: [PATCH 319/400] changed format of command to --use-dict=#
    
    ---
     tests/decodecorpus.c | 40 ++++++++++++++++++++++++++++++++++++----
     1 file changed, 36 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 3e20b3ba5..6447567f9 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1615,7 +1615,40 @@ static void advancedUsage(const char* programName)
         DISPLAY( "\n");
         DISPLAY( "Advanced arguments :\n");
         DISPLAY( " --content-size    : always include the content size in the frame header\n");
    -    DISPLAY( " --use-dict #      : include a dictionary used to decompress the corpus\n");
    +    DISPLAY( " --use-dict=#      : include a dictionary used to decompress the corpus\n");
    +}
    +
    +/*! readU32FromChar() :
    +    @return : unsigned integer value read from input in `char` format
    +    allows and interprets K, KB, KiB, M, MB and MiB suffix.
    +    Will also modify `*stringPtr`, advancing it to position where it stopped reading.
    +    Note : function result can overflow if digit string > MAX_UINT */
    +static unsigned readU32FromChar(const char** stringPtr)
    +{
    +    unsigned result = 0;
    +    while ((**stringPtr >='0') && (**stringPtr <='9'))
    +        result *= 10, result += **stringPtr - '0', (*stringPtr)++ ;
    +    if ((**stringPtr=='K') || (**stringPtr=='M')) {
    +        result <<= 10;
    +        if (**stringPtr=='M') result <<= 10;
    +        (*stringPtr)++ ;
    +        if (**stringPtr=='i') (*stringPtr)++;
    +        if (**stringPtr=='B') (*stringPtr)++;
    +    }
    +    return result;
    +}
    +
    +/** longCommandWArg() :
    + *  check if *stringPtr is the same as longCommand.
    + *  If yes, @return 1 and advances *stringPtr to the position which immediately follows longCommand.
    + *  @return 0 and doesn't modify *stringPtr otherwise.
    + */
    +static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
    +{
    +    size_t const comSize = strlen(longCommand);
    +    int const result = !strncmp(*stringPtr, longCommand, comSize);
    +    if (result) *stringPtr += comSize;
    +    return result;
     }
     
     int main(int argc, char** argv)
    @@ -1689,9 +1722,8 @@ int main(int argc, char** argv)
                         argument++;
                         if (strcmp(argument, "content-size") == 0) {
                             opts.contentSize = 1;
    -                    } else if (strcmp(argument, "use-dict") == 0) {
    -                        argument += 9;
    -                        dictSize = readInt(&argument);
    +                    } else if (longCommandWArg(&argument, "use-dict=")) {
    +                        dictSize = readU32FromChar(&argument);
                             useDict = 1;
                         } else {
                             advancedUsage(argv[0]);
    
    From 98751f69e77433013e6842f742626dc83f1b5cf5 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 10:23:36 -0700
    Subject: [PATCH 320/400] should be updating seed whenever multiple files are
     generated
    
    ---
     tests/decodecorpus.c | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 6447567f9..9e4ff810c 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1389,7 +1389,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
     
             {
                 dictInfo const info = initDictInfo(0, 0, NULL, 0);
    -            generateFrame(seed, &fr, info);
    +            seed = generateFrame(seed, &fr, info);
             }
     
             {   size_t const r = testDecodeSimple(&fr);
    @@ -1461,7 +1461,7 @@ static int generateCorpus(U32 seed, unsigned numFiles, const char* const path,
     
             {
                 dictInfo const info = initDictInfo(0, 0, NULL, 0);
    -            generateFrame(seed, &fr, info);
    +            seed = generateFrame(seed, &fr, info);
             }
     
             if (snprintf(outPath, MAX_PATH, "%s/z%06u.zst", path, fnum) + 1 > MAX_PATH) {
    
    From 028fb9d01bc451672a49bb3c4862ae6b393053f9 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 13:53:39 -0700
    Subject: [PATCH 321/400] added cli test case in Makefile
    
    ---
     tests/Makefile | 18 ++++++++++++++++++
     1 file changed, 18 insertions(+)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index debe83898..d551a85ef 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -340,6 +340,24 @@ test-legacy: legacy
     test-decodecorpus: decodecorpus
     	$(QEMU_SYS) ./decodecorpus -t $(DECODECORPUS_TESTTIME)
     
    +test-decodecorpus-cli: decodecorpus
    +	@echo "\n ---- decodecorpus basic cli tests ----"
    +	mkdir tests
    +	./decodecorpus -n5 -otests -ptests
    +	cd testdir
    +	zstd -d z000000.zst -D dictionary -o tmp0
    +	zstd -d z000001.zst -D dictionary -o tmp1
    +	zstd -d z000002.zst -D dictionary -o tmp2
    +	zstd -d z000003.zst -D dictionary -o tmp3
    +	zstd -d z000004.zst -D dictionary -o tmp4
    +	diff z000000 tmp0
    +	diff z000001 tmp1
    +	diff z000002 tmp2
    +	diff z000003 tmp3
    +	diff z000004 tmp4
    +	cd ..
    +	rm -rf testdir
    +
     test-pool: pool
     	$(QEMU_SYS) ./pool
     
    
    From 829eb29033a97f2d5f83e3bef06455f8b8473b90 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 14:43:44 -0700
    Subject: [PATCH 322/400] added cli test for decodecorpus inside
     tests/Makefile. Also changed calculation of offset
    
    ---
     tests/Makefile       | 45 +++++++++++++++++++++++++++++---------------
     tests/decodecorpus.c | 10 ++++++++--
     2 files changed, 38 insertions(+), 17 deletions(-)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index d551a85ef..4789b1ccf 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -342,21 +342,36 @@ test-decodecorpus: decodecorpus
     
     test-decodecorpus-cli: decodecorpus
     	@echo "\n ---- decodecorpus basic cli tests ----"
    -	mkdir tests
    -	./decodecorpus -n5 -otests -ptests
    -	cd testdir
    -	zstd -d z000000.zst -D dictionary -o tmp0
    -	zstd -d z000001.zst -D dictionary -o tmp1
    -	zstd -d z000002.zst -D dictionary -o tmp2
    -	zstd -d z000003.zst -D dictionary -o tmp3
    -	zstd -d z000004.zst -D dictionary -o tmp4
    -	diff z000000 tmp0
    -	diff z000001 tmp1
    -	diff z000002 tmp2
    -	diff z000003 tmp3
    -	diff z000004 tmp4
    -	cd ..
    -	rm -rf testdir
    +	@mkdir testdir
    +	./decodecorpus -n5 -otestdir -ptestdir
    +	@cd testdir \
    +	zstd -d z000000.zst -o tmp0 \
    +	zstd -d z000001.zst -o tmp1 \
    +	zstd -d z000002.zst -o tmp2 \
    +	zstd -d z000003.zst -o tmp3 \
    +	zstd -d z000004.zst -o tmp4 \
    +	diff z000000 tmp0 \
    +	diff z000001 tmp1 \
    +	diff z000002 tmp2 \
    +	diff z000003 tmp3 \
    +	diff z000004 tmp4 \
    +	@rm ./* \
    +	@cd ..
    +
    +	./decodecorpus -n5 -otestdir -ptestdir --use-dict=1MB
    +	@cd testdir \
    +	zstd -d z000000.zst -D dictionary -o tmp0 \
    +	zstd -d z000001.zst -D dictionary -o tmp1 \
    +	zstd -d z000002.zst -D dictionary -o tmp2 \
    +	zstd -d z000003.zst -D dictionary -o tmp3 \
    +	zstd -d z000004.zst -D dictionary -o tmp4 \
    +	diff z000000 tmp0 \
    +	diff z000001 tmp1 \
    +	diff z000002 tmp2 \
    +	diff z000003 tmp3 \
    +	diff z000004 tmp4 \
    +	@cd .. 
    +	@rm -rf testdir
     
     test-pool: pool
     	$(QEMU_SYS) ./pool
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 9e4ff810c..81ddc4b69 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -648,7 +648,6 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
         }
     
         DISPLAYLEVEL(5, "    total match lengths: %u\n", (U32)remainingMatch);
    -
         for (i = 0; i < numSequences; i++) {
             /* Generate match and literal lengths by exponential distribution to
              * ensure nice numbers */
    @@ -683,8 +682,15 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                              1;
                     if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
    -                    U32 const lenPastStart = RAND(seed) % info.dictContentSize + 1;
    +                    U32 const lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
                         offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
    +                    if (lenPastStart > frame->header.windowSize) {
    +                        matchLen = MIN(matchLen, frame->header.windowSize);
    +                    }
    +                    if (offset > frame->header.windowSize) {
    +                        U32 const matchLenBound = MIN(frame->header.windowSize, lenPastStart);
    +                        matchLen = MIN(matchLen, matchLenBound);
    +                    }
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
                     repIndex = 2;
    
    From 97a8f89bec49f285f779a4601aff7e27b93bfae1 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 15:13:41 -0700
    Subject: [PATCH 323/400] made changes to cli test so it runs properly
    
    ---
     tests/Makefile | 51 +++++++++++++++++++++++++-------------------------
     1 file changed, 25 insertions(+), 26 deletions(-)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index 4789b1ccf..033e3f782 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -344,33 +344,32 @@ test-decodecorpus-cli: decodecorpus
     	@echo "\n ---- decodecorpus basic cli tests ----"
     	@mkdir testdir
     	./decodecorpus -n5 -otestdir -ptestdir
    -	@cd testdir \
    -	zstd -d z000000.zst -o tmp0 \
    -	zstd -d z000001.zst -o tmp1 \
    -	zstd -d z000002.zst -o tmp2 \
    -	zstd -d z000003.zst -o tmp3 \
    -	zstd -d z000004.zst -o tmp4 \
    -	diff z000000 tmp0 \
    -	diff z000001 tmp1 \
    -	diff z000002 tmp2 \
    -	diff z000003 tmp3 \
    -	diff z000004 tmp4 \
    -	@rm ./* \
    -	@cd ..
    -
    +	@cd testdir && \
    +	$(ZSTD) -d z000000.zst -o tmp0 && \
    +	$(ZSTD) -d z000001.zst -o tmp1 && \
    +	$(ZSTD) -d z000002.zst -o tmp2 && \
    +	$(ZSTD) -d z000003.zst -o tmp3 && \
    +	$(ZSTD) -d z000004.zst -o tmp4 && \
    +	diff z000000 tmp0 && \
    +	diff z000001 tmp1 && \
    +	diff z000002 tmp2 && \
    +	diff z000003 tmp3 && \
    +	diff z000004 tmp4 && \
    +	rm ./* && \
    +	cd ..
     	./decodecorpus -n5 -otestdir -ptestdir --use-dict=1MB
    -	@cd testdir \
    -	zstd -d z000000.zst -D dictionary -o tmp0 \
    -	zstd -d z000001.zst -D dictionary -o tmp1 \
    -	zstd -d z000002.zst -D dictionary -o tmp2 \
    -	zstd -d z000003.zst -D dictionary -o tmp3 \
    -	zstd -d z000004.zst -D dictionary -o tmp4 \
    -	diff z000000 tmp0 \
    -	diff z000001 tmp1 \
    -	diff z000002 tmp2 \
    -	diff z000003 tmp3 \
    -	diff z000004 tmp4 \
    -	@cd .. 
    +	@cd testdir && \
    +	$(ZSTD) -d z000000.zst -D dictionary -o tmp0 && \
    +	$(ZSTD) -d z000001.zst -D dictionary -o tmp1 && \
    +	$(ZSTD) -d z000002.zst -D dictionary -o tmp2 && \
    +	$(ZSTD) -d z000003.zst -D dictionary -o tmp3 && \
    +	$(ZSTD) -d z000004.zst -D dictionary -o tmp4 && \
    +	diff z000000 tmp0 && \
    +	diff z000001 tmp1 && \
    +	diff z000002 tmp2 && \
    +	diff z000003 tmp3 && \
    +	diff z000004 tmp4 && \
    +	@cd ..
     	@rm -rf testdir
     
     test-pool: pool
    
    From 29352395445b2c84c08d91c940662f5471115fb0 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 15:23:59 -0700
    Subject: [PATCH 324/400] added description for dictionary cli tests
    
    ---
     tests/Makefile | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index 033e3f782..723c2a9d9 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -357,6 +357,7 @@ test-decodecorpus-cli: decodecorpus
     	diff z000004 tmp4 && \
     	rm ./* && \
     	cd ..
    +	@echo "\n ---- decodecorpus dictionary cli tests ----"
     	./decodecorpus -n5 -otestdir -ptestdir --use-dict=1MB
     	@cd testdir && \
     	$(ZSTD) -d z000000.zst -D dictionary -o tmp0 && \
    
    From b325a2e4dbc009f0caf60920b8e9d2a15917be67 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 15:36:28 -0700
    Subject: [PATCH 325/400] changed assignment
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 81ddc4b69..2517483ff 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1198,7 +1198,7 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
                 {
                     size_t k;
                     for (k = 0; k < currSize; k++) {
    -                    samples[samplesPos++] = (BYTE)literalValue;
    +                    *(samples + (samplesPos++)) = (BYTE)literalValue;
                     }
                 }
                 literalValue++;
    
    From 6d7f4421201c6cbea7ec717a350b6e4d81c1ff1a Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 15:44:01 -0700
    Subject: [PATCH 326/400] changed makefile test
    
    ---
     tests/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index 723c2a9d9..960708875 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -370,7 +370,7 @@ test-decodecorpus-cli: decodecorpus
     	diff z000002 tmp2 && \
     	diff z000003 tmp3 && \
     	diff z000004 tmp4 && \
    -	@cd ..
    +	cd ..
     	@rm -rf testdir
     
     test-pool: pool
    
    From 2e8cc6f12a59aad052770ef713fec826803d0afb Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Thu, 22 Jun 2017 15:52:33 -0700
    Subject: [PATCH 327/400] added sizeof for clarity
    
    ---
     tests/decodecorpus.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 2517483ff..60cdc2969 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1182,7 +1182,7 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
         int ret = 0;
         unsigned const numSamples = 4;
         size_t sampleSizes[4];
    -    BYTE* const samples = malloc(5000);
    +    BYTE* const samples = malloc(5000*sizeof(BYTE));
         if (samples == NULL) {
             DISPLAY("Error: could not allocate space for samples\n");
             return 1;
    
    From f570609286c65e227ee1d43bc3bf746c05f4a09b Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Thu, 22 Jun 2017 18:09:42 -0700
    Subject: [PATCH 328/400] [pzstd] Fix deadlock in the case of errors
    
    Fixes #720.
    ---
     contrib/pzstd/Pzstd.cpp | 5 ++++-
     1 file changed, 4 insertions(+), 1 deletion(-)
    
    diff --git a/contrib/pzstd/Pzstd.cpp b/contrib/pzstd/Pzstd.cpp
    index 1265b53ef..ae5d73444 100644
    --- a/contrib/pzstd/Pzstd.cpp
    +++ b/contrib/pzstd/Pzstd.cpp
    @@ -585,7 +585,10 @@ std::uint64_t writeFile(
       std::uint64_t bytesWritten = 0;
       std::shared_ptr out;
       // Grab the output queue for each decompression job (in order).
    -  while (outs.pop(out) && !errorHolder.hasError()) {
    +  while (outs.pop(out)) {
    +    if (errorHolder.hasError()) {
    +      continue;
    +    }
         if (!decompress) {
           // If we are compressing and want to write skippable frames we can't
           // start writing before compression is done because we need to know the
    
    From 32f546c7630f9c1c3219c297225a4d6c15815b4a Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 23 Jun 2017 00:09:02 -0700
    Subject: [PATCH 329/400] zstreamtest : disabled multi-threading tests with
     --newapi --no-big-tests
    
    --no-big-tests is typically used in combination with qemu-user-static
    qemu-user-static allocated 4 GB of RAM upfront.
    On 2 GB VM, this can degenerate into a crash.
    It's not a problem as long as memory is not used.
    But with multi-threading enabled, memory fragmentation kicks in,
    so the amoung of RAM effectively touched increases,
    and can pass beyond the 2 GB limit of the VM.
    
    In single-threaded mode, there is no such issue :
    memory requirement is smaller, and remains well-located,
    so very little fragmentation is expected.
    
    This modification should make `qemu-arm-static zstreamtests --newapi --no-big-tests`
    work fine on Travis CI.
    ---
     tests/zstreamtest.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 3ab8d0537..33ed11f93 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -1193,7 +1193,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
         size_t dictSize = 0;
         U32 oldTestLog = 0;
         U32 const cLevelMax = bigTests ? (U32)ZSTD_maxCLevel() : g_cLevelMax_smallTests;
    -    U32 const nbThreadsMax = bigTests ? 5 : 2;
    +    U32 const nbThreadsMax = bigTests ? 5 : 1;
     
         /* allocations */
         cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
    
    From 6122af9cf576f7dfd6bb376ca00fdaa7886981f9 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Fri, 23 Jun 2017 00:37:15 -0700
    Subject: [PATCH 330/400] --no-big-tests for msan
    
    msan tests require too much RAM for 2 GB VM
    ---
     Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Makefile b/Makefile
    index 3cf1cb0b0..679e05625 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -227,7 +227,7 @@ msan: clean
     	$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer"   # datagen.c fails this test for no obvious reason
     
     msan-%: clean
    -	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" $(MAKE) -C $(TESTDIR) $*
    +	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) $*
     
     asan32: clean
     	$(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
    
    From 4219acc60adcf6b0c87687a1cfc84920fae3481a Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 23 Jun 2017 11:22:29 -0700
    Subject: [PATCH 331/400] fixed bus error bug
    
    ---
     tests/decodecorpus.c | 21 +++++++++++++--------
     1 file changed, 13 insertions(+), 8 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 60cdc2969..f04a02fa7 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -672,7 +672,6 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
     
             memcpy(srcPtr, literals, literalLen);
             srcPtr += literalLen;
    -
             do {
                 if (RAND(seed) & 7) {
                     /* do a normal offset */
    @@ -682,14 +681,20 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                              1;
                     if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
    -                    U32 const lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
    +                    U32 lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
                         offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
    -                    if (lenPastStart > frame->header.windowSize) {
    -                        matchLen = MIN(matchLen, frame->header.windowSize);
    -                    }
                         if (offset > frame->header.windowSize) {
    -                        U32 const matchLenBound = MIN(frame->header.windowSize, lenPastStart);
    -                        matchLen = MIN(matchLen, matchLenBound);
    +                        if (lenPastStart < MIN_SEQ_LEN) {
    +                            /* when offset > windowSize, matchLen bound by end of dictionary (lenPastStart) */
    +                            /* this also means that lenPastStart must be greater than MIN_SEQ_LEN */
    +                            /* make sure lenPastStart does not go past dictionary start though */
    +                            lenPastStart = MIN(lenPastStart+MIN_SEQ_LEN, info.dictContentSize);
    +                            offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart) + lenPastStart;
    +                        }
    +                        {
    +                            U32 const matchLenBound = MIN(frame->header.windowSize, lenPastStart);
    +                            matchLen = MIN(matchLen, matchLenBound);
    +                        }
                         }
                     }
                     offsetCode = offset + ZSTD_REP_MOVE;
    @@ -713,7 +718,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                 size_t j;
                 BYTE* const dictEnd = info.dictContent + info.dictContentSize;
                 for (j = 0; j < matchLen; j++) {
    -                if ((void*)(srcPtr - offset) < (void*)frame->srcStart) {
    +                if (((BYTE*)srcPtr - (BYTE*)frame->srcStart) < offset) {
                         /* copy from dictionary instead of literals */
                         size_t const dictOffset = offset - (srcPtr - (BYTE*)frame->srcStart);
                         *srcPtr = *(dictEnd - dictOffset);
    
    From 8cd134559dc9a3bf63205f240b03b74f1f75d3d5 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 23 Jun 2017 12:00:48 -0700
    Subject: [PATCH 332/400] type warnings
    
    ---
     tests/decodecorpus.c | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index f04a02fa7..7ff7fc4f3 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -682,14 +682,14 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                     if (info.useDict && (RAND(seed) & 1)) {
                         /* need to occasionally generate offsets that go past the start */
                         U32 lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
    -                    offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
    +                    offset = (U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
                         if (offset > frame->header.windowSize) {
                             if (lenPastStart < MIN_SEQ_LEN) {
                                 /* when offset > windowSize, matchLen bound by end of dictionary (lenPastStart) */
                                 /* this also means that lenPastStart must be greater than MIN_SEQ_LEN */
                                 /* make sure lenPastStart does not go past dictionary start though */
    -                            lenPastStart = MIN(lenPastStart+MIN_SEQ_LEN, info.dictContentSize);
    -                            offset = ((BYTE*)srcPtr - (BYTE*)frame->srcStart) + lenPastStart;
    +                            lenPastStart = MIN(lenPastStart+MIN_SEQ_LEN, (U32)info.dictContentSize);
    +                            offset = (U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart) + lenPastStart;
                             }
                             {
                                 U32 const matchLenBound = MIN(frame->header.windowSize, lenPastStart);
    @@ -718,7 +718,7 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                 size_t j;
                 BYTE* const dictEnd = info.dictContent + info.dictContentSize;
                 for (j = 0; j < matchLen; j++) {
    -                if (((BYTE*)srcPtr - (BYTE*)frame->srcStart) < offset) {
    +                if ((U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart) < offset) {
                         /* copy from dictionary instead of literals */
                         size_t const dictOffset = offset - (srcPtr - (BYTE*)frame->srcStart);
                         *srcPtr = *(dictEnd - dictOffset);
    
    From 20853758162d0823b8e5130467ca809e7c728126 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 23 Jun 2017 13:44:24 -0700
    Subject: [PATCH 333/400] fixed bug detected by the API test
    
    ---
     tests/decodecorpus.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 7ff7fc4f3..eaeb05eac 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -679,8 +679,9 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
                               MIN(frame->header.windowSize,
                                   (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) +
                              1;
    -                if (info.useDict && (RAND(seed) & 1)) {
    +                if (info.useDict && (RAND(seed) & 1) && i + 1 != numSequences) {
                         /* need to occasionally generate offsets that go past the start */
    +                    /* including i+1 != numSequences because the last sequences has to adhere to predetermined contentSize */
                         U32 lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
                         offset = (U32)((BYTE*)srcPtr - (BYTE*)frame->srcStart)+lenPastStart;
                         if (offset > frame->header.windowSize) {
    
    From 3a295a91f8c8645888d7701eeb4c813c8fd663b8 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 23 Jun 2017 15:54:51 -0700
    Subject: [PATCH 334/400] added additional condition so large offsets into the
     dictionary are not generated past windowSize
    
    ---
     tests/decodecorpus.c | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index eaeb05eac..9e5e973ca 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -675,11 +675,12 @@ static U32 generateSequences(U32* seed, frame_t* frame, seqStore_t* seqStore,
             do {
                 if (RAND(seed) & 7) {
                     /* do a normal offset */
    +                U32 const dataDecompressed = (U32)((BYTE*)srcPtr-(BYTE*)frame->srcStart);
                     offset = (RAND(seed) %
                               MIN(frame->header.windowSize,
                                   (size_t)((BYTE*)srcPtr - (BYTE*)frame->srcStart))) +
                              1;
    -                if (info.useDict && (RAND(seed) & 1) && i + 1 != numSequences) {
    +                if (info.useDict && (RAND(seed) & 1) && i + 1 != numSequences && dataDecompressed < frame->header.windowSize) {
                         /* need to occasionally generate offsets that go past the start */
                         /* including i+1 != numSequences because the last sequences has to adhere to predetermined contentSize */
                         U32 lenPastStart = (RAND(seed) % info.dictContentSize) + 1;
    
    From 298fe9f23b25b0ce03e6238f6ec777e48e3c94ca Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Fri, 23 Jun 2017 17:10:41 -0700
    Subject: [PATCH 335/400] added cli tests to test-all
    
    ---
     tests/Makefile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/tests/Makefile b/tests/Makefile
    index 960708875..ebfdc1287 100644
    --- a/tests/Makefile
    +++ b/tests/Makefile
    @@ -272,7 +272,7 @@ endif
     
     test32: test-zstd32 test-fullbench32 test-fuzzer32 test-zstream32
     
    -test-all: test test32 valgrindTest
    +test-all: test test32 valgrindTest test-decodecorpus-cli
     
     test-zstd: ZSTD = $(PRGDIR)/zstd
     test-zstd: zstd zstd-playTests
    
    From 849ecf35103a3ea76f41196e63ccf2f076278fa4 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Fri, 23 Jun 2017 16:54:16 -0700
    Subject: [PATCH 336/400] [zstdcli] Support xz by default when liblzma is
     available
    
    ---
     programs/Makefile | 17 +++++++----------
     programs/fileio.c | 14 +++++++-------
     2 files changed, 14 insertions(+), 17 deletions(-)
    
    diff --git a/programs/Makefile b/programs/Makefile
    index ab2db7284..e956a7dfa 100644
    --- a/programs/Makefile
    +++ b/programs/Makefile
    @@ -139,16 +139,13 @@ all: zstd
     
     $(ZSTDDECOMP_O): CFLAGS += $(ALIGN_LOOP)
     
    -zstd xzstd zstd4 xzstd4 : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP)
    -zstd xzstd zstd4 xzstd4 : LDFLAGS += $(THREAD_LD) $(ZLIBLD)
    -xzstd xzstd4 : CPPFLAGS += $(LZMACPP)
    -xzstd xzstd4 : LDFLAGS += $(LZMALD)
    -zstd4 xzstd4 : CPPFLAGS += $(LZ4CPP)
    -zstd4 xzstd4 : LDFLAGS += $(LZ4LD)
    -zstd zstd4 : LZMA_MSG := - xz/lzma support is disabled
    -zstd xzstd : LZ4_MSG := - lz4 support is disabled
    -zstd xzstd zstd4 xzstd4 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
    -zstd xzstd zstd4 xzstd4 : $(ZSTDLIB_FILES) zstdcli.o fileio.o bench.o datagen.o dibio.o
    +zstd zstd4 : CPPFLAGS += $(THREAD_CPP) $(ZLIBCPP) $(LZMACPP)
    +zstd zstd4 : LDFLAGS += $(THREAD_LD) $(ZLIBLD) $(LZMALD)
    +zstd4 : CPPFLAGS += $(LZ4CPP)
    +zstd4 : LDFLAGS += $(LZ4LD)
    +zstd : LZ4_MSG := - lz4 support is disabled
    +zstd zstd4 : CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT)
    +zstd zstd4 : $(ZSTDLIB_FILES) zstdcli.o fileio.o bench.o datagen.o dibio.o
     	@echo "$(THREAD_MSG)"
     	@echo "$(ZLIB_MSG)"
     	@echo "$(LZMA_MSG)"
    diff --git a/programs/fileio.c b/programs/fileio.c
    index 78ac3ba6a..779437175 100644
    --- a/programs/fileio.c
    +++ b/programs/fileio.c
    @@ -559,7 +559,7 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress,
     
         strm.next_in = 0;
         strm.avail_in = 0;
    -    strm.next_out = ress->dstBuffer;
    +    strm.next_out = (BYTE*)ress->dstBuffer;
         strm.avail_out = ress->dstBufferSize;
     
         while (1) {
    @@ -567,7 +567,7 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress,
                 size_t const inSize = fread(ress->srcBuffer, 1, ress->srcBufferSize, ress->srcFile);
                 if (inSize == 0) action = LZMA_FINISH;
                 inFileSize += inSize;
    -            strm.next_in = ress->srcBuffer;
    +            strm.next_in = (BYTE const*)ress->srcBuffer;
                 strm.avail_in = inSize;
             }
     
    @@ -580,7 +580,7 @@ static unsigned long long FIO_compressLzmaFrame(cRess_t* ress,
                     if (fwrite(ress->dstBuffer, 1, compBytes, ress->dstFile) != compBytes)
                         EXM_THROW(73, "Write error : cannot write to output file");
                     outFileSize += compBytes;
    -                strm.next_out = ress->dstBuffer;
    +                strm.next_out = (BYTE*)ress->dstBuffer;
                     strm.avail_out = ress->dstBufferSize;
             }   }
             if (!srcFileSize)
    @@ -1490,16 +1490,16 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
             EXM_THROW(71, "zstd: %s: lzma_alone_decoder/lzma_stream_decoder error %d",
                             srcFileName, ret);
     
    -    strm.next_out = ress->dstBuffer;
    +    strm.next_out = (BYTE*)ress->dstBuffer;
         strm.avail_out = ress->dstBufferSize;
    +    strm.next_in = (BYTE const*)ress->srcBuffer;
         strm.avail_in = ress->srcBufferLoaded;
    -    strm.next_in = ress->srcBuffer;
     
         for ( ; ; ) {
             if (strm.avail_in == 0) {
                 ress->srcBufferLoaded = fread(ress->srcBuffer, 1, ress->srcBufferSize, srcFile);
                 if (ress->srcBufferLoaded == 0) action = LZMA_FINISH;
    -            strm.next_in = ress->srcBuffer;
    +            strm.next_in = (BYTE const*)ress->srcBuffer;
                 strm.avail_in = ress->srcBufferLoaded;
             }
             ret = lzma_code(&strm, action);
    @@ -1515,7 +1515,7 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile,
                     if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes)
                         EXM_THROW(31, "Write error : cannot write to output file");
                     outFileSize += decompBytes;
    -                strm.next_out = ress->dstBuffer;
    +                strm.next_out = (BYTE*)ress->dstBuffer;
                     strm.avail_out = ress->dstBufferSize;
             }   }
             if (ret == LZMA_STREAM_END) break;
    
    From eb7c2074e833189d92112062b2ef410a00293e1d Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Mon, 26 Jun 2017 11:23:56 -0700
    Subject: [PATCH 337/400] [zstdcli] Disable lzma support for MSAN testing
    
    ---
     Makefile | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Makefile b/Makefile
    index 679e05625..4194d7925 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -224,10 +224,10 @@ asan-%: clean
     	LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address" $(MAKE) -C $(TESTDIR) $*
     
     msan: clean
    -	$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer"   # datagen.c fails this test for no obvious reason
    +	$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer HAVE_LZMA=0"   # datagen.c fails this test for no obvious reason
     
     msan-%: clean
    -	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) $*
    +	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer HAVE_LZMA=0" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) $*
     
     asan32: clean
     	$(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
    
    From 6aeb50ea0d71de642eb0a6f53bd56b00ea51440a Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Mon, 26 Jun 2017 11:24:36 -0700
    Subject: [PATCH 338/400] [zstdcli] Add unlzma and unxz symlinks
    
    ---
     programs/zstdcli.c |  4 ++++
     tests/playTests.sh | 19 +++++++++++++++++++
     2 files changed, 23 insertions(+)
    
    diff --git a/programs/zstdcli.c b/programs/zstdcli.c
    index 57943863f..f59f9785f 100644
    --- a/programs/zstdcli.c
    +++ b/programs/zstdcli.c
    @@ -56,7 +56,9 @@
     #define ZSTD_GUNZIP "gunzip"
     #define ZSTD_GZCAT "gzcat"
     #define ZSTD_LZMA "lzma"
    +#define ZSTD_UNLZMA "unlzma"
     #define ZSTD_XZ "xz"
    +#define ZSTD_UNXZ "unxz"
     
     #define KB *(1 <<10)
     #define MB *(1 <<20)
    @@ -379,7 +381,9 @@ int main(int argCount, const char* argv[])
         if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; FIO_setRemoveSrcFile(1); }                                          /* behave like gunzip */
         if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; forceStdout=1; FIO_overwriteMode(); outFileName=stdoutmark; g_displayLevel=1; }  /* behave like gzcat */
         if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; FIO_setCompressionType(FIO_lzmaCompression); FIO_setRemoveSrcFile(1); }    /* behave like lzma */
    +    if (exeNameMatch(programName, ZSTD_UNLZMA)) { operation=zom_decompress; FIO_setCompressionType(FIO_lzmaCompression); FIO_setRemoveSrcFile(1); }    /* behave like unlzma */
         if (exeNameMatch(programName, ZSTD_XZ)) { suffix = XZ_EXTENSION; FIO_setCompressionType(FIO_xzCompression); FIO_setRemoveSrcFile(1); }    /* behave like xz */
    +    if (exeNameMatch(programName, ZSTD_UNXZ)) { operation=zom_decompress; FIO_setCompressionType(FIO_xzCompression); FIO_setRemoveSrcFile(1); }    /* behave like unxz */
         memset(&compressionParams, 0, sizeof(compressionParams));
     
         /* command switches */
    diff --git a/tests/playTests.sh b/tests/playTests.sh
    index fa82ae9e7..2e1cc6826 100755
    --- a/tests/playTests.sh
    +++ b/tests/playTests.sh
    @@ -442,6 +442,7 @@ if [ $LZMAMODE -eq 1 ]; then
         XZEXE=1
         xz -V && lzma -V || XZEXE=0
         if [ $XZEXE -eq 1 ]; then
    +        $ECHO "Testing zstd xz and lzma support"
             ./datagen > tmp
             $ZSTD --format=lzma -f tmp
             $ZSTD --format=xz -f tmp
    @@ -452,6 +453,24 @@ if [ $LZMAMODE -eq 1 ]; then
             $ZSTD -d -f -v tmp.xz
             $ZSTD -d -f -v tmp.lzma
             rm tmp*
    +        $ECHO "Creating symlinks"
    +        ln -s $ZSTD ./xz
    +        ln -s $ZSTD ./unxz
    +        ln -s $ZSTD ./lzma
    +        ln -s $ZSTD ./unlzma
    +        $ECHO "Testing xz and lzma symlinks"
    +        ./datagen > tmp
    +        ./xz tmp
    +        xz -d tmp.xz
    +        ./lzma tmp
    +        lzma -d tmp.lzma
    +        $ECHO "Testing unxz and unlzma symlinks"
    +        xz tmp
    +        ./xz -d tmp.xz
    +        lzma tmp
    +        ./lzma -d tmp.lzma
    +        rm xz unxz lzma unlzma
    +        rm tmp*
         else
             $ECHO "xz binary not detected"
         fi
    
    From d88a441406717cb8a594e4f0f32cb5f565071553 Mon Sep 17 00:00:00 2001
    From: Nick Terrell 
    Date: Mon, 26 Jun 2017 11:25:00 -0700
    Subject: [PATCH 339/400] [zstdcli] Document HAVE_LZMA and zstd-noxz
    
    ---
     programs/Makefile  |  5 +++++
     programs/README.md | 14 ++++++++++++--
     2 files changed, 17 insertions(+), 2 deletions(-)
    
    diff --git a/programs/Makefile b/programs/Makefile
    index e956a7dfa..8b080d446 100644
    --- a/programs/Makefile
    +++ b/programs/Makefile
    @@ -178,6 +178,11 @@ zstd-nogz : ZLIBLD :=
     zstd-nogz : ZLIB_MSG := - gzip support is disabled
     zstd-nogz : zstd
     
    +zstd-noxz : LZMACPP :=
    +zstd-noxz : LZMALD :=
    +zstd-noxz : LZMA_MSG := - xz/lzma support is disabled
    +zstd-noxz : zstd
    +
     
     zstd-pgo : MOREFLAGS = -fprofile-generate
     zstd-pgo : clean zstd
    diff --git a/programs/README.md b/programs/README.md
    index d7922a096..bd8fba069 100644
    --- a/programs/README.md
    +++ b/programs/README.md
    @@ -24,13 +24,23 @@ There are however other Makefile targets that create different variations of CLI
     - __HAVE_ZLIB__ : `zstd` can compress and decompress files in `.gz` format.
       This is done through command `--format=gzip`.
       Alternatively, symlinks named `gzip` or `gunzip` will mimic intended behavior.
    -  .gz support is automatically enabled when `zlib` library is detected at build time.
    -  It's possible to disable .gz support, by either compiling `zstd-nogz` target or using HAVE_ZLIB=0 variable.
    +  `.gz` support is automatically enabled when `zlib` library is detected at build time.
    +  It's possible to disable `.gz` support, by either compiling `zstd-nogz` target or using HAVE_ZLIB=0 variable.
       Example : make zstd HAVE_ZLIB=0
       It's also possible to force compilation with zlib support, using HAVE_ZLIB=1.
       In which case, linking stage will fail if `zlib` library cannot be found.
       This might be useful to prevent silent feature disabling.
     
    +- __HAVE_LZMA__ : `zstd` can compress and decompress files in `.xz` and `.lzma` formats.
    +  This is done through commands `--format=xz` and `--format=lzma` respectively.
    +  Alternatively, symlinks named `xz`, `unxz`, `lzma`, or `unlzma` will mimic intended behavior.
    +  `.xz` and `.lzma` support is automatically enabled when `lzma` library is detected at build time.
    +  It's possible to disable `.xz` and `.lzma` support, by either compiling `zstd-noxz` target or using HAVE_LZMA=0 variable.
    +  Example : make zstd HAVE_LZMA=0
    +  It's also possible to force compilation with lzma support, using HAVE_LZMA=1.
    +  In which case, linking stage will fail if `lzma` library cannot be found.
    +  This might be useful to prevent silent feature disabling.
    +
     
     #### Aggregation of parameters
     CLI supports aggregation of parameters i.e. `-b1`, `-e18`, and `-i1` can be joined into `-b1e18i1`.
    
    From 31af8290d155091f99c42da7b3787964ca4b37d7 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 26 Jun 2017 15:52:39 -0700
    Subject: [PATCH 340/400] ZSTD_estimateCCtx_advanced()
    
    ZSTD_estimateCCtx() is now a "simple" function,
    taking int compressionLevel as single argument.
    
    ZSTD_estimateCCtx_advanced() takes a CParams argument,
    which is both more complete and more complex to generate.
    ---
     doc/zstd_manual.html         | 15 ++++++++++++---
     lib/compress/zstd_compress.c | 16 +++++++++++-----
     lib/zstd.h                   |  9 ++++++---
     tests/paramgrill.c           |  4 ++--
     4 files changed, 31 insertions(+), 13 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 63704e67e..4397faf7a 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -389,6 +389,12 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
                 however it does mean that all frame data must be present and valid. 
     


    +
    size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
    +

    `src` should point to the start of a ZSTD frame + `srcSize` must be >= ZSTD_frameHeaderSize_prefix. + @return : size of the Frame Header +


    +

    Context memory usage

    
     
     
    size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
    @@ -401,12 +407,15 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
       Object memory usage can evolve if it's re-used multiple times. 
     


    -
    size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
    +
    size_t ZSTD_estimateCCtxSize(int compressionLevel);
    +size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
     size_t ZSTD_estimateDCtxSize(void);
     

    These functions make it possible to estimate memory usage - of a future target object, before its allocation, - given a set of parameters, which vary depending on target object. + of a future {D,C}Ctx, before its creation. The objective is to guide decision before allocation. + ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". + If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() will provide a better (smaller) estimation. + ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. Note : CCtx estimation is only correct for single-threaded compression


    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e53496091..1bf676926 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -532,7 +532,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u } -size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams) +size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams) { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); U32 const divider = (cParams.searchLength==3) ? 3 : 4; @@ -558,9 +558,15 @@ size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams) return sizeof(ZSTD_CCtx) + neededSpace; } +size_t ZSTD_estimateCCtxSize(int compressionLevel) +{ + ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0); + return ZSTD_estimateCCtxSize_advanced(cParams); +} + size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams) { - size_t const CCtxSize = ZSTD_estimateCCtxSize(cParams); + size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced(cParams); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize; size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1; @@ -3355,8 +3361,8 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference) { DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict)); - DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize(cParams)); - return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize(cParams) + DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize_advanced(cParams)); + return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_advanced(cParams) + (byReference ? 0 : dictSize); } @@ -3482,7 +3488,7 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize, unsigned byReference, ZSTD_dictMode_e dictMode, ZSTD_compressionParameters cParams) { - size_t const cctxSize = ZSTD_estimateCCtxSize(cParams); + size_t const cctxSize = ZSTD_estimateCCtxSize_advanced(cParams); size_t const neededSize = sizeof(ZSTD_CDict) + (byReference ? 0 : dictSize) + cctxSize; ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace; diff --git a/lib/zstd.h b/lib/zstd.h index 8cf9ba75f..65932088c 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -495,11 +495,14 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); /*! ZSTD_estimate*() : * These functions make it possible to estimate memory usage - * of a future target object, before its allocation, - * given a set of parameters, which vary depending on target object. + * of a future {D,C}Ctx, before its creation. * The objective is to guide decision before allocation. + * ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". + * If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() will provide a better (smaller) estimation. + * ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * Note : CCtx estimation is only correct for single-threaded compression */ -ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams); +ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); +ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams); ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimate?StreamSize() : diff --git a/tests/paramgrill.c b/tests/paramgrill.c index 1185c6649..da06ccb52 100644 --- a/tests/paramgrill.c +++ b/tests/paramgrill.c @@ -390,8 +390,8 @@ static int BMK_seed(winnerInfo_t* winners, const ZSTD_compressionParameters para double W_DMemUsed_note = W_ratioNote * ( 40 + 9*cLevel) - log((double)W_DMemUsed); double O_DMemUsed_note = O_ratioNote * ( 40 + 9*cLevel) - log((double)O_DMemUsed); - size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize(params); - size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize(winners[cLevel].params); + size_t W_CMemUsed = (1 << params.windowLog) + ZSTD_estimateCCtxSize_advanced(params); + size_t O_CMemUsed = (1 << winners[cLevel].params.windowLog) + ZSTD_estimateCCtxSize_advanced(winners[cLevel].params); double W_CMemUsed_note = W_ratioNote * ( 50 + 13*cLevel) - log((double)W_CMemUsed); double O_CMemUsed_note = O_ratioNote * ( 50 + 13*cLevel) - log((double)O_CMemUsed); From 0c9a915a280d24aa887a4dd19a72195fb8ade5cb Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 26 Jun 2017 16:02:25 -0700 Subject: [PATCH 341/400] ZSTD_estimateCStreamSize_advanced() --- doc/zstd_manual.html | 10 +++++++--- lib/compress/zstd_compress.c | 7 ++++++- lib/zstd.h | 8 ++++++-- tests/fuzzer.c | 3 +-- tests/zstreamtest.c | 2 +- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 4397faf7a..2cd4f78c5 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -414,14 +414,18 @@ size_t ZSTD_estimateDCtxSize(void); of a future {D,C}Ctx, before its creation. The objective is to guide decision before allocation. ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". - If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() will provide a better (smaller) estimation. + If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. Note : CCtx estimation is only correct for single-threaded compression


    -
    size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams);
    +
    size_t ZSTD_estimateCStreamSize(int compressionLevel);
    +size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
     size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
    -

    Note : if streaming is init with function ZSTD_init?Stream_usingDict(), +

    ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large". + If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. + ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. + Note : if streaming is init with function ZSTD_init?Stream_usingDict(), an internal ?Dict will be created, which size is not estimated here. In this case, get total size by adding ZSTD_estimate?DictSize


    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 1bf676926..f74f4d8ad 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -564,7 +564,7 @@ size_t ZSTD_estimateCCtxSize(int compressionLevel) return ZSTD_estimateCCtxSize_advanced(cParams); } -size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams) +size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams) { size_t const CCtxSize = ZSTD_estimateCCtxSize_advanced(cParams); size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog); @@ -575,6 +575,11 @@ size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams) return CCtxSize + streamingSize; } +size_t ZSTD_estimateCStreamSize(int compressionLevel) { + ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0); + return ZSTD_estimateCStreamSize_advanced(cParams); +} + static U32 ZSTD_equivalentParams(ZSTD_compressionParameters cParams1, ZSTD_compressionParameters cParams2) diff --git a/lib/zstd.h b/lib/zstd.h index 65932088c..9c6932fbb 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -498,7 +498,7 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); * of a future {D,C}Ctx, before its creation. * The objective is to guide decision before allocation. * ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". - * If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() will provide a better (smaller) estimation. + * If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. * ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * Note : CCtx estimation is only correct for single-threaded compression */ ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); @@ -506,10 +506,14 @@ ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cPa ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimate?StreamSize() : + * ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large". + * If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. + * ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * Note : if streaming is init with function ZSTD_init?Stream_usingDict(), * an internal ?Dict will be created, which size is not estimated here. * In this case, get total size by adding ZSTD_estimate?DictSize */ -ZSTDLIB_API size_t ZSTD_estimateCStreamSize(ZSTD_compressionParameters cParams); +ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel); +ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams); ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader); /*! ZSTD_estimate?DictSize() : diff --git a/tests/fuzzer.c b/tests/fuzzer.c index a3a56d9d8..7d33955f4 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -193,8 +193,7 @@ static int basicUnitTests(U32 seed, double compressibility) /* Static CCtx tests */ #define STATIC_CCTX_LEVEL 3 DISPLAYLEVEL(4, "test%3i : create static CCtx for level %u :", testNb++, STATIC_CCTX_LEVEL); - { ZSTD_compressionParameters const cParams = ZSTD_getCParams(STATIC_CCTX_LEVEL, 0, 0); - size_t const staticCCtxSize = ZSTD_estimateCStreamSize(cParams); + { size_t const staticCCtxSize = ZSTD_estimateCStreamSize(STATIC_CCTX_LEVEL); void* const staticCCtxBuffer = malloc(staticCCtxSize); size_t const staticDCtxSize = ZSTD_estimateDCtxSize(); void* const staticDCtxBuffer = malloc(staticDCtxSize); diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index 0e14fd23a..7c60b7067 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -210,7 +210,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo /* context size functions */ DISPLAYLEVEL(3, "test%3i : estimate CStream size : ", testNb++); { ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize); - size_t const s = ZSTD_estimateCStreamSize(cParams) + size_t const s = ZSTD_estimateCStreamSize_advanced(cParams) /* uses ZSTD_initCStream_usingDict() */ + ZSTD_estimateCDictSize(cParams, dictSize, 0); if (ZSTD_isError(s)) goto _output_error; From 09ae03a570c1725f261658bdfecb93451c66fc32 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 26 Jun 2017 16:47:32 -0700 Subject: [PATCH 342/400] ZSTD_estimateCDictSize_advanced() ZSTD_estimateCDictSize() now uses same arguments as ZSTD_createCDict() ZSTD_estimateCDictSize_advanced() uses same arguments as ZSTD_createCDict_advanced() --- doc/zstd_manual.html | 7 +++++-- lib/compress/zstd_compress.c | 10 ++++++++-- lib/zstd.h | 5 ++++- tests/fuzzer.c | 4 ++-- tests/zstreamtest.c | 2 +- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 2cd4f78c5..eff8ba0aa 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -430,9 +430,12 @@ size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader); In this case, get total size by adding ZSTD_estimate?DictSize


    -
    size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference);
    +
    size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
    +size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
     size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
    -

    Note : dictionary created "byReference" are smaller +

    ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict(). + ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced(). + Note : dictionary created "byReference" are smaller


    Advanced compression functions

    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index f74f4d8ad..781cdcd42 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3361,9 +3361,9 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
     
     /* =====  Dictionary API  ===== */
     
    -/*! ZSTD_estimateCDictSize() :
    +/*! ZSTD_estimateCDictSize_advanced() :
      *  Estimate amount of memory that will be needed to create a dictionary with following arguments */
    -size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference)
    +size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference)
     {
         DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
         DEBUGLOG(5, "CCtx estimate : %u", (U32)ZSTD_estimateCCtxSize_advanced(cParams));
    @@ -3371,6 +3371,12 @@ size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSiz
                + (byReference ? 0 : dictSize);
     }
     
    +size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
    +{
    +    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
    +    return ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
    +}
    +
     size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
     {
         if (cdict==NULL) return 0;   /* support sizeof on NULL */
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 9c6932fbb..492c3d43c 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -517,8 +517,11 @@ ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters
     ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
     
     /*! ZSTD_estimate?DictSize() :
    + *  ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
    + *  ZSTD_estimateCStreamSize_advanced() makes it possible to control precisely compression parameters, like ZSTD_createCDict_advanced().
      *  Note : dictionary created "byReference" are smaller */
    -ZSTDLIB_API size_t ZSTD_estimateCDictSize(ZSTD_compressionParameters cParams, size_t dictSize, unsigned byReference);
    +ZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
    +ZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, unsigned byReference);
     ZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);
     
     
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index 7d33955f4..0dcba3cea 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -501,7 +501,7 @@ static int basicUnitTests(U32 seed, double compressibility)
     
             DISPLAYLEVEL(4, "test%3i : estimate CDict size : ", testNb++);
             {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    -            size_t const estimatedSize = ZSTD_estimateCDictSize(cParams, dictSize, 1 /*byReference*/);
    +            size_t const estimatedSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, 1 /*byReference*/);
                 DISPLAYLEVEL(4, "OK : %u \n", (U32)estimatedSize);
             }
     
    @@ -534,7 +534,7 @@ static int basicUnitTests(U32 seed, double compressibility)
     
             DISPLAYLEVEL(4, "test%3i : compress with static CDict : ", testNb++);
             {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBuffSize, dictSize);
    -            size_t const cdictSize = ZSTD_estimateCDictSize(cParams, dictSize, 0);
    +            size_t const cdictSize = ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
                 void* const cdictBuffer = malloc(cdictSize);
                 if (cdictBuffer==NULL) goto _output_error;
                 {   ZSTD_CDict* const cdict = ZSTD_initStaticCDict(cdictBuffer, cdictSize,
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 7c60b7067..2c9cb5204 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -212,7 +212,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
         {   ZSTD_compressionParameters const cParams = ZSTD_getCParams(1, CNBufferSize, dictSize);
             size_t const s = ZSTD_estimateCStreamSize_advanced(cParams)
                             /* uses ZSTD_initCStream_usingDict() */
    -                       + ZSTD_estimateCDictSize(cParams, dictSize, 0);
    +                       + ZSTD_estimateCDictSize_advanced(dictSize, cParams, 0);
                 if (ZSTD_isError(s)) goto _output_error;
                 DISPLAYLEVEL(3, "OK (%u bytes) \n", (U32)s);
         }
    
    From dde10b23fe47dee5d290dffb2a33e0daea76712e Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 26 Jun 2017 17:44:26 -0700
    Subject: [PATCH 343/400] refactored ZSTD_estimateDStreamSize()
    
    now uses windowSize as argument.
    Also : created ZSTD_estimateDStreamSize_fromFrame()
    ---
     doc/zstd_manual.html             | 31 ++++++++++++++++++++-----------
     lib/compress/zstd_compress.c     |  5 +++++
     lib/decompress/zstd_decompress.c | 17 +++++++++++++++--
     lib/zstd.h                       | 31 ++++++++++++++++++++-----------
     tests/zstreamtest.c              |  4 ++--
     5 files changed, 62 insertions(+), 26 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index eff8ba0aa..6d524ae32 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -332,7 +332,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
     

    typedef struct {
         unsigned long long frameContentSize;
    -    unsigned windowSize;
    +    size_t windowSize;
         unsigned dictID;
         unsigned checksumFlag;
     } ZSTD_frameHeader;
    @@ -421,12 +421,17 @@ size_t ZSTD_estimateDCtxSize(void);
     
     
    size_t ZSTD_estimateCStreamSize(int compressionLevel);
     size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
    -size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
    +size_t ZSTD_estimateDStreamSize(size_t windowSize);
    +size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
     

    ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large". If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. + Note : CStream estimation is only correct for single-threaded compression. + ZSTD_DStream memory budget depends on window Size. + This information can be passed manually, using ZSTD_estimateDStreamSize, + or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame(); Note : if streaming is init with function ZSTD_init?Stream_usingDict(), - an internal ?Dict will be created, which size is not estimated here. + an internal ?Dict will be created, which additional size is not estimated here. In this case, get total size by adding ZSTD_estimate?DictSize


    @@ -622,6 +627,7 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference);

    Advanced streaming functions

    
     
     

    Advanced Streaming compression functions

    ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    +ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticCCtx() */
     size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
     size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
    @@ -640,6 +646,7 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict*
     
     

    Advanced Streaming decompression functions

    typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
    +ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */
     size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
     size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
    @@ -694,16 +701,18 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
       A ZSTD_DCtx object can be re-used multiple times.
     
       First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
    -  It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
    -  such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
    -  and the dictionary ID used.
    +  It fills a ZSTD_frameHeader structure with important information to correctly decode the frame,
    +  such as minimum rolling buffer size to allocate to decompress data (`windowSize`),
    +  and the dictionary ID in use.
       (Note : content size is optional, it may not be present. 0 means : content size unknown).
       Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
       As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
    -  Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
    -  Frame parameters are extracted from the beginning of the compressed frame.
    -  Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
    -  @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
    +  Each application can set its own limit, depending on local restrictions.
    +  For extended interoperability, it is recommended to support windowSize of at least 8 MB.
    +  Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
    +  Data fragment must be large enough to ensure successful decoding.
    +  `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.
    +  @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.
                >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
                errorCode, which can be tested using ZSTD_isError().
     
    @@ -747,7 +756,7 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned lo
       It also returns Frame Size as fparamsPtr->frameContentSize.
     
    -

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +

    Buffer-less streaming decompression functions

    size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */
     size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 781cdcd42..ea37197ff 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3594,6 +3594,11 @@ ZSTD_CStream* ZSTD_createCStream(void)
         return ZSTD_createCStream_advanced(ZSTD_defaultCMem);
     }
     
    +ZSTD_CStream* ZSTD_initStaticCStream(void *workspace, size_t workspaceSize)
    +{
    +    return ZSTD_initStaticCCtx(workspace, workspaceSize);
    +}
    +
     ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
     {   /* CStream and CCtx are now same object */
         return ZSTD_createCCtx_advanced(customMem);
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 95d18d4b5..940c3e033 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -2143,6 +2143,11 @@ ZSTD_DStream* ZSTD_createDStream(void)
         return ZSTD_createDStream_advanced(ZSTD_defaultCMem);
     }
     
    +ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
    +{
    +    return ZSTD_initStaticDCtx(workspace, workspaceSize);
    +}
    +
     ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
     {
         return ZSTD_createDCtx_advanced(customMem);
    @@ -2214,15 +2219,23 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
         return ZSTD_sizeof_DCtx(zds);
     }
     
    -size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader)
    +size_t ZSTD_estimateDStreamSize(size_t windowSize)
     {
    -    size_t const windowSize = fHeader.windowSize;
         size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
         size_t const inBuffSize = blockSize;  /* no block can be larger */
         size_t const outBuffSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
         return sizeof(ZSTD_DStream) + ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
     }
     
    +ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
    +{
    +    ZSTD_frameHeader fh;
    +    size_t const err = ZSTD_getFrameHeader(&fh, src, srcSize);
    +    if (ZSTD_isError(err)) return err;
    +    if (err>0) return ERROR(srcSize_wrong);
    +    return ZSTD_estimateDStreamSize(fh.windowSize);
    +}
    +
     
     /* *****   Decompression   ***** */
     
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 492c3d43c..08358f0df 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -412,7 +412,7 @@ typedef struct {
     
     typedef struct {
         unsigned long long frameContentSize;
    -    unsigned windowSize;
    +    size_t windowSize;
         unsigned dictID;
         unsigned checksumFlag;
     } ZSTD_frameHeader;
    @@ -509,12 +509,17 @@ ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
      *  ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large".
      *  If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation.
      *  ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
    + *  Note : CStream estimation is only correct for single-threaded compression.
    + *  ZSTD_DStream memory budget depends on window Size.
    + *  This information can be passed manually, using ZSTD_estimateDStreamSize,
    + *  or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame();
      *  Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
    - *         an internal ?Dict will be created, which size is not estimated here.
    + *         an internal ?Dict will be created, which additional size is not estimated here.
      *         In this case, get total size by adding ZSTD_estimate?DictSize */
     ZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
     ZSTDLIB_API size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams);
    -ZSTDLIB_API size_t ZSTD_estimateDStreamSize(ZSTD_frameHeader fHeader);
    +ZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
    +ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
     
     /*! ZSTD_estimate?DictSize() :
      *  ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
    @@ -717,6 +722,7 @@ ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
     
     /*=====   Advanced Streaming compression functions  =====*/
     ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
    +ZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticCCtx() */
     ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);   /**< pledgedSrcSize must be correct, a size of 0 means unknown.  for a frame size of 0 use initCStream_advanced */
     ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. */
     ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
    @@ -737,6 +743,7 @@ ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledg
     /*=====   Advanced Streaming decompression functions  =====*/
     typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
    +ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */
     ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
     ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
     ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
    @@ -803,16 +810,18 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
       A ZSTD_DCtx object can be re-used multiple times.
     
       First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
    -  It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
    -  such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
    -  and the dictionary ID used.
    +  It fills a ZSTD_frameHeader structure with important information to correctly decode the frame,
    +  such as minimum rolling buffer size to allocate to decompress data (`windowSize`),
    +  and the dictionary ID in use.
       (Note : content size is optional, it may not be present. 0 means : content size unknown).
       Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
       As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
    -  Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
    -  Frame parameters are extracted from the beginning of the compressed frame.
    -  Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
    -  @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
    +  Each application can set its own limit, depending on local restrictions.
    +  For extended interoperability, it is recommended to support windowSize of at least 8 MB.
    +  Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
    +  Data fragment must be large enough to ensure successful decoding.
    +  `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.
    +  @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.
                >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
                errorCode, which can be tested using ZSTD_isError().
     
    @@ -857,7 +866,7 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapaci
     */
     
     /*=====   Buffer-less streaming decompression functions  =====*/
    -ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input, see details below */
    +ZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */
     ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
     ZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 2c9cb5204..aae83972a 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -285,8 +285,8 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
             const void* cStart = (char*)compressedBuffer + (skippableFrameSize + 8);
             size_t const gfhError = ZSTD_getFrameHeader(&fhi, cStart, cSize);
             if (gfhError!=0) goto _output_error;
    -        DISPLAYLEVEL(5, " (windowSize : %u) ", fhi.windowSize);
    -        {   size_t const s = ZSTD_estimateDStreamSize(fhi)
    +        DISPLAYLEVEL(5, " (windowSize : %u) ", (U32)fhi.windowSize);
    +        {   size_t const s = ZSTD_estimateDStreamSize(fhi.windowSize)
                                 /* uses ZSTD_initDStream_usingDict() */
                                + ZSTD_estimateDDictSize(dictSize, 0);
                 if (ZSTD_isError(s)) goto _output_error;
    
    From c7fb884eeaa9f03fa25caa1da7ab8f19c203aa6f Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Mon, 26 Jun 2017 18:02:23 -0700
    Subject: [PATCH 344/400] fixed minor conversion warning
    
    ---
     lib/decompress/zstd_decompress.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 940c3e033..e823c3dbf 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -1282,7 +1282,7 @@ static size_t ZSTD_decompressSequencesLong(
         const BYTE* const base = (const BYTE*) (dctx->base);
         const BYTE* const vBase = (const BYTE*) (dctx->vBase);
         const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
    -    unsigned const windowSize = dctx->fParams.windowSize;
    +    unsigned const windowSize32 = (unsigned)dctx->fParams.windowSize;
         int nbSeq;
     
         /* Build Decoding Tables */
    @@ -1312,13 +1312,13 @@ static size_t ZSTD_decompressSequencesLong(
     
             /* prepare in advance */
             for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb
    Date: Mon, 26 Jun 2017 21:07:14 -0700
    Subject: [PATCH 345/400] [zdict] Make COVER the default algorithm
    
    ---
     lib/dictBuilder/cover.c |  60 ++++++--------
     lib/dictBuilder/zdict.c |  56 ++++++-------
     lib/dictBuilder/zdict.h | 179 +++++++++++++++++++++-------------------
     programs/dibio.c        |  36 ++++----
     programs/dibio.h        |   2 +-
     programs/zstdcli.c      |  22 ++---
     tests/fuzzer.c          |  18 ++--
     tests/symbols.c         |   5 +-
     8 files changed, 182 insertions(+), 196 deletions(-)
    
    diff --git a/lib/dictBuilder/cover.c b/lib/dictBuilder/cover.c
    index 1863c8f34..06c1b9fad 100644
    --- a/lib/dictBuilder/cover.c
    +++ b/lib/dictBuilder/cover.c
    @@ -398,7 +398,8 @@ typedef struct {
      */
     static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs,
                                                COVER_map_t *activeDmers, U32 begin,
    -                                           U32 end, COVER_params_t parameters) {
    +                                           U32 end,
    +                                           ZDICT_cover_params_t parameters) {
       /* Constants */
       const U32 k = parameters.k;
       const U32 d = parameters.d;
    @@ -478,7 +479,7 @@ static COVER_segment_t COVER_selectSegment(const COVER_ctx_t *ctx, U32 *freqs,
      * Check the validity of the parameters.
      * Returns non-zero if the parameters are valid and 0 otherwise.
      */
    -static int COVER_checkParameters(COVER_params_t parameters) {
    +static int COVER_checkParameters(ZDICT_cover_params_t parameters) {
       /* k and d are required parameters */
       if (parameters.d == 0 || parameters.k == 0) {
         return 0;
    @@ -600,7 +601,7 @@ static int COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
     static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
                                         COVER_map_t *activeDmers, void *dictBuffer,
                                         size_t dictBufferCapacity,
    -                                    COVER_params_t parameters) {
    +                                    ZDICT_cover_params_t parameters) {
       BYTE *const dict = (BYTE *)dictBuffer;
       size_t tail = dictBufferCapacity;
       /* Divide the data up into epochs of equal size.
    @@ -639,22 +640,10 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
       return tail;
     }
     
    -/**
    - * Translate from COVER_params_t to ZDICT_params_t required for finalizing the
    - * dictionary.
    - */
    -static ZDICT_params_t COVER_translateParams(COVER_params_t parameters) {
    -  ZDICT_params_t zdictParams;
    -  memset(&zdictParams, 0, sizeof(zdictParams));
    -  zdictParams.notificationLevel = 1;
    -  zdictParams.dictID = parameters.dictID;
    -  zdictParams.compressionLevel = parameters.compressionLevel;
    -  return zdictParams;
    -}
    -
    -ZDICTLIB_API size_t COVER_trainFromBuffer(
    +ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover(
         void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
    -    const size_t *samplesSizes, unsigned nbSamples, COVER_params_t parameters) {
    +    const size_t *samplesSizes, unsigned nbSamples,
    +    ZDICT_cover_params_t parameters) {
       BYTE *const dict = (BYTE *)dictBuffer;
       COVER_ctx_t ctx;
       COVER_map_t activeDmers;
    @@ -673,7 +662,7 @@ ZDICTLIB_API size_t COVER_trainFromBuffer(
         return ERROR(dstSize_tooSmall);
       }
       /* Initialize global data */
    -  g_displayLevel = parameters.notificationLevel;
    +  g_displayLevel = parameters.zParams.notificationLevel;
       /* Initialize context and activeDmers */
       if (!COVER_ctx_init(&ctx, samplesBuffer, samplesSizes, nbSamples,
                           parameters.d)) {
    @@ -690,10 +679,9 @@ ZDICTLIB_API size_t COVER_trainFromBuffer(
         const size_t tail =
             COVER_buildDictionary(&ctx, ctx.freqs, &activeDmers, dictBuffer,
                                   dictBufferCapacity, parameters);
    -    ZDICT_params_t zdictParams = COVER_translateParams(parameters);
         const size_t dictionarySize = ZDICT_finalizeDictionary(
             dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail,
    -        samplesBuffer, samplesSizes, nbSamples, zdictParams);
    +        samplesBuffer, samplesSizes, nbSamples, parameters.zParams);
         if (!ZSTD_isError(dictionarySize)) {
           DISPLAYLEVEL(2, "Constructed dictionary of size %u\n",
                        (U32)dictionarySize);
    @@ -718,7 +706,7 @@ typedef struct COVER_best_s {
       size_t liveJobs;
       void *dict;
       size_t dictSize;
    -  COVER_params_t parameters;
    +  ZDICT_cover_params_t parameters;
       size_t compressedSize;
     } COVER_best_t;
     
    @@ -786,7 +774,7 @@ static void COVER_best_start(COVER_best_t *best) {
      * If this dictionary is the best so far save it and its parameters.
      */
     static void COVER_best_finish(COVER_best_t *best, size_t compressedSize,
    -                              COVER_params_t parameters, void *dict,
    +                              ZDICT_cover_params_t parameters, void *dict,
                                   size_t dictSize) {
       if (!best) {
         return;
    @@ -830,7 +818,7 @@ typedef struct COVER_tryParameters_data_s {
       const COVER_ctx_t *ctx;
       COVER_best_t *best;
       size_t dictBufferCapacity;
    -  COVER_params_t parameters;
    +  ZDICT_cover_params_t parameters;
     } COVER_tryParameters_data_t;
     
     /**
    @@ -842,7 +830,7 @@ static void COVER_tryParameters(void *opaque) {
       /* Save parameters as local variables */
       COVER_tryParameters_data_t *const data = (COVER_tryParameters_data_t *)opaque;
       const COVER_ctx_t *const ctx = data->ctx;
    -  const COVER_params_t parameters = data->parameters;
    +  const ZDICT_cover_params_t parameters = data->parameters;
       size_t dictBufferCapacity = data->dictBufferCapacity;
       size_t totalCompressedSize = ERROR(GENERIC);
       /* Allocate space for hash table, dict, and freqs */
    @@ -863,10 +851,10 @@ static void COVER_tryParameters(void *opaque) {
       {
         const size_t tail = COVER_buildDictionary(ctx, freqs, &activeDmers, dict,
                                                   dictBufferCapacity, parameters);
    -    const ZDICT_params_t zdictParams = COVER_translateParams(parameters);
         dictBufferCapacity = ZDICT_finalizeDictionary(
             dict, dictBufferCapacity, dict + tail, dictBufferCapacity - tail,
    -        ctx->samples, ctx->samplesSizes, (unsigned)ctx->nbSamples, zdictParams);
    +        ctx->samples, ctx->samplesSizes, (unsigned)ctx->nbSamples,
    +        parameters.zParams);
         if (ZDICT_isError(dictBufferCapacity)) {
           DISPLAYLEVEL(1, "Failed to finalize dictionary\n");
           goto _cleanup;
    @@ -892,8 +880,8 @@ static void COVER_tryParameters(void *opaque) {
         }
         /* Create the cctx and cdict */
         cctx = ZSTD_createCCtx();
    -    cdict =
    -        ZSTD_createCDict(dict, dictBufferCapacity, parameters.compressionLevel);
    +    cdict = ZSTD_createCDict(dict, dictBufferCapacity,
    +                             parameters.zParams.compressionLevel);
         if (!dst || !cctx || !cdict) {
           goto _compressCleanup;
         }
    @@ -930,12 +918,10 @@ _cleanup:
       }
     }
     
    -ZDICTLIB_API size_t COVER_optimizeTrainFromBuffer(void *dictBuffer,
    -                                                  size_t dictBufferCapacity,
    -                                                  const void *samplesBuffer,
    -                                                  const size_t *samplesSizes,
    -                                                  unsigned nbSamples,
    -                                                  COVER_params_t *parameters) {
    +ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
    +    void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
    +    const size_t *samplesSizes, unsigned nbSamples,
    +    ZDICT_cover_params_t *parameters) {
       /* constants */
       const unsigned nbThreads = parameters->nbThreads;
       const unsigned kMinD = parameters->d == 0 ? 6 : parameters->d;
    @@ -947,7 +933,7 @@ ZDICTLIB_API size_t COVER_optimizeTrainFromBuffer(void *dictBuffer,
       const unsigned kIterations =
           (1 + (kMaxD - kMinD) / 2) * (1 + (kMaxK - kMinK) / kStepSize);
       /* Local variables */
    -  const int displayLevel = parameters->notificationLevel;
    +  const int displayLevel = parameters->zParams.notificationLevel;
       unsigned iteration = 1;
       unsigned d;
       unsigned k;
    @@ -976,7 +962,7 @@ ZDICTLIB_API size_t COVER_optimizeTrainFromBuffer(void *dictBuffer,
       /* Initialization */
       COVER_best_init(&best);
       /* Turn down global display level to clean up display at level 2 and below */
    -  g_displayLevel = parameters->notificationLevel - 1;
    +  g_displayLevel = parameters->zParams.notificationLevel - 1;
       /* Loop through d first because each new value needs a new context */
       LOCALDISPLAYLEVEL(displayLevel, 2, "Trying %u different sets of parameters\n",
                         kIterations);
    diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c
    index 943ddde0f..8bc6a0191 100644
    --- a/lib/dictBuilder/zdict.c
    +++ b/lib/dictBuilder/zdict.c
    @@ -487,7 +487,7 @@ static U32 ZDICT_dictSize(const dictItem* dictList)
     }
     
     
    -static size_t ZDICT_trainBuffer(dictItem* dictList, U32 dictListSize,
    +static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
                                 const void* const buffer, size_t bufferSize,   /* buffer must end with noisy guard band */
                                 const size_t* fileSizes, unsigned nbFiles,
                                 U32 minRatio, U32 notificationLevel)
    @@ -634,17 +634,6 @@ static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters params,
         }   }   }
     }
     
    -/*
    -static size_t ZDICT_maxSampleSize(const size_t* fileSizes, unsigned nbFiles)
    -{
    -    unsigned u;
    -    size_t max=0;
    -    for (u=0; u= 3) {
    +    if (params.zParams.notificationLevel>= 3) {
             U32 const nb = MIN(25, dictList[0].pos);
             U32 const dictContentSize = ZDICT_dictSize(dictList);
             U32 u;
    @@ -1026,7 +1015,7 @@ size_t ZDICT_trainFromBuffer_unsafe(
     
             dictSize = ZDICT_addEntropyTablesFromBuffer_advanced(dictBuffer, dictContentSize, maxDictSize,
                                                                  samplesBuffer, samplesSizes, nbSamples,
    -                                                             params);
    +                                                             params.zParams);
         }
     
         /* clean up */
    @@ -1037,9 +1026,9 @@ size_t ZDICT_trainFromBuffer_unsafe(
     
     /* issue : samplesBuffer need to be followed by a noisy guard band.
     *  work around : duplicate the buffer, and add the noise */
    -size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
    -                                      const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    -                                      ZDICT_params_t params)
    +size_t ZDICT_trainFromBuffer_legacy(void* dictBuffer, size_t dictBufferCapacity,
    +                              const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    +                              ZDICT_legacy_params_t params)
     {
         size_t result;
         void* newBuff;
    @@ -1052,10 +1041,9 @@ size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacit
         memcpy(newBuff, samplesBuffer, sBuffSize);
         ZDICT_fillNoise((char*)newBuff + sBuffSize, NOISELENGTH);   /* guard band, for end of buffer condition */
     
    -    result = ZDICT_trainFromBuffer_unsafe(
    -                                        dictBuffer, dictBufferCapacity,
    -                                        newBuff, samplesSizes, nbSamples,
    -                                        params);
    +    result =
    +        ZDICT_trainFromBuffer_unsafe_legacy(dictBuffer, dictBufferCapacity, newBuff,
    +                                            samplesSizes, nbSamples, params);
         free(newBuff);
         return result;
     }
    @@ -1064,11 +1052,13 @@ size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacit
     size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
                                  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples)
     {
    -    ZDICT_params_t params;
    +    ZDICT_cover_params_t params;
         memset(¶ms, 0, sizeof(params));
    -    return ZDICT_trainFromBuffer_advanced(dictBuffer, dictBufferCapacity,
    -                                          samplesBuffer, samplesSizes, nbSamples,
    -                                          params);
    +    params.d = 8;
    +    params.steps = 4;
    +    return ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, dictBufferCapacity,
    +                                               samplesBuffer, samplesSizes,
    +                                               nbSamples, ¶ms);
     }
     
     size_t ZDICT_addEntropyTablesFromBuffer(void* dictBuffer, size_t dictContentSize, size_t dictBufferCapacity,
    diff --git a/lib/dictBuilder/zdict.h b/lib/dictBuilder/zdict.h
    index 5ef2a3f5b..7bfbb351a 100644
    --- a/lib/dictBuilder/zdict.h
    +++ b/lib/dictBuilder/zdict.h
    @@ -36,18 +36,20 @@ extern "C" {
     #endif
     
     
    -/*! ZDICT_trainFromBuffer() :
    -    Train a dictionary from an array of samples.
    -    Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
    -    supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
    -    The resulting dictionary will be saved into `dictBuffer`.
    -    @return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    -              or an error code, which can be tested with ZDICT_isError().
    -    Tips : In general, a reasonable dictionary has a size of ~ 100 KB.
    -           It's obviously possible to target smaller or larger ones, just by specifying different `dictBufferCapacity`.
    -           In general, it's recommended to provide a few thousands samples, but this can vary a lot.
    -           It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
    -*/
    +/*! ZDICT_trainFromBuffer():
    + * Train a dictionary from an array of samples.
    + * Uses ZDICT_optimizeTrainFromBuffer_cover() single-threaded, with d=8 and steps=4.
    + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
    + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
    + * The resulting dictionary will be saved into `dictBuffer`.
    + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    + *           or an error code, which can be tested with ZDICT_isError().
    + * Note: ZDICT_trainFromBuffer() requires about 9 bytes of memory for each input byte.
    + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
    + *        It's obviously possible to target smaller or larger ones, just by specifying different `dictBufferCapacity`.
    + *        In general, it's recommended to provide a few thousands samples, but this can vary a lot.
    + *        It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
    + */
     ZDICTLIB_API size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
                            const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples);
     
    @@ -69,94 +71,78 @@ ZDICTLIB_API const char* ZDICT_getErrorName(size_t errorCode);
      * ==================================================================================== */
     
     typedef struct {
    -    unsigned selectivityLevel;   /* 0 means default; larger => select more => larger dictionary */
         int      compressionLevel;   /* 0 means default; target a specific zstd compression level */
         unsigned notificationLevel;  /* Write to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
         unsigned dictID;             /* 0 means auto mode (32-bits random value); other : force dictID value */
    -    unsigned reserved[2];        /* reserved space for future parameters */
     } ZDICT_params_t;
     
    -
    -/*! ZDICT_trainFromBuffer_advanced() :
    -    Same as ZDICT_trainFromBuffer() with control over more parameters.
    -    `parameters` is optional and can be provided with values set to 0 to mean "default".
    -    @return : size of dictionary stored into `dictBuffer` (<= `dictBufferSize`),
    -              or an error code, which can be tested by ZDICT_isError().
    -    note : ZDICT_trainFromBuffer_advanced() will send notifications into stderr if instructed to, using notificationLevel>0.
    -*/
    -ZDICTLIB_API size_t ZDICT_trainFromBuffer_advanced(void* dictBuffer, size_t dictBufferCapacity,
    -                                const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    -                                ZDICT_params_t parameters);
    -
    -/*! COVER_params_t :
    -    For all values 0 means default.
    -    k and d are the only required parameters.
    -*/
    +/*! ZDICT_cover_params_t:
    + *  For all values 0 means default.
    + *  k and d are the only required parameters.
    + */
     typedef struct {
         unsigned k;                  /* Segment size : constraint: 0 < k : Reasonable range [16, 2048+] */
         unsigned d;                  /* dmer size : constraint: 0 < d <= k : Reasonable range [6, 16] */
         unsigned steps;              /* Number of steps : Only used for optimization : 0 means default (32) : Higher means more parameters checked */
    -
         unsigned nbThreads;          /* Number of threads : constraint: 0 < nbThreads : 1 means single-threaded : Only used for optimization : Ignored if ZSTD_MULTITHREAD is not defined */
    -    unsigned notificationLevel;  /* Write to stderr; 0 = none (default); 1 = errors; 2 = progression; 3 = details; 4 = debug; */
    -    unsigned dictID;             /* 0 means auto mode (32-bits random value); other : force dictID value */
    -    int      compressionLevel;   /* 0 means default; target a specific zstd compression level */
    -} COVER_params_t;
    +    ZDICT_params_t zParams;
    +} ZDICT_cover_params_t;
     
     
    -/*! COVER_trainFromBuffer() :
    -    Train a dictionary from an array of samples using the COVER algorithm.
    -    Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
    -    supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
    -    The resulting dictionary will be saved into `dictBuffer`.
    -    @return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    -              or an error code, which can be tested with ZDICT_isError().
    -    Note : COVER_trainFromBuffer() requires about 9 bytes of memory for each input byte.
    -    Tips : In general, a reasonable dictionary has a size of ~ 100 KB.
    -           It's obviously possible to target smaller or larger ones, just by specifying different `dictBufferCapacity`.
    -           In general, it's recommended to provide a few thousands samples, but this can vary a lot.
    -           It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
    -*/
    -ZDICTLIB_API size_t COVER_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
    -                              const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    -                              COVER_params_t parameters);
    +/*! ZDICT_trainFromBuffer_cover():
    + * Train a dictionary from an array of samples using the COVER algorithm.
    + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
    + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
    + * The resulting dictionary will be saved into `dictBuffer`.
    + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    + *           or an error code, which can be tested with ZDICT_isError().
    + * Note: ZDICT_trainFromBuffer_cover() requires about 9 bytes of memory for each input byte.
    + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
    + *        It's obviously possible to target smaller or larger ones, just by specifying different `dictBufferCapacity`.
    + *        In general, it's recommended to provide a few thousands samples, but this can vary a lot.
    + *        It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
    + */
    +ZDICTLIB_API size_t ZDICT_trainFromBuffer_cover(
    +    void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
    +    const size_t *samplesSizes, unsigned nbSamples,
    +    ZDICT_cover_params_t parameters);
     
    -/*! COVER_optimizeTrainFromBuffer() :
    -    The same requirements as above hold for all the parameters except `parameters`.
    -    This function tries many parameter combinations and picks the best parameters.
    -    `*parameters` is filled with the best parameters found, and the dictionary
    -    constructed with those parameters is stored in `dictBuffer`.
    +/*! ZDICT_optimizeTrainFromBuffer_cover():
    + * The same requirements as above hold for all the parameters except `parameters`.
    + * This function tries many parameter combinations and picks the best parameters.
    + * `*parameters` is filled with the best parameters found, and the dictionary
    + * constructed with those parameters is stored in `dictBuffer`.
    + *
    + * All of the parameters d, k, steps are optional.
    + * If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8, 10, 12, 14, 16}.
    + * if steps is zero it defaults to its default value.
    + * If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [16, 2048].
    + *
    + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    + *           or an error code, which can be tested with ZDICT_isError().
    + *           On success `*parameters` contains the parameters selected.
    + * Note: ZDICT_optimizeTrainFromBuffer_cover() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread.
    + */
    +ZDICTLIB_API size_t ZDICT_optimizeTrainFromBuffer_cover(
    +    void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
    +    const size_t *samplesSizes, unsigned nbSamples,
    +    ZDICT_cover_params_t *parameters);
     
    -    All of the parameters d, k, steps are optional.
    -    If d is non-zero then we don't check multiple values of d, otherwise we check d = {6, 8, 10, 12, 14, 16}.
    -    if steps is zero it defaults to its default value.
    -    If k is non-zero then we don't check multiple values of k, otherwise we check steps values in [16, 2048].
    -
    -    @return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    -              or an error code, which can be tested with ZDICT_isError().
    -              On success `*parameters` contains the parameters selected.
    -    Note : COVER_optimizeTrainFromBuffer() requires about 8 bytes of memory for each input byte and additionally another 5 bytes of memory for each byte of memory for each thread.
    -*/
    -ZDICTLIB_API size_t COVER_optimizeTrainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
    -                                     const void* samplesBuffer, const size_t *samplesSizes, unsigned nbSamples,
    -                                     COVER_params_t *parameters);
    -
    -/*! ZDICT_finalizeDictionary() :
    -
    -    Given a custom content as a basis for dictionary, and a set of samples,
    -    finalize dictionary by adding headers and statistics.
    -
    -    Samples must be stored concatenated in a flat buffer `samplesBuffer`,
    -    supplied with an array of sizes `samplesSizes`, providing the size of each sample in order.
    -
    -    dictContentSize must be >= ZDICT_CONTENTSIZE_MIN bytes.
    -    maxDictSize must be >= dictContentSize, and must be >= ZDICT_DICTSIZE_MIN bytes.
    -
    -    @return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`),
    -              or an error code, which can be tested by ZDICT_isError().
    -    note : ZDICT_finalizeDictionary() will push notifications into stderr if instructed to, using notificationLevel>0.
    -    note 2 : dictBuffer and dictContent can overlap
    -*/
    +/*! ZDICT_finalizeDictionary():
    + * Given a custom content as a basis for dictionary, and a set of samples,
    + * finalize dictionary by adding headers and statistics.
    + *
    + * Samples must be stored concatenated in a flat buffer `samplesBuffer`,
    + * supplied with an array of sizes `samplesSizes`, providing the size of each sample in order.
    + *
    + * dictContentSize must be >= ZDICT_CONTENTSIZE_MIN bytes.
    + * maxDictSize must be >= dictContentSize, and must be >= ZDICT_DICTSIZE_MIN bytes.
    + *
    + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`),
    + *           or an error code, which can be tested by ZDICT_isError().
    + * Note: ZDICT_finalizeDictionary() will push notifications into stderr if instructed to, using notificationLevel>0.
    + * Note 2: dictBuffer and dictContent can overlap
    + */
     #define ZDICT_CONTENTSIZE_MIN 128
     #define ZDICT_DICTSIZE_MIN    256
     ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
    @@ -164,7 +150,28 @@ ZDICTLIB_API size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBuffer
                                     const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
                                     ZDICT_params_t parameters);
     
    +typedef struct {
    +    unsigned selectivityLevel;   /* 0 means default; larger => select more => larger dictionary */
    +    ZDICT_params_t zParams;
    +} ZDICT_legacy_params_t;
     
    +/*! ZDICT_trainFromBuffer_legacy():
    + * Train a dictionary from an array of samples.
    + * Samples must be stored concatenated in a single flat buffer `samplesBuffer`,
    + * supplied with an array of sizes `samplesSizes`, providing the size of each sample, in order.
    + * The resulting dictionary will be saved into `dictBuffer`.
    + * `parameters` is optional and can be provided with values set to 0 to mean "default".
    + * @return: size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
    + *           or an error code, which can be tested with ZDICT_isError().
    + * Tips: In general, a reasonable dictionary has a size of ~ 100 KB.
    + *        It's obviously possible to target smaller or larger ones, just by specifying different `dictBufferCapacity`.
    + *        In general, it's recommended to provide a few thousands samples, but this can vary a lot.
    + *        It's recommended that total size of all samples be about ~x100 times the target size of dictionary.
    + * Note: ZDICT_trainFromBuffer_legacy() will send notifications into stderr if instructed to, using notificationLevel>0.
    + */
    +ZDICTLIB_API size_t ZDICT_trainFromBuffer_legacy(
    +    void *dictBuffer, size_t dictBufferCapacity, const void *samplesBuffer,
    +    const size_t *samplesSizes, unsigned nbSamples, ZDICT_legacy_params_t parameters);
     
     /* Deprecation warnings */
     /* It is generally possible to disable deprecation warnings from compiler,
    diff --git a/programs/dibio.c b/programs/dibio.c
    index aac36425c..31cde5c95 100644
    --- a/programs/dibio.c
    +++ b/programs/dibio.c
    @@ -216,21 +216,21 @@ static U64 DiB_getTotalCappedFileSize(const char** fileNamesTable, unsigned nbFi
     }
     
     
    -/*! ZDICT_trainFromBuffer_unsafe() :
    +/*! ZDICT_trainFromBuffer_unsafe_legacy() :
         Strictly Internal use only !!
    -    Same as ZDICT_trainFromBuffer_advanced(), but does not control `samplesBuffer`.
    +    Same as ZDICT_trainFromBuffer_legacy(), but does not control `samplesBuffer`.
         `samplesBuffer` must be followed by noisy guard band to avoid out-of-buffer reads.
         @return : size of dictionary stored into `dictBuffer` (<= `dictBufferCapacity`)
                   or an error code.
     */
    -size_t ZDICT_trainFromBuffer_unsafe(void* dictBuffer, size_t dictBufferCapacity,
    -                              const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    -                              ZDICT_params_t parameters);
    +size_t ZDICT_trainFromBuffer_unsafe_legacy(void* dictBuffer, size_t dictBufferCapacity,
    +                                           const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
    +                                           ZDICT_legacy_params_t parameters);
     
     
     int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
                            const char** fileNamesTable, unsigned nbFiles,
    -                       ZDICT_params_t *params, COVER_params_t *coverParams,
    +                       ZDICT_legacy_params_t *params, ZDICT_cover_params_t *coverParams,
                            int optimizeCover)
     {
         void* const dictBuffer = malloc(maxDictSize);
    @@ -243,8 +243,8 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
         int result = 0;
     
         /* Checks */
    -    if (params) g_displayLevel = params->notificationLevel;
    -    else if (coverParams) g_displayLevel = coverParams->notificationLevel;
    +    if (params) g_displayLevel = params->zParams.notificationLevel;
    +    else if (coverParams) g_displayLevel = coverParams->zParams.notificationLevel;
         else EXM_THROW(13, "Neither dictionary algorith selected");   /* should not happen */
         if ((!fileSizes) || (!srcBuffer) || (!dictBuffer)) EXM_THROW(12, "not enough memory for DiB_trainFiles");   /* should not happen */
         if (g_tooLargeSamples) {
    @@ -273,20 +273,20 @@ int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
             size_t dictSize;
             if (params) {
                 DiB_fillNoise((char*)srcBuffer + benchedSize, NOISELENGTH);   /* guard band, for end of buffer condition */
    -            dictSize = ZDICT_trainFromBuffer_unsafe(dictBuffer, maxDictSize,
    -                                                    srcBuffer, fileSizes, nbFiles,
    -                                                    *params);
    +            dictSize = ZDICT_trainFromBuffer_unsafe_legacy(dictBuffer, maxDictSize,
    +                                                           srcBuffer, fileSizes, nbFiles,
    +                                                           *params);
             } else if (optimizeCover) {
    -            dictSize = COVER_optimizeTrainFromBuffer(
    -                dictBuffer, maxDictSize, srcBuffer, fileSizes, nbFiles,
    -                coverParams);
    +            dictSize = ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, maxDictSize,
    +                                                           srcBuffer, fileSizes, nbFiles,
    +                                                           coverParams);
                 if (!ZDICT_isError(dictSize)) {
    -              DISPLAYLEVEL(2, "k=%u\nd=%u\nsteps=%u\n", coverParams->k, coverParams->d, coverParams->steps);
    +                DISPLAYLEVEL(2, "k=%u\nd=%u\nsteps=%u\n", coverParams->k, coverParams->d, coverParams->steps);
                 }
             } else {
    -            dictSize = COVER_trainFromBuffer(dictBuffer, maxDictSize,
    -                                             srcBuffer, fileSizes, nbFiles,
    -                                             *coverParams);
    +            dictSize =
    +                ZDICT_trainFromBuffer_cover(dictBuffer, maxDictSize, srcBuffer,
    +                                            fileSizes, nbFiles, *coverParams);
             }
             if (ZDICT_isError(dictSize)) {
                 DISPLAYLEVEL(1, "dictionary training failed : %s \n", ZDICT_getErrorName(dictSize));   /* should not happen */
    diff --git a/programs/dibio.h b/programs/dibio.h
    index e61d0042c..84f7d5802 100644
    --- a/programs/dibio.h
    +++ b/programs/dibio.h
    @@ -32,7 +32,7 @@
     */
     int DiB_trainFromFiles(const char* dictFileName, unsigned maxDictSize,
                            const char** fileNamesTable, unsigned nbFiles,
    -                       ZDICT_params_t *params, COVER_params_t *coverParams,
    +                       ZDICT_legacy_params_t *params, ZDICT_cover_params_t *coverParams,
                            int optimizeCover);
     
     #endif
    diff --git a/programs/zstdcli.c b/programs/zstdcli.c
    index 57943863f..34826a6f6 100644
    --- a/programs/zstdcli.c
    +++ b/programs/zstdcli.c
    @@ -246,7 +246,7 @@ static unsigned longCommandWArg(const char** stringPtr, const char* longCommand)
      * @return 1 means that cover parameters were correct
      * @return 0 in case of malformed parameters
      */
    -static unsigned parseCoverParameters(const char* stringPtr, COVER_params_t* params)
    +static unsigned parseCoverParameters(const char* stringPtr, ZDICT_cover_params_t* params)
     {
         memset(params, 0, sizeof(*params));
         for (; ;) {
    @@ -275,9 +275,9 @@ static unsigned parseLegacyParameters(const char* stringPtr, unsigned* selectivi
         return 1;
     }
     
    -static COVER_params_t defaultCoverParams(void)
    +static ZDICT_cover_params_t defaultCoverParams(void)
     {
    -    COVER_params_t params;
    +    ZDICT_cover_params_t params;
         memset(¶ms, 0, sizeof(params));
         params.d = 8;
         params.steps = 4;
    @@ -356,7 +356,7 @@ int main(int argCount, const char* argv[])
         unsigned fileNamesNb;
     #endif
     #ifndef ZSTD_NODICT
    -    COVER_params_t coverParams = defaultCoverParams();
    +    ZDICT_cover_params_t coverParams = defaultCoverParams();
         int cover = 1;
     #endif
     
    @@ -695,20 +695,20 @@ int main(int argCount, const char* argv[])
         /* Check if dictionary builder is selected */
         if (operation==zom_train) {
     #ifndef ZSTD_NODICT
    +        ZDICT_params_t zParams;
    +        zParams.compressionLevel = dictCLevel;
    +        zParams.notificationLevel = g_displayLevel;
    +        zParams.dictID = dictID;
             if (cover) {
                 int const optimize = !coverParams.k || !coverParams.d;
                 coverParams.nbThreads = nbThreads;
    -            coverParams.compressionLevel = dictCLevel;
    -            coverParams.notificationLevel = g_displayLevel;
    -            coverParams.dictID = dictID;
    +            coverParams.zParams = zParams;
                 operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, NULL, &coverParams, optimize);
             } else {
    -            ZDICT_params_t dictParams;
    +            ZDICT_legacy_params_t dictParams;
                 memset(&dictParams, 0, sizeof(dictParams));
    -            dictParams.compressionLevel = dictCLevel;
                 dictParams.selectivityLevel = dictSelect;
    -            dictParams.notificationLevel = g_displayLevel;
    -            dictParams.dictID = dictID;
    +            dictParams.zParams = zParams;
                 operationResult = DiB_trainFromFiles(outFileName, maxDictSize, filenameTable, filenameIdx, &dictParams, NULL, 0);
             }
     #endif
    diff --git a/tests/fuzzer.c b/tests/fuzzer.c
    index a3a56d9d8..86f0555d5 100644
    --- a/tests/fuzzer.c
    +++ b/tests/fuzzer.c
    @@ -639,7 +639,7 @@ static int basicUnitTests(U32 seed, double compressibility)
             size_t const sampleUnitSize = 8 KB;
             U32 const nbSamples = (U32)(totalSampleSize / sampleUnitSize);
             size_t* const samplesSizes = (size_t*) malloc(nbSamples * sizeof(size_t));
    -        COVER_params_t params;
    +        ZDICT_cover_params_t params;
             U32 dictID;
     
             if (dictBuffer==NULL || samplesSizes==NULL) {
    @@ -648,14 +648,14 @@ static int basicUnitTests(U32 seed, double compressibility)
                 goto _output_error;
             }
     
    -        DISPLAYLEVEL(4, "test%3i : COVER_trainFromBuffer : ", testNb++);
    +        DISPLAYLEVEL(4, "test%3i : ZDICT_trainFromBuffer_cover : ", testNb++);
             { U32 u; for (u=0; u
    Date: Mon, 26 Jun 2017 18:57:04 -0700
    Subject: [PATCH 346/400] [tests] Fix HAVE_LZMA flag
    
    ---
     Makefile | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Makefile b/Makefile
    index 4194d7925..9afdf658b 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -224,10 +224,10 @@ asan-%: clean
     	LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=address" $(MAKE) -C $(TESTDIR) $*
     
     msan: clean
    -	$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer HAVE_LZMA=0"   # datagen.c fails this test for no obvious reason
    +	$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" HAVE_LZMA=0   # datagen.c fails this test for no obvious reason
     
     msan-%: clean
    -	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer HAVE_LZMA=0" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) $*
    +	LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) HAVE_LZMA=0 $*
     
     asan32: clean
     	$(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address"
    
    From fecc721fd9b88bdfbc0619f81a092d8f0ec6a4c0 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 27 Jun 2017 11:46:39 -0700
    Subject: [PATCH 347/400] added parameter ZSTD_p_refDictContent
    
    ---
     doc/zstd_manual.html         | 20 +++++++++-----------
     lib/compress/zstd_compress.c | 19 ++++++++++---------
     lib/zstd.h                   | 20 +++++++++-----------
     tests/zstreamtest.c          |  3 ++-
     4 files changed, 30 insertions(+), 32 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 6d524ae32..aac3ec383 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -816,13 +816,11 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
         ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
         ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
     
    -    /* dictionary parameters */
    -    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    -                              * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its users */
    -                             /* Not ready yet ! <=================================== */
    -    ZSTD_p_dictMode,         /* Select how dictionary must be interpreted. Value must be from type ZSTD_dictMode_e.
    +    /* dictionary parameters (must be set before loading) */
    +    ZSTD_p_dictMode=300,     /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
                                   * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
    +    ZSTD_p_refDictContent,   /* Dictionary content will be referenced, instead of copied (default:0==byCopy).
    +                              * It requires that dictionary buffer outlives its users */
     
         /* multi-threading parameters */
         ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    @@ -837,9 +835,9 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
                                   * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
     
         /* advanced parameters - may not remain available after API update */
    -    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    -                              * even when referencing into Dictionary content.
    -                              * default : 0 when using a CDict, 1 when using a Prefix */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
    +                              * even when referencing into Dictionary content (default:0) */
    +
     } ZSTD_cParameter;
     

    size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value);
    @@ -865,8 +863,8 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
      @result : 0, or an error code (which can be tested with ZSTD_isError()).
       Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
                 meaning "return to no-dictionary mode".
    -  Note 1 : Dictionary content will be copied internally,
    -           except if ZSTD_p_refDictContent is set.
    +  Note 1 : `dict` content will be copied internally,
    +           except if ZSTD_p_refDictContent is set before loading.
       Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
                For this reason, compression parameters cannot be changed anymore after loading a dictionary.
                It's also a CPU-heavy operation, with non-negligible impact on latency.
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index ea37197ff..b95b4770f 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -89,6 +89,7 @@ struct ZSTD_CCtx_s {
         U32   loadedDictEnd;    /* index of end of dictionary */
         U32   forceWindow;      /* force back-references to respect limit of 1<requestedParams.cParams.strategy = (ZSTD_strategy)value;
             return 0;
     
    -#if 0
    -    case ZSTD_p_windowSize :   /* to be done later */
    -        return ERROR(compressionParameter_unsupported);
    -#endif
    -
         case ZSTD_p_contentSizeFlag :
             DEBUGLOG(5, "set content size flag = %u", (value>0));
             /* Content size written in frame header _when known_ (default:1) */
    @@ -343,10 +339,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
             cctx->requestedParams.fParams.noDictIDFlag = (value==0);
             return 0;
     
    -    case ZSTD_p_refDictContent :   /* to be done later */
    -        return ERROR(compressionParameter_unsupported);
    -
    +    /* Dictionary parameters */
         case ZSTD_p_dictMode :
    +        if (cctx->cdict) return ERROR(stage_wrong);  /* must be set before loading */
             /* restrict dictionary mode, to "rawContent" or "fullDict" only */
             ZSTD_STATIC_ASSERT((U32)ZSTD_dm_fullDict > (U32)ZSTD_dm_rawContent);
             if (value > (unsigned)ZSTD_dm_fullDict)
    @@ -354,6 +349,12 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
             cctx->dictMode = (ZSTD_dictMode_e)value;
             return 0;
     
    +    case ZSTD_p_refDictContent :
    +        if (cctx->cdict) return ERROR(stage_wrong);  /* must be set before loading */
    +        /* dictionary content will be referenced, instead of copied */
    +        cctx->dictContentByRef = value>0;
    +        return 0;
    +
         case ZSTD_p_forceMaxWindow :  /* Force back-references to remain < windowSize,
                                        * even when referencing into Dictionary content
                                        * default : 0 when using a CDict, 1 when using a Prefix */
    @@ -417,7 +418,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
                     ZSTD_getCParams(cctx->compressionLevel, 0, dictSize);
             cctx->cdictLocal = ZSTD_createCDict_advanced(
                                     dict, dictSize,
    -                                0 /* byReference */, cctx->dictMode,
    +                                cctx->dictContentByRef, cctx->dictMode,
                                     cParams, cctx->customMem);
             cctx->cdict = cctx->cdictLocal;
             if (cctx->cdictLocal == NULL)
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 08358f0df..49a5b791c 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -956,13 +956,11 @@ typedef enum {
         ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
         ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
     
    -    /* dictionary parameters */
    -    ZSTD_p_refDictContent=300, /* Content of dictionary content will be referenced, instead of copied (default:0).
    -                              * This avoids duplicating dictionary content.
    -                              * But it also requires that dictionary buffer outlives its users */
    -                             /* Not ready yet ! <=================================== */
    -    ZSTD_p_dictMode,         /* Select how dictionary must be interpreted. Value must be from type ZSTD_dictMode_e.
    +    /* dictionary parameters (must be set before loading) */
    +    ZSTD_p_dictMode=300,     /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
                                   * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
    +    ZSTD_p_refDictContent,   /* Dictionary content will be referenced, instead of copied (default:0==byCopy).
    +                              * It requires that dictionary buffer outlives its users */
     
         /* multi-threading parameters */
         ZSTD_p_nbThreads=400,    /* Select how many threads a compression job can spawn (default:1)
    @@ -977,9 +975,9 @@ typedef enum {
                                   * 0 => no overlap, 6(default) => use 1/8th of windowSize, >=9 => use full windowSize */
     
         /* advanced parameters - may not remain available after API update */
    -    ZSTD_p_forceMaxWindow=1100, /* Force back-references to remain < windowSize,
    -                              * even when referencing into Dictionary content.
    -                              * default : 0 when using a CDict, 1 when using a Prefix */
    +    ZSTD_p_forceMaxWindow=1100, /* Force back-reference distances to remain < windowSize,
    +                              * even when referencing into Dictionary content (default:0) */
    +
     } ZSTD_cParameter;
     
     
    @@ -1006,8 +1004,8 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
      * @result : 0, or an error code (which can be tested with ZSTD_isError()).
      *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
      *            meaning "return to no-dictionary mode".
    - *  Note 1 : Dictionary content will be copied internally,
    - *           except if ZSTD_p_refDictContent is set.
    + *  Note 1 : `dict` content will be copied internally,
    + *           except if ZSTD_p_refDictContent is set before loading.
      *  Note 2 : Loading a dictionary involves building tables, which are dependent on compression parameters.
      *           For this reason, compression parameters cannot be changed anymore after loading a dictionary.
      *           It's also a CPU-heavy operation, with non-negligible impact on latency.
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index aae83972a..ca25e891f 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -1294,7 +1294,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                     ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize);
     
                     /* mess with compression parameters */
    -                CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) );   /* always cancel previous dict, to make user it's possible to pass compression parameters */
    +                CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) );   /* cancel previous dict, to allow new compression parameters */
                     cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1;
                     cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1;
                     cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1;
    @@ -1311,6 +1311,7 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                     if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_targetLength, cParams.targetLength) );
     
                     /* unconditionally set, to be sync with decoder */
    +                if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
                     CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
     
                     if (dict && dictSize) {
    
    From 7d3816183f5332eb2de75ef14ac9371173311bb7 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 27 Jun 2017 13:50:34 -0700
    Subject: [PATCH 348/400] exposed ZSTD_MAGIC_DICTIONARY in zstd.h
    
    makes it easier to explain ZSTD_dictMode
    ---
     doc/zstd_manual.html             |  9 ++++++---
     lib/common/zstd_internal.h       |  1 -
     lib/compress/zstd_compress.c     |  2 +-
     lib/decompress/zstd_decompress.c |  6 +++---
     lib/dictBuilder/zdict.c          |  6 +++---
     lib/zstd.h                       | 10 +++++++---
     6 files changed, 20 insertions(+), 14 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index aac3ec383..69b6fbf63 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -348,7 +348,7 @@ static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL };
     
    size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
     

    `src` should point to the start of a ZSTD encoded frame or skippable frame `srcSize` must be at least as large as the frame - @return : the compressed size of the frame pointed to by `src`, + @return : the compressed size of the frame pointed to by `src`,FUZ_rand(&lseed) & 1) suitable to pass to `ZSTD_decompress` or similar, or an error code if given invalid input.


    @@ -482,7 +482,10 @@ size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference); It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict


    -
    typedef enum { ZSTD_dm_auto=0, ZSTD_dm_rawContent, ZSTD_dm_fullDict } ZSTD_dictMode_e;
    +
    typedef enum { ZSTD_dm_auto=0,        /* dictionary is "full" if it starts with ZSTD_MAGIC_DICTIONARY, rawContent otherwize */
    +               ZSTD_dm_rawContent,    /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */
    +               ZSTD_dm_fullDict       /* refuses to load a dictionary if it does not respect Zstandard's specification */
    +} ZSTD_dictMode_e;
     

    ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
                                           unsigned byReference, ZSTD_dictMode_e dictMode,
    @@ -886,7 +889,7 @@ void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
     


    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! <===================================== */
    -

    Reference a prefix (content-only dictionary) to bootstrap next compression job. +

    Reference a prefix (raw-content dictionary) for next compression job. Decompression will have to use same prefix. Prefix is only used once. Tables are discarded at end of compression job. If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict. diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 4e216d728..bcf93e58d 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -98,7 +98,6 @@ * Common constants ***************************************/ #define ZSTD_OPT_NUM (1<<12) -#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */ #define ZSTD_REP_NUM 3 /* number of repcodes */ #define ZSTD_REP_CHECK (ZSTD_REP_NUM) /* number of repcodes to check by the optimal parser */ diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b95b4770f..b6b92f32c 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3181,7 +3181,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, if (dictMode==ZSTD_dm_rawContent) return ZSTD_loadDictionaryContent(cctx, dict, dictSize); - if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) { + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) { if (dictMode == ZSTD_dm_auto) { DEBUGLOG(5, "raw content dictionary detected"); return ZSTD_loadDictionaryContent(cctx, dict, dictSize); diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index e823c3dbf..61f766e21 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1884,7 +1884,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict { if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); { U32 const magic = MEM_readLE32(dict); - if (magic != ZSTD_DICT_MAGIC) { + if (magic != ZSTD_MAGIC_DICTIONARY) { return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ } } dctx->dictID = MEM_readLE32((const char*)dict + 4); @@ -1964,7 +1964,7 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict) ddict->entropyPresent = 0; if (ddict->dictSize < 8) return 0; { U32 const magic = MEM_readLE32(ddict->dictContent); - if (magic != ZSTD_DICT_MAGIC) return 0; /* pure content mode */ + if (magic != ZSTD_MAGIC_DICTIONARY) return 0; /* pure content mode */ } ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4); @@ -2083,7 +2083,7 @@ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) { if (dictSize < 8) return 0; - if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0; + if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0; return MEM_readLE32((const char*)dict + 4); } diff --git a/lib/dictBuilder/zdict.c b/lib/dictBuilder/zdict.c index 943ddde0f..04bfe661d 100644 --- a/lib/dictBuilder/zdict.c +++ b/lib/dictBuilder/zdict.c @@ -94,7 +94,7 @@ const char* ZDICT_getErrorName(size_t errorCode) { return ERR_getErrorName(error unsigned ZDICT_getDictID(const void* dictBuffer, size_t dictSize) { if (dictSize < 8) return 0; - if (MEM_readLE32(dictBuffer) != ZSTD_DICT_MAGIC) return 0; + if (MEM_readLE32(dictBuffer) != ZSTD_MAGIC_DICTIONARY) return 0; return MEM_readLE32((const char*)dictBuffer + 4); } @@ -865,7 +865,7 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity, if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) return ERROR(dstSize_tooSmall); /* dictionary header */ - MEM_writeLE32(header, ZSTD_DICT_MAGIC); + MEM_writeLE32(header, ZSTD_MAGIC_DICTIONARY); { U64 const randomID = XXH64(customDictContent, dictContentSize, 0); U32 const compliantID = (randomID % ((1U<<31)-32768)) + 32768; U32 const dictID = params.dictID ? params.dictID : compliantID; @@ -917,7 +917,7 @@ size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictCo } /* add dictionary header (after entropy tables) */ - MEM_writeLE32(dictBuffer, ZSTD_DICT_MAGIC); + MEM_writeLE32(dictBuffer, ZSTD_MAGIC_DICTIONARY); { U64 const randomID = XXH64((char*)dictBuffer + dictBufferCapacity - dictContentSize, dictContentSize, 0); U32 const compliantID = (randomID % ((1U<<31)-32768)) + 32768; U32 const dictID = params.dictID ? params.dictID : compliantID; diff --git a/lib/zstd.h b/lib/zstd.h index 49a5b791c..2b9018707 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -360,6 +360,7 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output /* --- Constants ---*/ #define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */ #define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U +#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* v0.7+ */ #define ZSTD_WINDOWLOG_MAX_32 27 #define ZSTD_WINDOWLOG_MAX_64 27 @@ -379,7 +380,7 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output #define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */ #define ZSTD_FRAMEHEADERSIZE_MIN 6 -static const size_t ZSTD_frameHeaderSize_prefix = 5; +static const size_t ZSTD_frameHeaderSize_prefix = 5; /* minimum input size to know frame header size */ static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN; static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX; static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */ @@ -573,7 +574,10 @@ ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter par ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); -typedef enum { ZSTD_dm_auto=0, ZSTD_dm_rawContent, ZSTD_dm_fullDict } ZSTD_dictMode_e; +typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with ZSTD_MAGIC_DICTIONARY, rawContent otherwize */ + ZSTD_dm_rawContent, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */ + ZSTD_dm_fullDict /* refuses to load a dictionary if it does not respect Zstandard's specification */ +} ZSTD_dictMode_e; /*! ZSTD_createCDict_advanced() : * Create a ZSTD_CDict using external alloc and free, and customized compression parameters */ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, @@ -1027,7 +1031,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /*! ZSTD_CCtx_refPrefix() : - * Reference a prefix (content-only dictionary) to bootstrap next compression job. + * Reference a prefix (raw-content dictionary) for next compression job. * Decompression will have to use same prefix. * Prefix is only used once. Tables are discarded at end of compression job. * If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict. From b7372933b833ec0d69be2f8a9589fe82fbeb8b96 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 27 Jun 2017 15:49:12 -0700 Subject: [PATCH 349/400] implemented ZSTD_refPrefix() --- doc/zstd_manual.html | 29 ++++++++----------- lib/compress/zstd_compress.c | 56 ++++++++++++++++++++++-------------- lib/zstd.h | 27 +++++++---------- tests/zstreamtest.c | 6 ++-- 4 files changed, 61 insertions(+), 57 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 69b6fbf63..f5a1394a7 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -348,7 +348,7 @@ static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL };

    size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
     

    `src` should point to the start of a ZSTD encoded frame or skippable frame `srcSize` must be at least as large as the frame - @return : the compressed size of the frame pointed to by `src`,FUZ_rand(&lseed) & 1) + @return : the compressed size of the frame pointed to by `src`, suitable to pass to `ZSTD_decompress` or similar, or an error code if given invalid input.


    @@ -806,20 +806,13 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx); * The higher the value of selected strategy, the more complex it is, * resulting in stronger and slower compression. * Special: value 0 means "do not change strategy". */ -#if 0 - ZSTD_p_windowSize,
    /* Maximum allowed back-reference distance. - * Can be set to a more precise value than windowLog. - * Will be transparently reduced to closest possible inferior value - * (see Zstandard compression format) */ - /* Not ready yet ! */ -#endif /* frame parameters */ ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */ ZSTD_p_checksumFlag, /* A 32-bits checksum of content is written at end of frame (default:0) */ ZSTD_p_dictIDFlag, /* When applicable, dictID of dictionary is provided in frame header (default:1) */ - /* dictionary parameters (must be set before loading) */ + /* dictionary parameters (must be set before ZSTD_CCtx_loadDictionary) */ ZSTD_p_dictMode=300, /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e. * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */ ZSTD_p_refDictContent, /* Dictionary content will be referenced, instead of copied (default:0==byCopy). @@ -876,7 +869,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);


    size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
    -

    Ref a prepared dictionary, to be used for all next compression jobs. +

    Reference a prepared dictionary, to be used for all next compression jobs. Note that compression parameters are enforced from within CDict, and supercede any compression parameter previously set within CCtx. The dictionary will remain valid for future compression jobs using same CCtx. @@ -888,16 +881,18 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);


    -
    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! <===================================== */
    -

    Reference a prefix (raw-content dictionary) for next compression job. - Decompression will have to use same prefix. - Prefix is only used once. Tables are discarded at end of compression job. - If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict. +

    size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);
    +

    Reference a prefix (single-usage dictionary) for next compression job. + Decompression need same prefix to properly regenerate data. + Prefix is **only used once**. Tables are discarded at end of compression job. + Subsequent compression jobs will be done without prefix (if none is explicitly referenced). + If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict instead. @result : 0, or an error code (which can be tested with ZSTD_isError()). - Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode". + Special : Adding any prefix (including NULL) invalidates any previous prefix or dictionary Note 1 : Prefix buffer is referenced. It must outlive compression job. Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters. - It's a CPU-heavy operation, with non-negligible impact on latency. + It's a CPU-heavy operation, with non-negligible impact on latency. + Note 3 : it's possible to alter ZSTD_p_dictMode using ZSTD_CCtx_setParameter()


    typedef enum {
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index b6b92f32c..93400c55c 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -88,8 +88,6 @@ struct ZSTD_CCtx_s {
         U32   hashLog3;         /* dispatch table : larger == faster, more memory */
         U32   loadedDictEnd;    /* index of end of dictionary */
         U32   forceWindow;      /* force back-references to respect limit of 1<streamStage != zcss_init) return ERROR(stage_wrong);
    -    return ERROR(compressionParameter_unsupported);
    -}
    -
     size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
     {
         if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
         cctx->cdict = cdict;
    -    return ERROR(compressionParameter_unsupported);
    +    cctx->prefix = NULL;   /* exclusive */
    +    cctx->prefixSize = 0;
    +    return 0;
    +}
    +
    +size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
    +{
    +    if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
    +    cctx->cdict = NULL;   /* prefix discards any prior cdict */
    +    cctx->prefix = prefix;
    +    cctx->prefixSize = prefixSize;
    +    return 0;
     }
     
     static void ZSTD_startNewCompression(ZSTD_CCtx* cctx)
    @@ -3622,14 +3629,17 @@ size_t ZSTD_CStreamOutSize(void)
     }
     
     static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
    -                                        ZSTD_parameters params,
    -                                        unsigned long long pledgedSrcSize)
    +                    const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
    +                    ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
         DEBUGLOG(5, "ZSTD_resetCStream_internal");
    +    /* params are supposed to be fully validated at this point */
    +    assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
    +    assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
     
         CHECK_F( ZSTD_compressBegin_internal(zcs,
    -                                        NULL, 0, ZSTD_dm_auto,
    -                                        zcs->cdict,
    +                                        dict, dictSize, ZSTD_dm_auto,   /* <========= Todo : make dictMode controllable ! */
    +                                        cdict,
                                             params, pledgedSrcSize,
                                             ZSTDb_buffered) );
     
    @@ -3650,10 +3660,11 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
         if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
             params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
         }
    -    return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
    +    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
     }
     
     /*! ZSTD_initCStream_internal() :
    + *  Note : not static, but hidden (not exposed). Used by zstdmt_compress.c
      *  Assumption 1 : params are valid
      *  Assumption 2 : either dict, or cdict, is defined, not both */
     size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
    @@ -3672,7 +3683,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
             }
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    -                                            0 /* byReference */, ZSTD_dm_auto,
    +                                            0 /* byReference */, ZSTD_dm_auto,  /* <======== Todo : make dictMode controllable */
                                                 params.cParams, zcs->customMem);
             zcs->cdict = zcs->cdictLocal;
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    @@ -3688,7 +3699,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
     
         zcs->requestedParams = params;
         zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
    -    return ZSTD_resetCStream_internal(zcs, params, pledgedSrcSize);
    +    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
     }
     
     /* ZSTD_initCStream_usingCDict_advanced() :
    @@ -3925,7 +3936,10 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
             } else
     #endif
             {
    -            CHECK_F( ZSTD_resetCStream_internal(cctx, params, cctx->pledgedSrcSizePlusOne-1) );
    +            const void* const prefix = cctx->prefix;
    +            size_t const prefixSize = cctx->prefixSize;
    +            cctx->prefix = NULL; cctx->prefixSize = 0;   /* single usage */
    +            CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
         }   }
     
     #ifdef ZSTD_MULTITHREAD
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 2b9018707..700a22f7b 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -947,20 +947,13 @@ typedef enum {
                                   * The higher the value of selected strategy, the more complex it is,
                                   * resulting in stronger and slower compression.
                                   * Special: value 0 means "do not change strategy". */
    -#if 0
    -    ZSTD_p_windowSize,       /* Maximum allowed back-reference distance.
    -                              * Can be set to a more precise value than windowLog.
    -                              * Will be transparently reduced to closest possible inferior value
    -                              * (see Zstandard compression format) */
    -                             /* Not ready yet ! */
    -#endif
     
         /* frame parameters */
         ZSTD_p_contentSizeFlag=200, /* Content size is written into frame header _whenever known_ (default:1) */
         ZSTD_p_checksumFlag,     /* A 32-bits checksum of content is written at end of frame (default:0) */
         ZSTD_p_dictIDFlag,       /* When applicable, dictID of dictionary is provided in frame header (default:1) */
     
    -    /* dictionary parameters (must be set before loading) */
    +    /* dictionary parameters (must be set before ZSTD_CCtx_loadDictionary) */
         ZSTD_p_dictMode=300,     /* Select how dictionary content must be interpreted. Value must be from type ZSTD_dictMode_e.
                                   * default : 0==auto : dictionary will be "full" if it respects specification, otherwise it will be "rawContent" */
         ZSTD_p_refDictContent,   /* Dictionary content will be referenced, instead of copied (default:0==byCopy).
    @@ -1018,7 +1011,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
     ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
     
     /*! ZSTD_CCtx_refCDict() :
    - *  Ref a prepared dictionary, to be used for all next compression jobs.
    + *  Reference a prepared dictionary, to be used for all next compression jobs.
      *  Note that compression parameters are enforced from within CDict,
      *  and supercede any compression parameter previously set within CCtx.
      *  The dictionary will remain valid for future compression jobs using same CCtx.
    @@ -1031,16 +1024,18 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, s
     ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
     
     /*! ZSTD_CCtx_refPrefix() :
    - *  Reference a prefix (raw-content dictionary) for next compression job.
    - *  Decompression will have to use same prefix.
    - *  Prefix is only used once. Tables are discarded at end of compression job.
    - *  If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict.
    + *  Reference a prefix (single-usage dictionary) for next compression job.
    + *  Decompression need same prefix to properly regenerate data.
    + *  Prefix is **only used once**. Tables are discarded at end of compression job.
    + *  Subsequent compression jobs will be done without prefix (if none is explicitly referenced).
    + *  If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_CDict instead.
      * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    - *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous prefix, meaning "return to no-dictionary mode".
    + *  Special : Adding any prefix (including NULL) invalidates any previous prefix or dictionary
      *  Note 1 : Prefix buffer is referenced. It must outlive compression job.
      *  Note 2 : Referencing a prefix involves building tables, which are dependent on compression parameters.
    - *           It's a CPU-heavy operation, with non-negligible impact on latency. */
    -ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);   /* Not ready yet ! <===================================== */
    + *           It's a CPU-heavy operation, with non-negligible impact on latency.
    + *  Note 3 : it's possible to alter ZSTD_p_dictMode using ZSTD_CCtx_setParameter() */
    +ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize);
     
     
     
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index ca25e891f..0f20d3253 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -1266,11 +1266,11 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
             }
     
             /* compression init */
    +        CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) );   /* cancel previous dict /*/
             if ((FUZ_rand(&lseed)&1) /* at beginning, to keep same nb of rand */
                 && oldTestLog /* at least one test happened */ && resetAllowed) {
                 maxTestSize = FUZ_randomLength(&lseed, oldTestLog+2);
                 if (maxTestSize >= srcBufferSize) maxTestSize = srcBufferSize-1;
    -            CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) );
                 {   int const compressionLevel = (FUZ_rand(&lseed) % 5) + 1;
                     CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_compressionLevel, compressionLevel) );
                 }
    @@ -1294,7 +1294,6 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                     ZSTD_compressionParameters cParams = ZSTD_getCParams(cLevel, pledgedSrcSize, dictSize);
     
                     /* mess with compression parameters */
    -                CHECK_Z( ZSTD_CCtx_loadDictionary(zc, NULL, 0) );   /* cancel previous dict, to allow new compression parameters */
                     cParams.windowLog += (FUZ_rand(&lseed) & 3) - 1;
                     cParams.hashLog += (FUZ_rand(&lseed) & 3) - 1;
                     cParams.chainLog += (FUZ_rand(&lseed) & 3) - 1;
    @@ -1312,7 +1311,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
     
                     /* unconditionally set, to be sync with decoder */
                     if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
    -                CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
    +                if (FUZ_rand(&lseed) & 1) { CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); }
    +                else { CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) ); }
     
                     if (dict && dictSize) {
                         /* test that compression parameters are correctly rejected after setting a dictionary */
    
    From 2e4274262dbb0c1b549a3f1effc334c38345b841 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Tue, 27 Jun 2017 17:09:12 -0700
    Subject: [PATCH 350/400] controlled dictMode
    
    ---
     lib/compress/zstd_compress.c | 13 +++++++------
     tests/zstreamtest.c          |  2 +-
     2 files changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 93400c55c..41be22edd 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3629,7 +3629,8 @@ size_t ZSTD_CStreamOutSize(void)
     }
     
     static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
    -                    const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
    +                    const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
    +                    const ZSTD_CDict* cdict,
                         ZSTD_parameters params, unsigned long long pledgedSrcSize)
     {
         DEBUGLOG(5, "ZSTD_resetCStream_internal");
    @@ -3638,7 +3639,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs,
         assert(!((dict) && (cdict)));  /* either dict or cdict, not both */
     
         CHECK_F( ZSTD_compressBegin_internal(zcs,
    -                                        dict, dictSize, ZSTD_dm_auto,   /* <========= Todo : make dictMode controllable ! */
    +                                        dict, dictSize, dictMode,
                                             cdict,
                                             params, pledgedSrcSize,
                                             ZSTDb_buffered) );
    @@ -3660,7 +3661,7 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
         if (zcs->compressionLevel != ZSTD_CLEVEL_CUSTOM) {
             params.cParams = ZSTD_getCParams(zcs->compressionLevel, pledgedSrcSize, 0 /* dictSize */);
         }
    -    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
    +    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
     }
     
     /*! ZSTD_initCStream_internal() :
    @@ -3683,7 +3684,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
             }
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    -                                            0 /* byReference */, ZSTD_dm_auto,  /* <======== Todo : make dictMode controllable */
    +                                            zcs->dictContentByRef, zcs->dictMode,
                                                 params.cParams, zcs->customMem);
             zcs->cdict = zcs->cdictLocal;
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    @@ -3699,7 +3700,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
     
         zcs->requestedParams = params;
         zcs->compressionLevel = ZSTD_CLEVEL_CUSTOM;
    -    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->cdict, params, pledgedSrcSize);
    +    return ZSTD_resetCStream_internal(zcs, NULL, 0, zcs->dictMode, zcs->cdict, params, pledgedSrcSize);
     }
     
     /* ZSTD_initCStream_usingCDict_advanced() :
    @@ -3939,7 +3940,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
                 const void* const prefix = cctx->prefix;
                 size_t const prefixSize = cctx->prefixSize;
                 cctx->prefix = NULL; cctx->prefixSize = 0;   /* single usage */
    -            CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
    +            CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
         }   }
     
     #ifdef ZSTD_MULTITHREAD
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 0f20d3253..f6bb440ce 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -415,7 +415,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo
     
         /* CDict scenario */
         DISPLAYLEVEL(3, "test%3i : digested dictionary : ", testNb++);
    -    {   ZSTD_CDict* const cdict = ZSTD_createCDict(dictionary.start, dictionary.filled, 1);
    +    {   ZSTD_CDict* const cdict = ZSTD_createCDict(dictionary.start, dictionary.filled, 1 /*byRef*/ );
             size_t const initError = ZSTD_initCStream_usingCDict(zc, cdict);
             if (ZSTD_isError(initError)) goto _output_error;
             cSize = 0;
    
    From 1fd2df9c2cfacb84fe7340842ea80b7e8a97cdc1 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 28 Jun 2017 09:57:59 -0700
    Subject: [PATCH 351/400] fixed zstreamtest
    
    modifying compression parameters is not allowed after ZSTD_CCtx_loadDictionary()
    but it is still allowed after ZSTD_refPrefix()
    ---
     tests/zstreamtest.c | 15 ++++++++-------
     1 file changed, 8 insertions(+), 7 deletions(-)
    
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index f6bb440ce..4c4479557 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -1311,13 +1311,14 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
     
                     /* unconditionally set, to be sync with decoder */
                     if (FUZ_rand(&lseed) & 1) CHECK_Z( ZSTD_CCtx_setParameter(zc, ZSTD_p_refDictContent, FUZ_rand(&lseed) & 1) );
    -                if (FUZ_rand(&lseed) & 1) { CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) ); }
    -                else { CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) ); }
    -
    -                if (dict && dictSize) {
    -                    /* test that compression parameters are correctly rejected after setting a dictionary */
    -                    size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1) ;
    -                    CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed");
    +                if (FUZ_rand(&lseed) & 1) {
    +                    CHECK_Z( ZSTD_CCtx_loadDictionary(zc, dict, dictSize) );
    +                    if (dict && dictSize) {
    +                        /* test that compression parameters are rejected (correctly) after loading a non-NULL dictionary */
    +                        size_t const setError = ZSTD_CCtx_setParameter(zc, ZSTD_p_windowLog, cParams.windowLog-1) ;
    +                        CHECK(!ZSTD_isError(setError), "ZSTD_CCtx_setParameter should have failed");
    +                }   } else {
    +                    CHECK_Z( ZSTD_CCtx_refPrefix(zc, dict, dictSize) );
                     }
     
                     /* mess with frame parameters */
    
    From 33a66390398334dc6a84e6b334194f226986e306 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 28 Jun 2017 11:09:43 -0700
    Subject: [PATCH 352/400] fixed ZSTD_refPrefix with Multithread-enabled CCtx
    
    ---
     lib/common/zstd_internal.h       | 17 +++++++++-----
     lib/compress/zstd_compress.c     | 15 +++++++------
     lib/compress/zstdmt_compress.c   |  2 +-
     lib/decompress/zstd_decompress.c | 38 +++++++++++++++++++++++---------
     tests/zstreamtest.c              |  5 ++++-
     5 files changed, 52 insertions(+), 25 deletions(-)
    
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index bcf93e58d..b2c7cfcdd 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -71,12 +71,17 @@
     
     #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
     #  include 
    -   static unsigned g_debugLevel = ZSTD_DEBUG;
    -#  define DEBUGLOG(l, ...) {                          \
    -                if (l<=g_debugLevel) {                \
    -                    fprintf(stderr, __FILE__ ": ");   \
    -                    fprintf(stderr, __VA_ARGS__);     \
    -                    fprintf(stderr, " \n");           \
    +/* recommended values for ZSTD_DEBUG display levels :
    + * 2 : reserved for currently active debugging path
    + * 3 : events once per object lifetime (CCtx, CDict)
    + * 4 : events once per frame
    + * 5 : events once per block
    + * 6 : events once per sequence (*very* verbose) */
    +#  define DEBUGLOG(l, ...) {                         \
    +                if (l<=ZSTD_DEBUG) {                 \
    +                    fprintf(stderr, __FILE__ ": ");  \
    +                    fprintf(stderr, __VA_ARGS__);    \
    +                    fprintf(stderr, " \n");          \
                 }   }
     #else
     #  define DEBUGLOG(l, ...)      {}    /* disabled */
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index 41be22edd..9ea866bf2 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3924,29 +3924,30 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
     
         if (cctx->streamStage == zcss_init) {
             /* transparent reset */
    +        const void* const prefix = cctx->prefix;
    +        size_t const prefixSize = cctx->prefixSize;
             ZSTD_parameters params = cctx->requestedParams;
             if (cctx->compressionLevel != ZSTD_CLEVEL_CUSTOM)
                 params.cParams = ZSTD_getCParams(cctx->compressionLevel,
    -                                    cctx->pledgedSrcSizePlusOne-1, 0 /* dictSize */);
    +                                cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
    +        cctx->prefix = NULL; cctx->prefixSize = 0;   /* single usage */
    +        assert(prefix==NULL || cctx->cdict==NULL);   /* only one can be set */
     
     #ifdef ZSTD_MULTITHREAD
             if (cctx->nbThreads > 1) {
    -            DEBUGLOG(4, "call ZSTDMT_initCStream_internal");
    -            CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, NULL, 0, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
    +            DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbThreads=%u", cctx->nbThreads);
    +            CHECK_F( ZSTDMT_initCStream_internal(cctx->mtctx, prefix, prefixSize, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
                 cctx->streamStage = zcss_load;
             } else
     #endif
             {
    -            const void* const prefix = cctx->prefix;
    -            size_t const prefixSize = cctx->prefixSize;
    -            cctx->prefix = NULL; cctx->prefixSize = 0;   /* single usage */
                 CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
         }   }
     
     #ifdef ZSTD_MULTITHREAD
         if (cctx->nbThreads > 1) {
             size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
    -        DEBUGLOG(4, "ZSTDMT_compressStream_generic : %u", (U32)flushMin);
    +        DEBUGLOG(5, "ZSTDMT_compressStream_generic : %u", (U32)flushMin);
             if ( ZSTD_isError(flushMin)
               || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
                 ZSTD_startNewCompression(cctx);
    diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c
    index 8a167ce1d..d5f08c76f 100644
    --- a/lib/compress/zstdmt_compress.c
    +++ b/lib/compress/zstdmt_compress.c
    @@ -586,7 +586,7 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
         if (dict) {
             ZSTD_freeCDict(zcs->cdictLocal);
             zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
    -                                                    0 /* byRef */, ZSTD_dm_auto,
    +                                                    0 /* byRef */, ZSTD_dm_auto,   /* note : a loadPrefix becomes an internal CDict */
                                                         params.cParams, zcs->cMem);
             zcs->cdict = zcs->cdictLocal;
             if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
    diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c
    index 61f766e21..a4844c5b3 100644
    --- a/lib/decompress/zstd_decompress.c
    +++ b/lib/decompress/zstd_decompress.c
    @@ -750,6 +750,7 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
         const BYTE* const istart = (const BYTE* const)src;
         const BYTE* const iend = istart + srcSize;
         const BYTE* ip = istart;
    +    DEBUGLOG(5, "ZSTD_decodeSeqHeaders");
     
         /* check */
         if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
    @@ -930,12 +931,18 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
             seq.offset = offset;
         }
     
    -    seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
    +    seq.matchLength = ML_base[mlCode]
    +                    + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */
         if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
     
    -    seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    -    if (MEM_32bits() ||
    -       (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
    +    seq.litLength = LL_base[llCode]
    +                  + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */
    +    if (  MEM_32bits()
    +      || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) )
    +       BIT_reloadDStream(&seqState->DStream);
    +
    +    DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
    +                (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
     
         /* ANS state update */
         FSE_updateState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */
    @@ -975,7 +982,8 @@ size_t ZSTD_execSequence(BYTE* op,
         /* copy Match */
         if (sequence.offset > (size_t)(oLitEnd - base)) {
             /* offset beyond prefix -> go into extDict */
    -        if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
    +        if (sequence.offset > (size_t)(oLitEnd - vBase))
    +            return ERROR(corruption_detected);
             match = dictEnd + (match - base);
             if (match + sequence.matchLength <= dictEnd) {
                 memmove(oLitEnd, match, sequence.matchLength);
    @@ -1043,9 +1051,12 @@ static size_t ZSTD_decompressSequences(
         const BYTE* const vBase = (const BYTE*) (dctx->vBase);
         const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
         int nbSeq;
    +    DEBUGLOG(5, "ZSTD_decompressSequences");
     
         /* Build Decoding Tables */
         {   size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
    +        DEBUGLOG(5, "ZSTD_decodeSeqHeaders: size=%u, nbSeq=%i",
    +                    (U32)seqHSize, nbSeq);
             if (ZSTD_isError(seqHSize)) return seqHSize;
             ip += seqHSize;
         }
    @@ -1064,11 +1075,13 @@ static size_t ZSTD_decompressSequences(
                 nbSeq--;
                 {   seq_t const sequence = ZSTD_decodeSequence(&seqState);
                     size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
    +                DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
                     if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
                     op += oneSeqSize;
             }   }
     
             /* check if reached exact end */
    +        DEBUGLOG(5, "after decode loop, remaining nbSeq : %i", nbSeq);
             if (nbSeq) return ERROR(corruption_detected);
             /* save reps for next block */
             { U32 i; for (i=0; ientropy.rep[i] = (U32)(seqState.prevOffset[i]); }
    @@ -1355,11 +1368,13 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
                           const void* src, size_t srcSize)
     {   /* blockType == blockCompressed */
         const BYTE* ip = (const BYTE*)src;
    +    DEBUGLOG(5, "ZSTD_decompressBlock_internal");
     
         if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
     
         /* Decode literals section */
         {   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
    +        DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize);
             if (ZSTD_isError(litCSize)) return litCSize;
             ip += litCSize;
             srcSize -= litCSize;
    @@ -1697,6 +1712,7 @@ static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skip
      *            or an error code, which can be tested using ZSTD_isError() */
     size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
     {
    +    DEBUGLOG(5, "ZSTD_decompressContinue");
         /* Sanity check */
         if (srcSize != dctx->expected) return ERROR(srcSize_wrong);   /* unauthorized */
         if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
    @@ -1756,10 +1772,12 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
             }
         case ZSTDds_decompressLastBlock:
         case ZSTDds_decompressBlock:
    +        DEBUGLOG(5, "case ZSTDds_decompressBlock");
             {   size_t rSize;
                 switch(dctx->bType)
                 {
                 case bt_compressed:
    +                DEBUGLOG(5, "case bt_compressed");
                     rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
                     break;
                 case bt_raw :
    @@ -2323,7 +2341,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }   }
     
                 /* Consume header (see ZSTDds_decodeFrameHeader) */
    -            DEBUGLOG(5, "Consume header");
    +            DEBUGLOG(4, "Consume header");
                 CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
     
                 if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {  /* skippable frame */
    @@ -2336,7 +2354,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                 }
     
                 /* control buffer memory usage */
    -            DEBUGLOG(5, "Control max buffer memory usage");
    +            DEBUGLOG(4, "Control max buffer memory usage");
                 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
                 if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
     
    @@ -2346,12 +2364,12 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
                     zds->blockSize = blockSize;
                     if ((zds->inBuffSize < blockSize) || (zds->outBuffSize < neededOutSize)) {
                         size_t const bufferSize = blockSize + neededOutSize;
    -                    DEBUGLOG(5, "inBuff  : from %u to %u",
    +                    DEBUGLOG(4, "inBuff  : from %u to %u",
                                     (U32)zds->inBuffSize, (U32)blockSize);
    -                    DEBUGLOG(5, "outBuff : from %u to %u",
    +                    DEBUGLOG(4, "outBuff : from %u to %u",
                                     (U32)zds->outBuffSize, (U32)neededOutSize);
                         if (zds->staticSize) {  /* static DCtx */
    -                        DEBUGLOG(5, "staticSize : %u", (U32)zds->staticSize);
    +                        DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
                             assert(zds->staticSize >= sizeof(ZSTD_DCtx));  /* controlled at init */
                             if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx))
                                 return ERROR(memory_allocation);
    diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c
    index 4c4479557..e4d40c66a 100644
    --- a/tests/zstreamtest.c
    +++ b/tests/zstreamtest.c
    @@ -1382,8 +1382,10 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
     
             /* multi - fragments decompression test */
             if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) {
    +            DISPLAYLEVEL(5, "resetting DCtx (dict:%08X) \n", (U32)(size_t)dict);
                 CHECK_Z( ZSTD_resetDStream(zd) );
             } else {
    +            DISPLAYLEVEL(5, "using dict of size %u \n", (U32)dictSize);
                 CHECK_Z( ZSTD_initDStream_usingDict(zd, dict, dictSize) );
             }
             {   size_t decompressionResult = 1;
    @@ -1395,7 +1397,8 @@ static int fuzzerTests_newAPI(U32 seed, U32 nbTests, unsigned startTest, double
                     size_t const dstBuffSize = MIN(dstBufferSize - totalGenSize, randomDstSize);
                     inBuff.size = inBuff.pos + readCSrcSize;
                     outBuff.size = inBuff.pos + dstBuffSize;
    -                DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes \n", (U32)readCSrcSize);
    +                DISPLAYLEVEL(5, "ZSTD_decompressStream input %u bytes (pos:%u/%u)\n",
    +                            (U32)readCSrcSize, (U32)inBuff.pos, (U32)cSize);
                     decompressionResult = ZSTD_decompressStream(zd, &outBuff, &inBuff);
                     CHECK (ZSTD_isError(decompressionResult), "decompression error : %s", ZSTD_getErrorName(decompressionResult));
                     DISPLAYLEVEL(5, "inBuff.pos = %u \n", (U32)readCSrcSize);
    
    From e667d33b0b102e8ff1f799945156393cbff05604 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 28 Jun 2017 12:19:37 -0700
    Subject: [PATCH 353/400] fixed generation of buggy test, corrected DISPLAY
     statements for errors
    
    ---
     tests/decodecorpus.c | 28 +++++++++++++++-------------
     1 file changed, 15 insertions(+), 13 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index 45c47182b..a377169f3 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1216,8 +1216,8 @@ static int genRandomDict(U32 dictID, U32 seed, size_t dictSize, BYTE* fullDict){
             /* create variables */
             size_t dictWriteSize = 0;
             ZDICT_params_t zdictParams;
    -        size_t const headerSize = dictSize/4;
    -        size_t const dictContentSize = dictSize - dictSize/4;
    +        size_t const headerSize = MAX(dictSize/4, 256);
    +        size_t const dictContentSize = dictSize - headerSize;
             BYTE* const dictContent = fullDict + headerSize;
             if (dictContentSize < ZDICT_CONTENTSIZE_MIN || dictSize < ZDICT_DICTSIZE_MIN) {
                 DISPLAY("Error: dictionary size is too small\n");
    @@ -1322,9 +1322,10 @@ cleanup:
         return ret;
     }
     
    -static size_t testDecodeWithDict(U32 seed, size_t dictSize)
    +static size_t testDecodeWithDict(U32 seed)
     {
         /* create variables */
    +    size_t const dictSize = RAND(&seed) % (10 << 20) + ZDICT_DICTSIZE_MIN + ZDICT_CONTENTSIZE_MIN;
         U32 const dictID = RAND(&seed);
         size_t errorDetected = 0;
         BYTE* const fullDict = malloc(dictSize);
    @@ -1347,8 +1348,9 @@ static size_t testDecodeWithDict(U32 seed, size_t dictSize)
     
             /* generate frame */
             {
    -            size_t const dictContentSize = dictSize-dictSize/4;
    -            BYTE* const dictContent = fullDict+dictSize/4;
    +            size_t const headerSize = MAX(dictSize/4, 256);
    +            size_t const dictContentSize = dictSize-headerSize;
    +            BYTE* const dictContent = fullDict+headerSize;
                 dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
                 seed = generateFrame(seed, &fr, info);
             }
    @@ -1392,7 +1394,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
     
         for (fnum = 0; fnum < numFiles || clockSpan(startClock) < maxClockSpan; fnum++) {
             frame_t fr;
    -
    +        U32 const seedCopy = seed;
             if (fnum < numFiles)
                 DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
             else
    @@ -1405,24 +1407,23 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
     
             {   size_t const r = testDecodeSimple(&fr);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in simple mode on test seed %u: %s\n", seed + fnum,
    +                DISPLAY("Error in simple mode on test seed %u, fnum %u: %s\n", seedCopy, fnum,
                             ZSTD_getErrorName(r));
                     return 1;
                 }
             }
             {   size_t const r = testDecodeStreaming(&fr);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in streaming mode on test seed %u: %s\n", seed + fnum,
    +                DISPLAY("Error in streaming mode on test seed %u, fnum %u: %s\n", seedCopy, fnum,
                             ZSTD_getErrorName(r));
                     return 1;
                 }
             }
             {
                 /* don't create a dictionary that is too big */
    -            size_t const dictSize = RAND(&seed) % (10 << 20) + ZDICT_DICTSIZE_MIN;
    -            size_t const r = testDecodeWithDict(seed, dictSize);
    +            size_t const r = testDecodeWithDict(seed);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in dictionary mode on test seed %u: %s\n", seed+fnum, ZSTD_getErrorName(r));
    +                DISPLAY("Error in dictionary mode on test seed %u, fnum %u: %s\n", seedCopy, fnum, ZSTD_getErrorName(r));
                     return 1;
                 }
             }
    @@ -1544,8 +1545,9 @@ static int generateCorpusWithDict(U32 seed, unsigned numFiles, const char* const
                 frame_t fr;
                 DISPLAYUPDATE("\r%u/%u        ", fnum, numFiles);
                 {
    -                size_t const dictContentSize = dictSize-dictSize/4;
    -                BYTE* const dictContent = fullDict+dictSize/4;
    +                size_t const headerSize = MAX(dictSize/4, 256);
    +                size_t const dictContentSize = dictSize-headerSize;
    +                BYTE* const dictContent = fullDict+headerSize;
                     dictInfo const info = initDictInfo(1, dictContentSize, dictContent, dictID);
                     seed = generateFrame(seed, &fr, info);
                 }
    
    From 7ac4724bd2c02ee10291561b07296b5439c0ee10 Mon Sep 17 00:00:00 2001
    From: Paul Cruz 
    Date: Wed, 28 Jun 2017 13:00:49 -0700
    Subject: [PATCH 354/400] removed fnum from DISPLAY statements
    
    ---
     tests/decodecorpus.c | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/tests/decodecorpus.c b/tests/decodecorpus.c
    index a377169f3..eaf074578 100644
    --- a/tests/decodecorpus.c
    +++ b/tests/decodecorpus.c
    @@ -1407,14 +1407,14 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
     
             {   size_t const r = testDecodeSimple(&fr);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in simple mode on test seed %u, fnum %u: %s\n", seedCopy, fnum,
    +                DISPLAY("Error in simple mode on test seed %u: %s\n", seedCopy,
                             ZSTD_getErrorName(r));
                     return 1;
                 }
             }
             {   size_t const r = testDecodeStreaming(&fr);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in streaming mode on test seed %u, fnum %u: %s\n", seedCopy, fnum,
    +                DISPLAY("Error in streaming mode on test seed %u: %s\n", seedCopy,
                             ZSTD_getErrorName(r));
                     return 1;
                 }
    @@ -1423,7 +1423,7 @@ static int runTestMode(U32 seed, unsigned numFiles, unsigned const testDurationS
                 /* don't create a dictionary that is too big */
                 size_t const r = testDecodeWithDict(seed);
                 if (ZSTD_isError(r)) {
    -                DISPLAY("Error in dictionary mode on test seed %u, fnum %u: %s\n", seedCopy, fnum, ZSTD_getErrorName(r));
    +                DISPLAY("Error in dictionary mode on test seed %u: %s\n", seedCopy, ZSTD_getErrorName(r));
                     return 1;
                 }
             }
    
    From adbe74a8ac099d9f97929478b9ba45c9fa2cdc27 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 28 Jun 2017 13:22:37 -0700
    Subject: [PATCH 355/400] adjusted compression levels to guarantee a
     monotonically increasing memory budget
    
    ---
     lib/compress/zstd_compress.c | 20 ++++++++++----------
     1 file changed, 10 insertions(+), 10 deletions(-)
    
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index ea37197ff..c781232c6 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -3992,30 +3992,30 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
     int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
     
     static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
    -{   /* "default" */
    +{   /* "default" - guarantees a monotonically increasing memory budget */
         /* W,  C,  H,  S,  L, TL, strat */
         { 18, 12, 12,  1,  7, 16, ZSTD_fast    },  /* level  0 - never used */
         { 19, 13, 14,  1,  7, 16, ZSTD_fast    },  /* level  1 */
         { 19, 15, 16,  1,  6, 16, ZSTD_fast    },  /* level  2 */
    -    { 20, 16, 17,  1,  5, 16, ZSTD_dfast   },  /* level  3.*/
    -    { 20, 18, 18,  1,  5, 16, ZSTD_dfast   },  /* level  4.*/
    -    { 20, 15, 18,  3,  5, 16, ZSTD_greedy  },  /* level  5 */
    -    { 21, 16, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
    -    { 21, 17, 20,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
    +    { 20, 16, 17,  1,  5, 16, ZSTD_dfast   },  /* level  3 */
    +    { 20, 17, 18,  1,  5, 16, ZSTD_dfast   },  /* level  4 */
    +    { 20, 17, 18,  2,  5, 16, ZSTD_greedy  },  /* level  5 */
    +    { 21, 17, 19,  2,  5, 16, ZSTD_lazy    },  /* level  6 */
    +    { 21, 18, 19,  3,  5, 16, ZSTD_lazy    },  /* level  7 */
         { 21, 18, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */
    -    { 21, 20, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
    +    { 21, 19, 20,  3,  5, 16, ZSTD_lazy2   },  /* level  9 */
         { 21, 19, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */
         { 22, 20, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */
         { 22, 20, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */
         { 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 13 */
         { 22, 21, 22,  6,  5, 16, ZSTD_lazy2   },  /* level 14 */
    -    { 22, 21, 21,  5,  5, 16, ZSTD_btlazy2 },  /* level 15 */
    +    { 22, 21, 22,  5,  5, 16, ZSTD_btlazy2 },  /* level 15 */
         { 23, 22, 22,  5,  5, 16, ZSTD_btlazy2 },  /* level 16 */
    -    { 23, 21, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
    +    { 23, 22, 22,  4,  5, 24, ZSTD_btopt   },  /* level 17 */
         { 23, 22, 22,  5,  4, 32, ZSTD_btopt   },  /* level 18 */
         { 23, 23, 22,  6,  3, 48, ZSTD_btopt   },  /* level 19 */
         { 25, 25, 23,  7,  3, 64, ZSTD_btultra },  /* level 20 */
    -    { 26, 26, 23,  7,  3,256, ZSTD_btultra },  /* level 21 */
    +    { 26, 26, 24,  7,  3,256, ZSTD_btultra },  /* level 21 */
         { 27, 27, 25,  9,  3,512, ZSTD_btultra },  /* level 22 */
     },
     {   /* for srcSize <= 256 KB */
    
    From 813535105b4883183fb7ebffea454944d0dd7552 Mon Sep 17 00:00:00 2001
    From: Yann Collet 
    Date: Wed, 28 Jun 2017 15:34:56 -0700
    Subject: [PATCH 356/400] added function to control monotonic memory budget
     increase of ZSTD_defaultCParameters[0]
    
    It's a runtime test, based on assert(),
    played once, on first ZSTD_getCParams() usage,
    when ZSTD_DEBUG is enabled.
    ---
     doc/zstd_manual.html         | 11 +++++----
     lib/compress/zstd_compress.c | 46 ++++++++++++++++++++++++++++++++++++
     lib/zstd.h                   | 11 +++++----
     3 files changed, 58 insertions(+), 10 deletions(-)
    
    diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html
    index 6d524ae32..bb6f0eac9 100644
    --- a/doc/zstd_manual.html
    +++ b/doc/zstd_manual.html
    @@ -412,9 +412,9 @@ size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams);
     size_t ZSTD_estimateDCtxSize(void);
     

    These functions make it possible to estimate memory usage of a future {D,C}Ctx, before its creation. - The objective is to guide decision before allocation. - ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". - If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. + ZSTD_estimateCCtxSize() will provide a budget large for any compression level up to selected one. + It will also consider src size to be arbitrarily "large", which is worst case. + If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. Note : CCtx estimation is only correct for single-threaded compression


    @@ -423,8 +423,9 @@ size_t ZSTD_estimateDCtxSize(void); size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams); size_t ZSTD_estimateDStreamSize(size_t windowSize); size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); -

    ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large". - If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. +

    ZSTD_estimateCStreamSize() will provide a budget large for any compression level up to selected one. + It will also consider src size to be arbitrarily "large", which is worst case. + If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. Note : CStream estimation is only correct for single-threaded compression. ZSTD_DStream memory budget depends on window Size. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c781232c6..c2adc56ab 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -4098,6 +4098,43 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV }, }; +/* This function just controls + * the monotonic memory budget increase of ZSTD_defaultCParameters[0]. + * Run only once, on first ZSTD_getCParams() usage, when ZSTD_DEBUG is enabled + */ +MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void) +{ +# define ZSTD_TABLECOST(h,c) ((1<<(h)) + (1<<(c))) +# define ZDCP_FIELD(l,field) (ZSTD_defaultCParameters[0][l].field) +# define ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(l) { \ + assert(ZDCP_FIELD(l,windowLog) <= ZDCP_FIELD(l+1,windowLog) ); \ + assert(ZSTD_TABLECOST(ZDCP_FIELD(l,hashLog), ZDCP_FIELD(l,chainLog)) <= ZSTD_TABLECOST(ZDCP_FIELD(l+1,hashLog), ZDCP_FIELD(l+1,chainLog)) ); \ + } + + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(1); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(2); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(3); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(4); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(5); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(6); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(7); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(8); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(9); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(10); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(11); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(12); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(13); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(14); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(15); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(16); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(17); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(18); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(19); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(20); + ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(21); + assert(ZSTD_maxCLevel()==22); +} + /*! ZSTD_getCParams() : * @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`. * Size values are optional, provide 0 if not known or unused */ @@ -4108,6 +4145,15 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */ if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; + +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1) + static int g_monotonicTest = 1; + if (g_monotonicTest) { + ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(); + g_monotonicTest=0; + } +#endif + { ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel]; return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); } } diff --git a/lib/zstd.h b/lib/zstd.h index 08358f0df..75bdb4895 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -496,9 +496,9 @@ ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict); /*! ZSTD_estimate*() : * These functions make it possible to estimate memory usage * of a future {D,C}Ctx, before its creation. - * The objective is to guide decision before allocation. - * ZSTD_estimateCCtxSize() will consider src size to be arbitrarily "large". - * If srcSize is known to be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. + * ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one. + * It will also consider src size to be arbitrarily "large", which is worst case. + * If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. * ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * Note : CCtx estimation is only correct for single-threaded compression */ ZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel); @@ -506,8 +506,9 @@ ZSTDLIB_API size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cPa ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void); /*! ZSTD_estimate?StreamSize() : - * ZSTD_estimateCStreamSize() will consider src size to be arbitrarily "large". - * If srcSize is known to be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. + * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. + * It will also consider src size to be arbitrarily "large", which is worst case. + * If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. * ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. * Note : CStream estimation is only correct for single-threaded compression. * ZSTD_DStream memory budget depends on window Size. From 1ca76039af730c11fc761961a9ccb7de99d4c057 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 28 Jun 2017 15:40:21 -0700 Subject: [PATCH 357/400] fixed -Wdeclaration-after-statement --- lib/compress/zstd_compress.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c2adc56ab..5c2035a24 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -4143,8 +4143,6 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l size_t const addedSize = srcSizeHint ? 0 : 500; U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : (U64)-1; U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */ - if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */ - if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1) static int g_monotonicTest = 1; @@ -4154,6 +4152,8 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l } #endif + if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */ + if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL; { ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel]; return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); } } From 62f7efc04a8313bef7ad830089c631f9ff6239c3 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 28 Jun 2017 16:25:13 -0700 Subject: [PATCH 358/400] added a test to ensure ZSTD_refPrefix() doesn't impact the following compression job --- tests/zstreamtest.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index e4d40c66a..f16cc4b0a 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -522,6 +522,55 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo DISPLAYLEVEL(3, "OK (%s)\n", ZSTD_getErrorName(r)); } + DISPLAYLEVEL(3, "test%3i : compress with ZSTD_CCtx_refPrefix : ", testNb++); + { size_t const refErr = ZSTD_CCtx_refPrefix(zc, dictionary.start, dictionary.filled); + if (ZSTD_isError(refErr)) goto _output_error; } + outBuff.dst = compressedBuffer; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = CNBufferSize; + inBuff.pos = 0; + { size_t const r = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end); + if (ZSTD_isError(r)) goto _output_error; } + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + cSize = outBuff.pos; + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBufferSize*100); + + DISPLAYLEVEL(3, "test%3i : decompress with dictionary : ", testNb++); + { size_t const r = ZSTD_decompress_usingDict(zd, + decodedBuffer, CNBufferSize, + compressedBuffer, cSize, + dictionary.start, dictionary.filled); + if (ZSTD_isError(r)) goto _output_error; /* must fail : dictionary not used */ + DISPLAYLEVEL(3, "OK \n"); + } + + DISPLAYLEVEL(3, "test%3i : decompress without dictionary (should fail): ", testNb++); + { size_t const r = ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, cSize); + if (!ZSTD_isError(r)) goto _output_error; /* must fail : dictionary not used */ + DISPLAYLEVEL(3, "OK (%s)\n", ZSTD_getErrorName(r)); + } + + DISPLAYLEVEL(3, "test%3i : compress again with ZSTD_compress_generic : ", testNb++); + outBuff.dst = compressedBuffer; + outBuff.size = compressedBufferSize; + outBuff.pos = 0; + inBuff.src = CNBuffer; + inBuff.size = CNBufferSize; + inBuff.pos = 0; + { size_t const r = ZSTD_compress_generic(zc, &outBuff, &inBuff, ZSTD_e_end); + if (ZSTD_isError(r)) goto _output_error; } + if (inBuff.pos != inBuff.size) goto _output_error; /* entire input should be consumed */ + cSize = outBuff.pos; + DISPLAYLEVEL(3, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBufferSize*100); + + DISPLAYLEVEL(3, "test%3i : decompress without dictionary (should work): ", testNb++); + { size_t const r = ZSTD_decompress(decodedBuffer, CNBufferSize, compressedBuffer, cSize); + if (ZSTD_isError(r)) goto _output_error; /* must fail : dictionary not used */ + DISPLAYLEVEL(3, "OK \n"); + } + /* Empty srcSize */ DISPLAYLEVEL(3, "test%3i : ZSTD_initCStream_advanced with pledgedSrcSize=0 and dict : ", testNb++); { ZSTD_parameters params = ZSTD_getParams(5, 0, 0); From 037466245fd01669d6a7347e5560000ae2aba44d Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 28 Jun 2017 20:17:22 -0700 Subject: [PATCH 359/400] refactor ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget() use less macro statements the initial version was meant to work with STATIC_ASSERT but since it doesn't work and needs assert() it's possible to rewrite it using normally compiled code which is better for compiler. Downside : the error message is less precise. There is a DEBUGLOG(3,) to compensate. --- doc/zstd_manual.html | 4 ++-- lib/compress/zstd_compress.c | 38 ++++++++++-------------------------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 683b70e80..cd2b06dd8 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -412,7 +412,7 @@ size_t ZSTD_estimateCCtxSize_advanced(ZSTD_compressionParameters cParams); size_t ZSTD_estimateDCtxSize(void);

    These functions make it possible to estimate memory usage of a future {D,C}Ctx, before its creation. - ZSTD_estimateCCtxSize() will provide a budget large for any compression level up to selected one. + ZSTD_estimateCCtxSize() will provide a budget large enough for any compression level up to selected one. It will also consider src size to be arbitrarily "large", which is worst case. If srcSize is known to always be small, ZSTD_estimateCCtxSize_advanced() can provide a tighter estimation. ZSTD_estimateCCtxSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. @@ -423,7 +423,7 @@ size_t ZSTD_estimateDCtxSize(void); size_t ZSTD_estimateCStreamSize_advanced(ZSTD_compressionParameters cParams); size_t ZSTD_estimateDStreamSize(size_t windowSize); size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize); -

    ZSTD_estimateCStreamSize() will provide a budget large for any compression level up to selected one. +

    ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one. It will also consider src size to be arbitrarily "large", which is worst case. If srcSize is known to always be small, ZSTD_estimateCStreamSize_advanced() can provide a tighter estimation. ZSTD_estimateCStreamSize_advanced() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b396311d3..f492d92bd 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -4115,42 +4115,24 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV }, }; +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1) /* This function just controls * the monotonic memory budget increase of ZSTD_defaultCParameters[0]. * Run only once, on first ZSTD_getCParams() usage, when ZSTD_DEBUG is enabled */ MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void) { -# define ZSTD_TABLECOST(h,c) ((1<<(h)) + (1<<(c))) -# define ZDCP_FIELD(l,field) (ZSTD_defaultCParameters[0][l].field) -# define ZSTD_CHECK_MONOTONIC_INCREASE_LEVEL(l) { \ - assert(ZDCP_FIELD(l,windowLog) <= ZDCP_FIELD(l+1,windowLog) ); \ - assert(ZSTD_TABLECOST(ZDCP_FIELD(l,hashLog), ZDCP_FIELD(l,chainLog)) <= ZSTD_TABLECOST(ZDCP_FIELD(l+1,hashLog), ZDCP_FIELD(l+1,chainLog)) ); \ + int level; + for (level=1; level Date: Mon, 26 Jun 2017 18:33:04 -0700 Subject: [PATCH 360/400] [linux-kernel] Update patches for v2 * Reduce stack usage of many zstd functions, none use over 388 B anymore. * Remove an incorrect `const` in `xxhash`. --- contrib/linux-kernel/0000-cover-letter.patch | 96 ++++ .../0001-lib-Add-xxhash-module.patch | 20 +- .../0002-lib-Add-zstd-modules.patch | 537 ++++++++++-------- .../0003-btrfs-Add-zstd-support.patch | 2 +- .../0004-squashfs-Add-zstd-support.patch | 2 +- contrib/linux-kernel/lib/xxhash.c | 2 +- contrib/linux-kernel/lib/zstd/compress.c | 47 +- contrib/linux-kernel/lib/zstd/decompress.c | 52 +- .../linux-kernel/lib/zstd/entropy_common.c | 5 +- contrib/linux-kernel/lib/zstd/fse.h | 13 +- contrib/linux-kernel/lib/zstd/fse_compress.c | 100 +--- .../linux-kernel/lib/zstd/fse_decompress.c | 33 +- contrib/linux-kernel/lib/zstd/huf.h | 49 +- contrib/linux-kernel/lib/zstd/huf_compress.c | 72 ++- .../linux-kernel/lib/zstd/huf_decompress.c | 92 ++- contrib/linux-kernel/lib/zstd/zstd_common.c | 2 +- contrib/linux-kernel/test/Makefile | 12 +- .../linux-kernel/test/include/linux/math64.h | 11 + 18 files changed, 691 insertions(+), 456 deletions(-) create mode 100644 contrib/linux-kernel/0000-cover-letter.patch create mode 100644 contrib/linux-kernel/test/include/linux/math64.h diff --git a/contrib/linux-kernel/0000-cover-letter.patch b/contrib/linux-kernel/0000-cover-letter.patch new file mode 100644 index 000000000..763b5a9cb --- /dev/null +++ b/contrib/linux-kernel/0000-cover-letter.patch @@ -0,0 +1,96 @@ +From 8bc9a0ae5c86a6d02d9a5274b9965ddac0e8d330 Mon Sep 17 00:00:00 2001 +From: Nick Terrell +Date: Wed, 28 Jun 2017 22:00:00 -0700 +Subject: [PATCH v2 0/4] Add xxhash and zstd modules + +Hi all, + +This patch set adds xxhash, zstd compression, and zstd decompression +modules. It also adds zstd support to BtrFS and SquashFS. + +Each patch has relevant summaries, benchmarks, and tests. + +Best, +Nick Terrell + +Changelog: + +v1 -> v2: +- Make pointer in lib/xxhash.c:394 non-const (1/4) +- Use div_u64() for division of u64s (2/4) +- Reduce stack usage of ZSTD_compressSequences(), ZSTD_buildSeqTable(), + ZSTD_decompressSequencesLong(), FSE_buildDTable(), FSE_decompress_wksp(), + HUF_writeCTable(), HUF_readStats(), HUF_readCTable(), + HUF_compressWeights(), HUF_readDTableX2(), and HUF_readDTableX4() (2/4) +- No zstd function uses more than 400 B of stack space (2/4) + +Nick Terrell (4): + lib: Add xxhash module + lib: Add zstd modules + btrfs: Add zstd support + squashfs: Add zstd support + + fs/btrfs/Kconfig | 2 + + fs/btrfs/Makefile | 2 +- + fs/btrfs/compression.c | 1 + + fs/btrfs/compression.h | 6 +- + fs/btrfs/ctree.h | 1 + + fs/btrfs/disk-io.c | 2 + + fs/btrfs/ioctl.c | 6 +- + fs/btrfs/props.c | 6 + + fs/btrfs/super.c | 12 +- + fs/btrfs/sysfs.c | 2 + + fs/btrfs/zstd.c | 433 ++++++ + fs/squashfs/Kconfig | 14 + + fs/squashfs/Makefile | 1 + + fs/squashfs/decompressor.c | 7 + + fs/squashfs/decompressor.h | 4 + + fs/squashfs/squashfs_fs.h | 1 + + fs/squashfs/zstd_wrapper.c | 150 ++ + include/linux/xxhash.h | 236 +++ + include/linux/zstd.h | 1157 +++++++++++++++ + include/uapi/linux/btrfs.h | 8 +- + lib/Kconfig | 11 + + lib/Makefile | 3 + + lib/xxhash.c | 500 +++++++ + lib/zstd/Makefile | 18 + + lib/zstd/bitstream.h | 374 +++++ + lib/zstd/compress.c | 3479 ++++++++++++++++++++++++++++++++++++++++++++ + lib/zstd/decompress.c | 2526 ++++++++++++++++++++++++++++++++ + lib/zstd/entropy_common.c | 243 ++++ + lib/zstd/error_private.h | 53 + + lib/zstd/fse.h | 575 ++++++++ + lib/zstd/fse_compress.c | 795 ++++++++++ + lib/zstd/fse_decompress.c | 332 +++++ + lib/zstd/huf.h | 212 +++ + lib/zstd/huf_compress.c | 771 ++++++++++ + lib/zstd/huf_decompress.c | 960 ++++++++++++ + lib/zstd/mem.h | 151 ++ + lib/zstd/zstd_common.c | 75 + + lib/zstd/zstd_internal.h | 269 ++++ + lib/zstd/zstd_opt.h | 1014 +++++++++++++ + 39 files changed, 14400 insertions(+), 12 deletions(-) + create mode 100644 fs/btrfs/zstd.c + create mode 100644 fs/squashfs/zstd_wrapper.c + create mode 100644 include/linux/xxhash.h + create mode 100644 include/linux/zstd.h + create mode 100644 lib/xxhash.c + create mode 100644 lib/zstd/Makefile + create mode 100644 lib/zstd/bitstream.h + create mode 100644 lib/zstd/compress.c + create mode 100644 lib/zstd/decompress.c + create mode 100644 lib/zstd/entropy_common.c + create mode 100644 lib/zstd/error_private.h + create mode 100644 lib/zstd/fse.h + create mode 100644 lib/zstd/fse_compress.c + create mode 100644 lib/zstd/fse_decompress.c + create mode 100644 lib/zstd/huf.h + create mode 100644 lib/zstd/huf_compress.c + create mode 100644 lib/zstd/huf_decompress.c + create mode 100644 lib/zstd/mem.h + create mode 100644 lib/zstd/zstd_common.c + create mode 100644 lib/zstd/zstd_internal.h + create mode 100644 lib/zstd/zstd_opt.h + +-- +2.9.3 diff --git a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch index 9a8f50a25..84a2c53c6 100644 --- a/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch +++ b/contrib/linux-kernel/0001-lib-Add-xxhash-module.patch @@ -1,7 +1,7 @@ -From e75beb7c2e05550b2846e31ad8a0082c188504da Mon Sep 17 00:00:00 2001 +From 5ac909c415ab4a18fd90794793c96e450795e8c6 Mon Sep 17 00:00:00 2001 From: Nick Terrell -Date: Wed, 21 Jun 2017 17:27:42 -0700 -Subject: [PATCH 1/4] lib: Add xxhash module +Date: Wed, 21 Jun 2017 17:37:36 -0700 +Subject: [PATCH v2 1/4] lib: Add xxhash module Adds xxhash kernel module with xxh32 and xxh64 hashes. xxhash is an extremely fast non-cryptographic hash algorithm for checksumming. @@ -73,6 +73,9 @@ XXHash source repository: https://github.com/cyan4973/xxhash Signed-off-by: Nick Terrell --- +v1 -> v2: +- Make pointer in lib/xxhash.c:394 non-const + include/linux/xxhash.h | 236 +++++++++++++++++++++++ lib/Kconfig | 3 + lib/Makefile | 1 + @@ -330,7 +333,7 @@ index 0c8b78a..b6009d7 100644 @@ -184,6 +184,9 @@ config CRC8 when they need to do cyclic redundancy check according CRC8 algorithm. Module will be called crc8. - + +config XXHASH + tristate + @@ -347,11 +350,11 @@ index 0166fbc..1338226 100644 obj-$(CONFIG_CRC8) += crc8.o +obj-$(CONFIG_XXHASH) += xxhash.o obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o - + obj-$(CONFIG_842_COMPRESS) += 842/ diff --git a/lib/xxhash.c b/lib/xxhash.c new file mode 100644 -index 0000000..dc94904 +index 0000000..aa61e2a --- /dev/null +++ b/lib/xxhash.c @@ -0,0 +1,500 @@ @@ -748,7 +751,7 @@ index 0000000..dc94904 + } + + if (state->memsize) { /* tmp buffer is full */ -+ const uint64_t *p64 = state->mem64; ++ uint64_t *p64 = state->mem64; + + memcpy(((uint8_t *)p64) + state->memsize, input, + 32 - state->memsize); @@ -855,6 +858,5 @@ index 0000000..dc94904 + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("xxHash"); --- +-- 2.9.3 - diff --git a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch index f94afe362..971093996 100644 --- a/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch +++ b/contrib/linux-kernel/0002-lib-Add-zstd-modules.patch @@ -1,7 +1,7 @@ -From b52ae824ae6c0f7c7786380b34da9daaa54bfc26 Mon Sep 17 00:00:00 2001 +From d2626127c6d6e60e940dd9a3ed58323bdcdc4930 Mon Sep 17 00:00:00 2001 From: Nick Terrell -Date: Wed, 21 Jun 2017 17:31:24 -0700 -Subject: [PATCH 2/4] lib: Add zstd modules +Date: Tue, 16 May 2017 14:55:36 -0700 +Subject: [PATCH v2 2/4] lib: Add zstd modules Add zstd compression and decompression kernel modules. zstd offers a wide varity of compression speed and quality trade-offs. @@ -102,26 +102,34 @@ zstd source repository: https://github.com/facebook/zstd Signed-off-by: Nick Terrell --- +v1 -> v2: +- Use div_u64() for division of u64s +- Reduce stack usage of ZSTD_compressSequences(), ZSTD_buildSeqTable(), + ZSTD_decompressSequencesLong(), FSE_buildDTable(), FSE_decompress_wksp(), + HUF_writeCTable(), HUF_readStats(), HUF_readCTable(), + HUF_compressWeights(), HUF_readDTableX2(), and HUF_readDTableX4() +- No function uses more than 400 B of stack space + include/linux/zstd.h | 1157 +++++++++++++++ lib/Kconfig | 8 + lib/Makefile | 2 + lib/zstd/Makefile | 18 + lib/zstd/bitstream.h | 374 +++++ - lib/zstd/compress.c | 3468 +++++++++++++++++++++++++++++++++++++++++++++ - lib/zstd/decompress.c | 2514 ++++++++++++++++++++++++++++++++ - lib/zstd/entropy_common.c | 244 ++++ + lib/zstd/compress.c | 3479 +++++++++++++++++++++++++++++++++++++++++++++ + lib/zstd/decompress.c | 2526 ++++++++++++++++++++++++++++++++ + lib/zstd/entropy_common.c | 243 ++++ lib/zstd/error_private.h | 53 + - lib/zstd/fse.h | 584 ++++++++ - lib/zstd/fse_compress.c | 857 +++++++++++ - lib/zstd/fse_decompress.c | 313 ++++ - lib/zstd/huf.h | 203 +++ - lib/zstd/huf_compress.c | 731 ++++++++++ - lib/zstd/huf_decompress.c | 920 ++++++++++++ + lib/zstd/fse.h | 575 ++++++++ + lib/zstd/fse_compress.c | 795 +++++++++++ + lib/zstd/fse_decompress.c | 332 +++++ + lib/zstd/huf.h | 212 +++ + lib/zstd/huf_compress.c | 771 ++++++++++ + lib/zstd/huf_decompress.c | 960 +++++++++++++ lib/zstd/mem.h | 151 ++ lib/zstd/zstd_common.c | 75 + lib/zstd/zstd_internal.h | 269 ++++ lib/zstd/zstd_opt.h | 1014 +++++++++++++ - 19 files changed, 12955 insertions(+) + 19 files changed, 13014 insertions(+) create mode 100644 include/linux/zstd.h create mode 100644 lib/zstd/Makefile create mode 100644 lib/zstd/bitstream.h @@ -1741,10 +1749,10 @@ index 0000000..a826b99 +#endif /* BITSTREAM_H_MODULE */ diff --git a/lib/zstd/compress.c b/lib/zstd/compress.c new file mode 100644 -index 0000000..1aff542 +index 0000000..d60ab7d --- /dev/null +++ b/lib/zstd/compress.c -@@ -0,0 +1,3468 @@ +@@ -0,0 +1,3479 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. @@ -1831,7 +1839,7 @@ index 0000000..1aff542 + FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; + FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; + FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; -+ unsigned tmpCounters[HUF_WORKSPACE_SIZE_U32]; ++ unsigned tmpCounters[HUF_COMPRESS_WORKSPACE_SIZE_U32]; +}; + +size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters cParams) @@ -2334,8 +2342,6 @@ index 0000000..1aff542 +{ + const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN; + const seqStore_t *seqStorePtr = &(zc->seqStore); -+ U32 count[MaxSeq + 1]; -+ S16 norm[MaxSeq + 1]; + FSE_CTable *CTable_LitLength = zc->litlengthCTable; + FSE_CTable *CTable_OffsetBits = zc->offcodeCTable; + FSE_CTable *CTable_MatchLength = zc->matchlengthCTable; @@ -2349,7 +2355,21 @@ index 0000000..1aff542 + BYTE *op = ostart; + size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; + BYTE *seqHead; -+ BYTE scratchBuffer[1 << MAX(MLFSELog, LLFSELog)]; ++ ++ U32 *count; ++ S16 *norm; ++ U32 *workspace; ++ size_t workspaceSize = sizeof(zc->tmpCounters); ++ { ++ size_t spaceUsed32 = 0; ++ count = (U32 *)zc->tmpCounters + spaceUsed32; ++ spaceUsed32 += MaxSeq + 1; ++ norm = (S16 *)((U32 *)zc->tmpCounters + spaceUsed32); ++ spaceUsed32 += ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; ++ ++ workspace = (U32 *)zc->tmpCounters + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ } + + /* Compress literals */ + { @@ -2385,7 +2405,7 @@ index 0000000..1aff542 + /* CTable for Literal Lengths */ + { + U32 max = MaxLL; -+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters); ++ size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = llCodeTable[0]; + FSE_buildCTable_rle(CTable_LitLength, (BYTE)max); @@ -2393,7 +2413,7 @@ index 0000000..1aff542 + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + LLtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog - 1)))) { -+ FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, workspace, workspaceSize); + LLtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; @@ -2409,7 +2429,7 @@ index 0000000..1aff542 + return NCountSize; + op += NCountSize; + } -+ FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, workspace, workspaceSize); + LLtype = set_compressed; + } + } @@ -2417,7 +2437,7 @@ index 0000000..1aff542 + /* CTable for Offsets */ + { + U32 max = MaxOff; -+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters); ++ size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = ofCodeTable[0]; + FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max); @@ -2425,7 +2445,7 @@ index 0000000..1aff542 + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + Offtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog - 1)))) { -+ FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, workspace, workspaceSize); + Offtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; @@ -2441,7 +2461,7 @@ index 0000000..1aff542 + return NCountSize; + op += NCountSize; + } -+ FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, workspace, workspaceSize); + Offtype = set_compressed; + } + } @@ -2449,7 +2469,7 @@ index 0000000..1aff542 + /* CTable for MatchLengths */ + { + U32 max = MaxML; -+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters); ++ size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); + if ((mostFrequent == nbSeq) && (nbSeq > 2)) { + *op++ = *mlCodeTable; + FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max); @@ -2457,7 +2477,7 @@ index 0000000..1aff542 + } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { + MLtype = set_repeat; + } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog - 1)))) { -+ FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, workspace, workspaceSize); + MLtype = set_basic; + } else { + size_t nbSeq_1 = nbSeq; @@ -2473,7 +2493,7 @@ index 0000000..1aff542 + return NCountSize; + op += NCountSize; + } -+ FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); ++ FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, workspace, workspaceSize); + MLtype = set_compressed; + } + } @@ -4359,14 +4379,13 @@ index 0000000..1aff542 + const BYTE *const dictEnd = dictPtr + dictSize; + short offcodeNCount[MaxOff + 1]; + unsigned offcodeMaxValue = MaxOff; -+ BYTE scratchBuffer[1 << MAX(MLFSELog, LLFSELog)]; + + dictPtr += 4; /* skip magic number */ + cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : ZSTD_readLE32(dictPtr); + dictPtr += 4; + + { -+ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr); ++ size_t const hufHeaderSize = HUF_readCTable_wksp(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr, cctx->tmpCounters, sizeof(cctx->tmpCounters)); + if (HUF_isError(hufHeaderSize)) + return ERROR(dictionary_corrupted); + dictPtr += hufHeaderSize; @@ -4380,7 +4399,7 @@ index 0000000..1aff542 + if (offcodeLog > OffFSELog) + return ERROR(dictionary_corrupted); + /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ -+ CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), ++ CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += offcodeHeaderSize; + } @@ -4396,7 +4415,7 @@ index 0000000..1aff542 + /* Every match length code must have non-zero probability */ + CHECK_F(ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); + CHECK_E( -+ FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), ++ FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += matchlengthHeaderSize; + } @@ -4411,7 +4430,7 @@ index 0000000..1aff542 + return ERROR(dictionary_corrupted); + /* Every literal length code must have non-zero probability */ + CHECK_F(ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); -+ CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), ++ CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), + dictionary_corrupted); + dictPtr += litlengthHeaderSize; + } @@ -5215,10 +5234,10 @@ index 0000000..1aff542 +MODULE_DESCRIPTION("Zstd Compressor"); diff --git a/lib/zstd/decompress.c b/lib/zstd/decompress.c new file mode 100644 -index 0000000..ec673d7 +index 0000000..62449ae --- /dev/null +++ b/lib/zstd/decompress.c -@@ -0,0 +1,2514 @@ +@@ -0,0 +1,2526 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. @@ -5291,6 +5310,7 @@ index 0000000..ec673d7 + FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; + FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; + HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ ++ U64 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32 / 2]; + U32 rep[ZSTD_REP_NUM]; +} ZSTD_entropyTables_t; + @@ -5704,8 +5724,10 @@ index 0000000..ec673d7 + ? (singleStream ? HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr) + : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr)) + : (singleStream -+ ? HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize) -+ : HUF_decompress4X_hufOnly(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize)))) ++ ? HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, ++ dctx->entropy.workspace, sizeof(dctx->entropy.workspace)) ++ : HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, ++ dctx->entropy.workspace, sizeof(dctx->entropy.workspace))))) + return ERROR(corruption_detected); + + dctx->litPtr = dctx->litBuffer; @@ -5968,7 +5990,7 @@ index 0000000..ec673d7 + or an error code if it fails, testable with ZSTD_isError() +*/ +static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, const FSE_DTable **DTablePtr, symbolEncodingType_e type, U32 max, U32 maxLog, const void *src, -+ size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable) ++ size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable, void *workspace, size_t workspaceSize) +{ + const void *const tmpPtr = defaultTable; /* bypass strict aliasing */ + switch (type) { @@ -5988,15 +6010,23 @@ index 0000000..ec673d7 + default: /* impossible */ + case set_compressed: { + U32 tableLog; -+ S16 norm[MaxSeq + 1]; -+ size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); -+ if (FSE_isError(headerSize)) -+ return ERROR(corruption_detected); -+ if (tableLog > maxLog) -+ return ERROR(corruption_detected); -+ FSE_buildDTable(DTableSpace, norm, max, tableLog); -+ *DTablePtr = DTableSpace; -+ return headerSize; ++ S16 *norm = (S16 *)workspace; ++ size_t const spaceUsed32 = ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(GENERIC); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ { ++ size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); ++ if (FSE_isError(headerSize)) ++ return ERROR(corruption_detected); ++ if (tableLog > maxLog) ++ return ERROR(corruption_detected); ++ FSE_buildDTable_wksp(DTableSpace, norm, max, tableLog, workspace, workspaceSize); ++ *DTablePtr = DTableSpace; ++ return headerSize; ++ } + } + } +} @@ -6044,21 +6074,21 @@ index 0000000..ec673d7 + /* Build DTables */ + { + size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, LLtype, MaxLL, LLFSELog, ip, iend - ip, -+ LL_defaultDTable, dctx->fseEntropy); ++ LL_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(llhSize)) + return ERROR(corruption_detected); + ip += llhSize; + } + { + size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, OFtype, MaxOff, OffFSELog, ip, iend - ip, -+ OF_defaultDTable, dctx->fseEntropy); ++ OF_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(ofhSize)) + return ERROR(corruption_detected); + ip += ofhSize; + } + { + size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, MLtype, MaxML, MLFSELog, ip, iend - ip, -+ ML_defaultDTable, dctx->fseEntropy); ++ ML_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); + if (ZSTD_isError(mlhSize)) + return ERROR(corruption_detected); + ip += mlhSize; @@ -6581,10 +6611,11 @@ index 0000000..ec673d7 +#define STORED_SEQS 4 +#define STOSEQ_MASK (STORED_SEQS - 1) +#define ADVANCED_SEQS 4 -+ seq_t sequences[STORED_SEQS]; ++ seq_t *sequences = (seq_t *)dctx->entropy.workspace; + int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); + seqState_t seqState; + int seqNb; ++ ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.workspace) >= sizeof(seq_t) * STORED_SEQS); + dctx->fseEntropy = 1; + { + U32 i; @@ -7087,7 +7118,7 @@ index 0000000..ec673d7 + dictPtr += 8; /* skip header = magic + dictID */ + + { -+ size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd - dictPtr); ++ size_t const hSize = HUF_readDTableX4_wksp(entropy->hufTable, dictPtr, dictEnd - dictPtr, entropy->workspace, sizeof(entropy->workspace)); + if (HUF_isError(hSize)) + return ERROR(dictionary_corrupted); + dictPtr += hSize; @@ -7101,7 +7132,7 @@ index 0000000..ec673d7 + return ERROR(dictionary_corrupted); + if (offcodeLog > OffFSELog) + return ERROR(dictionary_corrupted); -+ CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted); ++ CHECK_E(FSE_buildDTable_wksp(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += offcodeHeaderSize; + } + @@ -7113,7 +7144,7 @@ index 0000000..ec673d7 + return ERROR(dictionary_corrupted); + if (matchlengthLog > MLFSELog) + return ERROR(dictionary_corrupted); -+ CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted); ++ CHECK_E(FSE_buildDTable_wksp(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += matchlengthHeaderSize; + } + @@ -7125,7 +7156,7 @@ index 0000000..ec673d7 + return ERROR(dictionary_corrupted); + if (litlengthLog > LLFSELog) + return ERROR(dictionary_corrupted); -+ CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted); ++ CHECK_E(FSE_buildDTable_wksp(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); + dictPtr += litlengthHeaderSize; + } + @@ -7735,10 +7766,10 @@ index 0000000..ec673d7 +MODULE_DESCRIPTION("Zstd Decompressor"); diff --git a/lib/zstd/entropy_common.c b/lib/zstd/entropy_common.c new file mode 100644 -index 0000000..b354fc2 +index 0000000..2b0a643 --- /dev/null +++ b/lib/zstd/entropy_common.c -@@ -0,0 +1,244 @@ +@@ -0,0 +1,243 @@ +/* + * Common functions of New Generation Entropy library + * Copyright (C) 2016, Yann Collet. @@ -7905,7 +7936,7 @@ index 0000000..b354fc2 + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableX?() . +*/ -+size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize) ++size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ + U32 weightTotal; + const BYTE *ip = (const BYTE *)src; @@ -7933,10 +7964,9 @@ index 0000000..b354fc2 + } + } + } else { /* header compressed with FSE (normal case) */ -+ FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ + if (iSize + 1 > srcSize) + return ERROR(srcSize_wrong); -+ oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ ++ oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, 6, workspace, workspaceSize); /* max (hwSize-1) values decoded, as last one is implied */ + if (FSE_isError(oSize)) + return oSize; + } @@ -8044,10 +8074,10 @@ index 0000000..1a60b31 +#endif /* ERROR_H_MODULE */ diff --git a/lib/zstd/fse.h b/lib/zstd/fse.h new file mode 100644 -index 0000000..bc2962a +index 0000000..7460ab0 --- /dev/null +++ b/lib/zstd/fse.h -@@ -0,0 +1,584 @@ +@@ -0,0 +1,575 @@ +/* + * FSE : Finite State Entropy codec + * Public Prototypes declaration @@ -8237,7 +8267,7 @@ index 0000000..bc2962a +/*! FSE_buildDTable(): + Builds 'dt', which must be already allocated, using FSE_createDTable(). + return : 0, or an errorCode, which can be tested using FSE_isError() */ -+FSE_PUBLIC_API size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); ++FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize); + +/*! FSE_decompress_usingDTable(): + Decompress compressed source `cSrc` of size `cSrcSize` using `dt` @@ -8313,15 +8343,6 @@ index 0000000..bc2962a +unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); +/**< same as FSE_optimalTableLog(), which used `minus==2` */ + -+/* FSE_compress_wksp() : -+ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). -+ * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable. -+ */ -+#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) \ -+ (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024)) -+size_t FSE_compress_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, -+ size_t wkspSize); -+ +size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits); +/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ + @@ -8340,7 +8361,7 @@ index 0000000..bc2962a +size_t FSE_buildDTable_rle(FSE_DTable *dt, unsigned char symbolValue); +/**< build a fake FSE_DTable, designed to always generate the same symbolValue */ + -+size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, unsigned maxLog); ++size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize); +/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */ + +/* ***************************************** @@ -8634,10 +8655,10 @@ index 0000000..bc2962a +#endif /* FSE_H */ diff --git a/lib/zstd/fse_compress.c b/lib/zstd/fse_compress.c new file mode 100644 -index 0000000..e016bb1 +index 0000000..ef3d174 --- /dev/null +++ b/lib/zstd/fse_compress.c -@@ -0,0 +1,857 @@ +@@ -0,0 +1,795 @@ +/* + * FSE : Finite State Entropy encoder + * Copyright (C) 2013-2015, Yann Collet. @@ -8688,6 +8709,8 @@ index 0000000..e016bb1 +#include "bitstream.h" +#include "fse.h" +#include ++#include ++#include +#include /* memcpy, memset */ + +/* ************************************************************** @@ -8727,7 +8750,7 @@ index 0000000..e016bb1 + * wkspSize should be sized to handle worst case situation, which is `1<> 1 : 1); + FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT); + U32 const step = FSE_TABLESTEP(tableSize); -+ U32 cumul[FSE_MAX_SYMBOL_VALUE + 2]; -+ -+ FSE_FUNCTION_TYPE *const tableSymbol = (FSE_FUNCTION_TYPE *)workSpace; + U32 highThreshold = tableSize - 1; + -+ /* CTable header */ -+ if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) ++ U32 *cumul; ++ FSE_FUNCTION_TYPE *tableSymbol; ++ size_t spaceUsed32 = 0; ++ ++ cumul = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += FSE_MAX_SYMBOL_VALUE + 2; ++ tableSymbol = (FSE_FUNCTION_TYPE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(sizeof(FSE_FUNCTION_TYPE) * ((size_t)1 << tableLog), sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ ++ /* CTable header */ + tableU16[-2] = (U16)tableLog; + tableU16[-1] = (U16)maxSymbolValue; + @@ -9215,7 +9247,7 @@ index 0000000..e016bb1 + { + U64 const vStepLog = 62 - tableLog; + U64 const mid = (1ULL << (vStepLog - 1)) - 1; -+ U64 const rStep = ((((U64)1 << vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */ ++ U64 const rStep = div_u64((((U64)1 << vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */ + U64 tmpTotal = mid; + for (s = 0; s <= maxSymbolValue; s++) { + if (norm[s] == NOT_YET_ASSIGNED) { @@ -9249,7 +9281,7 @@ index 0000000..e016bb1 + { + U32 const rtbTable[] = {0, 473195, 504333, 520860, 550000, 700000, 750000, 830000}; + U64 const scale = 62 - tableLog; -+ U64 const step = ((U64)1 << 62) / total; /* <== here, one division ! */ ++ U64 const step = div_u64((U64)1 << 62, (U32)total); /* <== here, one division ! */ + U64 const vStep = 1ULL << (scale - 20); + int stillToDistribute = 1 << tableLog; + unsigned s; @@ -9422,85 +9454,12 @@ index 0000000..e016bb1 +} + +size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } -+ -+#define CHECK_V_F(e, f) \ -+ size_t const e = f; \ -+ if (ERR_isError(e)) \ -+ return f -+#define CHECK_F(f) \ -+ { \ -+ CHECK_V_F(_var_err__, f); \ -+ } -+ -+/* FSE_compress_wksp() : -+ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). -+ * `wkspSize` size must be `(1< not compressible */ -+ if (maxCount < (srcSize >> 7)) -+ return 0; /* Heuristic : not compressible enough */ -+ } -+ -+ tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); -+ CHECK_F(FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue)); -+ -+ /* Write table description header */ -+ { -+ CHECK_V_F(nc_err, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog)); -+ op += nc_err; -+ } -+ -+ /* Compress */ -+ CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize)); -+ { -+ CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable)); -+ if (cSize == 0) -+ return 0; /* not enough space for compressed data */ -+ op += cSize; -+ } -+ -+ /* check compressibility */ -+ if ((size_t)(op - ostart) >= srcSize - 1) -+ return 0; -+ -+ return op - ostart; -+} diff --git a/lib/zstd/fse_decompress.c b/lib/zstd/fse_decompress.c new file mode 100644 -index 0000000..96cf89f +index 0000000..a84300e --- /dev/null +++ b/lib/zstd/fse_decompress.c -@@ -0,0 +1,313 @@ +@@ -0,0 +1,332 @@ +/* + * FSE : Finite State Entropy decoder + * Copyright (C) 2013-2015, Yann Collet. @@ -9551,6 +9510,7 @@ index 0000000..96cf89f +#include "bitstream.h" +#include "fse.h" +#include ++#include +#include /* memcpy, memset */ + +/* ************************************************************** @@ -9594,17 +9554,19 @@ index 0000000..96cf89f + +/* Function templates */ + -+size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) ++size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize) +{ + void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ + FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr); -+ U16 symbolNext[FSE_MAX_SYMBOL_VALUE + 1]; ++ U16 *symbolNext = (U16 *)workspace; + + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; + U32 highThreshold = tableSize - 1; + + /* Sanity Checks */ ++ if (workspaceSize < sizeof(U16) * (FSE_MAX_SYMBOL_VALUE + 1)) ++ return ERROR(tableLog_tooLarge); + if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) + return ERROR(maxSymbolValue_tooLarge); + if (tableLog > FSE_MAX_TABLELOG) @@ -9791,16 +9753,32 @@ index 0000000..96cf89f + return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); +} + -+size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, unsigned maxLog) ++size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize) +{ + const BYTE *const istart = (const BYTE *)cSrc; + const BYTE *ip = istart; -+ short counting[FSE_MAX_SYMBOL_VALUE + 1]; + unsigned tableLog; + unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; ++ size_t NCountLength; ++ ++ FSE_DTable *dt; ++ short *counting; ++ size_t spaceUsed32 = 0; ++ ++ FSE_STATIC_ASSERT(sizeof(FSE_DTable) == sizeof(U32)); ++ ++ dt = (FSE_DTable *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += FSE_DTABLE_SIZE_U32(maxLog); ++ counting = (short *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE + 1), sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); + + /* normal FSE decoding mode */ -+ size_t const NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); ++ NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) + return NCountLength; + // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining @@ -9810,16 +9788,16 @@ index 0000000..96cf89f + ip += NCountLength; + cSrcSize -= NCountLength; + -+ CHECK_F(FSE_buildDTable(workSpace, counting, maxSymbolValue, tableLog)); ++ CHECK_F(FSE_buildDTable_wksp(dt, counting, maxSymbolValue, tableLog, workspace, workspaceSize)); + -+ return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ ++ return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, dt); /* always return, even if it is an error code */ +} diff --git a/lib/zstd/huf.h b/lib/zstd/huf.h new file mode 100644 -index 0000000..56abe2f +index 0000000..2143da2 --- /dev/null +++ b/lib/zstd/huf.h -@@ -0,0 +1,203 @@ +@@ -0,0 +1,212 @@ +/* + * Huffman coder, part of New Generation Entropy library + * header file @@ -9877,7 +9855,7 @@ index 0000000..56abe2f +/** HUF_compress4X_wksp() : +* Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */ +size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, -+ size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ ++ size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + +/* *** Dependencies *** */ +#include "mem.h" /* U32 */ @@ -9913,17 +9891,23 @@ index 0000000..56abe2f +#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = {((U32)(maxTableLog)*0x01000001)} + +/* The workspace must have alignment at least 4 and be at least this large */ -+#define HUF_WORKSPACE_SIZE (6 << 10) -+#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) ++#define HUF_COMPRESS_WORKSPACE_SIZE (6 << 10) ++#define HUF_COMPRESS_WORKSPACE_SIZE_U32 (HUF_COMPRESS_WORKSPACE_SIZE / sizeof(U32)) ++ ++/* The workspace must have alignment at least 4 and be at least this large */ ++#define HUF_DECOMPRESS_WORKSPACE_SIZE (3 << 10) ++#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +/* **************************************** +* Advanced decompression functions +******************************************/ -+size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ -+size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, -+ size_t cSrcSize); /**< considers RLE and uncompressed as errors */ -+size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */ -+size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */ ++size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); /**< decodes RLE and uncompressed */ ++size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, ++ size_t workspaceSize); /**< considers RLE and uncompressed as errors */ ++size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, ++ size_t workspaceSize); /**< single-symbol decoder */ ++size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, ++ size_t workspaceSize); /**< double-symbols decoder */ + +/* **************************************** +* HUF detailed API @@ -9933,7 +9917,7 @@ index 0000000..56abe2f +1. count symbol occurrence from source[] into table count[] using FSE_count() +2. (optional) refine tableLog using HUF_optimalTableLog() +3. build Huffman table from count using HUF_buildCTable() -+4. save Huffman table to memory buffer using HUF_writeCTable() ++4. save Huffman table to memory buffer using HUF_writeCTable_wksp() +5. encode the data stream using HUF_compress4X_usingCTable() + +The following API allows targeting specific sub-functions for advanced tasks. @@ -9943,7 +9927,7 @@ index 0000000..56abe2f +/* FSE_count() : find it within "fse.h" */ +unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); +typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ -+size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog); ++size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog, void *workspace, size_t workspaceSize); +size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); + +typedef enum { @@ -9959,7 +9943,7 @@ index 0000000..56abe2f +* If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, -+ int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ ++ int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + +/** HUF_buildCTable_wksp() : + * Same as HUF_buildCTable(), but using externally allocated scratch buffer. @@ -9972,11 +9956,12 @@ index 0000000..56abe2f + `huffWeight` is destination buffer. + @return : size read from `src` , or an error Code . + Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ -+size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize); ++size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, ++ void *workspace, size_t workspaceSize); + +/** HUF_readCTable() : +* Loading a CTable saved with HUF_writeCTable() */ -+size_t HUF_readCTable(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize); ++size_t HUF_readCTable_wksp(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); + +/* +HUF_decompress() does the following: @@ -9992,8 +9977,8 @@ index 0000000..56abe2f +* Assumption : 0 < cSrcSize < dstSize <= 128 KB */ +U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize); + -+size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize); -+size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize); ++size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); ++size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); + +size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); +size_t HUF_decompress4X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); @@ -10002,7 +9987,7 @@ index 0000000..56abe2f +/* single stream variants */ + +size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, -+ size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ ++ size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ +size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); +/** HUF_compress1X_repeat() : +* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. @@ -10011,11 +9996,13 @@ index 0000000..56abe2f +* If preferRepeat then the old table will always be used if valid. */ +size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, + size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, -+ int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ ++ int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ + -+size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); -+size_t HUF_decompress1X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */ -+size_t HUF_decompress1X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */ ++size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); ++size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, ++ size_t workspaceSize); /**< single-symbol decoder */ ++size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, ++ size_t workspaceSize); /**< double-symbols decoder */ + +size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, + const HUF_DTable *DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ @@ -10025,10 +10012,10 @@ index 0000000..56abe2f +#endif /* HUF_H_298734234 */ diff --git a/lib/zstd/huf_compress.c b/lib/zstd/huf_compress.c new file mode 100644 -index 0000000..e82a136 +index 0000000..0361f38 --- /dev/null +++ b/lib/zstd/huf_compress.c -@@ -0,0 +1,731 @@ +@@ -0,0 +1,771 @@ +/* + * Huffman encoder, part of New Generation Entropy library + * Copyright (C) 2013-2016, Yann Collet. @@ -10074,6 +10061,7 @@ index 0000000..e82a136 +#include "bitstream.h" +#include "fse.h" /* header compression */ +#include "huf.h" ++#include +#include /* memcpy, memset */ + +/* ************************************************************** @@ -10109,7 +10097,7 @@ index 0000000..e82a136 + * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. + */ +#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 -+size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, size_t wtSize) ++size_t HUF_compressWeights_wksp(void *dst, size_t dstSize, const void *weightTable, size_t wtSize, void *workspace, size_t workspaceSize) +{ + BYTE *const ostart = (BYTE *)dst; + BYTE *op = ostart; @@ -10118,11 +10106,24 @@ index 0000000..e82a136 + U32 maxSymbolValue = HUF_TABLELOG_MAX; + U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; + -+ FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; -+ BYTE scratchBuffer[1 << MAX_FSE_TABLELOG_FOR_HUFF_HEADER]; ++ FSE_CTable *CTable; ++ U32 *count; ++ S16 *norm; ++ size_t spaceUsed32 = 0; + -+ U32 count[HUF_TABLELOG_MAX + 1]; -+ S16 norm[HUF_TABLELOG_MAX + 1]; ++ HUF_STATIC_ASSERT(sizeof(FSE_CTable) == sizeof(U32)); ++ ++ CTable = (FSE_CTable *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX); ++ count = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += HUF_TABLELOG_MAX + 1; ++ norm = (S16 *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(sizeof(S16) * (HUF_TABLELOG_MAX + 1), sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); + + /* init conditions */ + if (wtSize <= 1) @@ -10147,7 +10148,7 @@ index 0000000..e82a136 + } + + /* Compress */ -+ CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer))); ++ CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, workspace, workspaceSize)); + { + CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable)); + if (cSize == 0) @@ -10163,16 +10164,28 @@ index 0000000..e82a136 + BYTE nbBits; +}; /* typedef'd to HUF_CElt within "huf.h" */ + -+/*! HUF_writeCTable() : ++/*! HUF_writeCTable_wksp() : + `CTable` : Huffman tree to save, using huf representation. + @return : size of saved CTable */ -+size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog) ++size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog, void *workspace, size_t workspaceSize) +{ -+ BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ -+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; + BYTE *op = (BYTE *)dst; + U32 n; + ++ BYTE *bitsToWeight; ++ BYTE *huffWeight; ++ size_t spaceUsed32 = 0; ++ ++ bitsToWeight = (BYTE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(HUF_TABLELOG_MAX + 1, sizeof(U32)) >> 2; ++ huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX, sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ + /* check conditions */ + if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) + return ERROR(maxSymbolValue_tooLarge); @@ -10186,7 +10199,7 @@ index 0000000..e82a136 + + /* attempt weights compression by FSE */ + { -+ CHECK_V_F(hSize, HUF_compressWeights(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue)); ++ CHECK_V_F(hSize, HUF_compressWeights_wksp(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue, workspace, workspaceSize)); + if ((hSize > 1) & (hSize < maxSymbolValue / 2)) { /* FSE compressed */ + op[0] = (BYTE)hSize; + return hSize + 1; @@ -10205,15 +10218,29 @@ index 0000000..e82a136 + return ((maxSymbolValue + 1) / 2) + 1; +} + -+size_t HUF_readCTable(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize) ++size_t HUF_readCTable_wksp(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ -+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */ -+ U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ ++ U32 *rankVal; ++ BYTE *huffWeight; + U32 tableLog = 0; + U32 nbSymbols = 0; ++ size_t readSize; ++ size_t spaceUsed32 = 0; ++ ++ rankVal = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; ++ huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); + + /* get symbol weights */ -+ CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize)); ++ readSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); ++ if (ERR_isError(readSize)) ++ return readSize; + + /* check result */ + if (tableLog > HUF_TABLELOG_MAX) @@ -10711,7 +10738,7 @@ index 0000000..e82a136 + + /* Write table description header */ + { -+ CHECK_V_F(hSize, HUF_writeCTable(op, dstSize, CTable, maxSymbolValue, huffLog)); ++ CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, CTable, maxSymbolValue, huffLog, workSpace, wkspSize)); + /* Check if using the previous table will be beneficial */ + if (repeat && *repeat != HUF_repeat_none) { + size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue); @@ -10762,10 +10789,10 @@ index 0000000..e82a136 +} diff --git a/lib/zstd/huf_decompress.c b/lib/zstd/huf_decompress.c new file mode 100644 -index 0000000..950c194 +index 0000000..6526482 --- /dev/null +++ b/lib/zstd/huf_decompress.c -@@ -0,0 +1,920 @@ +@@ -0,0 +1,960 @@ +/* + * Huffman decoder, part of New Generation Entropy library + * Copyright (C) 2013-2016, Yann Collet. @@ -10817,6 +10844,7 @@ index 0000000..950c194 +#include "fse.h" /* header compression */ +#include "huf.h" +#include ++#include +#include /* memcpy, memset */ + +/* ************************************************************** @@ -10854,20 +10882,32 @@ index 0000000..950c194 + BYTE nbBits; +} HUF_DEltX2; /* single-symbol decoding */ + -+size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize) ++size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ -+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; -+ U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ + U32 tableLog = 0; + U32 nbSymbols = 0; + size_t iSize; + void *const dtPtr = DTable + 1; + HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr; + ++ U32 *rankVal; ++ BYTE *huffWeight; ++ size_t spaceUsed32 = 0; ++ ++ rankVal = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; ++ huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ + HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); + /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ + -+ iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); ++ iSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (HUF_isError(iSize)) + return iSize; + @@ -10984,11 +11024,11 @@ index 0000000..950c194 + return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + -+size_t HUF_decompress1X2_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + -+ size_t const hSize = HUF_readDTableX2(DCtx, cSrc, cSrcSize); ++ size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) @@ -11115,11 +11155,11 @@ index 0000000..950c194 + return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + -+size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + -+ size_t const hSize = HUF_readDTableX2(dctx, cSrc, cSrcSize); ++ size_t const hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) @@ -11190,6 +11230,7 @@ index 0000000..950c194 +} + +typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; ++typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; + +static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart, + rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline) @@ -11233,27 +11274,50 @@ index 0000000..950c194 + } +} + -+size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize) ++size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) +{ -+ BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; -+ sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; -+ U32 rankStats[HUF_TABLELOG_MAX + 1] = {0}; -+ U32 rankStart0[HUF_TABLELOG_MAX + 2] = {0}; -+ U32 *const rankStart = rankStart0 + 1; -+ rankVal_t rankVal; + U32 tableLog, maxW, sizeOfSort, nbSymbols; + DTableDesc dtd = HUF_getDTableDesc(DTable); + U32 const maxTableLog = dtd.maxTableLog; + size_t iSize; + void *dtPtr = DTable + 1; /* force compiler to avoid strict-aliasing */ + HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr; ++ U32 *rankStart; ++ ++ rankValCol_t *rankVal; ++ U32 *rankStats; ++ U32 *rankStart0; ++ sortedSymbol_t *sortedSymbol; ++ BYTE *weightList; ++ size_t spaceUsed32 = 0; ++ ++ HUF_STATIC_ASSERT((sizeof(rankValCol_t) & 3) == 0); ++ ++ rankVal = (rankValCol_t *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; ++ rankStats = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += HUF_TABLELOG_MAX + 1; ++ rankStart0 = (U32 *)workspace + spaceUsed32; ++ spaceUsed32 += HUF_TABLELOG_MAX + 2; ++ sortedSymbol = (sortedSymbol_t *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; ++ weightList = (BYTE *)((U32 *)workspace + spaceUsed32); ++ spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; ++ ++ if ((spaceUsed32 << 2) > workspaceSize) ++ return ERROR(tableLog_tooLarge); ++ workspace = (U32 *)workspace + spaceUsed32; ++ workspaceSize -= (spaceUsed32 << 2); ++ ++ rankStart = rankStart0 + 1; ++ memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); + + HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ + if (maxTableLog > HUF_TABLELOG_MAX) + return ERROR(tableLog_tooLarge); + /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ + -+ iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); ++ iSize = HUF_readStats_wksp(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (HUF_isError(iSize)) + return iSize; + @@ -11420,11 +11484,11 @@ index 0000000..950c194 + return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + -+size_t HUF_decompress1X4_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + -+ size_t const hSize = HUF_readDTableX4(DCtx, cSrc, cSrcSize); ++ size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) @@ -11553,11 +11617,11 @@ index 0000000..950c194 + return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); +} + -+size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + const BYTE *ip = (const BYTE *)cSrc; + -+ size_t hSize = HUF_readDTableX4(dctx, cSrc, cSrcSize); ++ size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); + if (HUF_isError(hSize)) + return hSize; + if (hSize >= cSrcSize) @@ -11629,7 +11693,7 @@ index 0000000..950c194 + +typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); + -+size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) @@ -11647,11 +11711,12 @@ index 0000000..950c194 + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); -+ return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); ++ return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) ++ : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} + -+size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) @@ -11661,11 +11726,12 @@ index 0000000..950c194 + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); -+ return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); ++ return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) ++ : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} + -+size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) ++size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) +{ + /* validation checks */ + if (dstSize == 0) @@ -11683,7 +11749,8 @@ index 0000000..950c194 + + { + U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); -+ return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); ++ return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) ++ : HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); + } +} diff --git a/lib/zstd/mem.h b/lib/zstd/mem.h @@ -11845,7 +11912,7 @@ index 0000000..3a0f34c +#endif /* MEM_H_MODULE */ diff --git a/lib/zstd/zstd_common.c b/lib/zstd/zstd_common.c new file mode 100644 -index 0000000..6ebf68d +index 0000000..a282624 --- /dev/null +++ b/lib/zstd/zstd_common.c @@ -0,0 +1,75 @@ @@ -11902,7 +11969,7 @@ index 0000000..6ebf68d +void *ZSTD_stackAllocAll(void *opaque, size_t *size) +{ + ZSTD_stack *stack = (ZSTD_stack *)opaque; -+ *size = stack->end - ZSTD_PTR_ALIGN(stack->ptr); ++ *size = (BYTE const *)stack->end - (BYTE *)ZSTD_PTR_ALIGN(stack->ptr); + return stack_push(stack, *size); +} + diff --git a/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch b/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch index 53d03d3ca..abc8326cc 100644 --- a/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch +++ b/contrib/linux-kernel/0003-btrfs-Add-zstd-support.patch @@ -1,7 +1,7 @@ From 599f8f2aaace3df939cb145368574a52268d82d0 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 21 Jun 2017 17:31:39 -0700 -Subject: [PATCH 3/4] btrfs: Add zstd support +Subject: [PATCH v2 3/4] btrfs: Add zstd support Add zstd compression and decompression support to BtrFS. zstd at its fastest level compresses almost as well as zlib, while offering much diff --git a/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch b/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch index e9c4b98c5..b638194f6 100644 --- a/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch +++ b/contrib/linux-kernel/0004-squashfs-Add-zstd-support.patch @@ -1,7 +1,7 @@ From 5ff6a64abaea7b7f11d37cb0fdf08642316a3a90 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 12 Jun 2017 12:18:23 -0700 -Subject: [PATCH 4/4] squashfs: Add zstd support +Subject: [PATCH v2 4/4] squashfs: Add zstd support Add zstd compression and decompression support to SquashFS. zstd is a great fit for SquashFS because it can compress at ratios approaching xz, diff --git a/contrib/linux-kernel/lib/xxhash.c b/contrib/linux-kernel/lib/xxhash.c index dc94904c6..aa61e2a38 100644 --- a/contrib/linux-kernel/lib/xxhash.c +++ b/contrib/linux-kernel/lib/xxhash.c @@ -391,7 +391,7 @@ int xxh64_update(struct xxh64_state *state, const void *input, const size_t len) } if (state->memsize) { /* tmp buffer is full */ - const uint64_t *p64 = state->mem64; + uint64_t *p64 = state->mem64; memcpy(((uint8_t *)p64) + state->memsize, input, 32 - state->memsize); diff --git a/contrib/linux-kernel/lib/zstd/compress.c b/contrib/linux-kernel/lib/zstd/compress.c index 1aff542b0..d60ab7d4f 100644 --- a/contrib/linux-kernel/lib/zstd/compress.c +++ b/contrib/linux-kernel/lib/zstd/compress.c @@ -84,7 +84,7 @@ struct ZSTD_CCtx_s { FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)]; FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)]; FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)]; - unsigned tmpCounters[HUF_WORKSPACE_SIZE_U32]; + unsigned tmpCounters[HUF_COMPRESS_WORKSPACE_SIZE_U32]; }; size_t ZSTD_CCtxWorkspaceBound(ZSTD_compressionParameters cParams) @@ -587,8 +587,6 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa { const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN; const seqStore_t *seqStorePtr = &(zc->seqStore); - U32 count[MaxSeq + 1]; - S16 norm[MaxSeq + 1]; FSE_CTable *CTable_LitLength = zc->litlengthCTable; FSE_CTable *CTable_OffsetBits = zc->offcodeCTable; FSE_CTable *CTable_MatchLength = zc->matchlengthCTable; @@ -602,7 +600,21 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa BYTE *op = ostart; size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart; BYTE *seqHead; - BYTE scratchBuffer[1 << MAX(MLFSELog, LLFSELog)]; + + U32 *count; + S16 *norm; + U32 *workspace; + size_t workspaceSize = sizeof(zc->tmpCounters); + { + size_t spaceUsed32 = 0; + count = (U32 *)zc->tmpCounters + spaceUsed32; + spaceUsed32 += MaxSeq + 1; + norm = (S16 *)((U32 *)zc->tmpCounters + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; + + workspace = (U32 *)zc->tmpCounters + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + } /* Compress literals */ { @@ -638,7 +650,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa /* CTable for Literal Lengths */ { U32 max = MaxLL; - size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = llCodeTable[0]; FSE_buildCTable_rle(CTable_LitLength, (BYTE)max); @@ -646,7 +658,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { LLtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog - 1)))) { - FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, workspace, workspaceSize); LLtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -662,7 +674,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa return NCountSize; op += NCountSize; } - FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, workspace, workspaceSize); LLtype = set_compressed; } } @@ -670,7 +682,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa /* CTable for Offsets */ { U32 max = MaxOff; - size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = ofCodeTable[0]; FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max); @@ -678,7 +690,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { Offtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog - 1)))) { - FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, workspace, workspaceSize); Offtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -694,7 +706,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa return NCountSize; op += NCountSize; } - FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, workspace, workspaceSize); Offtype = set_compressed; } } @@ -702,7 +714,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa /* CTable for MatchLengths */ { U32 max = MaxML; - size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters); + size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); if ((mostFrequent == nbSeq) && (nbSeq > 2)) { *op++ = *mlCodeTable; FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max); @@ -710,7 +722,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) { MLtype = set_repeat; } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog - 1)))) { - FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, workspace, workspaceSize); MLtype = set_basic; } else { size_t nbSeq_1 = nbSeq; @@ -726,7 +738,7 @@ ZSTD_STATIC size_t ZSTD_compressSequences(ZSTD_CCtx *zc, void *dst, size_t dstCa return NCountSize; op += NCountSize; } - FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer)); + FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, workspace, workspaceSize); MLtype = set_compressed; } } @@ -2612,14 +2624,13 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t const BYTE *const dictEnd = dictPtr + dictSize; short offcodeNCount[MaxOff + 1]; unsigned offcodeMaxValue = MaxOff; - BYTE scratchBuffer[1 << MAX(MLFSELog, LLFSELog)]; dictPtr += 4; /* skip magic number */ cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : ZSTD_readLE32(dictPtr); dictPtr += 4; { - size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr); + size_t const hufHeaderSize = HUF_readCTable_wksp(cctx->hufTable, 255, dictPtr, dictEnd - dictPtr, cctx->tmpCounters, sizeof(cctx->tmpCounters)); if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted); dictPtr += hufHeaderSize; @@ -2633,7 +2644,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */ - CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), + CHECK_E(FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), dictionary_corrupted); dictPtr += offcodeHeaderSize; } @@ -2649,7 +2660,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t /* Every match length code must have non-zero probability */ CHECK_F(ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML)); CHECK_E( - FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), + FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), dictionary_corrupted); dictPtr += matchlengthHeaderSize; } @@ -2664,7 +2675,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx *cctx, const void *dict, size_t return ERROR(dictionary_corrupted); /* Every literal length code must have non-zero probability */ CHECK_F(ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL)); - CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), + CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, cctx->tmpCounters, sizeof(cctx->tmpCounters)), dictionary_corrupted); dictPtr += litlengthHeaderSize; } diff --git a/contrib/linux-kernel/lib/zstd/decompress.c b/contrib/linux-kernel/lib/zstd/decompress.c index ec673d7e6..62449ae05 100644 --- a/contrib/linux-kernel/lib/zstd/decompress.c +++ b/contrib/linux-kernel/lib/zstd/decompress.c @@ -70,6 +70,7 @@ typedef struct { FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ + U64 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32 / 2]; U32 rep[ZSTD_REP_NUM]; } ZSTD_entropyTables_t; @@ -483,8 +484,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize ? (singleStream ? HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr) : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr)) : (singleStream - ? HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize) - : HUF_decompress4X_hufOnly(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize)))) + ? HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace)) + : HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace))))) return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; @@ -747,7 +750,7 @@ static const FSE_decode_t4 OF_defaultDTable[(1 << OF_DEFAULTNORMLOG) + 1] = { or an error code if it fails, testable with ZSTD_isError() */ static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, const FSE_DTable **DTablePtr, symbolEncodingType_e type, U32 max, U32 maxLog, const void *src, - size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable) + size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable, void *workspace, size_t workspaceSize) { const void *const tmpPtr = defaultTable; /* bypass strict aliasing */ switch (type) { @@ -767,15 +770,23 @@ static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, const FSE_DTable **DTa default: /* impossible */ case set_compressed: { U32 tableLog; - S16 norm[MaxSeq + 1]; - size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); - if (FSE_isError(headerSize)) - return ERROR(corruption_detected); - if (tableLog > maxLog) - return ERROR(corruption_detected); - FSE_buildDTable(DTableSpace, norm, max, tableLog); - *DTablePtr = DTableSpace; - return headerSize; + S16 *norm = (S16 *)workspace; + size_t const spaceUsed32 = ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(GENERIC); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + { + size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); + if (FSE_isError(headerSize)) + return ERROR(corruption_detected); + if (tableLog > maxLog) + return ERROR(corruption_detected); + FSE_buildDTable_wksp(DTableSpace, norm, max, tableLog, workspace, workspaceSize); + *DTablePtr = DTableSpace; + return headerSize; + } } } } @@ -823,21 +834,21 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, si /* Build DTables */ { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, LLtype, MaxLL, LLFSELog, ip, iend - ip, - LL_defaultDTable, dctx->fseEntropy); + LL_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); if (ZSTD_isError(llhSize)) return ERROR(corruption_detected); ip += llhSize; } { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, OFtype, MaxOff, OffFSELog, ip, iend - ip, - OF_defaultDTable, dctx->fseEntropy); + OF_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected); ip += ofhSize; } { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, MLtype, MaxML, MLFSELog, ip, iend - ip, - ML_defaultDTable, dctx->fseEntropy); + ML_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace)); if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected); ip += mlhSize; @@ -1360,10 +1371,11 @@ static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx *dctx, void *dst, size_t ma #define STORED_SEQS 4 #define STOSEQ_MASK (STORED_SEQS - 1) #define ADVANCED_SEQS 4 - seq_t sequences[STORED_SEQS]; + seq_t *sequences = (seq_t *)dctx->entropy.workspace; int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS); seqState_t seqState; int seqNb; + ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.workspace) >= sizeof(seq_t) * STORED_SEQS); dctx->fseEntropy = 1; { U32 i; @@ -1866,7 +1878,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const dictPtr += 8; /* skip header = magic + dictID */ { - size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd - dictPtr); + size_t const hSize = HUF_readDTableX4_wksp(entropy->hufTable, dictPtr, dictEnd - dictPtr, entropy->workspace, sizeof(entropy->workspace)); if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); dictPtr += hSize; @@ -1880,7 +1892,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const return ERROR(dictionary_corrupted); if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); - CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); dictPtr += offcodeHeaderSize; } @@ -1892,7 +1904,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const return ERROR(dictionary_corrupted); if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); - CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); dictPtr += matchlengthHeaderSize; } @@ -1904,7 +1916,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const return ERROR(dictionary_corrupted); if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); - CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted); + CHECK_E(FSE_buildDTable_wksp(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted); dictPtr += litlengthHeaderSize; } diff --git a/contrib/linux-kernel/lib/zstd/entropy_common.c b/contrib/linux-kernel/lib/zstd/entropy_common.c index b354fc2cd..2b0a643c3 100644 --- a/contrib/linux-kernel/lib/zstd/entropy_common.c +++ b/contrib/linux-kernel/lib/zstd/entropy_common.c @@ -164,7 +164,7 @@ size_t FSE_readNCount(short *normalizedCounter, unsigned *maxSVPtr, unsigned *ta @return : size read from `src` , or an error Code . Note : Needed by HUF_readCTable() and HUF_readDTableX?() . */ -size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize) +size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) { U32 weightTotal; const BYTE *ip = (const BYTE *)src; @@ -192,10 +192,9 @@ size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSym } } } else { /* header compressed with FSE (normal case) */ - FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */ if (iSize + 1 > srcSize) return ERROR(srcSize_wrong); - oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */ + oSize = FSE_decompress_wksp(huffWeight, hwSize - 1, ip + 1, iSize, 6, workspace, workspaceSize); /* max (hwSize-1) values decoded, as last one is implied */ if (FSE_isError(oSize)) return oSize; } diff --git a/contrib/linux-kernel/lib/zstd/fse.h b/contrib/linux-kernel/lib/zstd/fse.h index bc2962aec..7460ab04b 100644 --- a/contrib/linux-kernel/lib/zstd/fse.h +++ b/contrib/linux-kernel/lib/zstd/fse.h @@ -187,7 +187,7 @@ typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more /*! FSE_buildDTable(): Builds 'dt', which must be already allocated, using FSE_createDTable(). return : 0, or an errorCode, which can be tested using FSE_isError() */ -FSE_PUBLIC_API size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); +FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize); /*! FSE_decompress_usingDTable(): Decompress compressed source `cSrc` of size `cSrcSize` using `dt` @@ -263,15 +263,6 @@ size_t FSE_count_simple(unsigned *count, unsigned *maxSymbolValuePtr, const void unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus); /**< same as FSE_optimalTableLog(), which used `minus==2` */ -/* FSE_compress_wksp() : - * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable. - */ -#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) \ - (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024)) -size_t FSE_compress_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, - size_t wkspSize); - size_t FSE_buildCTable_raw(FSE_CTable *ct, unsigned nbBits); /**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */ @@ -290,7 +281,7 @@ size_t FSE_buildDTable_raw(FSE_DTable *dt, unsigned nbBits); size_t FSE_buildDTable_rle(FSE_DTable *dt, unsigned char symbolValue); /**< build a fake FSE_DTable, designed to always generate the same symbolValue */ -size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, unsigned maxLog); +size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize); /**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */ /* ***************************************** diff --git a/contrib/linux-kernel/lib/zstd/fse_compress.c b/contrib/linux-kernel/lib/zstd/fse_compress.c index e016bb177..ef3d1741d 100644 --- a/contrib/linux-kernel/lib/zstd/fse_compress.c +++ b/contrib/linux-kernel/lib/zstd/fse_compress.c @@ -48,6 +48,8 @@ #include "bitstream.h" #include "fse.h" #include +#include +#include #include /* memcpy, memset */ /* ************************************************************** @@ -87,7 +89,7 @@ * wkspSize should be sized to handle worst case situation, which is `1<> 1 : 1); FSE_symbolCompressionTransform *const symbolTT = (FSE_symbolCompressionTransform *)(FSCT); U32 const step = FSE_TABLESTEP(tableSize); - U32 cumul[FSE_MAX_SYMBOL_VALUE + 2]; - - FSE_FUNCTION_TYPE *const tableSymbol = (FSE_FUNCTION_TYPE *)workSpace; U32 highThreshold = tableSize - 1; - /* CTable header */ - if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) + U32 *cumul; + FSE_FUNCTION_TYPE *tableSymbol; + size_t spaceUsed32 = 0; + + cumul = (U32 *)workspace + spaceUsed32; + spaceUsed32 += FSE_MAX_SYMBOL_VALUE + 2; + tableSymbol = (FSE_FUNCTION_TYPE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(FSE_FUNCTION_TYPE) * ((size_t)1 << tableLog), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + /* CTable header */ tableU16[-2] = (U16)tableLog; tableU16[-1] = (U16)maxSymbolValue; @@ -575,7 +586,7 @@ static size_t FSE_normalizeM2(short *norm, U32 tableLog, const unsigned *count, { U64 const vStepLog = 62 - tableLog; U64 const mid = (1ULL << (vStepLog - 1)) - 1; - U64 const rStep = ((((U64)1 << vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */ + U64 const rStep = div_u64((((U64)1 << vStepLog) * ToDistribute) + mid, (U32)total); /* scale on remaining */ U64 tmpTotal = mid; for (s = 0; s <= maxSymbolValue; s++) { if (norm[s] == NOT_YET_ASSIGNED) { @@ -609,7 +620,7 @@ size_t FSE_normalizeCount(short *normalizedCounter, unsigned tableLog, const uns { U32 const rtbTable[] = {0, 473195, 504333, 520860, 550000, 700000, 750000, 830000}; U64 const scale = 62 - tableLog; - U64 const step = ((U64)1 << 62) / total; /* <== here, one division ! */ + U64 const step = div_u64((U64)1 << 62, (U32)total); /* <== here, one division ! */ U64 const vStep = 1ULL << (scale - 20); int stillToDistribute = 1 << tableLog; unsigned s; @@ -782,76 +793,3 @@ size_t FSE_compress_usingCTable(void *dst, size_t dstSize, const void *src, size } size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); } - -#define CHECK_V_F(e, f) \ - size_t const e = f; \ - if (ERR_isError(e)) \ - return f -#define CHECK_F(f) \ - { \ - CHECK_V_F(_var_err__, f); \ - } - -/* FSE_compress_wksp() : - * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`). - * `wkspSize` size must be `(1< not compressible */ - if (maxCount < (srcSize >> 7)) - return 0; /* Heuristic : not compressible enough */ - } - - tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); - CHECK_F(FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue)); - - /* Write table description header */ - { - CHECK_V_F(nc_err, FSE_writeNCount(op, oend - op, norm, maxSymbolValue, tableLog)); - op += nc_err; - } - - /* Compress */ - CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize)); - { - CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable)); - if (cSize == 0) - return 0; /* not enough space for compressed data */ - op += cSize; - } - - /* check compressibility */ - if ((size_t)(op - ostart) >= srcSize - 1) - return 0; - - return op - ostart; -} diff --git a/contrib/linux-kernel/lib/zstd/fse_decompress.c b/contrib/linux-kernel/lib/zstd/fse_decompress.c index 96cf89ff9..a84300e5a 100644 --- a/contrib/linux-kernel/lib/zstd/fse_decompress.c +++ b/contrib/linux-kernel/lib/zstd/fse_decompress.c @@ -48,6 +48,7 @@ #include "bitstream.h" #include "fse.h" #include +#include #include /* memcpy, memset */ /* ************************************************************** @@ -91,17 +92,19 @@ /* Function templates */ -size_t FSE_buildDTable(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) +size_t FSE_buildDTable_wksp(FSE_DTable *dt, const short *normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void *workspace, size_t workspaceSize) { void *const tdPtr = dt + 1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ FSE_DECODE_TYPE *const tableDecode = (FSE_DECODE_TYPE *)(tdPtr); - U16 symbolNext[FSE_MAX_SYMBOL_VALUE + 1]; + U16 *symbolNext = (U16 *)workspace; U32 const maxSV1 = maxSymbolValue + 1; U32 const tableSize = 1 << tableLog; U32 highThreshold = tableSize - 1; /* Sanity Checks */ + if (workspaceSize < sizeof(U16) * (FSE_MAX_SYMBOL_VALUE + 1)) + return ERROR(tableLog_tooLarge); if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); if (tableLog > FSE_MAX_TABLELOG) @@ -288,16 +291,32 @@ size_t FSE_decompress_usingDTable(void *dst, size_t originalSize, const void *cS return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); } -size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, FSE_DTable *workSpace, unsigned maxLog) +size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size_t cSrcSize, unsigned maxLog, void *workspace, size_t workspaceSize) { const BYTE *const istart = (const BYTE *)cSrc; const BYTE *ip = istart; - short counting[FSE_MAX_SYMBOL_VALUE + 1]; unsigned tableLog; unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE; + size_t NCountLength; + + FSE_DTable *dt; + short *counting; + size_t spaceUsed32 = 0; + + FSE_STATIC_ASSERT(sizeof(FSE_DTable) == sizeof(U32)); + + dt = (FSE_DTable *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += FSE_DTABLE_SIZE_U32(maxLog); + counting = (short *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(short) * (FSE_MAX_SYMBOL_VALUE + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); /* normal FSE decoding mode */ - size_t const NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + NCountLength = FSE_readNCount(counting, &maxSymbolValue, &tableLog, istart, cSrcSize); if (FSE_isError(NCountLength)) return NCountLength; // if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining @@ -307,7 +326,7 @@ size_t FSE_decompress_wksp(void *dst, size_t dstCapacity, const void *cSrc, size ip += NCountLength; cSrcSize -= NCountLength; - CHECK_F(FSE_buildDTable(workSpace, counting, maxSymbolValue, tableLog)); + CHECK_F(FSE_buildDTable_wksp(dt, counting, maxSymbolValue, tableLog, workspace, workspaceSize)); - return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */ + return FSE_decompress_usingDTable(dst, dstCapacity, ip, cSrcSize, dt); /* always return, even if it is an error code */ } diff --git a/contrib/linux-kernel/lib/zstd/huf.h b/contrib/linux-kernel/lib/zstd/huf.h index 56abe2f1c..2143da28d 100644 --- a/contrib/linux-kernel/lib/zstd/huf.h +++ b/contrib/linux-kernel/lib/zstd/huf.h @@ -55,7 +55,7 @@ unsigned HUF_isError(size_t code); /**< tells if a return value is an error code /** HUF_compress4X_wksp() : * Same as HUF_compress2(), but uses externally allocated `workSpace`, which must be a table of >= 1024 unsigned */ size_t HUF_compress4X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, - size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ + size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ /* *** Dependencies *** */ #include "mem.h" /* U32 */ @@ -91,17 +91,23 @@ typedef U32 HUF_DTable; #define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = {((U32)(maxTableLog)*0x01000001)} /* The workspace must have alignment at least 4 and be at least this large */ -#define HUF_WORKSPACE_SIZE (6 << 10) -#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) +#define HUF_COMPRESS_WORKSPACE_SIZE (6 << 10) +#define HUF_COMPRESS_WORKSPACE_SIZE_U32 (HUF_COMPRESS_WORKSPACE_SIZE / sizeof(U32)) + +/* The workspace must have alignment at least 4 and be at least this large */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE (3 << 10) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) /* **************************************** * Advanced decompression functions ******************************************/ -size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ -size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, - size_t cSrcSize); /**< considers RLE and uncompressed as errors */ -size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); /**< decodes RLE and uncompressed */ +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< single-symbol decoder */ +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< double-symbols decoder */ /* **************************************** * HUF detailed API @@ -111,7 +117,7 @@ HUF_compress() does the following: 1. count symbol occurrence from source[] into table count[] using FSE_count() 2. (optional) refine tableLog using HUF_optimalTableLog() 3. build Huffman table from count using HUF_buildCTable() -4. save Huffman table to memory buffer using HUF_writeCTable() +4. save Huffman table to memory buffer using HUF_writeCTable_wksp() 5. encode the data stream using HUF_compress4X_usingCTable() The following API allows targeting specific sub-functions for advanced tasks. @@ -121,7 +127,7 @@ or to save and regenerate 'CTable' using external methods. /* FSE_count() : find it within "fse.h" */ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue); typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */ -size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog); +size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, unsigned maxSymbolValue, unsigned huffLog, void *workspace, size_t workspaceSize); size_t HUF_compress4X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); typedef enum { @@ -137,7 +143,7 @@ typedef enum { * If preferRepeat then the old table will always be used if valid. */ size_t HUF_compress4X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, - int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ + int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ /** HUF_buildCTable_wksp() : * Same as HUF_buildCTable(), but using externally allocated scratch buffer. @@ -150,11 +156,12 @@ size_t HUF_buildCTable_wksp(HUF_CElt *tree, const U32 *count, U32 maxSymbolValue `huffWeight` is destination buffer. @return : size read from `src` , or an error Code . Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */ -size_t HUF_readStats(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize); +size_t HUF_readStats_wksp(BYTE *huffWeight, size_t hwSize, U32 *rankStats, U32 *nbSymbolsPtr, U32 *tableLogPtr, const void *src, size_t srcSize, + void *workspace, size_t workspaceSize); /** HUF_readCTable() : * Loading a CTable saved with HUF_writeCTable() */ -size_t HUF_readCTable(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize); +size_t HUF_readCTable_wksp(HUF_CElt *CTable, unsigned maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); /* HUF_decompress() does the following: @@ -170,8 +177,8 @@ HUF_decompress() does the following: * Assumption : 0 < cSrcSize < dstSize <= 128 KB */ U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize); -size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize); -size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize); +size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); +size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize); size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); size_t HUF_decompress4X2_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); @@ -180,7 +187,7 @@ size_t HUF_decompress4X4_usingDTable(void *dst, size_t maxDstSize, const void *c /* single stream variants */ size_t HUF_compress1X_wksp(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, - size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ + size_t wkspSize); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, size_t srcSize, const HUF_CElt *CTable); /** HUF_compress1X_repeat() : * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none. @@ -189,11 +196,13 @@ size_t HUF_compress1X_usingCTable(void *dst, size_t dstSize, const void *src, si * If preferRepeat then the old table will always be used if valid. */ size_t HUF_compress1X_repeat(void *dst, size_t dstSize, const void *src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void *workSpace, size_t wkspSize, HUF_CElt *hufTable, HUF_repeat *repeat, - int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */ + int preferRepeat); /**< `workSpace` must be a table of at least HUF_COMPRESS_WORKSPACE_SIZE_U32 unsigned */ -size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); -size_t HUF_decompress1X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< single-symbol decoder */ -size_t HUF_decompress1X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize); +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< single-symbol decoder */ +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, + size_t workspaceSize); /**< double-symbols decoder */ size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ diff --git a/contrib/linux-kernel/lib/zstd/huf_compress.c b/contrib/linux-kernel/lib/zstd/huf_compress.c index e82a136a1..0361f387f 100644 --- a/contrib/linux-kernel/lib/zstd/huf_compress.c +++ b/contrib/linux-kernel/lib/zstd/huf_compress.c @@ -43,6 +43,7 @@ #include "bitstream.h" #include "fse.h" /* header compression */ #include "huf.h" +#include #include /* memcpy, memset */ /* ************************************************************** @@ -78,7 +79,7 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX. */ #define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6 -size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, size_t wtSize) +size_t HUF_compressWeights_wksp(void *dst, size_t dstSize, const void *weightTable, size_t wtSize, void *workspace, size_t workspaceSize) { BYTE *const ostart = (BYTE *)dst; BYTE *op = ostart; @@ -87,11 +88,24 @@ size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, s U32 maxSymbolValue = HUF_TABLELOG_MAX; U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER; - FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)]; - BYTE scratchBuffer[1 << MAX_FSE_TABLELOG_FOR_HUFF_HEADER]; + FSE_CTable *CTable; + U32 *count; + S16 *norm; + size_t spaceUsed32 = 0; - U32 count[HUF_TABLELOG_MAX + 1]; - S16 norm[HUF_TABLELOG_MAX + 1]; + HUF_STATIC_ASSERT(sizeof(FSE_CTable) == sizeof(U32)); + + CTable = (FSE_CTable *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX); + count = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + norm = (S16 *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(S16) * (HUF_TABLELOG_MAX + 1), sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); /* init conditions */ if (wtSize <= 1) @@ -116,7 +130,7 @@ size_t HUF_compressWeights(void *dst, size_t dstSize, const void *weightTable, s } /* Compress */ - CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer))); + CHECK_F(FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, workspace, workspaceSize)); { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable)); if (cSize == 0) @@ -132,16 +146,28 @@ struct HUF_CElt_s { BYTE nbBits; }; /* typedef'd to HUF_CElt within "huf.h" */ -/*! HUF_writeCTable() : +/*! HUF_writeCTable_wksp() : `CTable` : Huffman tree to save, using huf representation. @return : size of saved CTable */ -size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog) +size_t HUF_writeCTable_wksp(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 maxSymbolValue, U32 huffLog, void *workspace, size_t workspaceSize) { - BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */ - BYTE huffWeight[HUF_SYMBOLVALUE_MAX]; BYTE *op = (BYTE *)dst; U32 n; + BYTE *bitsToWeight; + BYTE *huffWeight; + size_t spaceUsed32 = 0; + + bitsToWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_TABLELOG_MAX + 1, sizeof(U32)) >> 2; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + /* check conditions */ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge); @@ -155,7 +181,7 @@ size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 /* attempt weights compression by FSE */ { - CHECK_V_F(hSize, HUF_compressWeights(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue)); + CHECK_V_F(hSize, HUF_compressWeights_wksp(op + 1, maxDstSize - 1, huffWeight, maxSymbolValue, workspace, workspaceSize)); if ((hSize > 1) & (hSize < maxSymbolValue / 2)) { /* FSE compressed */ op[0] = (BYTE)hSize; return hSize + 1; @@ -174,15 +200,29 @@ size_t HUF_writeCTable(void *dst, size_t maxDstSize, const HUF_CElt *CTable, U32 return ((maxSymbolValue + 1) / 2) + 1; } -size_t HUF_readCTable(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize) +size_t HUF_readCTable_wksp(HUF_CElt *CTable, U32 maxSymbolValue, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) { - BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */ - U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ + U32 *rankVal; + BYTE *huffWeight; U32 tableLog = 0; U32 nbSymbols = 0; + size_t readSize; + size_t spaceUsed32 = 0; + + rankVal = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); /* get symbol weights */ - CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize)); + readSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); + if (ERR_isError(readSize)) + return readSize; /* check result */ if (tableLog > HUF_TABLELOG_MAX) @@ -680,7 +720,7 @@ static size_t HUF_compress_internal(void *dst, size_t dstSize, const void *src, /* Write table description header */ { - CHECK_V_F(hSize, HUF_writeCTable(op, dstSize, CTable, maxSymbolValue, huffLog)); + CHECK_V_F(hSize, HUF_writeCTable_wksp(op, dstSize, CTable, maxSymbolValue, huffLog, workSpace, wkspSize)); /* Check if using the previous table will be beneficial */ if (repeat && *repeat != HUF_repeat_none) { size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue); diff --git a/contrib/linux-kernel/lib/zstd/huf_decompress.c b/contrib/linux-kernel/lib/zstd/huf_decompress.c index 950c19443..652648204 100644 --- a/contrib/linux-kernel/lib/zstd/huf_decompress.c +++ b/contrib/linux-kernel/lib/zstd/huf_decompress.c @@ -49,6 +49,7 @@ #include "fse.h" /* header compression */ #include "huf.h" #include +#include #include /* memcpy, memset */ /* ************************************************************** @@ -86,20 +87,32 @@ typedef struct { BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */ -size_t HUF_readDTableX2(HUF_DTable *DTable, const void *src, size_t srcSize) +size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) { - BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; - U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ U32 tableLog = 0; U32 nbSymbols = 0; size_t iSize; void *const dtPtr = DTable + 1; HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr; + U32 *rankVal; + BYTE *huffWeight; + size_t spaceUsed32 = 0; + + rankVal = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ - iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); + iSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); if (HUF_isError(iSize)) return iSize; @@ -216,11 +229,11 @@ size_t HUF_decompress1X2_usingDTable(void *dst, size_t dstSize, const void *cSrc return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress1X2_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { const BYTE *ip = (const BYTE *)cSrc; - size_t const hSize = HUF_readDTableX2(DCtx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) @@ -347,11 +360,11 @@ size_t HUF_decompress4X2_usingDTable(void *dst, size_t dstSize, const void *cSrc return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress4X2_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { const BYTE *ip = (const BYTE *)cSrc; - size_t const hSize = HUF_readDTableX2(dctx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) @@ -422,6 +435,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4 *DTable, U32 sizeLog, const U32 co } typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart, rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline) @@ -465,27 +479,50 @@ static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sort } } -size_t HUF_readDTableX4(HUF_DTable *DTable, const void *src, size_t srcSize) +size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize) { - BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; - sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; - U32 rankStats[HUF_TABLELOG_MAX + 1] = {0}; - U32 rankStart0[HUF_TABLELOG_MAX + 2] = {0}; - U32 *const rankStart = rankStart0 + 1; - rankVal_t rankVal; U32 tableLog, maxW, sizeOfSort, nbSymbols; DTableDesc dtd = HUF_getDTableDesc(DTable); U32 const maxTableLog = dtd.maxTableLog; size_t iSize; void *dtPtr = DTable + 1; /* force compiler to avoid strict-aliasing */ HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr; + U32 *rankStart; + + rankValCol_t *rankVal; + U32 *rankStats; + U32 *rankStart0; + sortedSymbol_t *sortedSymbol; + BYTE *weightList; + size_t spaceUsed32 = 0; + + HUF_STATIC_ASSERT((sizeof(rankValCol_t) & 3) == 0); + + rankVal = (rankValCol_t *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; + rankStats = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + rankStart0 = (U32 *)workspace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 2; + sortedSymbol = (sortedSymbol_t *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; + weightList = (BYTE *)((U32 *)workspace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + + if ((spaceUsed32 << 2) > workspaceSize) + return ERROR(tableLog_tooLarge); + workspace = (U32 *)workspace + spaceUsed32; + workspaceSize -= (spaceUsed32 << 2); + + rankStart = rankStart0 + 1; + memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */ - iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); + iSize = HUF_readStats_wksp(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize); if (HUF_isError(iSize)) return iSize; @@ -652,11 +689,11 @@ size_t HUF_decompress1X4_usingDTable(void *dst, size_t dstSize, const void *cSrc return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress1X4_DCtx(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { const BYTE *ip = (const BYTE *)cSrc; - size_t const hSize = HUF_readDTableX4(DCtx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) @@ -785,11 +822,11 @@ size_t HUF_decompress4X4_usingDTable(void *dst, size_t dstSize, const void *cSrc return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress4X4_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { const BYTE *ip = (const BYTE *)cSrc; - size_t hSize = HUF_readDTableX4(dctx, cSrc, cSrcSize); + size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) @@ -861,7 +898,7 @@ U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize) typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize); -size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { /* validation checks */ if (dstSize == 0) @@ -879,11 +916,12 @@ size_t HUF_decompress4X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); + return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); } } -size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { /* validation checks */ if (dstSize == 0) @@ -893,11 +931,12 @@ size_t HUF_decompress4X_hufOnly(HUF_DTable *dctx, void *dst, size_t dstSize, con { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); + return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); } } -size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize) +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize) { /* validation checks */ if (dstSize == 0) @@ -915,6 +954,7 @@ size_t HUF_decompress1X_DCtx(HUF_DTable *dctx, void *dst, size_t dstSize, const { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize); + return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize) + : HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize); } } diff --git a/contrib/linux-kernel/lib/zstd/zstd_common.c b/contrib/linux-kernel/lib/zstd/zstd_common.c index 6ebf68d2a..a282624ee 100644 --- a/contrib/linux-kernel/lib/zstd/zstd_common.c +++ b/contrib/linux-kernel/lib/zstd/zstd_common.c @@ -51,7 +51,7 @@ ZSTD_customMem ZSTD_initStack(void *workspace, size_t workspaceSize) void *ZSTD_stackAllocAll(void *opaque, size_t *size) { ZSTD_stack *stack = (ZSTD_stack *)opaque; - *size = stack->end - ZSTD_PTR_ALIGN(stack->ptr); + *size = (BYTE const *)stack->end - (BYTE *)ZSTD_PTR_ALIGN(stack->ptr); return stack_push(stack, *size); } diff --git a/contrib/linux-kernel/test/Makefile b/contrib/linux-kernel/test/Makefile index 892264f4c..8411462c9 100644 --- a/contrib/linux-kernel/test/Makefile +++ b/contrib/linux-kernel/test/Makefile @@ -5,21 +5,21 @@ SOURCES := $(wildcard ../lib/zstd/*.c) OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) ARFLAGS := rcs -CXXFLAGS += -std=c++11 -CFLAGS += -g -O0 +CXXFLAGS += -std=c++11 -g -O3 -Wcast-align +CFLAGS += -g -O3 -Wframe-larger-than=400 -Wcast-align CPPFLAGS += $(IFLAGS) ../lib/zstd/libzstd.a: $(OBJECTS) $(AR) $(ARFLAGS) $@ $^ DecompressCrash: DecompressCrash.o $(OBJECTS) libFuzzer.a - $(CXX) $(TEST_CPPFLAGS) $(TEST_CXXFLAGS) $(LDFLAGS) $^ -o $@ + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ RoundTripCrash: RoundTripCrash.o $(OBJECTS) ../lib/xxhash.o libFuzzer.a - $(CXX) $(TEST_CPPFLAGS) $(TEST_CXXFLAGS) $(LDFLAGS) $^ -o $@ + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $^ -o $@ UserlandTest: UserlandTest.cpp ../lib/zstd/libzstd.a ../lib/xxhash.o - $(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@ + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@ XXHashUserlandTest: XXHashUserlandTest.cpp ../lib/xxhash.o ../../../lib/common/xxhash.o $(CXX) $(CXXFLAGS) $(CFLAGS) $(CPPFLAGS) $^ googletest/build/googlemock/gtest/libgtest.a googletest/build/googlemock/gtest/libgtest_main.a -o $@ @@ -39,5 +39,5 @@ googletest: @cd googletest/build && cmake .. && $(MAKE) clean: - $(RM) -f *.{o,a} ../lib/zstd/*.{o,a} + $(RM) -f *.{o,a} ../lib/zstd/*.{o,a} ../lib/*.o $(RM) -f DecompressCrash RoundTripCrash UserlandTest XXHashUserlandTest diff --git a/contrib/linux-kernel/test/include/linux/math64.h b/contrib/linux-kernel/test/include/linux/math64.h new file mode 100644 index 000000000..3d0ae72d5 --- /dev/null +++ b/contrib/linux-kernel/test/include/linux/math64.h @@ -0,0 +1,11 @@ +#ifndef LINUX_MATH64_H +#define LINUX_MATH64_H + +#include + +static uint64_t div_u64(uint64_t n, uint32_t d) +{ + return n / d; +} + +#endif From acbef3decdde96e30b11a09e13563cff08d35311 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 05:18:09 -0700 Subject: [PATCH 361/400] ZSTD_getFrameContentSize() is promoted to "stable" status --- NEWS | 5 ++- lib/zstd.h | 91 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/NEWS b/NEWS index db9df9634..d23a58f02 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,15 @@ v1.3.0 cli : new : `--list` command, by Paul Cruz +cli : changed : xz/lzma support enabled by default cli : changed : `-t *` continue processing list after a decompression error API : added : ZSTD_versionString() +API : promoted to stable status : ZSTD_getFrameContentSize(), by Sean Purcell API exp : new advanced API : ZSTD_compress_generic(), ZSTD_CCtx_setParameter() API exp : new : API for static or external allocation : ZSTD_initStatic?Ctx() API exp : added : ZSTD_decompressBegin_usingDDict(), requested by Guy Riddle (#700) +API exp : clarified memory estimation / measurement functions. API exp : changed : strongest strategy renamed ZSTD_btultra, fastest strategy ZSTD_fast set to 1 -API exp : clarified presentation of memory estimation / measurement functions. +tools : decodecorpus can generate random dictionary-compressed samples, by Paul Cruz new : contrib/seekable_format, demo and API, by Sean Purcell changed : contrib/linux-kernel, updated version and license, by Nick Terrell diff --git a/lib/zstd.h b/lib/zstd.h index 59a09be6f..71b641004 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -68,7 +68,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< useful to check dll versio #define ZSTD_QUOTE(str) #str #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) -ZSTDLIB_API const char* ZSTD_versionString(void); /* >= v1.3.0 */ +ZSTDLIB_API const char* ZSTD_versionString(void); /* v1.3.0 */ /*************************************** @@ -92,27 +92,41 @@ ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity, ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity, const void* src, size_t compressedSize); -/*! ZSTD_getDecompressedSize() : - * NOTE: This function is planned to be obsolete, in favor of ZSTD_getFrameContentSize(). - * ZSTD_getFrameContentSize() works the same way, - * returning the decompressed size of a single frame, - * but distinguishes empty frames from frames with an unknown size, or errors. - * - * 'src' is the start of a zstd compressed frame. - * @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise. - * note 1 : decompressed size is an optional field, it may not be present, typically in streaming mode. - * When `return==0`, data to decompress could be any size. +/*! ZSTD_getFrameContentSize() : v1.3.0 + * `src` should point to the start of a ZSTD encoded frame. + * `srcSize` must be at least as large as the frame header. + * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough. + * @return : - decompressed size of the frame in `src`, if known + * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined + * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) + * note 1 : a 0 return value means the frame is valid but "empty". + * note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode. + * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. * In which case, it's necessary to use streaming mode to decompress data. - * Optionally, application can use ZSTD_decompress() while relying on implied limits. - * (For example, data may be necessarily cut into blocks <= 16 KB). - * note 2 : decompressed size is always present when compression is done with ZSTD_compress() - * note 3 : decompressed size can be very large (64-bits value), + * Optionally, application can rely on some implicit limit, + * as ZSTD_decompress() only needs an upper bound of decompressed size. + * (For example, data could be necessarily cut into blocks <= 16 KB). + * note 3 : decompressed size is always present when compression is done with ZSTD_compress() + * note 4 : decompressed size can be very large (64-bits value), * potentially larger than what local system can handle as a single memory segment. * In which case, it's necessary to use streaming mode to decompress data. - * note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified. - * Always ensure result fits within application's authorized limits. + * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified. + * Always ensure return value fits within application's authorized limits. * Each application can set its own limits. - * note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameHeader() to know more. */ + * note 6 : This function replaces ZSTD_getDecompressedSize() */ +#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) +#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) +ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); + +/*! ZSTD_getDecompressedSize() : + * NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize(). + * Both functions work the same way, + * but ZSTD_getDecompressedSize() blends + * "empty", "unknown" and "error" results in the same return value (0), + * while ZSTD_getFrameContentSize() distinguishes them. + * + * 'src' is the start of a zstd compressed frame. + * @return : content size to be decompressed, as a 64-bits value _if known and not empty_, 0 otherwise. */ ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize); @@ -291,7 +305,7 @@ typedef struct ZSTD_outBuffer_s { * *******************************************************************/ typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same object (>= v1.3.0) */ - /* But continue to distinguish them for compatibility with versions <= v1.2.0 */ + /* Continue to distinguish them for compatibility with versions <= v1.2.0 */ /*===== ZSTD_CStream management functions =====*/ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); @@ -330,7 +344,7 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output * *******************************************************************************/ typedef ZSTD_DCtx ZSTD_DStream; /**< DCtx and DStream are now effectively same object (>= v1.3.0) */ - /* But continue to distinguish them for compatibility with versions <= v1.2.0 */ + /* Continue to distinguish them for compatibility with versions <= v1.2.0 */ /*===== ZSTD_DStream management functions =====*/ ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void); ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); @@ -349,8 +363,8 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output /**************************************************************************************** * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS * The definitions in this section are considered experimental. - * They should never be used with a dynamic library, as they may change in the future. - * They are provided for advanced usages. + * They should never be used with a dynamic library, as prototypes may change in the future. + * They are provided for advanced scenarios. * Use them only in association with static linking. * ***************************************************************************************/ @@ -381,8 +395,8 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output #define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */ #define ZSTD_FRAMEHEADERSIZE_MIN 6 static const size_t ZSTD_frameHeaderSize_prefix = 5; /* minimum input size to know frame header size */ -static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN; static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX; +static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN; static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */ @@ -433,26 +447,15 @@ static const ZSTD_customMem ZSTD_defaultCMem = { NULL, NULL, NULL }; /*! ZSTD_findFrameCompressedSize() : * `src` should point to the start of a ZSTD encoded frame or skippable frame * `srcSize` must be at least as large as the frame - * @return : the compressed size of the frame pointed to by `src`, + * @return : the compressed size of the first frame starting at `src`, * suitable to pass to `ZSTD_decompress` or similar, - * or an error code if given invalid input. */ + * or an error code if input is invalid */ ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize); -/*! ZSTD_getFrameContentSize() : - * `src` should point to the start of a ZSTD encoded frame. - * `srcSize` must be at least as large as the frame header. - * A value >= `ZSTD_frameHeaderSize_max` is guaranteed to be large enough. - * @return : - decompressed size of the frame pointed to be `src` if known - * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined - * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ -#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1) -#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2) -ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize); - /*! ZSTD_findDecompressedSize() : * `src` should point the start of a series of ZSTD encoded and/or skippable frames - * `srcSize` must be the _exact_ size of this series - * (i.e. there should be a frame boundary exactly `srcSize` bytes after `src`) + * `srcSize` must be the _exact_ size of this serie + * (i.e. there should be a frame boundary exactly at `srcSize` bytes after `src`) * @return : - decompressed size of all data in all successive frames * - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN * - if an error occurred: ZSTD_CONTENTSIZE_ERROR @@ -460,8 +463,6 @@ ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t * note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode. * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size. * In which case, it's necessary to use streaming mode to decompress data. - * Optionally, application can still use ZSTD_decompress() while relying on implied limits. - * (For example, data may be necessarily cut into blocks <= 16 KB). * note 2 : decompressed size is always present when compression is done with ZSTD_compress() * note 3 : decompressed size can be very large (64-bits value), * potentially larger than what local system can handle as a single memory segment. @@ -470,7 +471,7 @@ ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t * Always ensure result fits within application's authorized limits. * Each application can set its own limits. * note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to - * read each contained frame header. This is efficient as most of the data is skipped, + * read each contained frame header. This is fast as most of the data is skipped, * however it does mean that all frame data must be present and valid. */ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize); @@ -478,7 +479,8 @@ ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t * `src` should point to the start of a ZSTD frame * `srcSize` must be >= ZSTD_frameHeaderSize_prefix. * @return : size of the Frame Header */ -size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); + /*************************************** * Context memory usage @@ -575,7 +577,7 @@ ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter par ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel); -typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with ZSTD_MAGIC_DICTIONARY, rawContent otherwize */ +typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */ ZSTD_dm_rawContent, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */ ZSTD_dm_fullDict /* refuses to load a dictionary if it does not respect Zstandard's specification */ } ZSTD_dictMode_e; @@ -583,7 +585,8 @@ typedef enum { ZSTD_dm_auto=0, /* dictionary is "full" if it starts with * Create a ZSTD_CDict using external alloc and free, and customized compression parameters */ ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_dictMode_e dictMode, - ZSTD_compressionParameters cParams, ZSTD_customMem customMem); + ZSTD_compressionParameters cParams, + ZSTD_customMem customMem); /*! ZSTD_initStaticCDict_advanced() : * Generate a digested dictionary in provided memory area. From 7303ed5d74fa185d6c37228ae4370e983921d26c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 11:30:31 -0700 Subject: [PATCH 362/400] minor : specify compression level in tags --- tests/fullbench.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fullbench.c b/tests/fullbench.c index 2cdad2e38..251d3ece4 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -236,14 +236,14 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) switch(benchNb) { case 1: - benchFunction = local_ZSTD_compress; benchName = "ZSTD_compress"; + benchFunction = local_ZSTD_compress; benchName = "ZSTD_compress(1)"; break; case 2: benchFunction = local_ZSTD_decompress; benchName = "ZSTD_decompress"; break; #ifndef ZSTD_DLL_IMPORT case 11: - benchFunction = local_ZSTD_compressContinue; benchName = "ZSTD_compressContinue"; + benchFunction = local_ZSTD_compressContinue; benchName = "ZSTD_compressContinue(1)"; break; case 12: benchFunction = local_ZSTD_compressContinue_extDict; benchName = "ZSTD_compressContinue_extDict"; @@ -259,7 +259,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) break; #endif case 41: - benchFunction = local_ZSTD_compressStream; benchName = "ZSTD_compressStream"; + benchFunction = local_ZSTD_compressStream; benchName = "ZSTD_compressStream(1)"; break; case 42: benchFunction = local_ZSTD_decompressStream; benchName = "ZSTD_decompressStream"; From 97f2bf66dace6b837bec09be182498a547053dd2 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 11:31:40 -0700 Subject: [PATCH 363/400] minor : fix typo --- lib/zstd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zstd.h b/lib/zstd.h index 71b641004..58e9a5606 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -454,7 +454,7 @@ ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize) /*! ZSTD_findDecompressedSize() : * `src` should point the start of a series of ZSTD encoded and/or skippable frames - * `srcSize` must be the _exact_ size of this serie + * `srcSize` must be the _exact_ size of this series * (i.e. there should be a frame boundary exactly at `srcSize` bytes after `src`) * @return : - decompressed size of all data in all successive frames * - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN From 99e315999c69f3d443c5992e4d21c6b5848e23ed Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Thu, 29 Jun 2017 11:49:59 -0700 Subject: [PATCH 364/400] Reduce stack usage of HUF_readDTableX4 and HUF_readDTableX2 --- lib/common/huf.h | 11 ++ lib/decompress/huf_decompress.c | 172 +++++++++++++++++++++++++++---- lib/decompress/zstd_decompress.c | 11 +- 3 files changed, 170 insertions(+), 24 deletions(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 7873ca3d4..801f74c1e 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -111,6 +111,9 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, const void* #define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); +/* The workspace must have alignment at least 4 and be at least this large */ +#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) +#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) /* ****************************************************************** @@ -170,8 +173,11 @@ size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cS size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */ size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */ +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */ size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ /* **************************************** @@ -243,7 +249,9 @@ HUF_decompress() does the following: U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize); size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize); +size_t HUF_readDTableX4_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize); size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); @@ -266,8 +274,11 @@ size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cS size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); +size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */ +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */ size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */ +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */ size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */ size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index d40b3be04..4011dee39 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -67,6 +67,12 @@ #define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ +/* ************************************************************** +* Byte alignment for workSpace management +****************************************************************/ +#define ALIGN(x, a) ALIGN_MASK((x), (a) - 1) +#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) + /*-***************************/ /* generic DTableDesc */ /*-***************************/ @@ -87,16 +93,29 @@ static DTableDesc HUF_getDTableDesc(const HUF_DTable* table) typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */ -size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize) +size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize) { - BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; - U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */ U32 tableLog = 0; U32 nbSymbols = 0; size_t iSize; void* const dtPtr = DTable + 1; HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; + U32 *rankVal; + BYTE *huffWeight; + size_t spaceUsed = 0; + + rankVal = (U32 *)((BYTE *)workSpace + spaceUsed); + spaceUsed += sizeof(U32) * (HUF_TABLELOG_ABSOLUTEMAX + 1); + huffWeight = (BYTE *)workSpace + spaceUsed; + spaceUsed += HUF_SYMBOLVALUE_MAX + 1; + spaceUsed = ALIGN(spaceUsed, sizeof(U32)); + + if (spaceUsed > wkspSize) + return ERROR(tableLog_tooLarge); + workSpace = (BYTE *)workSpace + spaceUsed; + wkspSize -= spaceUsed; + HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ @@ -135,6 +154,13 @@ size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize) return iSize; } +size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX2_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} + static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog) { @@ -212,11 +238,13 @@ size_t HUF_decompress1X2_usingDTable( return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) { const BYTE* ip = (const BYTE*) cSrc; - size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -224,6 +252,15 @@ size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, cons return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx); } + +size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); @@ -335,11 +372,14 @@ size_t HUF_decompress4X2_usingDTable( } -size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) { const BYTE* ip = (const BYTE*) cSrc; - size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX2_wksp (dctx, cSrc, cSrcSize, + workSpace, wkspSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -347,6 +387,13 @@ size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, cons return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx); } + +size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX); @@ -404,6 +451,7 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co } typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; +typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog, const sortedSymbol_t* sortedList, const U32 sortedListSize, @@ -447,20 +495,44 @@ static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog, } } -size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) +size_t HUF_readDTableX4_wksp(HUF_DTable* DTable, const void* src, + size_t srcSize, void* workSpace, + size_t wkspSize) { - BYTE weightList[HUF_SYMBOLVALUE_MAX + 1]; - sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1]; - U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 }; - U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 }; - U32* const rankStart = rankStart0+1; - rankVal_t rankVal; U32 tableLog, maxW, sizeOfSort, nbSymbols; DTableDesc dtd = HUF_getDTableDesc(DTable); U32 const maxTableLog = dtd.maxTableLog; size_t iSize; void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */ HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr; + U32 *rankStart; + + rankValCol_t *rankVal; + U32 *rankStats; + U32 *rankStart0; + sortedSymbol_t *sortedSymbol; + BYTE *weightList; + size_t spaceUsed = 0; + + rankVal = (rankValCol_t *)((BYTE *)workSpace + spaceUsed); + spaceUsed += sizeof(rankValCol_t) * HUF_TABLELOG_MAX; + rankStats = (U32 *)((BYTE *)workSpace + spaceUsed); + spaceUsed += sizeof(U32) * (HUF_TABLELOG_MAX + 1); + rankStart0 = (U32 *)((BYTE *)workSpace + spaceUsed); + spaceUsed += sizeof(U32) * (HUF_TABLELOG_MAX + 2); + sortedSymbol = (sortedSymbol_t *)((BYTE *)workSpace + spaceUsed); + spaceUsed += sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1); + weightList = (BYTE *)workSpace + spaceUsed; + spaceUsed += HUF_SYMBOLVALUE_MAX + 1; + spaceUsed = ALIGN(spaceUsed, sizeof(U32)); + + if (spaceUsed > wkspSize) + return ERROR(tableLog_tooLarge); + workSpace = (BYTE *)workSpace + spaceUsed; + wkspSize -= spaceUsed; + + rankStart = rankStart0 + 1; + memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */ if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge); @@ -527,6 +599,12 @@ size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize) return iSize; } +size_t HUF_readDTableX4(HUF_DTable* DTable, const void* src, size_t srcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_readDTableX4_wksp(DTable, src, srcSize, + workSpace, sizeof(workSpace)); +} static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog) { @@ -627,11 +705,14 @@ size_t HUF_decompress1X4_usingDTable( return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable); } -size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) { const BYTE* ip = (const BYTE*) cSrc; - size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, + workSpace, wkspSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -639,6 +720,15 @@ size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, cons return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx); } + +size_t HUF_decompress1X4_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X4_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX); @@ -749,11 +839,14 @@ size_t HUF_decompress4X4_usingDTable( } -size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) { const BYTE* ip = (const BYTE*) cSrc; - size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize); + size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, + workSpace, wkspSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; cSrcSize -= hSize; @@ -761,6 +854,15 @@ size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, cons return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx); } + +size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} + size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX); @@ -874,7 +976,25 @@ size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, co } } -size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) + +size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, + size_t dstSize, const void* cSrc, + size_t cSrcSize, void* workSpace, + size_t wkspSize) +{ + /* validation checks */ + if (dstSize == 0) return ERROR(dstSize_tooSmall); + if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected); /* invalid */ + + { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); + return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize): + HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize); + } +} + +size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize, + void* workSpace, size_t wkspSize) { /* validation checks */ if (dstSize == 0) return ERROR(dstSize_tooSmall); @@ -883,7 +1003,17 @@ size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : - HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; + return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize): + HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, + cSrcSize, workSpace, wkspSize); } } + +size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, + const void* cSrc, size_t cSrcSize) +{ + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); +} diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 95d18d4b5..b87925c54 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -93,6 +93,7 @@ typedef struct { FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ + U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; U32 rep[ZSTD_REP_NUM]; } ZSTD_entropyTables_t; @@ -559,8 +560,10 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) : ( singleStream ? - HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) : - HUF_decompress4X_hufOnly (dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) )) + HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace)) : + HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize, + dctx->entropy.workspace, sizeof(dctx->entropy.workspace))))) return ERROR(corruption_detected); dctx->litPtr = dctx->litBuffer; @@ -1836,7 +1839,9 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const dictPtr += 8; /* skip header = magic + dictID */ - { size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr); + { size_t const hSize = HUF_readDTableX4_wksp( + entropy->hufTable, dictPtr, dictEnd - dictPtr, + entropy->workspace, sizeof(entropy->workspace)); if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); dictPtr += hSize; } From c6a5275a281accb56ac6023aafb5adaea9285b26 Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Thu, 29 Jun 2017 12:39:34 -0700 Subject: [PATCH 365/400] Fix alignment warnings with pointer casting --- lib/decompress/huf_decompress.c | 60 ++++++++++++++++----------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 4011dee39..45e00618f 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -101,20 +101,19 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize void* const dtPtr = DTable + 1; HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr; - U32 *rankVal; - BYTE *huffWeight; - size_t spaceUsed = 0; + U32* rankVal; + BYTE* huffWeight; + size_t spaceUsed32 = 0; - rankVal = (U32 *)((BYTE *)workSpace + spaceUsed); - spaceUsed += sizeof(U32) * (HUF_TABLELOG_ABSOLUTEMAX + 1); - huffWeight = (BYTE *)workSpace + spaceUsed; - spaceUsed += HUF_SYMBOLVALUE_MAX + 1; - spaceUsed = ALIGN(spaceUsed, sizeof(U32)); + rankVal = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; + huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - if (spaceUsed > wkspSize) + if ((spaceUsed32 >> 2) > wkspSize) return ERROR(tableLog_tooLarge); - workSpace = (BYTE *)workSpace + spaceUsed; - wkspSize -= spaceUsed; + workSpace = (U32 *)workSpace + spaceUsed32; + wkspSize -= (spaceUsed32 << 2); HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable)); /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */ @@ -507,29 +506,28 @@ size_t HUF_readDTableX4_wksp(HUF_DTable* DTable, const void* src, HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr; U32 *rankStart; - rankValCol_t *rankVal; - U32 *rankStats; - U32 *rankStart0; - sortedSymbol_t *sortedSymbol; - BYTE *weightList; - size_t spaceUsed = 0; + rankValCol_t* rankVal; + U32* rankStats; + U32* rankStart0; + sortedSymbol_t* sortedSymbol; + BYTE* weightList; + size_t spaceUsed32 = 0; - rankVal = (rankValCol_t *)((BYTE *)workSpace + spaceUsed); - spaceUsed += sizeof(rankValCol_t) * HUF_TABLELOG_MAX; - rankStats = (U32 *)((BYTE *)workSpace + spaceUsed); - spaceUsed += sizeof(U32) * (HUF_TABLELOG_MAX + 1); - rankStart0 = (U32 *)((BYTE *)workSpace + spaceUsed); - spaceUsed += sizeof(U32) * (HUF_TABLELOG_MAX + 2); - sortedSymbol = (sortedSymbol_t *)((BYTE *)workSpace + spaceUsed); - spaceUsed += sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1); - weightList = (BYTE *)workSpace + spaceUsed; - spaceUsed += HUF_SYMBOLVALUE_MAX + 1; - spaceUsed = ALIGN(spaceUsed, sizeof(U32)); + rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2; + rankStats = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 1; + rankStart0 = (U32 *)workSpace + spaceUsed32; + spaceUsed32 += HUF_TABLELOG_MAX + 2; + sortedSymbol = (sortedSymbol_t *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; + weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); + spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - if (spaceUsed > wkspSize) + if ((spaceUsed32 >> 2) > wkspSize) return ERROR(tableLog_tooLarge); - workSpace = (BYTE *)workSpace + spaceUsed; - wkspSize -= spaceUsed; + workSpace = (U32 *)workSpace + spaceUsed32; + wkspSize -= (spaceUsed32 << 2); rankStart = rankStart0 + 1; memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1)); From 2e84bec9ac6ed31b8cf809e1198b2860c76624ed Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 13:03:10 -0700 Subject: [PATCH 366/400] updated fullbench to also measure ZSTD_compress_generic() will make it possible to visualize optimization opportunity for ZSTD_e_end --- tests/fullbench.c | 56 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/tests/fullbench.c b/tests/fullbench.c index 251d3ece4..1c1807a5a 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -153,6 +153,39 @@ size_t local_ZSTD_compressStream(void* dst, size_t dstCapacity, void* buff2, con return buffOut.pos; } +static size_t local_ZSTD_compress_generic_end(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) +{ + ZSTD_outBuffer buffOut; + ZSTD_inBuffer buffIn; + (void)buff2; + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); + buffOut.dst = dst; + buffOut.size = dstCapacity; + buffOut.pos = 0; + buffIn.src = src; + buffIn.size = srcSize; + buffIn.pos = 0; + ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_end); + return buffOut.pos; +} + +static size_t local_ZSTD_compress_generic_continue(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) +{ + ZSTD_outBuffer buffOut; + ZSTD_inBuffer buffIn; + (void)buff2; + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); + buffOut.dst = dst; + buffOut.size = dstCapacity; + buffOut.pos = 0; + buffIn.src = src; + buffIn.size = srcSize; + buffIn.pos = 0; + ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_continue); + ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_end); + return buffOut.pos; +} + static ZSTD_DStream* g_dstream= NULL; static size_t local_ZSTD_decompressStream(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) { @@ -264,6 +297,12 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) case 42: benchFunction = local_ZSTD_decompressStream; benchName = "ZSTD_decompressStream"; break; + case 51: + benchFunction = local_ZSTD_compress_generic_continue; benchName = "ZSTD_compress_generic, continue"; + break; + case 52: + benchFunction = local_ZSTD_compress_generic_end; benchName = "ZSTD_compress_generic, end"; + break; default : return 0; } @@ -276,6 +315,10 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) free(dstBuff); free(buff2); return 12; } + if (g_zcc==NULL) g_zcc = ZSTD_createCCtx(); + if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); + if (g_cstream==NULL) g_cstream = ZSTD_createCStream(); + if (g_dstream==NULL) g_dstream = ZSTD_createDStream(); /* Preparation */ switch(benchNb) @@ -284,18 +327,10 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; #ifndef ZSTD_DLL_IMPORT - case 11 : - if (g_zcc==NULL) g_zcc = ZSTD_createCCtx(); - break; - case 12 : - if (g_zcc==NULL) g_zcc = ZSTD_createCCtx(); - break; case 13 : - if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; case 31: /* ZSTD_decodeLiteralsBlock */ - if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); { blockProperties_t bp; ZSTD_frameHeader zfp; size_t frameHeaderSize, skippedSize; @@ -313,7 +348,6 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) break; } case 32: /* ZSTD_decodeSeqHeaders */ - if (g_zdc==NULL) g_zdc = ZSTD_createDCtx(); { blockProperties_t bp; ZSTD_frameHeader zfp; const BYTE* ip = dstBuff; @@ -342,11 +376,7 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) case 31: goto _cleanOut; #endif - case 41 : - if (g_cstream==NULL) g_cstream = ZSTD_createCStream(); - break; case 42 : - if (g_dstream==NULL) g_dstream = ZSTD_createDStream(); g_cSize = ZSTD_compress(buff2, dstBuffSize, src, srcSize, 1); break; From fedc94de8c1d7265db7d2bdebb2458270f8ceab1 Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Thu, 29 Jun 2017 13:04:15 -0700 Subject: [PATCH 367/400] Fix pointer casting warning --- lib/decompress/huf_decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 45e00618f..cbf78e807 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -519,7 +519,7 @@ size_t HUF_readDTableX4_wksp(HUF_DTable* DTable, const void* src, spaceUsed32 += HUF_TABLELOG_MAX + 1; rankStart0 = (U32 *)workSpace + spaceUsed32; spaceUsed32 += HUF_TABLELOG_MAX + 2; - sortedSymbol = (sortedSymbol_t *)((U32 *)workSpace + spaceUsed32); + sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t); spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; From a3d9926c405d664519089e20884beff0c5970e74 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 14:44:49 -0700 Subject: [PATCH 368/400] compression optimization opportunity switch to single-pass mode directly into output buffer when outputSize >= ZSTD_compressBound(inputSize). Speed gains observed with fullbench (~+15% on level 1) --- lib/common/zstd_internal.h | 1 + lib/compress/zstd_compress.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index b2c7cfcdd..59761b134 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -72,6 +72,7 @@ #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2) # include /* recommended values for ZSTD_DEBUG display levels : + * 1 : no display, enables assert() only * 2 : reserved for currently active debugging path * 3 : events once per object lifetime (CCtx, CDict) * 4 : events once per frame diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f492d92bd..d4c029e90 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2954,6 +2954,8 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, const BYTE* const ip = (const BYTE*) src; size_t fhSize = 0; + DEBUGLOG(5, "ZSTD_compressContinue_internal"); + DEBUGLOG(5, "stage: %u", cctx->stage); if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */ if (frame && (cctx->stage==ZSTDcs_init)) { @@ -3211,9 +3213,9 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 pledgedSrcSize, ZSTD_buffered_policy_e zbuff) { - DEBUGLOG(5, "ZSTD_compressBegin_internal"); - DEBUGLOG(5, "dict ? %s", dict ? "dict" : cdict ? "cdict" : "none"); - DEBUGLOG(5, "dictMode : %u", (U32)dictMode); + DEBUGLOG(4, "ZSTD_compressBegin_internal"); + DEBUGLOG(4, "dict ? %s", dict ? "dict" : cdict ? "cdict" : "none"); + DEBUGLOG(4, "dictMode : %u", (U32)dictMode); /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); assert(!((dict) && (cdict))); /* either dict or cdict, not both */ @@ -3633,7 +3635,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - DEBUGLOG(5, "ZSTD_resetCStream_internal"); + DEBUGLOG(4, "ZSTD_resetCStream_internal"); /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); assert(!((dict) && (cdict))); /* either dict or cdict, not both */ @@ -3766,6 +3768,9 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, return length; } +/** ZSTD_compressStream_generic(): + * internal function for all *compressStream*() variants and *compress_generic() + * @return : hint size for next input */ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input, @@ -3780,7 +3785,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, U32 someMoreWork = 1; /* check expectations */ - DEBUGLOG(5, "ZSTD_compressStream_generic"); + DEBUGLOG(5, "ZSTD_compressStream_generic, order %u", (U32)flushMode); assert(zcs->inBuff != NULL); assert(zcs->inBuffSize>0); assert(zcs->outBuff!= NULL); @@ -3796,6 +3801,20 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, return ERROR(init_missing); case zcss_load: + if ( (flushMode == ZSTD_e_end) + && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip)) + && (zcs->inBuffPos == 0) ) { + /* shortcut to compression pass directly into output buffer */ + size_t const cSize = ZSTD_compressEnd(zcs, + op, oend-op, ip, iend-ip); + DEBUGLOG(4, "ZSTD_compressEnd : %u", (U32)cSize); + if (ZSTD_isError(cSize)) return cSize; + ip = iend; + op += cSize; + zcs->frameEnded = 1; + ZSTD_startNewCompression(zcs); + someMoreWork = 0; break; + } /* complete inBuffer */ { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; size_t const loaded = ZSTD_limitCopy( @@ -3922,8 +3941,8 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, if (input->pos > input->size) return ERROR(GENERIC); assert(cctx!=NULL); + /* transparent initialization stage */ if (cctx->streamStage == zcss_init) { - /* transparent reset */ const void* const prefix = cctx->prefix; size_t const prefixSize = cctx->prefixSize; ZSTD_parameters params = cctx->requestedParams; @@ -3944,6 +3963,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, CHECK_F( ZSTD_resetCStream_internal(cctx, prefix, prefixSize, cctx->dictMode, cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) ); } } + /* compression stage */ #ifdef ZSTD_MULTITHREAD if (cctx->nbThreads > 1) { size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp); @@ -3956,7 +3976,6 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx, } #endif - DEBUGLOG(5, "calling ZSTD_compressStream_generic(%i,...)", endOp); CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) ); DEBUGLOG(5, "completed ZSTD_compress_generic"); return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */ From 104c4d57c1fa7ca6872ad95925a9448bc3d1f1db Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Thu, 29 Jun 2017 15:40:49 -0700 Subject: [PATCH 369/400] Fix bitshift error --- lib/decompress/huf_decompress.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index cbf78e807..68938aebd 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -110,8 +110,8 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - if ((spaceUsed32 >> 2) > wkspSize) - return ERROR(tableLog_tooLarge); + if ((spaceUsed32 << 2) > wkspSize) + return ERROR(tableLog_tooLarge); workSpace = (U32 *)workSpace + spaceUsed32; wkspSize -= (spaceUsed32 << 2); @@ -524,7 +524,7 @@ size_t HUF_readDTableX4_wksp(HUF_DTable* DTable, const void* src, weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; - if ((spaceUsed32 >> 2) > wkspSize) + if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); workSpace = (U32 *)workSpace + spaceUsed32; wkspSize -= (spaceUsed32 << 2); From 70ad6829e751fb542ae5f3534c0c62096bab3ce9 Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Thu, 29 Jun 2017 16:22:32 -0700 Subject: [PATCH 370/400] Delegate HUF_decompress4X_hufOnly to workspace version --- lib/decompress/huf_decompress.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 68938aebd..4343eb6ea 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -962,16 +962,11 @@ size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const } } -size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) +size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { - /* validation checks */ - if (dstSize == 0) return ERROR(dstSize_tooSmall); - if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected); /* invalid */ - - { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize); - return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) : - HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ; - } + U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; + return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize, + workSpace, sizeof(workSpace)); } From afb0aca7392a1407b62edd9f5fc6bef8e7b1a669 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 18:19:09 -0700 Subject: [PATCH 371/400] zstreamtest : big tests are only enabled in 64-bits mode to avoid requesting too much memory in 32-bits mode during MT tests --- Makefile | 12 +++++++++--- tests/zstreamtest.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9afdf658b..ac3034c9b 100644 --- a/Makefile +++ b/Makefile @@ -117,30 +117,36 @@ CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_B list: @$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$' | xargs -.PHONY: install uninstall travis-install clangtest gpptest armtest usan asan uasan +.PHONY: install clangtest gpptest armtest usan asan uasan install: @$(MAKE) -C $(ZSTDDIR) $@ @$(MAKE) -C $(PRGDIR) $@ +.PHONY: uninstall uninstall: @$(MAKE) -C $(ZSTDDIR) $@ @$(MAKE) -C $(PRGDIR) $@ +.PHONY: travis-install travis-install: $(MAKE) install PREFIX=~/install_test_dir +.PHONY: gppbuild gppbuild: clean g++ -v CC=g++ $(MAKE) -C programs all CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror" +.PHONY: gcc5build gcc5build: clean gcc-5 -v CC=gcc-5 $(MAKE) all MOREFLAGS="-Werror" +.PHONY: gcc6build gcc6build: clean gcc-6 -v CC=gcc-6 $(MAKE) all MOREFLAGS="-Werror" +.PHONY: clangbuild clangbuild: clean clang -v CXX=clang++ CC=clang $(MAKE) all MOREFLAGS="-Werror -Wconversion -Wno-sign-conversion -Wdocumentation" @@ -227,7 +233,7 @@ msan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=memory -fno-omit-frame-pointer" HAVE_LZMA=0 # datagen.c fails this test for no obvious reason msan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) HAVE_LZMA=0 $* + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=memory -fno-omit-frame-pointer" FUZZER_FLAGS=--no-big-tests $(MAKE) -C $(TESTDIR) HAVE_LZMA=0 $* asan32: clean $(MAKE) -C $(TESTDIR) test32 CC=clang MOREFLAGS="-g -fsanitize=address" @@ -236,7 +242,7 @@ uasan: clean $(MAKE) test CC=clang MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined" uasan-%: clean - LDFLAGS=-fuse-ld=gold MOREFLAGS="-Og -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined" $(MAKE) -C $(TESTDIR) $* + LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow -fsanitize=address,undefined" $(MAKE) -C $(TESTDIR) $* tsan-%: clean LDFLAGS=-fuse-ld=gold MOREFLAGS="-g -fno-sanitize-recover=all -fsanitize=thread" $(MAKE) -C $(TESTDIR) $* FUZZER_FLAGS=--no-big-tests diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index f16cc4b0a..9b2b8eaf8 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -1540,7 +1540,7 @@ int main(int argc, const char** argv) int proba = FUZ_COMPRESSIBILITY_DEFAULT; int result=0; int mainPause = 0; - int bigTests = 1; + int bigTests = (sizeof(size_t) == 8); e_api selected_api = simple_api; const char* const programName = argv[0]; ZSTD_customMem const customMem = { allocFunction, freeFunction, NULL }; From e7e5a8cef7b6e1ac3bcbb7a25a4401072fd02a36 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 29 Jun 2017 18:56:24 -0700 Subject: [PATCH 372/400] made fullbench compatible with multi-threading fullbench 61/62 measure speed of ZSTD_compress_generic with 2 threads --- tests/Makefile | 10 ++--- tests/fullbench.c | 96 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 34 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index 5c240800f..0b8deec2a 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -94,11 +94,11 @@ zstd-nolegacy: gzstd: $(MAKE) -C $(PRGDIR) $@ -fullbench : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c - $(CC) $(FLAGS) $^ -o $@$(EXT) - -fullbench32 : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c - $(CC) -m32 $(FLAGS) $^ -o $@$(EXT) +fullbench32: CPPFLAGS += -m32 +fullbench fullbench32 : CPPFLAGS += $(MULTITHREAD_CPP) +fullbench fullbench32 : LDFLAGS += $(MULTITHREAD_LD) +fullbench fullbench32 : $(ZSTD_FILES) $(PRGDIR)/datagen.c fullbench.c + $(CC) $(FLAGS) $^ -o $@$(EXT) fullbench-lib: $(PRGDIR)/datagen.c fullbench.c $(MAKE) -C $(ZSTDDIR) libzstd.a diff --git a/tests/fullbench.c b/tests/fullbench.c index 1c1807a5a..176e5a629 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -14,9 +14,8 @@ #include "util.h" /* Compiler options, UTIL_GetFileSize */ #include /* malloc */ #include /* fprintf, fopen, ftello64 */ -#include /* clock_t, clock, CLOCKS_PER_SEC */ -#include "mem.h" +#include "mem.h" /* U32 */ #ifndef ZSTD_DLL_IMPORT #include "zstd_internal.h" /* ZSTD_blockHeaderSize, blockType_e, KB, MB */ #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ @@ -26,7 +25,8 @@ #define GB *(1U<<30) typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; #endif -#include "zstd.h" /* ZSTD_VERSION_STRING */ +#include "zstd.h" /* ZSTD_versionString */ +#include "util.h" /* time functions */ #include "datagen.h" @@ -35,7 +35,7 @@ **************************************/ #define PROGRAM_DESCRIPTION "Zstandard speed analyzer" #define AUTHOR "Yann Collet" -#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_VERSION_STRING, (int)(sizeof(void*)*8), AUTHOR, __DATE__ +#define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, ZSTD_versionString(), (int)(sizeof(void*)*8), AUTHOR, __DATE__ #define NBLOOPS 6 #define TIMELOOP_S 2 @@ -69,12 +69,6 @@ static void BMK_SetNbIterations(U32 nbLoops) /*_******************************************************* * Private functions *********************************************************/ -static clock_t BMK_clockSpan( clock_t clockStart ) -{ - return clock() - clockStart; /* works even if overflow, span limited to <= ~30mn */ -} - - static size_t BMK_findMaxMem(U64 requiredMem) { size_t const step = 64 MB; @@ -186,6 +180,41 @@ static size_t local_ZSTD_compress_generic_continue(void* dst, size_t dstCapacity return buffOut.pos; } +static size_t local_ZSTD_compress_generic_T2_end(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) +{ + ZSTD_outBuffer buffOut; + ZSTD_inBuffer buffIn; + (void)buff2; + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbThreads, 2); + buffOut.dst = dst; + buffOut.size = dstCapacity; + buffOut.pos = 0; + buffIn.src = src; + buffIn.size = srcSize; + buffIn.pos = 0; + while (ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_end)) {} + return buffOut.pos; +} + +static size_t local_ZSTD_compress_generic_T2_continue(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) +{ + ZSTD_outBuffer buffOut; + ZSTD_inBuffer buffIn; + (void)buff2; + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_compressionLevel, 1); + ZSTD_CCtx_setParameter(g_cstream, ZSTD_p_nbThreads, 2); + buffOut.dst = dst; + buffOut.size = dstCapacity; + buffOut.pos = 0; + buffIn.src = src; + buffIn.size = srcSize; + buffIn.pos = 0; + ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_continue); + while(ZSTD_compress_generic(g_cstream, &buffOut, &buffIn, ZSTD_e_end)) {} + return buffOut.pos; +} + static ZSTD_DStream* g_dstream= NULL; static size_t local_ZSTD_decompressStream(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) { @@ -269,39 +298,45 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) switch(benchNb) { case 1: - benchFunction = local_ZSTD_compress; benchName = "ZSTD_compress(1)"; + benchFunction = local_ZSTD_compress; benchName = "compress(1)"; break; case 2: - benchFunction = local_ZSTD_decompress; benchName = "ZSTD_decompress"; + benchFunction = local_ZSTD_decompress; benchName = "decompress"; break; #ifndef ZSTD_DLL_IMPORT case 11: - benchFunction = local_ZSTD_compressContinue; benchName = "ZSTD_compressContinue(1)"; + benchFunction = local_ZSTD_compressContinue; benchName = "compressContinue(1)"; break; case 12: - benchFunction = local_ZSTD_compressContinue_extDict; benchName = "ZSTD_compressContinue_extDict"; + benchFunction = local_ZSTD_compressContinue_extDict; benchName = "compressContinue_extDict"; break; case 13: - benchFunction = local_ZSTD_decompressContinue; benchName = "ZSTD_decompressContinue"; + benchFunction = local_ZSTD_decompressContinue; benchName = "decompressContinue"; break; case 31: - benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "ZSTD_decodeLiteralsBlock"; + benchFunction = local_ZSTD_decodeLiteralsBlock; benchName = "decodeLiteralsBlock"; break; case 32: - benchFunction = local_ZSTD_decodeSeqHeaders; benchName = "ZSTD_decodeSeqHeaders"; + benchFunction = local_ZSTD_decodeSeqHeaders; benchName = "decodeSeqHeaders"; break; #endif case 41: - benchFunction = local_ZSTD_compressStream; benchName = "ZSTD_compressStream(1)"; + benchFunction = local_ZSTD_compressStream; benchName = "compressStream(1)"; break; case 42: - benchFunction = local_ZSTD_decompressStream; benchName = "ZSTD_decompressStream"; + benchFunction = local_ZSTD_decompressStream; benchName = "decompressStream"; break; case 51: - benchFunction = local_ZSTD_compress_generic_continue; benchName = "ZSTD_compress_generic, continue"; + benchFunction = local_ZSTD_compress_generic_continue; benchName = "compress_generic, continue"; break; case 52: - benchFunction = local_ZSTD_compress_generic_end; benchName = "ZSTD_compress_generic, end"; + benchFunction = local_ZSTD_compress_generic_end; benchName = "compress_generic, end"; + break; + case 61: + benchFunction = local_ZSTD_compress_generic_T2_continue; benchName = "compress_generic, -T2, continue"; + break; + case 62: + benchFunction = local_ZSTD_compress_generic_T2_end; benchName = "compress_generic, -T2, end"; break; default : return 0; @@ -389,22 +424,25 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) { size_t i; for (i=0; i %s !! \n", benchName, ZSTD_getErrorName(benchResult)); exit(1); } } - { clock_t const clockTotal = BMK_clockSpan(clockStart); - double const averageTime = (double)clockTotal / CLOCKS_PER_SEC / nbRounds; + { U64 const clockSpanMicro = UTIL_clockSpanMicro(clockStart, ticksPerSecond); + double const averageTime = (double)clockSpanMicro / TIME_SEC_MICROSEC / nbRounds; if (averageTime < bestTime) bestTime = averageTime; DISPLAY("%2i- %-30.30s : %7.1f MB/s (%9u)\r", loopNb, benchName, (double)srcSize / (1 MB) / bestTime, (U32)benchResult); } } } From b5bb7c6d952d4cf1890afde07d55ca286ad2f7dd Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Thu, 29 Jun 2017 19:59:37 -0700 Subject: [PATCH 373/400] fixed Visual compilation of fullbench-dll --- tests/fullbench.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/fullbench.c b/tests/fullbench.c index 176e5a629..0f2873481 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -18,13 +18,13 @@ #include "mem.h" /* U32 */ #ifndef ZSTD_DLL_IMPORT #include "zstd_internal.h" /* ZSTD_blockHeaderSize, blockType_e, KB, MB */ - #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ #else #define KB *(1 <<10) #define MB *(1 <<20) #define GB *(1U<<30) typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e; #endif +#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_compressBegin, ZSTD_compressContinue, etc. */ #include "zstd.h" /* ZSTD_versionString */ #include "util.h" /* time functions */ #include "datagen.h" @@ -110,8 +110,9 @@ size_t local_ZSTD_decompress(void* dst, size_t dstSize, void* buff2, const void* return ZSTD_decompress(dst, dstSize, buff2, g_cSize); } -#ifndef ZSTD_DLL_IMPORT static ZSTD_DCtx* g_zdc = NULL; + +#ifndef ZSTD_DLL_IMPORT extern size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* ctx, const void* src, size_t srcSize); size_t local_ZSTD_decodeLiteralsBlock(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize) { @@ -232,8 +233,9 @@ static size_t local_ZSTD_decompressStream(void* dst, size_t dstCapacity, void* b return buffOut.pos; } -#ifndef ZSTD_DLL_IMPORT static ZSTD_CCtx* g_zcc = NULL; + +#ifndef ZSTD_DLL_IMPORT size_t local_ZSTD_compressContinue(void* dst, size_t dstCapacity, void* buff2, const void* src, size_t srcSize) { (void)buff2; From 28f711ef9513f30c8e20604542f84328b053abcd Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Fri, 30 Jun 2017 09:38:11 -0700 Subject: [PATCH 374/400] Rename ALIGN and ALIGN_MASK to HUF_ALIGN and HUF_ALIGN_MASK --- lib/decompress/huf_decompress.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 4343eb6ea..b9fc4d51e 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -70,8 +70,8 @@ /* ************************************************************** * Byte alignment for workSpace management ****************************************************************/ -#define ALIGN(x, a) ALIGN_MASK((x), (a) - 1) -#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) +#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1) +#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) /*-***************************/ /* generic DTableDesc */ @@ -108,7 +108,7 @@ size_t HUF_readDTableX2_wksp(HUF_DTable* DTable, const void* src, size_t srcSize rankVal = (U32 *)workSpace + spaceUsed32; spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1; huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); @@ -520,9 +520,9 @@ size_t HUF_readDTableX4_wksp(HUF_DTable* DTable, const void* src, rankStart0 = (U32 *)workSpace + spaceUsed32; spaceUsed32 += HUF_TABLELOG_MAX + 2; sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t); - spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; + spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2; weightList = (BYTE *)((U32 *)workSpace + spaceUsed32); - spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; + spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2; if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge); From 4c71f59c775340a267f0c6070cbc4cbab50923cc Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Fri, 30 Jun 2017 09:52:20 -0700 Subject: [PATCH 375/400] Clarify typedef of rankVal_t and rankValCol_t --- lib/decompress/huf_decompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index b9fc4d51e..2a1b70ea5 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -449,8 +449,8 @@ static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 co } } } -typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1]; typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1]; +typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX]; static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog, const sortedSymbol_t* sortedList, const U32 sortedListSize, From b0513b519c81d51565e4ffd6c0856eefb8b03fc0 Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Fri, 30 Jun 2017 12:53:56 -0700 Subject: [PATCH 376/400] Add comment to HUF_DECOMPRESS_WORKSPACE_SIZE --- lib/common/huf.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 801f74c1e..16184e490 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -111,7 +111,16 @@ HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, const void* #define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32)) HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); -/* The workspace must have alignment at least 4 and be at least this large */ +/** + * The minimum workspace size for the `workSpace` used in + * HUF_readDTableX2_wksp() and HUF_readDTableX4_wksp(). + * + * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when + * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. + * Buffer overflow errors may potentially occur if code modifications result in + * a requiredw workspace size greater than that specified in the following + * macro. + */ #define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) #define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32)) From 32df49e9f85f11f961655c70bae85203087db730 Mon Sep 17 00:00:00 2001 From: Stella Lau Date: Fri, 30 Jun 2017 12:56:24 -0700 Subject: [PATCH 377/400] Fix typo --- lib/common/huf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/huf.h b/lib/common/huf.h index 16184e490..dabd35991 100644 --- a/lib/common/huf.h +++ b/lib/common/huf.h @@ -118,7 +118,7 @@ HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15. * Buffer overflow errors may potentially occur if code modifications result in - * a requiredw workspace size greater than that specified in the following + * a required workspace size greater than that specified in the following * macro. */ #define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10) From d5c046c609c77bd2ab8035d7b0e11d2084272a36 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 30 Jun 2017 14:51:01 -0700 Subject: [PATCH 378/400] implemented shortcut for zstd_compress_generic() in MT mode added ZSTDMT_compress_advanced() API --- lib/common/zstd_internal.h | 6 ++ lib/compress/zstd_compress.c | 8 +- lib/compress/zstdmt_compress.c | 146 ++++++++++++++++++++++++++------- lib/compress/zstdmt_compress.h | 8 ++ 4 files changed, 133 insertions(+), 35 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index 59761b134..a0cc938a3 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -333,6 +333,12 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_parameters params, unsigned long long pledgedSrcSize); +/*! ZSTD_initCStream_internal() : + * Private use only. To be called from zstdmt_compress.c in single-thread mode. */ +size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective const flushMode); /*! ZSTD_getParamsFromCDict() : * as the name implies */ diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d4c029e90..f2afe625a 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3771,10 +3771,10 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, /** ZSTD_compressStream_generic(): * internal function for all *compressStream*() variants and *compress_generic() * @return : hint size for next input */ -static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input, - ZSTD_EndDirective const flushMode) +size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective const flushMode) { const char* const istart = (const char*)input->src; const char* const iend = istart + input->size; diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index d5f08c76f..f7ee7502d 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -261,7 +261,7 @@ void ZSTDMT_compressChunk(void* jobDescription) ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription; const void* const src = (const char*)job->srcStart + job->dictSize; buffer_t const dstBuff = job->dstBuff; - DEBUGLOG(4, "job (first:%u) (last:%u) : dictSize %u, srcSize %u", + DEBUGLOG(5, "job (first:%u) (last:%u) : dictSize %u, srcSize %u", job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize); if (job->cdict) { /* should only happen for first segment */ size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize); @@ -285,7 +285,7 @@ void ZSTDMT_compressChunk(void* jobDescription) job->cSize = (job->lastChunk) ? ZSTD_compressEnd (job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize) : ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize); - DEBUGLOG(4, "compressed %u bytes into %u bytes (first:%u) (last:%u)", + DEBUGLOG(5, "compressed %u bytes into %u bytes (first:%u) (last:%u)", (unsigned)job->srcSize, (unsigned)job->cSize, job->firstChunk, job->lastChunk); DEBUGLOG(5, "dstBuff.size : %u ; => %s", (U32)dstBuff.size, ZSTD_getErrorName(job->cSize)); @@ -374,10 +374,11 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads) } /* ZSTDMT_releaseAllJobResources() : - * Ensure all workers are killed first. */ + * note : ensure all workers are killed first ! */ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx) { unsigned jobID; + DEBUGLOG(4, "ZSTDMT_releaseAllJobResources"); for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) { ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[jobID].dstBuff); mtctx->jobs[jobID].dstBuff = g_nullBuffer; @@ -439,14 +440,14 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, /* ===== Multi-threaded compression ===== */ /* ------------------------------------------ */ -size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, +size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, - int compressionLevel) + const ZSTD_CDict* cdict, + ZSTD_parameters const params, + unsigned overlapRLog) { - ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0); - U32 const overlapLog = (compressionLevel >= ZSTD_maxCLevel()) ? 0 : 3; - size_t const overlapSize = (size_t)1 << (params.cParams.windowLog - overlapLog); + size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (params.cParams.windowLog - overlapRLog); size_t const chunkTargetSize = (size_t)1 << (params.cParams.windowLog + 2); unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + 1; unsigned nbChunks = MIN(nbChunksMax, mtctx->nbThreads); @@ -459,11 +460,10 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, DEBUGLOG(4, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize); DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); - params.fParams.contentSizeFlag = 1; if (nbChunks==1) { /* fallback to single-thread mode */ ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0]; - return ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel); + return ZSTD_compress_advanced(cctx, dst, dstCapacity, src, srcSize, NULL, 0, params); } { unsigned u; @@ -485,8 +485,11 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, mtctx->jobs[u].srcStart = srcStart + frameStartPos - dictSize; mtctx->jobs[u].dictSize = dictSize; mtctx->jobs[u].srcSize = chunkSize; + mtctx->jobs[u].cdict = mtctx->nextJobID==0 ? cdict : NULL; mtctx->jobs[u].fullFrameSize = srcSize; mtctx->jobs[u].params = params; + /* do not calculate checksum within sections, but write it in header for first section */ + if (mtctx->nextJobID) mtctx->jobs[u].params.fParams.checksumFlag = 0; mtctx->jobs[u].dstBuff = dstBuffer; mtctx->jobs[u].cctx = cctx; mtctx->jobs[u].firstChunk = (u==0); @@ -495,8 +498,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex; mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond; - DEBUGLOG(4, "posting job %u (%u bytes)", u, (U32)chunkSize); - DEBUG_PRINTHEX(5, mtctx->jobs[u].srcStart, 12); + DEBUGLOG(5, "posting job %u (%u bytes)", u, (U32)chunkSize); + DEBUG_PRINTHEX(6, mtctx->jobs[u].srcStart, 12); POOL_add(mtctx->factory, ZSTDMT_compressChunk, &mtctx->jobs[u]); frameStartPos += chunkSize; @@ -526,8 +529,10 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, if (chunkID) { /* note : chunk 0 is already written directly into dst */ if (!error) memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize); /* may overlap if chunk decompressed within dst */ - if (chunkID >= compressWithinDst) /* otherwise, it decompresses within dst */ + if (chunkID >= compressWithinDst) { /* otherwise, it decompresses within dst */ + DEBUGLOG(5, "releasing buffer %u>=%u", chunkID, compressWithinDst); ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff); + } mtctx->jobs[chunkID].dstBuff = g_nullBuffer; } dstPos += cSize ; @@ -536,7 +541,18 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, if (!error) DEBUGLOG(4, "compressed size : %u ", (U32)dstPos); return error ? error : dstPos; } +} + +size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + int compressionLevel) +{ + U32 const overlapRLog = (compressionLevel >= ZSTD_maxCLevel()) ? 0 : 3; + ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0); + params.fParams.contentSizeFlag = 1; + return ZSTDMT_compress_advanced(mtctx, dst, dstCapacity, src, srcSize, NULL, params, overlapRLog); } @@ -546,6 +562,7 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) { + DEBUGLOG(4, "ZSTDMT_waitForAllJobsCompleted"); while (zcs->doneJobID < zcs->nextJobID) { unsigned const jobID = zcs->doneJobID & zcs->jobIDMask; PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex); @@ -559,17 +576,19 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) } +/** ZSTDMT_initCStream_internal() : + * internal usage only */ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, const void* dict, size_t dictSize, const ZSTD_CDict* cdict, ZSTD_parameters params, unsigned long long pledgedSrcSize) { - DEBUGLOG(5, "ZSTDMT_initCStream_internal"); + DEBUGLOG(4, "ZSTDMT_initCStream_internal"); /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); assert(!((dict) && (cdict))); /* either dict or cdict, not both */ if (zcs->nbThreads==1) { - DEBUGLOG(5, "single thread mode"); + DEBUGLOG(4, "single thread mode"); return ZSTD_initCStream_internal(zcs->cctxPool->cctx[0], dict, dictSize, cdict, params, pledgedSrcSize); @@ -584,6 +603,7 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, zcs->params = params; zcs->frameContentSize = pledgedSrcSize; if (dict) { + DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal); ZSTD_freeCDict(zcs->cdictLocal); zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* byRef */, ZSTD_dm_auto, /* note : a loadPrefix becomes an internal CDict */ @@ -591,18 +611,19 @@ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs, zcs->cdict = zcs->cdictLocal; if (zcs->cdictLocal == NULL) return ERROR(memory_allocation); } else { + DEBUGLOG(4,"cdictLocal: %08X", (U32)(size_t)zcs->cdictLocal); ZSTD_freeCDict(zcs->cdictLocal); zcs->cdictLocal = NULL; zcs->cdict = cdict; } zcs->targetDictSize = (zcs->overlapRLog>=9) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog); - DEBUGLOG(5, "overlapRLog : %u ", zcs->overlapRLog); - DEBUGLOG(5, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); + DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog); + DEBUGLOG(4, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10)); zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2); zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize); zcs->targetSectionSize = MAX(zcs->targetDictSize, zcs->targetSectionSize); - DEBUGLOG(5, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10)); + DEBUGLOG(4, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10)); zcs->marginSize = zcs->targetSectionSize >> 2; zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize; zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize); @@ -797,6 +818,75 @@ static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsi } } +/** ZSTDMT_compressStream_generic() : + * internal use only + * assumption : output and input are valid (pos <= size) + * @return : minimum amount of data remaining to flush, 0 if none */ +size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input, + ZSTD_EndDirective endOp) +{ + size_t const newJobThreshold = mtctx->dictSize + mtctx->targetSectionSize + mtctx->marginSize; + assert(output->pos <= output->size); + assert(input->pos <= input->size); + if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) { + /* current frame being ended. Only flush/end are allowed. Or start new job with init */ + return ERROR(stage_wrong); + } + if (mtctx->nbThreads==1) { + return ZSTD_compressStream_generic(mtctx->cctxPool->cctx[0], output, input, endOp); + } + if ( (mtctx->nextJobID==0) /* just started */ + && (mtctx->inBuff.filled==0) /* nothing buffered yet */ + && (endOp==ZSTD_e_end) /* end order, immediately at beginning */ + && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) /* enough room */ + && (mtctx->cdict==NULL) ) { /* no dictionary */ + size_t const cSize = ZSTDMT_compress_advanced(mtctx, + (char*)output->dst + output->pos, output->size - output->pos, + (const char*)input->src + input->pos, input->size - input->pos, + mtctx->cdict, mtctx->params, mtctx->overlapRLog); + if (ZSTD_isError(cSize)) return cSize; + input->pos = input->size; + output->pos += cSize; + ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->inBuff.buffer); /* was allocated in initStream */ + mtctx->allJobsCompleted = 1; + mtctx->frameEnded = 1; + return 0; + } + + /* fill input buffer */ + { size_t const toLoad = MIN(input->size - input->pos, mtctx->inBuffSize - mtctx->inBuff.filled); + memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, toLoad); + input->pos += toLoad; + mtctx->inBuff.filled += toLoad; + } + + if ( (mtctx->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ + && (mtctx->nextJobID <= mtctx->doneJobID + mtctx->jobIDMask) ) { /* avoid overwriting job round buffer */ + CHECK_F( ZSTDMT_createCompressionJob(mtctx, mtctx->targetSectionSize, 0 /* endFrame */) ); + } + + /* check for potential compressed data ready to be flushed */ + CHECK_F( ZSTDMT_flushNextJob(mtctx, output, (mtctx->inBuff.filled == mtctx->inBuffSize) /* blockToFlush */) ); /* block if it wasn't possible to create new job due to saturation */ + + if (input->pos < input->size) /* input not consumed : do not flush yet */ + endOp = ZSTD_e_continue; + + switch(endOp) + { + case ZSTD_e_flush: + return ZSTDMT_flushStream(mtctx, output); + case ZSTD_e_end: + return ZSTDMT_endStream(mtctx, output); + case ZSTD_e_continue: + return 1; + default: + return ERROR(GENERIC); /* invalid endDirective */ + } +} + + size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) { size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize; @@ -833,21 +923,13 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* outp { size_t const srcSize = zcs->inBuff.filled - zcs->dictSize; - if (srcSize) - DEBUGLOG(5, "ZSTDMT_flushStream_internal : %u bytes left to compress", - (U32)srcSize); if ( ((srcSize > 0) || (endFrame && !zcs->frameEnded)) && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { - DEBUGLOG(5, "create new job with %u bytes to compress", (U32)srcSize); - DEBUGLOG(5, "end order : %u", endFrame); CHECK_F( ZSTDMT_createCompressionJob(zcs, srcSize, endFrame) ); - DEBUGLOG(5, "resulting zcs->frameEnded : %u", zcs->frameEnded); } /* check if there is any data available to flush */ - DEBUGLOG(5, "zcs->doneJobID : %u ; zcs->nextJobID : %u", - zcs->doneJobID, zcs->nextJobID); - return ZSTDMT_flushNextJob(zcs, output, 1 /*blockToFlush */); + return ZSTDMT_flushNextJob(zcs, output, 1 /* blockToFlush */); } @@ -861,22 +943,24 @@ size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) { - DEBUGLOG(5, "ZSTDMT_endStream"); + DEBUGLOG(4, "ZSTDMT_endStream"); if (zcs->nbThreads==1) return ZSTD_endStream(zcs->cctxPool->cctx[0], output); return ZSTDMT_flushStream_internal(zcs, output, 1 /* endFrame */); } -size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, +size_t ZSTDMT_compressStream_generic2(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input, ZSTD_EndDirective endOp) { + DEBUGLOG(5, "ZSTDMT_compressStream_generic"); DEBUGLOG(5, "in: pos:%u / size:%u ; endOp=%u", (U32)input->pos, (U32)input->size, (U32)endOp); - if (input->pos < input->size) /* exclude final flushes */ + if (input->pos < input->size) /* some input to consume */ CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); - if (input->pos < input->size) endOp = ZSTD_e_continue; + if (input->pos < input->size) /* input not consumed : do not flush yet */ + endOp = ZSTD_e_continue; switch(endOp) { case ZSTD_e_flush: diff --git a/lib/compress/zstdmt_compress.h b/lib/compress/zstdmt_compress.h index d36914de5..fad63b6d8 100644 --- a/lib/compress/zstdmt_compress.h +++ b/lib/compress/zstdmt_compress.h @@ -44,6 +44,7 @@ ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx, int compressionLevel); + /* === Streaming functions === */ ZSTDLIB_API size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel); @@ -61,6 +62,13 @@ ZSTDLIB_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); # define ZSTDMT_SECTION_SIZE_MIN (1U << 20) /* 1 MB - Minimum size of each compression job */ #endif +ZSTDLIB_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, + void* dst, size_t dstCapacity, + const void* src, size_t srcSize, + const ZSTD_CDict* cdict, + ZSTD_parameters const params, + unsigned overlapRLog); + ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* dict, size_t dictSize, /* dict can be released after init, a local copy is preserved within zcs */ ZSTD_parameters params, From d8b33a598d9b707732969bd3da02b0fea1b1985c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 30 Jun 2017 15:44:57 -0700 Subject: [PATCH 379/400] Optimized ZSTDMT single-pass mode speed on large sources by ensuring job sizes remain "not too large" --- lib/compress/zstdmt_compress.c | 55 +++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index f7ee7502d..c96ef4825 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -331,14 +331,20 @@ struct ZSTDMT_CCtx_s { const ZSTD_CDict* cdict; }; +static ZSTDMT_jobDescription* ZSTDMT_allocJobsTable(U32* nbJobsPtr, ZSTD_customMem cMem) +{ + U32 const nbJobsLog2 = ZSTD_highbit32(*nbJobsPtr) + 1; + U32 const nbJobs = 1 << nbJobsLog2; + *nbJobsPtr = nbJobs; + return (ZSTDMT_jobDescription*) ZSTD_calloc( + nbJobs * sizeof(ZSTDMT_jobDescription), cMem); +} + ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem) { ZSTDMT_CCtx* mtctx; - U32 const minNbJobs = nbThreads + 2; - U32 const nbJobsLog2 = ZSTD_highbit32(minNbJobs) + 1; - U32 const nbJobs = 1 << nbJobsLog2; - DEBUGLOG(5, "nbThreads: %u ; minNbJobs: %u ; nbJobsLog2: %u ; nbJobs: %u", - nbThreads, minNbJobs, nbJobsLog2, nbJobs); + U32 nbJobs = nbThreads + 2; + DEBUGLOG(3, "ZSTDMT_createCCtx_advanced"); if ((nbThreads < 1) | (nbThreads > ZSTDMT_NBTHREADS_MAX)) return NULL; if ((cMem.customAlloc!=NULL) ^ (cMem.customFree!=NULL)) @@ -349,13 +355,12 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem) if (!mtctx) return NULL; mtctx->cMem = cMem; mtctx->nbThreads = nbThreads; - mtctx->jobIDMask = nbJobs - 1; mtctx->allJobsCompleted = 1; mtctx->sectionSize = 0; mtctx->overlapRLog = 3; mtctx->factory = POOL_create(nbThreads, 1); - mtctx->jobs = (ZSTDMT_jobDescription*)ZSTD_calloc( - nbJobs * sizeof(*mtctx->jobs), cMem); + mtctx->jobs = ZSTDMT_allocJobsTable(&nbJobs, cMem); + mtctx->jobIDMask = nbJobs - 1; mtctx->buffPool = ZSTDMT_createBufferPool(nbThreads, cMem); mtctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads, cMem); if (!mtctx->factory | !mtctx->jobs | !mtctx->buffPool | !mtctx->cctxPool) { @@ -448,24 +453,39 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, unsigned overlapRLog) { size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (params.cParams.windowLog - overlapRLog); - size_t const chunkTargetSize = (size_t)1 << (params.cParams.windowLog + 2); - unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + 1; - unsigned nbChunks = MIN(nbChunksMax, mtctx->nbThreads); + size_t const chunkSizeTarget = (size_t)1 << (params.cParams.windowLog + 2); + size_t const chunkMaxSize = chunkSizeTarget << 2; + size_t const passSizeMax = chunkMaxSize * mtctx->nbThreads; + unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1; + unsigned nbChunksLarge = multiplier * mtctx->nbThreads; + unsigned const nbChunksMax = (unsigned)(srcSize / chunkSizeTarget) + 1; + unsigned nbChunksSmall = MIN(nbChunksMax, mtctx->nbThreads); + unsigned nbChunks = (multiplier>1) ? nbChunksLarge : nbChunksSmall; size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks; - size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0xFFFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */ - size_t remainingSrcSize = srcSize; + size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */ const char* const srcStart = (const char*)src; + size_t remainingSrcSize = srcSize; unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */ size_t frameStartPos = 0, dstBufferPos = 0; - DEBUGLOG(4, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize); + DEBUGLOG(4, "windowLog : %2u => chunkSizeTarget : %u bytes ", params.cParams.windowLog, (U32)chunkSizeTarget); DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); + assert(avgChunkSize >= 256 KB); /* required for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B) */ if (nbChunks==1) { /* fallback to single-thread mode */ ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0]; return ZSTD_compress_advanced(cctx, dst, dstCapacity, src, srcSize, NULL, 0, params); } + if (nbChunks > mtctx->jobIDMask+1) { /* enlarge job table */ + U32 nbJobs = nbChunks; + ZSTD_free(mtctx->jobs, mtctx->cMem); + mtctx->jobIDMask = 0; + mtctx->jobs = ZSTDMT_allocJobsTable(&nbJobs, mtctx->cMem); + if (mtctx->jobs==NULL) return ERROR(memory_allocation); + mtctx->jobIDMask = nbJobs - 1; + } + { unsigned u; for (u=0; ujobs[u].fullFrameSize = srcSize; mtctx->jobs[u].params = params; /* do not calculate checksum within sections, but write it in header for first section */ - if (mtctx->nextJobID) mtctx->jobs[u].params.fParams.checksumFlag = 0; + if (u!=0) mtctx->jobs[u].params.fParams.checksumFlag = 0; mtctx->jobs[u].dstBuff = dstBuffer; mtctx->jobs[u].cctx = cctx; mtctx->jobs[u].firstChunk = (u==0); @@ -837,11 +857,12 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, if (mtctx->nbThreads==1) { return ZSTD_compressStream_generic(mtctx->cctxPool->cctx[0], output, input, endOp); } + + /* single-pass shortcut (note : this is blocking-mode) */ if ( (mtctx->nextJobID==0) /* just started */ && (mtctx->inBuff.filled==0) /* nothing buffered yet */ && (endOp==ZSTD_e_end) /* end order, immediately at beginning */ - && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) /* enough room */ - && (mtctx->cdict==NULL) ) { /* no dictionary */ + && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough room */ size_t const cSize = ZSTDMT_compress_advanced(mtctx, (char*)output->dst + output->pos, output->size - output->pos, (const char*)input->src + input->pos, input->size - input->pos, From 58bd0e70fc83b1e519ea41b264fe2bfab8e43348 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Fri, 30 Jun 2017 16:01:02 -0700 Subject: [PATCH 380/400] fixed : dictionary compression with new advanced API in Multi-threading mode --- lib/compress/zstdmt_compress.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index c96ef4825..38f8af2e7 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -474,6 +474,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, if (nbChunks==1) { /* fallback to single-thread mode */ ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0]; + if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, params.fParams); return ZSTD_compress_advanced(cctx, dst, dstCapacity, src, srcSize, NULL, 0, params); } From 56e3964d8589aee1b7f27e3ced5bd9a175327f0c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 30 Jun 2017 16:29:37 -0700 Subject: [PATCH 381/400] [man] Specify that strategies start at 1 --- programs/zstd.1 | 6 +++++- programs/zstd.1.md | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/programs/zstd.1 b/programs/zstd.1 index 7e2e99159..5df45db21 100644 --- a/programs/zstd.1 +++ b/programs/zstd.1 @@ -89,6 +89,10 @@ Benchmark file(s) using compression level # \fB\-\-train FILEs\fR Use FILEs as a training set to create a dictionary\. The training set should contain a lot of small files (> 100)\. . +.TP +\fB\-l\fR, \fB\-\-list\fR +Display information related to a zstd compressed file, such as size, ratio, and checksum\. Some of these fields may not be available\. This command can be augmented with the \fB\-v\fR modifier\. +. .SS "Operation modifiers" . .TP @@ -252,7 +256,7 @@ set process priority to real\-time Specify a strategy used by a match finder\. . .IP -There are 8 strategies numbered from 0 to 7, from faster to stronger: 0=ZSTD_fast, 1=ZSTD_dfast, 2=ZSTD_greedy, 3=ZSTD_lazy, 4=ZSTD_lazy2, 5=ZSTD_btlazy2, 6=ZSTD_btopt, 7=ZSTD_btultra\. +There are 8 strategies numbered from 1 to 8, from faster to stronger: 1=ZSTD_fast, 2=ZSTD_dfast, 3=ZSTD_greedy, 4=ZSTD_lazy, 5=ZSTD_lazy2, 6=ZSTD_btlazy2, 7=ZSTD_btopt, 8=ZSTD_btultra\. . .TP \fBwindowLog\fR=\fIwlog\fR, \fBwlog\fR=\fIwlog\fR diff --git a/programs/zstd.1.md b/programs/zstd.1.md index d68efe764..24e25a2f3 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -96,7 +96,7 @@ the last one takes effect. * `-l`, `--list`: Display information related to a zstd compressed file, such as size, ratio, and checksum. Some of these fields may not be available. - This command can be augmented with the `-v` modifier. + This command can be augmented with the `-v` modifier. ### Operation modifiers @@ -254,7 +254,7 @@ The list of available _options_: - `strategy`=_strat_, `strat`=_strat_: Specify a strategy used by a match finder. - There are 8 strategies numbered from 0 to 7, from faster to stronger: + There are 8 strategies numbered from 1 to 8, from faster to stronger: 1=ZSTD\_fast, 2=ZSTD\_dfast, 3=ZSTD\_greedy, 4=ZSTD\_lazy, 5=ZSTD\_lazy2, 6=ZSTD\_btlazy2, 7=ZSTD\_btopt, 8=ZSTD\_btultra. From 88481e40520b0c764b0f6513d0c650065e501733 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 30 Jun 2017 16:31:11 -0700 Subject: [PATCH 382/400] [pzstd] Remove appveyor tests The appveyor tests sometimes hang, and pzstd is now deprecated in favor of zstdmt, so delete the tests. --- appveyor.yml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1f8b8cf8a..1815563e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,12 +30,6 @@ SCRIPT: "" TEST: "cmake" - - COMPILER: "gcc" - HOST: "mingw" - PLATFORM: "x64" - SCRIPT: "" - TEST: "pzstd" - - COMPILER: "visual" HOST: "visual" PLATFORM: "x64" @@ -157,13 +151,6 @@ cd ..\..\.. && make clean ) - - if [%TEST%]==[pzstd] ( - make -C contrib\pzstd googletest-mingw64 && - make -C contrib\pzstd pzstd.exe && - make -C contrib\pzstd tests && - make -C contrib\pzstd check && - make -C contrib\pzstd clean - ) - SET "FUZZERTEST=-T30s" - if [%HOST%]==[visual] if [%CONFIGURATION%]==[Release] ( CD tests && From 4be7f0d45c6886f2fb8ca2bc4ca56186665e283c Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Thu, 29 Jun 2017 16:53:52 -0700 Subject: [PATCH 383/400] [fuzz] Add libFuzzer targets * The regression driver serves both as a regression test, and as a binary for afl-fuzz. * Next, we want to check in a seed corpus for each target. Then we can run the regression test binary on them on Travis or Circle CI. --- fuzz/Makefile | 108 +++++++++++++++++++++++++++ fuzz/README.md | 34 +++++++++ fuzz/fuzz.h | 52 +++++++++++++ fuzz/fuzz_helpers.h | 70 ++++++++++++++++++ fuzz/regression_driver.c | 69 ++++++++++++++++++ fuzz/simple_decompress.c | 46 ++++++++++++ fuzz/simple_round_trip.c | 81 +++++++++++++++++++++ fuzz/stream_decompress.c | 85 ++++++++++++++++++++++ fuzz/stream_round_trip.c | 153 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 698 insertions(+) create mode 100644 fuzz/Makefile create mode 100644 fuzz/README.md create mode 100644 fuzz/fuzz.h create mode 100644 fuzz/fuzz_helpers.h create mode 100644 fuzz/regression_driver.c create mode 100644 fuzz/simple_decompress.c create mode 100644 fuzz/simple_round_trip.c create mode 100644 fuzz/stream_decompress.c create mode 100644 fuzz/stream_round_trip.c diff --git a/fuzz/Makefile b/fuzz/Makefile new file mode 100644 index 000000000..9b084fd3b --- /dev/null +++ b/fuzz/Makefile @@ -0,0 +1,108 @@ +# ########################################################################## +# Copyright (c) 2016-present, Facebook, Inc. +# All rights reserved. +# +# This Makefile is validated for Linux, and macOS targets +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. +# ########################################################################## + +CFLAGS ?= -O3 +CXXFLAGS ?= -O3 + +ZSTDDIR = ../lib +PRGDIR = ../programs + +FUZZ_CPPFLAGS := -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ + -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ + -DZSTD_DEBUG=1 -DMEM_FORCE_MEMORY_ACCESS=0 \ + -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION $(CPPFLAGS) +FUZZ_CFLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum -Wdeclaration-after-statement \ + -Wstrict-prototypes -Wundef -Wformat-security \ + -Wvla -Wformat=2 -Winit-self -Wfloat-equal -Wwrite-strings \ + -Wredundant-decls \ + -g -fno-omit-frame-pointer $(CFLAGS) +FUZZ_CXXFLAGS := -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \ + -Wstrict-aliasing=1 -Wswitch-enum \ + -Wdeclaration-after-statement -Wstrict-prototypes -Wundef \ + -Wformat-security -Wvla -Wformat=2 -Winit-self -Wfloat-equal \ + -Wwrite-strings -Wredundant-decls \ + -g -fno-omit-frame-pointer -std=c++11 $(CXXFLAGS) +FUZZ_LDFLAGS := $(LDFLAGS) +FUZZ_ARFLAGS := $(ARFLAGS) +FUZZ_TARGET_FLAGS = $(FUZZ_CPPFLAGS) $(FUZZ_CXXFLAGS) $(FUZZ_LDFLAGS) + +FUZZ_HEADERS := fuzz_helpers.h fuzz.h + +ZSTDCOMMON_FILES := $(ZSTDDIR)/common/*.c +ZSTDCOMP_FILES := $(ZSTDDIR)/compress/*.c +ZSTDDECOMP_FILES := $(ZSTDDIR)/decompress/*.c +ZSTD_FILES := $(ZSTDDECOMP_FILES) $(ZSTDCOMMON_FILES) $(ZSTDCOMP_FILES) + +ZSTD_OBJ := $(patsubst %.c,%.o, $(wildcard $(ZSTD_FILES))) + +LIBFUZZER ?= -lFuzzer + +.PHONY: default all clean + +default: all + +all: round_trip simple_decompress + +%.o: %.c + $(CC) $(FUZZ_CPPFLAGS) $(FUZZ_CFLAGS) $^ -c -o $@ + +simple_round_trip: $(FUZZ_HEADERS) $(ZSTD_OBJ) simple_round_trip.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(ZSTD_OBJ) simple_round_trip.o $(LIBFUZZER) -o $@ + +stream_round_trip: $(FUZZ_HEADERS) $(ZSTD_OBJ) stream_round_trip.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(ZSTD_OBJ) stream_round_trip.o $(LIBFUZZER) -o $@ + +simple_decompress: $(FUZZ_HEADERS) $(ZSTD_OBJ) simple_decompress.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(ZSTD_OBJ) simple_decompress.o $(LIBFUZZER) -o $@ + +stream_decompress: $(FUZZ_HEADERS) $(ZSTD_OBJ) stream_decompress.o + $(CXX) $(FUZZ_TARGET_FLAGS) $(ZSTD_OBJ) stream_decompress.o $(LIBFUZZER) -o $@ + +libregression.a: $(FUZZ_HEADERS) $(PRGDIR)/util.h regression_driver.o + $(AR) $(FUZZ_ARFLAGS) $@ regression_driver.o + +%-regression: libregression.a + $(RM) $* + $(MAKE) $* LDFLAGS="$(FUZZ_LDFLAGS) -L." LIBFUZZER=-lregression + +%-regression-test: %-regression + ./$* corpora/$* + +regression-test: \ + simple_round_trip-regression-test \ + stream_round_trip-regression-test \ + simple_decompress-regression-test \ + stream_decompress-regression-test + +%-msan: clean + $(MAKE) $* CFLAGS="-fsanitize=memory $(FUZZ_CFLAGS)" \ + CXXFLAGS="-fsanitize=memory $(FUZZ_CXXFLAGS)" + +UASAN_FLAGS := -fsanitize=address,undefined -fno-sanitize-recover=undefined \ + -fno-sanitize=pointer-overflow +%-uasan: clean + $(MAKE) $* CFLAGS="$(FUZZ_CFLAGS) $(UASAN_FLAGS)" \ + CXXFLAGS="$(FUZZ_CXXFLAGS) $(UASAN_FLAGS)" + +# Install libfuzzer (not usable for MSAN testing) +# Provided for convienence. To use this library run make libFuzzer and +# set LDFLAGS=-L. +.PHONY: libFuzzer +libFuzzer: + @$(RM) -rf Fuzzer + @git clone https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer + @./Fuzzer/build.sh + +clean: + @$(MAKE) -C $(ZSTDDIR) clean + @$(RM) -f *.a *.o + @$(RM) -f simple_round_trip stream_round_trip simple_decompress stream_decompress diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 000000000..38a4f3d1a --- /dev/null +++ b/fuzz/README.md @@ -0,0 +1,34 @@ +# Fuzzing + +Each fuzzing target can be built with multiple engines. + +## LibFuzzer + +You can install `libFuzzer` with `make libFuzzer`. Then you can make each target +with `make target LDFLAGS=-L. CC=clang CXX=clang++`. + +## AFL + +The regression driver also serves as a binary for `afl-fuzz`. You can make each +target with one of these commands: + +``` +make target-regression CC=afl-clang CXX=afl-clang++ +AFL_MSAN=1 make target-regression-msan CC=afl-clang CXX=afl-clang++ +AFL_ASAN=1 make target-regression-uasan CC=afl-clang CXX=afl-clang++ +``` + +Then run as `./target @@`. + +## Regression Testing + +Each fuzz target has a corpus checked into the repo under `fuzz/corpora/`. +You can run regression tests on the corpora to ensure that inputs which +previously exposed bugs still pass. You can make these targets to run the +regression tests with different sanitizers. + +``` +make regression-test +make regression-test-msan +make regression-test-uasan +``` diff --git a/fuzz/fuzz.h b/fuzz/fuzz.h new file mode 100644 index 000000000..5b71aba89 --- /dev/null +++ b/fuzz/fuzz.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * Fuzz target interface. + * Fuzz targets have some common parameters passed as macros during compilation. + * Check the documentation for each individual fuzzer for more parameters. + * + * @param STATEFULL_FUZZING: + * Define this to reuse state between fuzzer runs. This can be useful to + * test code paths which are only executed when contexts are reused. + * WARNING: Makes reproducing crashes much harder. + * Default: Not defined. + * @param FUZZ_RNG_SEED_SIZE: + * The number of bytes of the source to look at when constructing a seed + * for the deterministic RNG. + * Default: 128. + * @param ZSTD_DEBUG: + * This is a parameter for the zstd library. Defining `ZSTD_DEBUG=1` + * enables assert() statements in the zstd library. Higher levels enable + * logging, so aren't recommended. Defining `ZSTD_DEBUG=1` is + * recommended. + * @param MEM_FORCE_MEMORY_ACCESS: + * This flag controls how the zstd library accesses unaligned memory. + * It can be undefined, or 0 through 2. If it is undefined, it selects + * the method to use based on the compiler. If testing with UBSAN set + * MEM_FORCE_MEMORY_ACCESS=0 to use the standard compliant method. + * @param FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + * This is the canonical flag to enable deterministic builds for fuzzing. + * Changes to zstd for fuzzing are gated behind this define. + * It is recommended to define this when building zstd for fuzzing. + */ + +#ifndef FUZZ_H +#define FUZZ_H + +#ifndef FUZZ_RNG_SEED_SIZE +# define FUZZ_RNG_SEED_SIZE 128 +#endif + +#include +#include + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size); + +#endif diff --git a/fuzz/fuzz_helpers.h b/fuzz/fuzz_helpers.h new file mode 100644 index 000000000..5f07fa4de --- /dev/null +++ b/fuzz/fuzz_helpers.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * Helper functions for fuzzing. + */ + +#ifndef FUZZ_HELPERS_H +#define FUZZ_HELPERS_H + +#include "fuzz.h" +#include "xxhash.h" +#include +#include + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define FUZZ_QUOTE_IMPL(str) #str +#define FUZZ_QUOTE(str) FUZZ_QUOTE_IMPL(str) + +/** + * Asserts for fuzzing that are always enabled. + */ +#define FUZZ_ASSERT_MSG(cond, msg) \ + ((cond) ? (void)0 \ + : (fprintf(stderr, "%s: %u: Assertion: `%s' failed. %s\n", __FILE__, \ + __LINE__, FUZZ_QUOTE(cond), (msg)), \ + abort())) +#define FUZZ_ASSERT(cond) FUZZ_ASSERT_MSG((cond), ""); + +#if defined(__GNUC__) +#define FUZZ_STATIC static __inline __attribute__((unused)) +#elif defined(__cplusplus) || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +#define FUZZ_STATIC static inline +#elif defined(_MSC_VER) +#define FUZZ_STATIC static __inline +#else +#define FUZZ_STATIC static +#endif + +/** + * Determininistically constructs a seed based on the fuzz input. + * Only looks at the first FUZZ_RNG_SEED_SIZE bytes of the input. + */ +FUZZ_STATIC uint32_t FUZZ_seed(const uint8_t *src, size_t size) { + size_t const toHash = MIN(FUZZ_RNG_SEED_SIZE, size); + return XXH32(src, toHash, 0); +} + +#define FUZZ_rotl32(x, r) (((x) << (r)) | ((x) >> (32 - (r)))) +FUZZ_STATIC uint32_t FUZZ_rand(uint32_t *state) { + static const uint32_t prime1 = 2654435761U; + static const uint32_t prime2 = 2246822519U; + uint32_t rand32 = *state; + rand32 *= prime1; + rand32 += prime2; + rand32 = FUZZ_rotl32(rand32, 13); + *state = rand32; + return rand32 >> 5; +} + +#endif diff --git a/fuzz/regression_driver.c b/fuzz/regression_driver.c new file mode 100644 index 000000000..eee5f0a2a --- /dev/null +++ b/fuzz/regression_driver.c @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include "fuzz.h" +#include "fuzz_helpers.h" +#include "util.h" +#include +#include +#include +#include + +int main(int argc, char const **argv) { + size_t const kMaxFileSize = (size_t)1 << 20; + int const kFollowLinks = 1; + char *fileNamesBuf = NULL; + char const **files = argv + 1; + unsigned numFiles = argc - 1; + uint8_t *buffer = NULL; + size_t bufferSize = 0; + unsigned i; + int ret; + +#ifdef UTIL_HAS_CREATEFILELIST + files = UTIL_createFileList(files, numFiles, &fileNamesBuf, &numFiles, + kFollowLinks); + FUZZ_ASSERT(files); +#endif + + for (i = 0; i < numFiles; ++i) { + char const *fileName = files[i]; + size_t const fileSize = UTIL_getFileSize(fileName); + size_t readSize; + FILE *file; + + /* Check that it is a regular file, and that the fileSize is valid */ + FUZZ_ASSERT_MSG(UTIL_isRegFile(fileName), fileName); + FUZZ_ASSERT_MSG(fileSize <= kMaxFileSize, fileName); + /* Ensure we have a large enough buffer allocated */ + if (fileSize > bufferSize) { + free(buffer); + buffer = (uint8_t *)malloc(fileSize); + FUZZ_ASSERT_MSG(buffer, fileName); + bufferSize = fileSize; + } + /* Open the file */ + file = fopen(fileName, "rb"); + FUZZ_ASSERT_MSG(file, fileName); + /* Read the file */ + readSize = fread(buffer, 1, fileSize, file); + FUZZ_ASSERT_MSG(readSize == fileSize, fileName); + /* Close the file */ + fclose(file); + /* Run the fuzz target */ + LLVMFuzzerTestOneInput(buffer, fileSize); + } + + ret = 0; + free(buffer); +#ifdef UTIL_HAS_CREATEFILELIST + UTIL_freeFileList(files, fileNamesBuf); +#endif + return ret; +} diff --git a/fuzz/simple_decompress.c b/fuzz/simple_decompress.c new file mode 100644 index 000000000..c22ad7c53 --- /dev/null +++ b/fuzz/simple_decompress.c @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * This fuzz target attempts to decompress the fuzzed data with the simple + * decompression function to ensure the decompressor never crashes. + */ + +#include +#include +#include +#include "fuzz_helpers.h" +#include "zstd.h" + +static ZSTD_DCtx *dctx = NULL; +static void* rBuf = NULL; +static size_t bufSize = 0; + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + size_t const neededBufSize = MAX(20 * size, (size_t)256 << 10); + + /* Allocate all buffers and contexts if not already allocated */ + if (neededBufSize > bufSize) { + free(rBuf); + rBuf = malloc(neededBufSize); + bufSize = neededBufSize; + FUZZ_ASSERT(rBuf); + } + if (!dctx) { + dctx = ZSTD_createDCtx(); + FUZZ_ASSERT(dctx); + } + ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, src, size); + +#ifndef STATEFULL_FUZZING + ZSTD_freeDCtx(dctx); dctx = NULL; +#endif + return 0; +} diff --git a/fuzz/simple_round_trip.c b/fuzz/simple_round_trip.c new file mode 100644 index 000000000..703ea5826 --- /dev/null +++ b/fuzz/simple_round_trip.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * This fuzz target performs a zstd round-trip test (compress & decompress), + * compares the result with the original, and calls abort() on corruption. + */ + +#include +#include +#include +#include +#include "fuzz_helpers.h" +#include "zstd.h" + +static const int kMaxClevel = 19; + +static ZSTD_CCtx *cctx = NULL; +static ZSTD_DCtx *dctx = NULL; +static void* cBuf = NULL; +static void* rBuf = NULL; +static size_t bufSize = 0; +static uint32_t seed; + +static size_t roundTripTest(void *result, size_t resultCapacity, + void *compressed, size_t compressedCapacity, + const void *src, size_t srcSize) +{ + int const cLevel = FUZZ_rand(&seed) % kMaxClevel; + size_t const cSize = ZSTD_compressCCtx(cctx, compressed, compressedCapacity, + src, srcSize, cLevel); + if (ZSTD_isError(cSize)) { + fprintf(stderr, "Compression error: %s\n", ZSTD_getErrorName(cSize)); + return cSize; + } + return ZSTD_decompressDCtx(dctx, result, resultCapacity, compressed, cSize); +} + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + size_t const neededBufSize = ZSTD_compressBound(size); + + seed = FUZZ_seed(src, size); + + /* Allocate all buffers and contexts if not already allocated */ + if (neededBufSize > bufSize) { + free(cBuf); + free(rBuf); + cBuf = malloc(neededBufSize); + rBuf = malloc(neededBufSize); + bufSize = neededBufSize; + FUZZ_ASSERT(cBuf && rBuf); + } + if (!cctx) { + cctx = ZSTD_createCCtx(); + FUZZ_ASSERT(cctx); + } + if (!dctx) { + dctx = ZSTD_createDCtx(); + FUZZ_ASSERT(dctx); + } + + { + size_t const result = + roundTripTest(rBuf, neededBufSize, cBuf, neededBufSize, src, size); + FUZZ_ASSERT_MSG(!ZSTD_isError(result), ZSTD_getErrorName(result)); + FUZZ_ASSERT_MSG(result == size, "Incorrect regenerated size"); + FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); + } +#ifndef STATEFULL_FUZZING + ZSTD_freeCCtx(cctx); cctx = NULL; + ZSTD_freeDCtx(dctx); dctx = NULL; +#endif + return 0; +} diff --git a/fuzz/stream_decompress.c b/fuzz/stream_decompress.c new file mode 100644 index 000000000..778a426de --- /dev/null +++ b/fuzz/stream_decompress.c @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * This fuzz target attempts to decompress the fuzzed data with the simple + * decompression function to ensure the decompressor never crashes. + */ + +#define ZSTD_STATIC_LINKING_ONLY + +#include +#include +#include +#include "fuzz_helpers.h" +#include "zstd.h" + +static size_t const kBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX; + +static ZSTD_DStream *dstream = NULL; +static void* buf = NULL; +uint32_t seed; + +static ZSTD_outBuffer makeOutBuffer(void) +{ + ZSTD_outBuffer buffer = { buf, 0, 0 }; + + buffer.size = (FUZZ_rand(&seed) % kBufSize) + 1; + FUZZ_ASSERT(buffer.size <= kBufSize); + + return buffer; +} + +static ZSTD_inBuffer makeInBuffer(const uint8_t **src, size_t *size) +{ + ZSTD_inBuffer buffer = { *src, 0, 0 }; + + FUZZ_ASSERT(*size > 0); + buffer.size = (FUZZ_rand(&seed) % *size) + 1; + FUZZ_ASSERT(buffer.size <= *size); + *src += buffer.size; + *size -= buffer.size; + + return buffer; +} + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + seed = FUZZ_seed(src, size); + + /* Allocate all buffers and contexts if not already allocated */ + if (!buf) { + buf = malloc(kBufSize); + FUZZ_ASSERT(buf); + } + + if (!dstream) { + dstream = ZSTD_createDStream(); + FUZZ_ASSERT(dstream); + FUZZ_ASSERT(!ZSTD_isError(ZSTD_initDStream(dstream))); + } else { + FUZZ_ASSERT(!ZSTD_isError(ZSTD_resetDStream(dstream))); + } + + while (size > 0) { + ZSTD_inBuffer in = makeInBuffer(&src, &size); + while (in.pos != in.size) { + ZSTD_outBuffer out = makeOutBuffer(); + size_t const rc = ZSTD_decompressStream(dstream, &out, &in); + if (ZSTD_isError(rc)) goto error; + if (rc == 0) FUZZ_ASSERT(!ZSTD_isError(ZSTD_resetDStream(dstream))); + } + } + +error: +#ifndef STATEFULL_FUZZING + ZSTD_freeDStream(dstream); dstream = NULL; +#endif + return 0; +} diff --git a/fuzz/stream_round_trip.c b/fuzz/stream_round_trip.c new file mode 100644 index 000000000..17c7dfdd2 --- /dev/null +++ b/fuzz/stream_round_trip.c @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +/** + * This fuzz target performs a zstd round-trip test (compress & decompress), + * compares the result with the original, and calls abort() on corruption. + */ + +#include +#include +#include +#include +#include "fuzz_helpers.h" +#include "zstd.h" + +static const int kMaxClevel = 19; + +static ZSTD_CStream *cstream = NULL; +static ZSTD_DCtx *dctx = NULL; +static uint8_t* cBuf = NULL; +static uint8_t* rBuf = NULL; +static size_t bufSize = 0; +static uint32_t seed; + +static ZSTD_outBuffer makeOutBuffer(uint8_t *dst, size_t capacity) +{ + ZSTD_outBuffer buffer = { dst, 0, 0 }; + + FUZZ_ASSERT(capacity > 0); + buffer.size = (FUZZ_rand(&seed) % capacity) + 1; + FUZZ_ASSERT(buffer.size <= capacity); + + return buffer; +} + +static ZSTD_inBuffer makeInBuffer(const uint8_t **src, size_t *size) +{ + ZSTD_inBuffer buffer = { *src, 0, 0 }; + + FUZZ_ASSERT(*size > 0); + buffer.size = (FUZZ_rand(&seed) % *size) + 1; + FUZZ_ASSERT(buffer.size <= *size); + *src += buffer.size; + *size -= buffer.size; + + return buffer; +} + +static size_t compress(uint8_t *dst, size_t capacity, + const uint8_t *src, size_t srcSize) +{ + int cLevel = FUZZ_rand(&seed) % kMaxClevel; + size_t dstSize = 0; + FUZZ_ASSERT(!ZSTD_isError(ZSTD_initCStream(cstream, cLevel))); + + while (srcSize > 0) { + ZSTD_inBuffer in = makeInBuffer(&src, &srcSize); + /* Mode controls the action. If mode == -1 we pick a new mode */ + int mode = -1; + while (in.pos < in.size) { + ZSTD_outBuffer out = makeOutBuffer(dst, capacity); + /* Previous action finished, pick a new mode. */ + if (mode == -1) mode = FUZZ_rand(&seed) % 10; + switch (mode) { + case 0: /* fall-though */ + case 1: /* fall-though */ + case 2: { + size_t const ret = ZSTD_flushStream(cstream, &out); + FUZZ_ASSERT_MSG(!ZSTD_isError(ret), ZSTD_getErrorName(ret)); + if (ret == 0) mode = -1; + break; + } + case 3: { + size_t ret = ZSTD_endStream(cstream, &out); + FUZZ_ASSERT_MSG(!ZSTD_isError(ret), ZSTD_getErrorName(ret)); + /* Reset the compressor when the frame is finished */ + if (ret == 0) { + cLevel = FUZZ_rand(&seed) % kMaxClevel; + ret = ZSTD_initCStream(cstream, cLevel); + FUZZ_ASSERT(!ZSTD_isError(ret)); + mode = -1; + } + break; + } + default: { + size_t const ret = ZSTD_compressStream(cstream, &out, &in); + FUZZ_ASSERT_MSG(!ZSTD_isError(ret), ZSTD_getErrorName(ret)); + mode = -1; + } + } + dst += out.pos; + dstSize += out.pos; + capacity -= out.pos; + } + } + for (;;) { + ZSTD_outBuffer out = makeOutBuffer(dst, capacity); + size_t const ret = ZSTD_endStream(cstream, &out); + FUZZ_ASSERT_MSG(!ZSTD_isError(ret), ZSTD_getErrorName(ret)); + + dst += out.pos; + dstSize += out.pos; + capacity -= out.pos; + if (ret == 0) break; + } + return dstSize; +} + +int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) +{ + size_t const neededBufSize = ZSTD_compressBound(size) * 2; + + seed = FUZZ_seed(src, size); + + /* Allocate all buffers and contexts if not already allocated */ + if (neededBufSize > bufSize) { + free(cBuf); + free(rBuf); + cBuf = (uint8_t*)malloc(neededBufSize); + rBuf = (uint8_t*)malloc(neededBufSize); + bufSize = neededBufSize; + FUZZ_ASSERT(cBuf && rBuf); + } + if (!cstream) { + cstream = ZSTD_createCStream(); + FUZZ_ASSERT(cstream); + } + if (!dctx) { + dctx = ZSTD_createDCtx(); + FUZZ_ASSERT(dctx); + } + + { + size_t const cSize = compress(cBuf, neededBufSize, src, size); + size_t const rSize = + ZSTD_decompressDCtx(dctx, rBuf, neededBufSize, cBuf, cSize); + FUZZ_ASSERT_MSG(!ZSTD_isError(rSize), ZSTD_getErrorName(rSize)); + FUZZ_ASSERT_MSG(rSize == size, "Incorrect regenerated size"); + FUZZ_ASSERT_MSG(!memcmp(src, rBuf, size), "Corruption!"); + } + +#ifndef STATEFULL_FUZZING + ZSTD_freeCStream(cstream); cstream = NULL; + ZSTD_freeDCtx(dctx); dctx = NULL; +#endif + return 0; +} From 1bafe393e4e185404a1b29155b6bbaf66371c2d7 Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Sat, 1 Jul 2017 06:59:24 -0700 Subject: [PATCH 384/400] fix : ZSTDMT_compressStream_generic() can accept NULL input also : converge implementations towards new version of ZSTDMT_compressStream_generic() --- lib/compress/zstdmt_compress.c | 56 +++------------------------------- 1 file changed, 4 insertions(+), 52 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 38f8af2e7..c203bf337 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -50,7 +50,7 @@ static unsigned long long GetCurrentClockTimeMicroseconds(void) return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond); } } -#define MUTEX_WAIT_TIME_DLEVEL 5 +#define MUTEX_WAIT_TIME_DLEVEL 6 #define PTHREAD_MUTEX_LOCK(mutex) { \ if (ZSTD_DEBUG>=MUTEX_WAIT_TIME_DLEVEL) { \ unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \ @@ -878,7 +878,8 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, } /* fill input buffer */ - { size_t const toLoad = MIN(input->size - input->pos, mtctx->inBuffSize - mtctx->inBuff.filled); + if (input->src) { /* support NULL input */ + size_t const toLoad = MIN(input->size - input->pos, mtctx->inBuffSize - mtctx->inBuff.filled); memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, toLoad); input->pos += toLoad; mtctx->inBuff.filled += toLoad; @@ -911,30 +912,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input) { - size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize; - if (zcs->frameEnded) { - /* current frame being ended. Only flush is allowed. Or start new job with init */ - DEBUGLOG(5, "ZSTDMT_compressStream: zcs::frameEnded==1"); - return ERROR(stage_wrong); - } - if (zcs->nbThreads==1) { - return ZSTD_compressStream(zcs->cctxPool->cctx[0], output, input); - } - - /* fill input buffer */ - { size_t const toLoad = MIN(input->size - input->pos, zcs->inBuffSize - zcs->inBuff.filled); - memcpy((char*)zcs->inBuff.buffer.start + zcs->inBuff.filled, (const char*)input->src + input->pos, toLoad); - input->pos += toLoad; - zcs->inBuff.filled += toLoad; - } - - if ( (zcs->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */ - && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { /* avoid overwriting job round buffer */ - CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0 /* endFrame */) ); - } - - /* check for data to flush */ - CHECK_F( ZSTDMT_flushNextJob(zcs, output, (zcs->inBuff.filled == zcs->inBuffSize) /* blockToFlush */) ); /* block if it wasn't possible to create new job due to saturation */ + CHECK_F( ZSTDMT_compressStream_generic(zcs, output, input, ZSTD_e_continue) ); /* recommended next input size : fill current input buffer */ return zcs->inBuffSize - zcs->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */ @@ -970,29 +948,3 @@ size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output) return ZSTD_endStream(zcs->cctxPool->cctx[0], output); return ZSTDMT_flushStream_internal(zcs, output, 1 /* endFrame */); } - -size_t ZSTDMT_compressStream_generic2(ZSTDMT_CCtx* mtctx, - ZSTD_outBuffer* output, - ZSTD_inBuffer* input, - ZSTD_EndDirective endOp) -{ - DEBUGLOG(5, "ZSTDMT_compressStream_generic"); - DEBUGLOG(5, "in: pos:%u / size:%u ; endOp=%u", - (U32)input->pos, (U32)input->size, (U32)endOp); - if (input->pos < input->size) /* some input to consume */ - CHECK_F(ZSTDMT_compressStream(mtctx, output, input)); - if (input->pos < input->size) /* input not consumed : do not flush yet */ - endOp = ZSTD_e_continue; - switch(endOp) - { - case ZSTD_e_flush: - return ZSTDMT_flushStream(mtctx, output); - case ZSTD_e_end: - DEBUGLOG(5, "endOp:%u; calling ZSTDMT_endStream", (U32)endOp); - return ZSTDMT_endStream(mtctx, output); - case ZSTD_e_continue: - return 1; - default: - return ERROR(GENERIC); /* invalid endDirective */ - } -} From c07e43c2b512e7633dc524129967aa0ac21b4c01 Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Sat, 1 Jul 2017 07:05:11 -0700 Subject: [PATCH 385/400] added --show-leak-kind=all to valgrind tests --- tests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Makefile b/tests/Makefile index 0b8deec2a..e6ddce066 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -224,7 +224,7 @@ clean: ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU OpenBSD FreeBSD NetBSD DragonFly SunOS)) HOST_OS = POSIX -valgrindTest: VALGRIND = valgrind --leak-check=full --error-exitcode=1 +valgrindTest: VALGRIND = valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 valgrindTest: zstd datagen fuzzer fullbench @echo "\n ---- valgrind tests : memory analyzer ----" $(VALGRIND) ./datagen -g50M > $(VOID) From 4b26306cb82d7ec4d3b96001f3342224c51aa3e0 Mon Sep 17 00:00:00 2001 From: cyan4973 Date: Sat, 1 Jul 2017 08:03:59 -0700 Subject: [PATCH 386/400] blindfix : fullbench's one-time leak, detected by valgrind --- tests/fullbench.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/fullbench.c b/tests/fullbench.c index 0f2873481..81de5157b 100644 --- a/tests/fullbench.c +++ b/tests/fullbench.c @@ -453,6 +453,10 @@ static size_t benchMem(const void* src, size_t srcSize, U32 benchNb) _cleanOut: free(dstBuff); free(buff2); + ZSTD_freeCCtx(g_zcc); g_zcc=NULL; + ZSTD_freeDCtx(g_zdc); g_zdc=NULL; + ZSTD_freeCStream(g_cstream); g_cstream=NULL; + ZSTD_freeDStream(g_dstream); g_dstream=NULL; return 0; } From 2485f88bf8104e52a2ef9b50d00db35960daa270 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sat, 1 Jul 2017 09:09:34 -0700 Subject: [PATCH 387/400] fixed legacy version init bug --- lib/decompress/zstd_decompress.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index ff791969e..152d16a5a 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -198,6 +198,7 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) if (!dctx) return NULL; dctx->customMem = customMem; dctx->legacyContext = NULL; + dctx->previousLegacyVersion = 0; ZSTD_initDCtx_internal(dctx); return dctx; } From c34185df13ded25bef0fa72879d41ad6dbae849a Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 10:27:16 -0700 Subject: [PATCH 388/400] fileio : decoding malformed lzma frame does no longer exit() makes it possible to continue decoding file list --- programs/fileio.c | 227 ++++++++++++++++++++++++++-------------------- 1 file changed, 129 insertions(+), 98 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 779437175..780c29b2f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -107,6 +107,17 @@ static clock_t g_time = 0; /*-************************************* * Errors ***************************************/ +/*-************************************* +* Debug +***************************************/ +#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1) +# include +#else +# ifndef assert +# define assert(condition) ((void)0) +# endif +#endif + #ifndef ZSTD_DEBUG # define ZSTD_DEBUG 0 #endif @@ -1347,10 +1358,10 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ /** FIO_decompressFrame() : - @return : size of decoded frame, or an error code + * @return : size of decoded zstd frame, or an error code */ -#define FIO_ERROR_ZSTD_DECODING ((unsigned long long)(-2)) -unsigned long long FIO_decompressFrame(dRess_t* ress, +#define FIO_ERROR_FRAME_DECODING ((unsigned long long)(-2)) +unsigned long long FIO_decompressZstdFrame(dRess_t* ress, FILE* finput, const char* srcFileName, U64 alreadyDecoded) @@ -1375,7 +1386,7 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, if (ZSTD_isError(readSizeHint)) { DISPLAYLEVEL(1, "%s : Decoding error (36) : %s \n", srcFileName, ZSTD_getErrorName(readSizeHint)); - return FIO_ERROR_ZSTD_DECODING; + return FIO_ERROR_FRAME_DECODING; } /* Write block */ @@ -1393,7 +1404,7 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, if (inBuff.size != inBuff.pos) { DISPLAYLEVEL(1, "%s : Decoding error (37) : should consume entire input \n", srcFileName); - return FIO_ERROR_ZSTD_DECODING; + return FIO_ERROR_FRAME_DECODING; } /* Fill input buffer */ @@ -1404,7 +1415,7 @@ unsigned long long FIO_decompressFrame(dRess_t* ress, if (ress->srcBufferLoaded < toRead) { DISPLAYLEVEL(1, "%s : Read error (39) : premature end \n", srcFileName); - return FIO_ERROR_ZSTD_DECODING; + return FIO_ERROR_FRAME_DECODING; } } } FIO_fwriteSparseEnd(ress->dstFile, storedSkips); @@ -1444,7 +1455,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, strm.avail_in = (uInt)ress->srcBufferLoaded; } ret = inflate(&strm, flush); - if (ret == Z_BUF_ERROR) EXM_THROW(39, "zstd: %s: premature end", srcFileName); + if (ret == Z_BUF_ERROR) EXM_THROW(89, "zstd: %s: premature gz end", srcFileName); if (ret != Z_OK && ret != Z_STREAM_END) { DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); return 0; @@ -1476,19 +1487,23 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, unsigned long long outFileSize = 0; lzma_stream strm = LZMA_STREAM_INIT; lzma_action action = LZMA_RUN; - lzma_ret ret; + lzma_ret initRet; + int decodingError = 0; strm.next_in = 0; strm.avail_in = 0; if (plain_lzma) { - ret = lzma_alone_decoder(&strm, UINT64_MAX); /* LZMA */ + initRet = lzma_alone_decoder(&strm, UINT64_MAX); /* LZMA */ } else { - ret = lzma_stream_decoder(&strm, UINT64_MAX, 0); /* XZ */ + initRet = lzma_stream_decoder(&strm, UINT64_MAX, 0); /* XZ */ } - if (ret != LZMA_OK) - EXM_THROW(71, "zstd: %s: lzma_alone_decoder/lzma_stream_decoder error %d", - srcFileName, ret); + if (initRet != LZMA_OK) { + DISPLAYLEVEL(1, "zstd: %s: %s error %d \n", + plain_lzma ? "lzma_alone_decoder" : "lzma_stream_decoder", + srcFileName, initRet); + return FIO_ERROR_FRAME_DECODING; + } strm.next_out = (BYTE*)ress->dstBuffer; strm.avail_out = ress->dstBufferSize; @@ -1496,6 +1511,7 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, strm.avail_in = ress->srcBufferLoaded; for ( ; ; ) { + lzma_ret ret; if (strm.avail_in == 0) { ress->srcBufferLoaded = fread(ress->srcBuffer, 1, ress->srcBufferSize, srcFile); if (ress->srcBufferLoaded == 0) action = LZMA_FINISH; @@ -1504,16 +1520,21 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, } ret = lzma_code(&strm, action); - if (ret == LZMA_BUF_ERROR) - EXM_THROW(39, "zstd: %s: premature end", srcFileName); + if (ret == LZMA_BUF_ERROR) { + DISPLAYLEVEL(1, "zstd: %s: premature lzma end \n", srcFileName); + decodingError = 1; break; + } if (ret != LZMA_OK && ret != LZMA_STREAM_END) { - DISPLAY("zstd: %s: lzma_code decoding error %d \n", srcFileName, ret); - return 0; + DISPLAYLEVEL(1, "zstd: %s: lzma_code decoding error %d \n", + srcFileName, ret); + decodingError = 1; break; } { size_t const decompBytes = ress->dstBufferSize - strm.avail_out; if (decompBytes) { - if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) - EXM_THROW(31, "Write error : cannot write to output file"); + if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) { + DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno)); + decodingError = 1; break; + } outFileSize += decompBytes; strm.next_out = (BYTE*)ress->dstBuffer; strm.avail_out = ress->dstBufferSize; @@ -1524,7 +1545,7 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); ress->srcBufferLoaded = strm.avail_in; lzma_end(&strm); - return outFileSize; + return decodingError ? FIO_ERROR_FRAME_DECODING : outFileSize; } #endif @@ -1596,6 +1617,87 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, +/** FIO_decompressFrames() : + * Find and decode frames inside srcFile + * srcFile presumed opened and valid + * @return : 0 : OK + * 1 : error + */ +static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, + const char* dstFileName, const char* srcFileName) +{ + unsigned readSomething = 0; + unsigned long long filesize = 0; + assert(srcFile != NULL); + + /* for each frame */ + for ( ; ; ) { + /* check magic number -> version */ + size_t const toRead = 4; + const BYTE* const buf = (const BYTE*)ress.srcBuffer; + if (ress.srcBufferLoaded < toRead) + ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, + (size_t)1, toRead - ress.srcBufferLoaded, srcFile); + if (ress.srcBufferLoaded==0) { + if (readSomething==0) { + DISPLAYLEVEL(1, "zstd: %s: unexpected end of file \n", srcFileName); + return 1; + } /* else, srcFileName is just empty */ + break; /* no more input */ + } + readSomething = 1; /* there is at least 1 byte in srcFile */ + if (ress.srcBufferLoaded < toRead) { + DISPLAYLEVEL(1, "zstd: %s: unknown header \n", srcFileName); + return 1; + } + if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */ +#ifdef ZSTD_GZDECOMPRESS + unsigned long long const result = FIO_decompressGzFrame(&ress, srcFile, srcFileName); + if (result == 0) return 1; + filesize += result; +#else + DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without HAVE_ZLIB) -- ignored \n", srcFileName); + return 1; +#endif + } else if ((buf[0] == 0xFD && buf[1] == 0x37) /* xz magic number */ + || (buf[0] == 0x5D && buf[1] == 0x00)) { /* lzma header (no magic number) */ +#ifdef ZSTD_LZMADECOMPRESS + unsigned long long const frameSize = FIO_decompressLzmaFrame(&ress, srcFile, srcFileName, buf[0] != 0xFD); + if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; + filesize += frameSize; +#else + DISPLAYLEVEL(1, "zstd: %s: xz/lzma file cannot be uncompressed (zstd compiled without HAVE_LZMA) -- ignored \n", srcFileName); + return 1; +#endif + } else if (MEM_readLE32(buf) == LZ4_MAGICNUMBER) { +#ifdef ZSTD_LZ4DECOMPRESS + unsigned long long const result = FIO_decompressLz4Frame(&ress, srcFile, srcFileName); + if (result == 0) return 1; + filesize += result; +#else + DISPLAYLEVEL(1, "zstd: %s: lz4 file cannot be uncompressed (zstd compiled without HAVE_LZ4) -- ignored \n", srcFileName); + return 1; +#endif + } else if (ZSTD_isFrame(buf, toRead)) { + unsigned long long const frameSize = FIO_decompressZstdFrame(&ress, srcFile, srcFileName, filesize); + if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; + filesize += frameSize; + } else if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ + return FIO_passThrough(ress.dstFile, srcFile, + ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); + } else { + DISPLAYLEVEL(1, "zstd: %s: unsupported format \n", srcFileName); + return 1; + } } /* for each frame */ + + /* Final Status */ + DISPLAYLEVEL(2, "\r%79s\r", ""); + DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); + + return 0; +} + + /** FIO_decompressSrcFile() : Decompression `srcFileName` into `ress.dstFile` @return : 0 : OK @@ -1604,8 +1706,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const char* srcFileName) { FILE* srcFile; - unsigned readSomething = 0; - unsigned long long filesize = 0; + int result; if (UTIL_isDirectory(srcFileName)) { DISPLAYLEVEL(1, "zstd: %s is a directory -- ignored \n", srcFileName); @@ -1615,88 +1716,18 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch srcFile = FIO_openSrcFile(srcFileName); if (srcFile==NULL) return 1; - /* for each frame */ - for ( ; ; ) { - /* check magic number -> version */ - size_t const toRead = 4; - const BYTE* buf = (const BYTE*)ress.srcBuffer; - if (ress.srcBufferLoaded < toRead) - ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, - (size_t)1, toRead - ress.srcBufferLoaded, srcFile); - if (ress.srcBufferLoaded==0) { - if (readSomething==0) { - DISPLAY("zstd: %s: unexpected end of file \n", srcFileName); - fclose(srcFile); - return 1; - } /* srcFileName is empty */ - break; /* no more input */ - } - readSomething = 1; /* there is at least >= 4 bytes in srcFile */ - if (ress.srcBufferLoaded < toRead) { - DISPLAY("zstd: %s: unknown header \n", srcFileName); - fclose(srcFile); - return 1; - } - if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */ -#ifdef ZSTD_GZDECOMPRESS - unsigned long long const result = FIO_decompressGzFrame(&ress, srcFile, srcFileName); - if (result == 0) return 1; - filesize += result; -#else - DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without ZSTD_GZDECOMPRESS) -- ignored \n", srcFileName); - return 1; -#endif - } else if ((buf[0] == 0xFD && buf[1] == 0x37) /* xz magic number */ - || (buf[0] == 0x5D && buf[1] == 0x00)) { /* lzma header (no magic number) */ -#ifdef ZSTD_LZMADECOMPRESS - unsigned long long const result = FIO_decompressLzmaFrame(&ress, srcFile, srcFileName, buf[0] != 0xFD); - if (result == 0) return 1; - filesize += result; -#else - DISPLAYLEVEL(1, "zstd: %s: xz/lzma file cannot be uncompressed (zstd compiled without ZSTD_LZMADECOMPRESS) -- ignored \n", srcFileName); - return 1; -#endif - } else if (MEM_readLE32(buf) == LZ4_MAGICNUMBER) { -#ifdef ZSTD_LZ4DECOMPRESS - unsigned long long const result = FIO_decompressLz4Frame(&ress, srcFile, srcFileName); - if (result == 0) return 1; - filesize += result; -#else - DISPLAYLEVEL(1, "zstd: %s: lz4 file cannot be uncompressed (zstd compiled without ZSTD_LZ4DECOMPRESS) -- ignored \n", srcFileName); - return 1; -#endif - } else { - if (!ZSTD_isFrame(ress.srcBuffer, toRead)) { - if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ - unsigned const result = FIO_passThrough(ress.dstFile, srcFile, - ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); - if (fclose(srcFile)) EXM_THROW(32, "zstd: %s close error", srcFileName); /* error should never happen */ - return result; - } else { - DISPLAYLEVEL(1, "zstd: %s: not in zstd format \n", srcFileName); - fclose(srcFile); - return 1; - } } - { unsigned long long const frameSize = FIO_decompressFrame(&ress, srcFile, srcFileName, filesize); - if (frameSize == FIO_ERROR_ZSTD_DECODING) { - fclose(srcFile); - return 1; - } - filesize += frameSize; - } } - } /* for each frame */ - - /* Final Status */ - DISPLAYLEVEL(2, "\r%79s\r", ""); - DISPLAYLEVEL(2, "%-20s: %llu bytes \n", srcFileName, filesize); + result = FIO_decompressFrames(ress, srcFile, dstFileName, srcFileName); /* Close file */ - if (fclose(srcFile)) EXM_THROW(33, "zstd: %s close error", srcFileName); /* error should never happen */ + if (fclose(srcFile)) { + EXM_THROW(33, "zstd: %s: %s", srcFileName, strerror(errno)); /* error should never happen */ + return 1; + } if (g_removeSrcFile /* --rm */ && strcmp(srcFileName, stdinmark)) { if (remove(srcFileName)) EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); } - return 0; + return result; } From e97ff3b54a8b45149561c80ecfe30ec214cd254f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 11:27:29 -0700 Subject: [PATCH 389/400] decoding malformed lz4 frames does no longer exit() --- programs/fileio.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 780c29b2f..8509d24f3 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1557,19 +1557,24 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, LZ4F_errorCode_t nextToLoad; LZ4F_decompressionContext_t dCtx; LZ4F_errorCode_t const errorCode = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION); + int decodingError = 0; - if (LZ4F_isError(errorCode)) - EXM_THROW(61, "zstd: failed to create lz4 decompression context"); + if (LZ4F_isError(errorCode)) { + DISPLAYLEVEL(1, "zstd: failed to create lz4 decompression context"); + return FIO_ERROR_FRAME_DECODING; + } /* Init feed with magic number (already consumed from FILE* sFile) */ { size_t inSize = 4; size_t outSize= 0; MEM_writeLE32(ress->srcBuffer, LZ4_MAGICNUMBER); nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &outSize, ress->srcBuffer, &inSize, NULL); - if (LZ4F_isError(nextToLoad)) - EXM_THROW(62, "zstd: %s: lz4 header error : %s", + if (LZ4F_isError(nextToLoad)) { + DISPLAYLEVEL(1, "zstd: %s: lz4 header error : %s", srcFileName, LZ4F_getErrorName(nextToLoad)); - } + LZ4F_freeDecompressionContext(dCtx); + return FIO_ERROR_FRAME_DECODING; + } } /* Main Loop */ for (;nextToLoad;) { @@ -1587,15 +1592,19 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, size_t remaining = readSize - pos; decodedBytes = ress->dstBufferSize; nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &decodedBytes, (char*)(ress->srcBuffer)+pos, &remaining, NULL); - if (LZ4F_isError(nextToLoad)) - EXM_THROW(66, "zstd: %s: decompression error : %s", + if (LZ4F_isError(nextToLoad)) { + DISPLAYLEVEL(1, "zstd: %s: lz4 decompression error : %s", srcFileName, LZ4F_getErrorName(nextToLoad)); + decodingError = 1; break; + } pos += remaining; /* Write Block */ if (decodedBytes) { - if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) - EXM_THROW(63, "Write error : cannot write to output file"); + if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) { + DISPLAYLEVEL(1, "zstd: %s", strerr(errno)); + decodingError = 1; break; + } filesize += decodedBytes; DISPLAYUPDATE(2, "\rDecompressed : %u MB ", (unsigned)(filesize>>20)); } @@ -1604,14 +1613,20 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, } } /* can be out because readSize == 0, which could be an fread() error */ - if (ferror(srcFile)) EXM_THROW(67, "zstd: %s: read error", srcFileName); + if (ferror(srcFile)) { + DISPLAYLEVEL(1, "zstd: %s: read error", srcFileName); + decodingError=1; + } - if (nextToLoad!=0) EXM_THROW(68, "zstd: %s: unfinished stream", srcFileName); + if (nextToLoad!=0) { + DISPLAYLEVEL(1, "zstd: %s: unfinished lz4 stream", srcFileName); + decodingError=1; + } LZ4F_freeDecompressionContext(dCtx); ress->srcBufferLoaded = 0; /* LZ4F will go to the frame boundary */ - return filesize; + return decodingError ? FIO_ERROR_FRAME_DECODING : filesize; } #endif @@ -1671,9 +1686,9 @@ static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, #endif } else if (MEM_readLE32(buf) == LZ4_MAGICNUMBER) { #ifdef ZSTD_LZ4DECOMPRESS - unsigned long long const result = FIO_decompressLz4Frame(&ress, srcFile, srcFileName); - if (result == 0) return 1; - filesize += result; + unsigned long long const frameSize = FIO_decompressLz4Frame(&ress, srcFile, srcFileName); + if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; + filesize += frameSize; #else DISPLAYLEVEL(1, "zstd: %s: lz4 file cannot be uncompressed (zstd compiled without HAVE_LZ4) -- ignored \n", srcFileName); return 1; From c80fc50a8dd211b904071049d4519569e199935f Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 3 Jul 2017 12:31:55 -0700 Subject: [PATCH 390/400] [libzstd] Fix memcpy() on potential NULL source * `ZSTD_decompressStream_generic()` `ip` may be `NULL` for one of the calls to `memcpy()` * Assert the source is not `NULL` for calls to `memcpy()` where I believe the source should not be `NULL`. --- lib/decompress/zstd_decompress.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index ff791969e..47099928d 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1690,6 +1690,7 @@ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) { switch(dctx->stage) { default: /* should not happen */ + assert(0); case ZSTDds_getFrameHeaderSize: case ZSTDds_decodeFrameHeader: return ZSTDnit_frameHeader; @@ -1724,6 +1725,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c { case ZSTDds_getFrameHeaderSize : if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* unauthorized */ + assert(src != NULL); if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix); dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */ @@ -1741,6 +1743,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c dctx->expected = 0; /* not necessary to copy more */ case ZSTDds_decodeFrameHeader: + assert(src != NULL); memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected); CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize)); dctx->expected = ZSTD_blockHeaderSize; @@ -1820,7 +1823,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c return 0; } case ZSTDds_decodeSkippableHeader: - { memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected); + { assert(src != NULL); + memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected); dctx->expected = MEM_readLE32(dctx->headerBuffer + 4); dctx->stage = ZSTDds_skipFrame; return 0; @@ -2063,6 +2067,8 @@ ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize, { size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize); ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace; + assert(workspace != NULL); + assert(dict != NULL); if ((size_t)workspace & 7) return NULL; /* 8-aligned */ if (workspaceSize < neededSpace) return NULL; if (!byReference) { @@ -2321,11 +2327,14 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB if (hSize != 0) { /* need more input */ size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */ - memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip); - zds->lhSize += iend-ip; + if (iend-ip > 0) { + memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip); + zds->lhSize += iend-ip; + } input->pos = input->size; return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ } + assert(ip != NULL); memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; break; } } From bea0f0cfa0bec20dfdd44ad9a1a964595b06ff6a Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Mon, 3 Jul 2017 12:40:12 -0700 Subject: [PATCH 391/400] [fuzz] Move from fuzz/ to tests/fuzz/ --- {fuzz => tests/fuzz}/Makefile | 4 ++-- {fuzz => tests/fuzz}/README.md | 0 {fuzz => tests/fuzz}/fuzz.h | 0 {fuzz => tests/fuzz}/fuzz_helpers.h | 0 {fuzz => tests/fuzz}/regression_driver.c | 0 {fuzz => tests/fuzz}/simple_decompress.c | 0 {fuzz => tests/fuzz}/simple_round_trip.c | 0 {fuzz => tests/fuzz}/stream_decompress.c | 0 {fuzz => tests/fuzz}/stream_round_trip.c | 0 9 files changed, 2 insertions(+), 2 deletions(-) rename {fuzz => tests/fuzz}/Makefile (98%) rename {fuzz => tests/fuzz}/README.md (100%) rename {fuzz => tests/fuzz}/fuzz.h (100%) rename {fuzz => tests/fuzz}/fuzz_helpers.h (100%) rename {fuzz => tests/fuzz}/regression_driver.c (100%) rename {fuzz => tests/fuzz}/simple_decompress.c (100%) rename {fuzz => tests/fuzz}/simple_round_trip.c (100%) rename {fuzz => tests/fuzz}/stream_decompress.c (100%) rename {fuzz => tests/fuzz}/stream_round_trip.c (100%) diff --git a/fuzz/Makefile b/tests/fuzz/Makefile similarity index 98% rename from fuzz/Makefile rename to tests/fuzz/Makefile index 9b084fd3b..da22ed0d0 100644 --- a/fuzz/Makefile +++ b/tests/fuzz/Makefile @@ -12,8 +12,8 @@ CFLAGS ?= -O3 CXXFLAGS ?= -O3 -ZSTDDIR = ../lib -PRGDIR = ../programs +ZSTDDIR = ../../lib +PRGDIR = ../../programs FUZZ_CPPFLAGS := -I$(ZSTDDIR) -I$(ZSTDDIR)/common -I$(ZSTDDIR)/compress \ -I$(ZSTDDIR)/dictBuilder -I$(ZSTDDIR)/deprecated -I$(PRGDIR) \ diff --git a/fuzz/README.md b/tests/fuzz/README.md similarity index 100% rename from fuzz/README.md rename to tests/fuzz/README.md diff --git a/fuzz/fuzz.h b/tests/fuzz/fuzz.h similarity index 100% rename from fuzz/fuzz.h rename to tests/fuzz/fuzz.h diff --git a/fuzz/fuzz_helpers.h b/tests/fuzz/fuzz_helpers.h similarity index 100% rename from fuzz/fuzz_helpers.h rename to tests/fuzz/fuzz_helpers.h diff --git a/fuzz/regression_driver.c b/tests/fuzz/regression_driver.c similarity index 100% rename from fuzz/regression_driver.c rename to tests/fuzz/regression_driver.c diff --git a/fuzz/simple_decompress.c b/tests/fuzz/simple_decompress.c similarity index 100% rename from fuzz/simple_decompress.c rename to tests/fuzz/simple_decompress.c diff --git a/fuzz/simple_round_trip.c b/tests/fuzz/simple_round_trip.c similarity index 100% rename from fuzz/simple_round_trip.c rename to tests/fuzz/simple_round_trip.c diff --git a/fuzz/stream_decompress.c b/tests/fuzz/stream_decompress.c similarity index 100% rename from fuzz/stream_decompress.c rename to tests/fuzz/stream_decompress.c diff --git a/fuzz/stream_round_trip.c b/tests/fuzz/stream_round_trip.c similarity index 100% rename from fuzz/stream_round_trip.c rename to tests/fuzz/stream_round_trip.c From 6c35112d08748d6306b61f63564aa8903f481d08 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 13:24:50 -0700 Subject: [PATCH 392/400] gzip decoding does no longer exit() on invalid input --- programs/fileio.c | 78 ++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 8509d24f3..94c629303 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1344,8 +1344,11 @@ static unsigned FIO_passThrough(FILE* foutput, FILE* finput, void* buffer, size_ unsigned storedSkips = 0; /* assumption : ress->srcBufferLoaded bytes already loaded and stored within buffer */ - { size_t const sizeCheck = fwrite(buffer, 1, alreadyLoaded, foutput); - if (sizeCheck != alreadyLoaded) EXM_THROW(50, "Pass-through write error"); } + { size_t const sizeCheck = fwrite(buffer, 1, alreadyLoaded, foutput); + if (sizeCheck != alreadyLoaded) { + DISPLAYLEVEL(1, "Pass-through write error \n"); + return 1; + } } while (readFromInput) { readFromInput = fread(buffer, 1, blockSize, finput); @@ -1431,7 +1434,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, unsigned long long outFileSize = 0; z_stream strm; int flush = Z_NO_FLUSH; - int ret; + int decodingError = 0; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; @@ -1440,7 +1443,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, strm.avail_in = 0; /* see http://www.zlib.net/manual.html */ if (inflateInit2(&strm, 15 /* maxWindowLogSize */ + 16 /* gzip only */) != Z_OK) - return 0; + return FIO_ERROR_FRAME_DECODING; strm.next_out = (Bytef*)ress->dstBuffer; strm.avail_out = (uInt)ress->dstBufferSize; @@ -1448,6 +1451,7 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, strm.next_in = (z_const unsigned char*)ress->srcBuffer; for ( ; ; ) { + int ret; if (strm.avail_in == 0) { ress->srcBufferLoaded = fread(ress->srcBuffer, 1, ress->srcBufferSize, srcFile); if (ress->srcBufferLoaded == 0) flush = Z_FINISH; @@ -1455,15 +1459,20 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, strm.avail_in = (uInt)ress->srcBufferLoaded; } ret = inflate(&strm, flush); - if (ret == Z_BUF_ERROR) EXM_THROW(89, "zstd: %s: premature gz end", srcFileName); + if (ret == Z_BUF_ERROR) { + DISPLAYLEVEL(1, "zstd: %s: premature gz end \n", srcFileName); + decodingError = 1; break; + } if (ret != Z_OK && ret != Z_STREAM_END) { - DISPLAY("zstd: %s: inflate error %d \n", srcFileName, ret); - return 0; + DISPLAYLEVEL(1, "zstd: %s: inflate error %d \n", srcFileName, ret); + decodingError = 1; break; } { size_t const decompBytes = ress->dstBufferSize - strm.avail_out; if (decompBytes) { - if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) - EXM_THROW(31, "Write error : cannot write to output file"); + if (fwrite(ress->dstBuffer, 1, decompBytes, ress->dstFile) != decompBytes) { + DISPLAYLEVEL(1, "zstd: %s \n", strerror(errno)); + decodingError = 1; break; + } outFileSize += decompBytes; strm.next_out = (Bytef*)ress->dstBuffer; strm.avail_out = (uInt)ress->dstBufferSize; @@ -1474,9 +1483,11 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); ress->srcBufferLoaded = strm.avail_in; - ret = inflateEnd(&strm); - if (ret != Z_OK) EXM_THROW(32, "zstd: %s: inflateEnd error %d", srcFileName, ret); - return outFileSize; + if (inflateEnd(&strm) != Z_OK) { + DISPLAYLEVEL(1, "zstd: %s: inflateEnd error \n", srcFileName); + decodingError = 1; + } + return decodingError ? FIO_ERROR_FRAME_DECODING : outFileSize; } #endif @@ -1560,7 +1571,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, int decodingError = 0; if (LZ4F_isError(errorCode)) { - DISPLAYLEVEL(1, "zstd: failed to create lz4 decompression context"); + DISPLAYLEVEL(1, "zstd: failed to create lz4 decompression context \n"); return FIO_ERROR_FRAME_DECODING; } @@ -1570,7 +1581,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, MEM_writeLE32(ress->srcBuffer, LZ4_MAGICNUMBER); nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &outSize, ress->srcBuffer, &inSize, NULL); if (LZ4F_isError(nextToLoad)) { - DISPLAYLEVEL(1, "zstd: %s: lz4 header error : %s", + DISPLAYLEVEL(1, "zstd: %s: lz4 header error : %s \n", srcFileName, LZ4F_getErrorName(nextToLoad)); LZ4F_freeDecompressionContext(dCtx); return FIO_ERROR_FRAME_DECODING; @@ -1593,7 +1604,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, decodedBytes = ress->dstBufferSize; nextToLoad = LZ4F_decompress(dCtx, ress->dstBuffer, &decodedBytes, (char*)(ress->srcBuffer)+pos, &remaining, NULL); if (LZ4F_isError(nextToLoad)) { - DISPLAYLEVEL(1, "zstd: %s: lz4 decompression error : %s", + DISPLAYLEVEL(1, "zstd: %s: lz4 decompression error : %s \n", srcFileName, LZ4F_getErrorName(nextToLoad)); decodingError = 1; break; } @@ -1602,7 +1613,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, /* Write Block */ if (decodedBytes) { if (fwrite(ress->dstBuffer, 1, decodedBytes, ress->dstFile) != decodedBytes) { - DISPLAYLEVEL(1, "zstd: %s", strerr(errno)); + DISPLAYLEVEL(1, "zstd: %s \n", strerr(errno)); decodingError = 1; break; } filesize += decodedBytes; @@ -1614,12 +1625,12 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, } /* can be out because readSize == 0, which could be an fread() error */ if (ferror(srcFile)) { - DISPLAYLEVEL(1, "zstd: %s: read error", srcFileName); + DISPLAYLEVEL(1, "zstd: %s: read error \n", srcFileName); decodingError=1; } if (nextToLoad!=0) { - DISPLAYLEVEL(1, "zstd: %s: unfinished lz4 stream", srcFileName); + DISPLAYLEVEL(1, "zstd: %s: unfinished lz4 stream \n", srcFileName); decodingError=1; } @@ -1735,13 +1746,17 @@ static int FIO_decompressSrcFile(dRess_t ress, const char* dstFileName, const ch /* Close file */ if (fclose(srcFile)) { - EXM_THROW(33, "zstd: %s: %s", srcFileName, strerror(errno)); /* error should never happen */ + DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno)); /* error should never happen */ return 1; } - if (g_removeSrcFile /* --rm */ && strcmp(srcFileName, stdinmark)) { - if (remove(srcFileName)) - EXM_THROW(34, "zstd: %s: %s", srcFileName, strerror(errno)); - } + if ( g_removeSrcFile /* --rm */ + && (result==0) /* decompression successful */ + && strcmp(srcFileName, stdinmark) ) /* not stdin */ { + if (remove(srcFileName)) { + /* failed to remove src file */ + DISPLAYLEVEL(1, "zstd: %s: %s \n", srcFileName, strerror(errno)); + return 1; + } } return result; } @@ -1765,12 +1780,14 @@ static int FIO_decompressDstFile(dRess_t ress, stat_result = 1; result = FIO_decompressSrcFile(ress, dstFileName, srcFileName); - if (fclose(ress.dstFile)) - EXM_THROW(38, "Write error : cannot properly close %s", dstFileName); + if (fclose(ress.dstFile)) { + DISPLAYLEVEL(1, "zstd: %s: %s \n", dstFileName, strerror(errno)); + result = 1; + } - if ( (result != 0) + if ( (result != 0) /* operation failure */ && strcmp(dstFileName, nulmark) /* special case : don't remove() /dev/null (#316) */ - && remove(dstFileName) ) + && remove(dstFileName) /* remove artefact */ ) result=1; /* don't do anything special if remove() fails */ else if (strcmp (dstFileName, stdoutmark) && stat_result) UTIL_setFileStat(dstFileName, &statbuf); @@ -1781,13 +1798,12 @@ static int FIO_decompressDstFile(dRess_t ress, int FIO_decompressFilename(const char* dstFileName, const char* srcFileName, const char* dictFileName) { - int missingFiles = 0; - dRess_t ress = FIO_createDResources(dictFileName); + dRess_t const ress = FIO_createDResources(dictFileName); - missingFiles += FIO_decompressDstFile(ress, dstFileName, srcFileName); + int const decodingError = FIO_decompressDstFile(ress, dstFileName, srcFileName); FIO_freeDResources(ress); - return missingFiles; + return decodingError; } From c9f21c8a711ce9ee7ce4acca15606174d32afed6 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 13:45:09 -0700 Subject: [PATCH 393/400] gzip : only display inflateEnd error when there is no error before --- programs/fileio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/fileio.c b/programs/fileio.c index 94c629303..1d98e474a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1483,7 +1483,8 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); ress->srcBufferLoaded = strm.avail_in; - if (inflateEnd(&strm) != Z_OK) { + if ( (inflateEnd(&strm) != Z_OK) /* release resources ; error detected */ + && (decodingError==0) ) { DISPLAYLEVEL(1, "zstd: %s: inflateEnd error \n", srcFileName); decodingError = 1; } From 368b97438732915fc437229a9ee7e811530828a7 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 13:47:46 -0700 Subject: [PATCH 394/400] fixed gz error reporting --- programs/fileio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 1d98e474a..2557c08e8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1679,9 +1679,9 @@ static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, } if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */ #ifdef ZSTD_GZDECOMPRESS - unsigned long long const result = FIO_decompressGzFrame(&ress, srcFile, srcFileName); - if (result == 0) return 1; - filesize += result; + unsigned long long const frameSize = FIO_decompressGzFrame(&ress, srcFile, srcFileName); + if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; + filesize += frameSize; #else DISPLAYLEVEL(1, "zstd: %s: gzip file cannot be uncompressed (zstd compiled without HAVE_ZLIB) -- ignored \n", srcFileName); return 1; From b8280fe9294b491d1633ea6f08d01b3dc94b6479 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 15:14:55 -0700 Subject: [PATCH 395/400] minor code refactoring --- programs/fileio.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 2557c08e8..1dd8008e8 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1481,7 +1481,8 @@ static unsigned long long FIO_decompressGzFrame(dRess_t* ress, if (ret == Z_STREAM_END) break; } - if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); + if (strm.avail_in > 0) + memmove(ress->srcBuffer, strm.next_in, strm.avail_in); ress->srcBufferLoaded = strm.avail_in; if ( (inflateEnd(&strm) != Z_OK) /* release resources ; error detected */ && (decodingError==0) ) { @@ -1554,7 +1555,8 @@ static unsigned long long FIO_decompressLzmaFrame(dRess_t* ress, FILE* srcFile, if (ret == LZMA_STREAM_END) break; } - if (strm.avail_in > 0) memmove(ress->srcBuffer, strm.next_in, strm.avail_in); + if (strm.avail_in > 0) + memmove(ress->srcBuffer, strm.next_in, strm.avail_in); ress->srcBufferLoaded = strm.avail_in; lzma_end(&strm); return decodingError ? FIO_ERROR_FRAME_DECODING : outFileSize; @@ -1636,7 +1638,7 @@ static unsigned long long FIO_decompressLz4Frame(dRess_t* ress, } LZ4F_freeDecompressionContext(dCtx); - ress->srcBufferLoaded = 0; /* LZ4F will go to the frame boundary */ + ress->srcBufferLoaded = 0; /* LZ4F will reach exact frame boundary */ return decodingError ? FIO_ERROR_FRAME_DECODING : filesize; } @@ -1662,14 +1664,14 @@ static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, /* check magic number -> version */ size_t const toRead = 4; const BYTE* const buf = (const BYTE*)ress.srcBuffer; - if (ress.srcBufferLoaded < toRead) + if (ress.srcBufferLoaded < toRead) /* load up to 4 bytes for header */ ress.srcBufferLoaded += fread((char*)ress.srcBuffer + ress.srcBufferLoaded, (size_t)1, toRead - ress.srcBufferLoaded, srcFile); if (ress.srcBufferLoaded==0) { - if (readSomething==0) { + if (readSomething==0) { /* srcFile is empty (which is invalid) */ DISPLAYLEVEL(1, "zstd: %s: unexpected end of file \n", srcFileName); return 1; - } /* else, srcFileName is just empty */ + } /* else, just reached frame boundary */ break; /* no more input */ } readSomething = 1; /* there is at least 1 byte in srcFile */ @@ -1677,7 +1679,11 @@ static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, DISPLAYLEVEL(1, "zstd: %s: unknown header \n", srcFileName); return 1; } - if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */ + if (ZSTD_isFrame(buf, ress.srcBufferLoaded)) { + unsigned long long const frameSize = FIO_decompressZstdFrame(&ress, srcFile, srcFileName, filesize); + if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; + filesize += frameSize; + } else if (buf[0] == 31 && buf[1] == 139) { /* gz magic number */ #ifdef ZSTD_GZDECOMPRESS unsigned long long const frameSize = FIO_decompressGzFrame(&ress, srcFile, srcFileName); if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; @@ -1705,10 +1711,6 @@ static int FIO_decompressFrames(dRess_t ress, FILE* srcFile, DISPLAYLEVEL(1, "zstd: %s: lz4 file cannot be uncompressed (zstd compiled without HAVE_LZ4) -- ignored \n", srcFileName); return 1; #endif - } else if (ZSTD_isFrame(buf, toRead)) { - unsigned long long const frameSize = FIO_decompressZstdFrame(&ress, srcFile, srcFileName, filesize); - if (frameSize == FIO_ERROR_FRAME_DECODING) return 1; - filesize += frameSize; } else if ((g_overwrite) && !strcmp (dstFileName, stdoutmark)) { /* pass-through mode */ return FIO_passThrough(ress.dstFile, srcFile, ress.srcBuffer, ress.srcBufferSize, ress.srcBufferLoaded); From 5a773615950616c2ec2d2357cdaabcb4a7119c8c Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 15:21:24 -0700 Subject: [PATCH 396/400] fixed wrong function name in comment --- lib/common/zstd_internal.h | 16 +--------------- lib/compress/zstd_compress.c | 1 + 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index a0cc938a3..f2c4e6249 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -309,20 +309,6 @@ MEM_STATIC U32 ZSTD_highbit32(U32 val) void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); -typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; -#if 0 -/*! ZSTD_compressBegin_internal() : - * innermost initialization function. Private use only. - * expects params to be valid. - * must receive dict, or cdict, or none, but not both. - * @return : 0, or an error code */ -size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, - const void* dict, size_t dictSize, - const ZSTD_CDict* cdict, - ZSTD_parameters params, U64 pledgedSrcSize, - ZSTD_buffered_policy_e zbuff); -#endif - /*! ZSTD_initCStream_internal() : * Private use only. Init streaming operation. * expects params to be valid. @@ -333,7 +319,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, ZSTD_parameters params, unsigned long long pledgedSrcSize); -/*! ZSTD_initCStream_internal() : +/*! ZSTD_compressStream_generic() : * Private use only. To be called from zstdmt_compress.c in single-thread mode. */ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ZSTD_outBuffer* output, diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f2afe625a..2d57bc2d0 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -627,6 +627,7 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 ple } typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e; +typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e; /*! ZSTD_resetCCtx_internal() : note : `params` are assumed fully validated at this stage */ From 2084b041f4a508e7fa668cd67ca2750a352c2621 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 15:52:19 -0700 Subject: [PATCH 397/400] fixed comments --- lib/compress/zstd_compress.c | 8 ++++---- lib/compress/zstdmt_compress.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 2d57bc2d0..c1e7cb5c5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3215,7 +3215,7 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx, ZSTD_buffered_policy_e zbuff) { DEBUGLOG(4, "ZSTD_compressBegin_internal"); - DEBUGLOG(4, "dict ? %s", dict ? "dict" : cdict ? "cdict" : "none"); + DEBUGLOG(4, "dict ? %s", dict ? "dict" : (cdict ? "cdict" : "none")); DEBUGLOG(4, "dictMode : %u", (U32)dictMode); /* params are supposed to be fully validated at this point */ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams))); @@ -3803,7 +3803,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, case zcss_load: if ( (flushMode == ZSTD_e_end) - && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip)) + && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip)) /* enough dstCapacity */ && (zcs->inBuffPos == 0) ) { /* shortcut to compression pass directly into output buffer */ size_t const cSize = ZSTD_compressEnd(zcs, @@ -3815,8 +3815,8 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, zcs->frameEnded = 1; ZSTD_startNewCompression(zcs); someMoreWork = 0; break; - } - /* complete inBuffer */ + } + /* complete loading into inBuffer */ { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos; size_t const loaded = ZSTD_limitCopy( zcs->inBuff + zcs->inBuffPos, toLoad, diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index c203bf337..9e44da8b2 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -527,8 +527,8 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, dstBufferPos += dstBufferCapacity; remainingSrcSize -= chunkSize; } } - /* note : since nbChunks <= nbThreads, all jobs should be running immediately in parallel */ + /* collect result */ { unsigned chunkID; size_t error = 0, dstPos = 0; for (chunkID=0; chunkIDjobs[chunkID].cSize; if (ZSTD_isError(cSize)) error = cSize; if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall); - if (chunkID) { /* note : chunk 0 is already written directly into dst */ + if (chunkID) { /* note : chunk 0 is written directly at dst, which is correct position */ if (!error) - memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize); /* may overlap if chunk decompressed within dst */ - if (chunkID >= compressWithinDst) { /* otherwise, it decompresses within dst */ + memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize); /* may overlap when chunk compressed within dst */ + if (chunkID >= compressWithinDst) { /* chunk compressed into its own buffer, which must be released */ DEBUGLOG(5, "releasing buffer %u>=%u", chunkID, compressWithinDst); ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff); } From 2de2396a36a7412916563f8a96ccf4572dc2b561 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Mon, 3 Jul 2017 16:23:36 -0700 Subject: [PATCH 398/400] refactor ZSTDMT_compress() --- lib/compress/zstdmt_compress.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 9e44da8b2..17f3b37a2 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -445,6 +445,18 @@ size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, /* ===== Multi-threaded compression ===== */ /* ------------------------------------------ */ +static unsigned computeNbChunks(size_t srcSize, unsigned windowLog, unsigned nbThreads) { + size_t const chunkSizeTarget = (size_t)1 << (windowLog + 2); + size_t const chunkMaxSize = chunkSizeTarget << 2; + size_t const passSizeMax = chunkMaxSize * nbThreads; + unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1; + unsigned const nbChunksLarge = multiplier * nbThreads; + unsigned const nbChunksMax = (unsigned)(srcSize / chunkSizeTarget) + 1; + unsigned const nbChunksSmall = MIN(nbChunksMax, nbThreads); + return (multiplier>1) ? nbChunksLarge : nbChunksSmall; +} + + size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, @@ -453,14 +465,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, unsigned overlapRLog) { size_t const overlapSize = (overlapRLog>=9) ? 0 : (size_t)1 << (params.cParams.windowLog - overlapRLog); - size_t const chunkSizeTarget = (size_t)1 << (params.cParams.windowLog + 2); - size_t const chunkMaxSize = chunkSizeTarget << 2; - size_t const passSizeMax = chunkMaxSize * mtctx->nbThreads; - unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1; - unsigned nbChunksLarge = multiplier * mtctx->nbThreads; - unsigned const nbChunksMax = (unsigned)(srcSize / chunkSizeTarget) + 1; - unsigned nbChunksSmall = MIN(nbChunksMax, mtctx->nbThreads); - unsigned nbChunks = (multiplier>1) ? nbChunksLarge : nbChunksSmall; + unsigned nbChunks = computeNbChunks(srcSize, params.cParams.windowLog, mtctx->nbThreads); size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks; size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0x7FFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */ const char* const srcStart = (const char*)src; @@ -468,7 +473,6 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */ size_t frameStartPos = 0, dstBufferPos = 0; - DEBUGLOG(4, "windowLog : %2u => chunkSizeTarget : %u bytes ", params.cParams.windowLog, (U32)chunkSizeTarget); DEBUGLOG(4, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize); assert(avgChunkSize >= 256 KB); /* required for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B) */ @@ -499,7 +503,7 @@ size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx, if ((cctx==NULL) || (dstBuffer.start==NULL)) { mtctx->jobs[u].cSize = ERROR(memory_allocation); /* job result */ mtctx->jobs[u].jobCompleted = 1; - nbChunks = u+1; + nbChunks = u+1; /* only wait and free u jobs, instead of initially expected nbChunks ones */ break; /* let's wait for previous jobs to complete, but don't start new ones */ } From 6383372decd70f30c2600ce70fa8885e0e688f88 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 4 Jul 2017 10:36:41 -0700 Subject: [PATCH 399/400] fixed : 0-copy in NULL is UB --- lib/compress/zstdmt_compress.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/compress/zstdmt_compress.c b/lib/compress/zstdmt_compress.c index 17f3b37a2..9f8d70973 100644 --- a/lib/compress/zstdmt_compress.c +++ b/lib/compress/zstdmt_compress.c @@ -122,7 +122,8 @@ static size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool) return poolSize + totalBufferSize; } -/* assumption : invocation from main thread only ! */ +/** ZSTDMT_getBuffer() : + * assumption : invocation from main thread only ! */ static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* pool, size_t bSize) { if (pool->nbBuffers) { /* try to use an existing buffer */ @@ -190,7 +191,7 @@ static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads, cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */ cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem); if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; } - DEBUGLOG(4, "cctxPool created, with %u threads", nbThreads); + DEBUGLOG(3, "cctxPool created, with %u threads", nbThreads); return cctxPool; } @@ -369,7 +370,7 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbThreads, ZSTD_customMem cMem) } pthread_mutex_init(&mtctx->jobCompleted_mutex, NULL); /* Todo : check init function return */ pthread_cond_init(&mtctx->jobCompleted_cond, NULL); - DEBUGLOG(4, "mt_cctx created, for %u threads", nbThreads); + DEBUGLOG(3, "mt_cctx created, for %u threads", nbThreads); return mtctx; } @@ -383,7 +384,7 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads) static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx) { unsigned jobID; - DEBUGLOG(4, "ZSTDMT_releaseAllJobResources"); + DEBUGLOG(3, "ZSTDMT_releaseAllJobResources"); for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) { ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[jobID].dstBuff); mtctx->jobs[jobID].dstBuff = g_nullBuffer; @@ -856,7 +857,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, assert(output->pos <= output->size); assert(input->pos <= input->size); if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) { - /* current frame being ended. Only flush/end are allowed. Or start new job with init */ + /* current frame being ended. Only flush/end are allowed. Or start new frame with init */ return ERROR(stage_wrong); } if (mtctx->nbThreads==1) { @@ -865,8 +866,8 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, /* single-pass shortcut (note : this is blocking-mode) */ if ( (mtctx->nextJobID==0) /* just started */ - && (mtctx->inBuff.filled==0) /* nothing buffered yet */ - && (endOp==ZSTD_e_end) /* end order, immediately at beginning */ + && (mtctx->inBuff.filled==0) /* nothing buffered */ + && (endOp==ZSTD_e_end) /* end order */ && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough room */ size_t const cSize = ZSTDMT_compress_advanced(mtctx, (char*)output->dst + output->pos, output->size - output->pos, @@ -879,11 +880,12 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx, mtctx->allJobsCompleted = 1; mtctx->frameEnded = 1; return 0; - } + } /* fill input buffer */ - if (input->src) { /* support NULL input */ + if ((input->src) && (mtctx->inBuff.buffer.start)) { /* support NULL input */ size_t const toLoad = MIN(input->size - input->pos, mtctx->inBuffSize - mtctx->inBuff.filled); + DEBUGLOG(2, "inBuff:%08X; inBuffSize=%u; ToCopy=%u", (U32)(size_t)mtctx->inBuff.buffer.start, (U32)mtctx->inBuffSize, (U32)toLoad); memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, toLoad); input->pos += toLoad; mtctx->inBuff.filled += toLoad; From 2cb9774f5ea52b4f7399164010b21dead9d32e14 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Tue, 4 Jul 2017 12:39:26 -0700 Subject: [PATCH 400/400] more precise estimation of amount to flush at end of stream (single thread mode) also : can use DEBUGLEVEL variable in /tests --- lib/compress/zstd_compress.c | 22 +++++++++++++--------- tests/Makefile | 7 +++---- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c1e7cb5c5..9300357f2 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3786,7 +3786,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, U32 someMoreWork = 1; /* check expectations */ - DEBUGLOG(5, "ZSTD_compressStream_generic, order %u", (U32)flushMode); + DEBUGLOG(5, "ZSTD_compressStream_generic, flush=%u", (U32)flushMode); assert(zcs->inBuff != NULL); assert(zcs->inBuffSize>0); assert(zcs->outBuff!= NULL); @@ -3880,11 +3880,13 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize; size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush); - DEBUGLOG(5, "toFlush: %u ; flushed: %u", (U32)toFlush, (U32)flushed); + DEBUGLOG(5, "toFlush: %u into %u ==> flushed: %u", + (U32)toFlush, (U32)(oend-op), (U32)flushed); op += flushed; zcs->outBuffFlushedSize += flushed; if (toFlush!=flushed) { - /* dst too small to store flushed data : stop there */ + /* flush not fully completed, presumably because dst is too small */ + assert(op==oend); someMoreWork = 0; break; } @@ -4016,10 +4018,13 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) ZSTD_inBuffer input = { NULL, 0, 0 }; if (output->pos > output->size) return ERROR(GENERIC); CHECK_F( ZSTD_compressStream_generic(zcs, output, &input, ZSTD_e_end) ); - - DEBUGLOG(5, "ZSTD_endStream : remaining to flush : %u", - (unsigned)(zcs->outBuffContentSize - zcs->outBuffFlushedSize)); - return zcs->outBuffContentSize - zcs->outBuffFlushedSize; + { size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE; + size_t const checksumSize = zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4; + size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize + lastBlockSize + checksumSize; + DEBUGLOG(5, "ZSTD_endStream : remaining to flush : %u", + (unsigned)toFlush); + return toFlush; + } } @@ -4138,7 +4143,7 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1) /* This function just controls * the monotonic memory budget increase of ZSTD_defaultCParameters[0]. - * Run only once, on first ZSTD_getCParams() usage, when ZSTD_DEBUG is enabled + * Run once, on first ZSTD_getCParams() usage, if ZSTD_DEBUG is enabled */ MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void) { @@ -4146,7 +4151,6 @@ MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void) for (level=1; level