]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
changed dictionary format
authorYann Collet <yann.collet.73@gmail.com>
Wed, 27 Jan 2016 23:18:06 +0000 (00:18 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Wed, 27 Jan 2016 23:21:13 +0000 (00:21 +0100)
NEWS
lib/fse.c
lib/fse.h
lib/fse_static.h
lib/zstd_compress.c
lib/zstd_decompress.c
lib/zstd_internal.h
programs/bench.c

diff --git a/NEWS b/NEWS
index 8aaf02d99e4e94b8356dac86a5e612ff2a7683cb..f146eb1403958647e9503be182b3b3c012791475 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,6 @@
+v0.5.0
+Changed streaming & dictionary API
+
 v0.4.7
 Improved : small compression speed improvement in HC mode
 Changed : `zstd_decompress.c` has ZSTD_LEGACY_SUPPORT to 0 by default
index e74c1e833d404f50ced5344100775a276fe50689..309b28caf3089bbb45edcaf69975b0b73cd6dfe0 100644 (file)
--- a/lib/fse.c
+++ b/lib/fse.c
@@ -425,10 +425,7 @@ size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
 }
 
-static short FSE_abs(short a)
-{
-    return a<0 ? -a : a;
-}
+static short FSE_abs(short a) { return a<0 ? -a : a; }
 
 static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
                                        const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
@@ -457,14 +454,11 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
     threshold = tableSize;
     nbBits = tableLog+1;
 
-    while (remaining>1)   /* stops at 1 */
-    {
-        if (previous0)
-        {
+    while (remaining>1) {  /* stops at 1 */
+        if (previous0) {
             unsigned start = charnum;
             while (!normalizedCounter[charnum]) charnum++;
-            while (charnum >= start+24)
-            {
+            while (charnum >= start+24) {
                 start+=24;
                 bitStream += 0xFFFFU << bitCount;
                 if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
@@ -473,24 +467,21 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
                 out+=2;
                 bitStream>>=16;
             }
-            while (charnum >= start+3)
-            {
+            while (charnum >= start+3) {
                 start+=3;
                 bitStream += 3 << bitCount;
                 bitCount += 2;
             }
             bitStream += (charnum-start) << bitCount;
             bitCount += 2;
-            if (bitCount>16)
-            {
+            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;
-            }
-        }
+        }   }
         {
             short count = normalizedCounter[charnum++];
             const short max = (short)((2*threshold-1)-remaining);
@@ -504,8 +495,7 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
             previous0 = (count==1);
             while (remaining<threshold) nbBits--, threshold>>=1;
         }
-        if (bitCount>16)
-        {
+        if (bitCount>16) {
             if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
             out[0] = (BYTE)bitStream;
             out[1] = (BYTE)(bitStream>>8);
@@ -564,27 +554,19 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
     threshold = 1<<nbBits;
     nbBits++;
 
-    while ((remaining>1) && (charnum<=*maxSVPtr))
-    {
-        if (previous0)
-        {
+    while ((remaining>1) && (charnum<=*maxSVPtr)) {
+        if (previous0) {
             unsigned n0 = charnum;
-            while ((bitStream & 0xFFFF) == 0xFFFF)
-            {
+            while ((bitStream & 0xFFFF) == 0xFFFF) {
                 n0+=24;
-                if (ip < iend-5)
-                {
+                if (ip < iend-5) {
                     ip+=2;
                     bitStream = MEM_readLE32(ip) >> bitCount;
-                }
-                else
-                {
+                } else {
                     bitStream >>= 16;
                     bitCount+=16;
-                }
-            }
-            while ((bitStream & 3) == 3)
-            {
+            }   }
+            while ((bitStream & 3) == 3) {
                 n0+=3;
                 bitStream>>=2;
                 bitCount+=2;
@@ -593,8 +575,7 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
             bitCount += 2;
             if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
             while (charnum < n0) normalizedCounter[charnum++] = 0;
-            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4))
-            {
+            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
                 ip += bitCount>>3;
                 bitCount &= 7;
                 bitStream = MEM_readLE32(ip) >> bitCount;
@@ -606,13 +587,10 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
             const short max = (short)((2*threshold-1)-remaining);
             short count;
 
-            if ((bitStream & (threshold-1)) < (U32)max)
-            {
+            if ((bitStream & (threshold-1)) < (U32)max) {
                 count = (short)(bitStream & (threshold-1));
                 bitCount   += nbBits-1;
-            }
-            else
-            {
+            } else {
                 count = (short)(bitStream & (2*threshold-1));
                 if (count >= threshold) count -= max;
                 bitCount   += nbBits;
@@ -622,27 +600,20 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
             remaining -= FSE_abs(count);
             normalizedCounter[charnum++] = count;
             previous0 = !count;
-            while (remaining < threshold)
-            {
+            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);
+            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);
+    }   }
     if (remaining != 1) return ERROR(GENERIC);
     *maxSVPtr = charnum-1;
 
@@ -723,22 +694,18 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     U32 lowThreshold = (U32)(total >> tableLog);
     U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
 
-    for (s=0; s<=maxSymbolValue; s++)
-    {
-        if (count[s] == 0)
-        {
+    for (s=0; s<=maxSymbolValue; s++) {
+        if (count[s] == 0) {
             norm[s]=0;
             continue;
         }
-        if (count[s] <= lowThreshold)
-        {
+        if (count[s] <= lowThreshold) {
             norm[s] = -1;
             distributed++;
             total -= count[s];
             continue;
         }
-        if (count[s] <= lowOne)
-        {
+        if (count[s] <= lowOne) {
             norm[s] = 1;
             distributed++;
             total -= count[s];
@@ -748,25 +715,20 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
     }
     ToDistribute = (1 << tableLog) - distributed;
 
-    if ((total / ToDistribute) > lowOne)
-    {
+    if ((total / ToDistribute) > lowOne) {
         /* risk of rounding to zero */
         lowOne = (U32)((total * 3) / (ToDistribute * 2));
-        for (s=0; s<=maxSymbolValue; s++)
-        {
-            if ((norm[s] == -2) && (count[s] <= lowOne))
-            {
+        for (s=0; s<=maxSymbolValue; s++) {
+            if ((norm[s] == -2) && (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 */
@@ -782,10 +744,8 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
         U64 const mid = (1ULL << (vStepLog-1)) - 1;
         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
         U64 tmpTotal = mid;
-        for (s=0; s<=maxSymbolValue; s++)
-        {
-            if (norm[s]==-2)
-            {
+        for (s=0; s<=maxSymbolValue; s++) {
+            if (norm[s]==-2) {
                 U64 end = tmpTotal + (count[s] * rStep);
                 U32 sStart = (U32)(tmpTotal >> vStepLog);
                 U32 sEnd = (U32)(end >> vStepLog);
@@ -794,9 +754,7 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
                     return ERROR(GENERIC);
                 norm[s] = (short)weight;
                 tmpTotal = end;
-            }
-        }
-    }
+    }   }   }
 
     return 0;
 }
@@ -809,7 +767,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
     /* 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(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 */
 
     {
@@ -823,38 +781,23 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
         short largestP=0;
         U32 lowThreshold = (U32)(total >> tableLog);
 
-        for (s=0; s<=maxSymbolValue; s++)
-        {
-            if (count[s] == total) return 0;
-            if (count[s] == 0)
-            {
-                normalizedCounter[s]=0;
-                continue;
-            }
-            if (count[s] <= lowThreshold)
-            {
+        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
-            {
+            } else {
                 short proba = (short)((count[s]*step) >> scale);
-                if (proba<8)
-                {
+                if (proba<8) {
                     U64 restToBeat = vStep * rtbTable[proba];
                     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))
-        {
+        }   }
+        if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
             /* corner case, need another normalization method */
             size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
             if (FSE_isError(errorCode)) return errorCode;
@@ -904,8 +847,7 @@ size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
         tableU16[s] = (U16)(tableSize + s);
 
     /* Build Symbol Transformation Table */
-    for (s=0; s<=maxSymbolValue; s++)
-    {
+    for (s=0; s<=maxSymbolValue; s++) {
         symbolTT[s].deltaNbBits = nbBits << 16;
         symbolTT[s].deltaFindState = s-1;
     }
index dd1190f86cffcd22c368ae4b00f10145d5ac41b1..e98f1a54adc131a1469b01eda2e969f0e894e31c 100644 (file)
--- a/lib/fse.h
+++ b/lib/fse.h
@@ -46,7 +46,7 @@ extern "C" {
 #include <stddef.h>    /* size_t, ptrdiff_t */
 
 
-/* *****************************************
+/*-****************************************
 *  FSE simple functions
 ******************************************/
 size_t FSE_compress(void* dst, size_t maxDstSize,
index a881e351fc86aa597fb868c835edb25be01cf08e..3028a2f4020bb433f1477aa25f1a191d1865806f 100644 (file)
@@ -223,8 +223,7 @@ static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t
 /* *****************************************
 *  Implementation of inlined functions
 *******************************************/
-typedef struct
-{
+typedef struct {
     int deltaFindState;
     U32 deltaNbBits;
 } FSE_symbolCompressionTransform; /* total 8 bytes */
index 8ebd58bebd357e052013493dd8dce769dca905a9..2c67c8ae02b30dfc845b96fd42c7c15dff3fbc5a 100644 (file)
@@ -126,7 +126,10 @@ struct ZSTD_CCtx_s
     U32* hashTable;
     U32* contentTable;
     HUF_CElt* hufTable;
-    U32 flagHufTable;
+    U32 flagStaticTables;
+    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)];
 };
 
 
@@ -158,8 +161,7 @@ void ZSTD_validateParams(ZSTD_parameters* params)
     if (params->windowLog   < ZSTD_WINDOWLOG_MIN) params->windowLog = ZSTD_WINDOWLOG_MIN;
 
     /* correct params, to use less memory */
-    if ((params->srcSize > 0) && (params->srcSize < (1<<ZSTD_WINDOWLOG_MAX)))
-    {
+    if ((params->srcSize > 0) && (params->srcSize < (1<<ZSTD_WINDOWLOG_MAX))) {
         U32 srcLog = ZSTD_highbit((U32)(params->srcSize)-1) + 1;
         if (params->windowLog > srcLog) params->windowLog = srcLog;
     }
@@ -188,8 +190,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
         const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog;
         const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog)) * sizeof(U32);
         const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize);
-        if (zc->workSpaceSize < neededSpace)
-        {
+        if (zc->workSpaceSize < neededSpace) {
             free(zc->workSpace);
             zc->workSpace = malloc(neededSpace);
             if (zc->workSpace == NULL) return ERROR(memory_allocation);
@@ -200,7 +201,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
         zc->contentTable = zc->hashTable + ((size_t)1 << params.hashLog);
         zc->seqStore.buffer = zc->contentTable + ((size_t)1 << contentLog);
         zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
-        zc->flagHufTable = 0;
+        zc->flagStaticTables = 0;
         zc->seqStore.buffer = (U32*)(zc->seqStore.buffer) + 256;
     }
 
@@ -253,9 +254,14 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
     dstCCtx->dictLimit   = srcCCtx->dictLimit;
     dstCCtx->lowLimit    = srcCCtx->lowLimit;
 
-    dstCCtx->flagHufTable = srcCCtx->flagHufTable;
-    if (dstCCtx->flagHufTable)
+    /* copy entropy tables */
+    dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
+    if (dstCCtx->flagStaticTables) {
         memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
+        memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
+        memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
+        memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
+    }
 
     return 0;
 }
@@ -271,8 +277,7 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc,
     U32* table32 = zc->hashTable;
     U32 index;
 
-    for (index=0 ; index < tableSpaceU32 ; index++)
-    {
+    for (index=0 ; index < tableSpaceU32 ; index++) {
         if (table32[index] < reducerValue) table32[index] = 0;
         else table32[index] -= reducerValue;
     }
@@ -338,15 +343,35 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc,
    1.2.1) Huff0 block, using sizes from header
         See Huff0 format
 
-   1.2.2) Raw content
+   1.2.2) Huff0 block, using prepared table
 
-   1.2.3) single byte
+   1.2.3) Raw content
 
-   1.2.4) _usingDTable variant ?
+   1.2.4) single byte
 
 
    2) Sequences section
-      TO DO
+
+      - Nb Sequences : 2 bytes, little endian
+      - Control Token : 1 byte (see below)
+      - Dumps Length : 1 or 2 bytes (depending on control token)
+      - Dumps : as stated by dumps length
+      - Literal Lengths FSE table (as needed depending on encoding method)
+      - Offset Codes FSE table (as needed depending on encoding method)
+      - Match Lengths FSE table (as needed depending on encoding method)
+
+    2.1) Control Token
+      8 bits, divided as :
+      0-1 : dumpsLength
+      2-3 : MatchLength, FSE encoding method
+      4-5 : Offset Codes, FSE encoding method
+      6-7 : Literal Lengths, FSE encoding method
+
+      FSE encoding method :
+      FSE_ENCODING_RAW : uncompressed; no header
+      FSE_ENCODING_RLE : single repeated value; header 1 byte
+      FSE_ENCODING_STATIC : use prepared table; no header
+      FSE_ENCODING_DYNAMIC : read NCount
 */
 
 size_t ZSTD_noCompressBlock (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
@@ -399,7 +424,7 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t maxDstSize, const
     BYTE* const ostart = (BYTE* const)dst;
     U32 flSize = 1 + (srcSize>31) + (srcSize>4095);
 
-    (void)maxDstSize;  /* maxDstSize guaranteed to be >=4, hence large enough */
+    (void)maxDstSize;  /* maxDstSize guaranteed to be >=4, hence large enough */
 
     switch(flSize)
     {
@@ -438,14 +463,11 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
 
     if (maxDstSize < 4) return ERROR(dstSize_tooSmall);   /* not enough space for compression */
 
-    if (zc->flagHufTable && (lhSize==3))
-    {
+    if (zc->flagStaticTables && (lhSize==3)) {
         hType = IS_PCH;
         singleStream = 1;
         clitSize = HUF_compress1X_usingCTable(ostart+lhSize, maxDstSize-lhSize, src, srcSize, zc->hufTable);
-    }
-    else
-    {
+    } else {
         clitSize = singleStream ? HUF_compress1X(ostart+lhSize, maxDstSize-lhSize, src, srcSize, 255, 12)
                                 : HUF_compress2 (ostart+lhSize, maxDstSize-lhSize, src, srcSize, 255, 12);
     }
@@ -491,11 +513,10 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
     U32 count[MaxSeq+1];
     S16 norm[MaxSeq+1];
     size_t mostFrequent;
-    U32 max = 255;
-    U32 tableLog = 11;
-    U32 CTable_LitLength  [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL )];
-    U32 CTable_OffsetBits [FSE_CTABLE_SIZE_U32(OffFSELog,MaxOff)];
-    U32 CTable_MatchLength[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML )];
+    U32 max;
+    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 BYTE* const op_lit_start = seqStorePtr->litStart;
     const BYTE* const llTable = seqStorePtr->litLengthStart;
@@ -516,7 +537,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
     {
         size_t cSize;
         size_t litSize = seqStorePtr->lit - op_lit_start;
-        const size_t minLitSize = zc->flagHufTable ? 6 : LITERAL_NOENTROPY;
+        const size_t minLitSize = zc->flagStaticTables ? 6 : LITERAL_NOENTROPY;
 
         if (litSize <= minLitSize)
             cSize = ZSTD_noCompressLiterals(op, maxDstSize, op_lit_start, litSize);
@@ -535,14 +556,11 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
     /* dumps : contains too large lengths */
     {
         size_t dumpsLength = seqStorePtr->dumps - seqStorePtr->dumpsStart;
-        if (dumpsLength < 512)
-        {
+        if (dumpsLength < 512) {
             op[0] = (BYTE)(dumpsLength >> 8);
             op[1] = (BYTE)(dumpsLength);
             op += 2;
-        }
-        else
-        {
+        } else {
             op[0] = 2;
             op[1] = (BYTE)(dumpsLength>>8);
             op[2] = (BYTE)(dumpsLength);
@@ -553,94 +571,86 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
         op += dumpsLength;
     }
 
+#define MIN_SEQ_FOR_DYNAMIC_FSE   64
+#define MAX_SEQ_FOR_STATIC_FSE  1000
+
     /* CTable for Literal Lengths */
     max = MaxLL;
     mostFrequent = FSE_countFast(count, &max, seqStorePtr->litLengthStart, nbSeq);
-    if ((mostFrequent == nbSeq) && (nbSeq > 2))
-    {
+    if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
         *op++ = *(seqStorePtr->litLengthStart);
         FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
-        LLtype = bt_rle;
-    }
-    else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (LLbits-1))))
-    {
+        LLtype = FSE_ENCODING_RLE;
+    } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+        LLtype = FSE_ENCODING_STATIC;
+    } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LLbits-1)))) {
         FSE_buildCTable_raw(CTable_LitLength, LLbits);
-        LLtype = bt_raw;
-    }
-    else
-    {
+        LLtype = FSE_ENCODING_RAW;
+    } else {
         size_t NCountSize;
-        tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
+        U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
         FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
         NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
         if (FSE_isError(NCountSize)) return ERROR(GENERIC);
         op += NCountSize;
         FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
-        LLtype = bt_compressed;
+        LLtype = FSE_ENCODING_DYNAMIC;
     }
 
-    /* CTable for Offsets codes */
-    {
-        /* create Offset codes */
-        size_t i;
-        max = MaxOff;
-        for (i=0; i<nbSeq; i++)
-        {
+    /* CTable for Offset codes */
+    {   /* create Offset codes */
+        size_t i; for (i=0; i<nbSeq; i++) {
             offCodeTable[i] = (BYTE)ZSTD_highbit(offsetTable[i]) + 1;
             if (offsetTable[i]==0) offCodeTable[i]=0;
         }
-        mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
     }
-    if ((mostFrequent == nbSeq) && (nbSeq > 2))
-    {
+    max = MaxOff;
+    mostFrequent = FSE_countFast(count, &max, offCodeTable, nbSeq);
+    if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
         *op++ = *offCodeTable;
         FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
-        Offtype = bt_rle;
-    }
-    else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (Offbits-1))))
-    {
+        Offtype = FSE_ENCODING_RLE;
+    } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+        Offtype = FSE_ENCODING_STATIC;
+    } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (Offbits-1)))) {
         FSE_buildCTable_raw(CTable_OffsetBits, Offbits);
-        Offtype = bt_raw;
-    }
-    else
-    {
+        Offtype = FSE_ENCODING_RAW;
+    } else {
         size_t NCountSize;
-        tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
+        U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
         FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
         NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
         if (FSE_isError(NCountSize)) return ERROR(GENERIC);
         op += NCountSize;
         FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
-        Offtype = bt_compressed;
+        Offtype = FSE_ENCODING_DYNAMIC;
     }
 
     /* CTable for MatchLengths */
     max = MaxML;
     mostFrequent = FSE_countFast(count, &max, seqStorePtr->matchLengthStart, nbSeq);
-    if ((mostFrequent == nbSeq) && (nbSeq > 2))
-    {
+    if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
         *op++ = *seqStorePtr->matchLengthStart;
         FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
-        MLtype = bt_rle;
-    }
-    else if ((nbSeq < 64) || (mostFrequent < (nbSeq >> (MLbits-1))))
-    {
+        MLtype = FSE_ENCODING_RLE;
+    } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+        MLtype = FSE_ENCODING_STATIC;
+    } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (MLbits-1)))) {
         FSE_buildCTable_raw(CTable_MatchLength, MLbits);
-        MLtype = bt_raw;
-    }
-    else
-    {
+        MLtype = FSE_ENCODING_RAW;
+    } else {
         size_t NCountSize;
-        tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
+        U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
         FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
         NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog);   /* overflow protected */
         if (FSE_isError(NCountSize)) return ERROR(GENERIC);
         op += NCountSize;
         FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
-        MLtype = bt_compressed;
+        MLtype = FSE_ENCODING_DYNAMIC;
     }
 
     seqHead[0] += (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
+    zc->flagStaticTables = 0;
 
     /* Encoding Sequences */
     {
@@ -657,14 +667,13 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
         FSE_initCState(&stateOffsetBits, CTable_OffsetBits);
         FSE_initCState(&stateLitLength, CTable_LitLength);
 
-        for (i=(int)nbSeq-1; i>=0; i--)
-        {
-            BYTE matchLength = mlTable[i];
+        for (i=(int)nbSeq-1; i>=0; i--) {
+            BYTE mlCode = mlTable[i];
             U32  offset = offsetTable[i];
             BYTE offCode = offCodeTable[i];                                 /* 32b*/  /* 64b*/
             U32 nbBits = (offCode-1) * (!!offCode);
             BYTE litLength = llTable[i];                                    /* (7)*/  /* (7)*/
-            FSE_encodeSymbol(&blockStream, &stateMatchLength, matchLength); /* 17 */  /* 17 */
+            FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 17 */  /* 17 */
             if (MEM_32bits()) BIT_flushBits(&blockStream);                  /*  7 */
             BIT_addBits(&blockStream, offset, nbBits);                      /* 31 */  /* 42 */   /* 24 bits max in 32-bits mode */
             if (MEM_32bits()) BIT_flushBits(&blockStream);                  /*  7 */
@@ -699,7 +708,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B
 #if 0
     static const BYTE* g_start = NULL;
     if (g_start==NULL) g_start = literals;
-    if (literals - g_start == 8695)
+    //if (literals - g_start == 8695)
     printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
            (U32)(literals - g_start), (U32)litLength, (U32)matchCode+4, (U32)offsetCode);
 #endif
@@ -709,34 +718,28 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B
     seqStorePtr->lit += litLength;
 
     /* literal Length */
-    if (litLength >= MaxLL)
-    {
+    if (litLength >= MaxLL) {
         *(seqStorePtr->litLength++) = MaxLL;
-        if (litLength<255 + MaxLL)
+        if (litLength<255 + MaxLL) {
             *(seqStorePtr->dumps++) = (BYTE)(litLength - MaxLL);
-        else
-        {
+        } else {
             *(seqStorePtr->dumps++) = 255;
             MEM_writeLE32(seqStorePtr->dumps, (U32)litLength); seqStorePtr->dumps += 3;
-        }
-    }
+    }   }
     else *(seqStorePtr->litLength++) = (BYTE)litLength;
 
     /* match offset */
     *(seqStorePtr->offset++) = (U32)offsetCode;
 
     /* match Length */
-    if (matchCode >= MaxML)
-    {
+    if (matchCode >= MaxML) {
         *(seqStorePtr->matchLength++) = MaxML;
-        if (matchCode < 255+MaxML)
+        if (matchCode < 255+MaxML) {
             *(seqStorePtr->dumps++) = (BYTE)(matchCode - MaxML);
-        else
-        {
+        } else {
             *(seqStorePtr->dumps++) = 255;
             MEM_writeLE32(seqStorePtr->dumps, (U32)matchCode); seqStorePtr->dumps += 3;
-        }
-    }
+    }   }
     else *(seqStorePtr->matchLength++) = (BYTE)matchCode;
 }
 
@@ -841,8 +844,7 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLim
 {
     const BYTE* const pStart = pIn;
 
-    while ((pIn<pInLimit-(sizeof(size_t)-1)))
-    {
+    while ((pIn<pInLimit-(sizeof(size_t)-1))) {
         size_t diff = ZSTD_read_ARCH(pMatch) ^ ZSTD_read_ARCH(pIn);
         if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
         pIn += ZSTD_NbCommonBytes(diff);
@@ -917,8 +919,7 @@ static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
     const BYTE* ip = base + zc->nextToUpdate;
     const BYTE* const iend = (const BYTE*) end;
 
-    while(ip <= iend)
-    {
+    while(ip <= iend) {
         hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
         ip += FILLHASHSTEP;
     }
@@ -947,8 +948,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
 
     /* init */
     ZSTD_resetSeqStore(seqStorePtr);
-    if (ip < lowest+4)
-    {
+    if (ip < lowest+4) {
         hashTable[ZSTD_hashPtr(lowest+1, hBits, mls)] = lowIndex+1;
         hashTable[ZSTD_hashPtr(lowest+2, hBits, mls)] = lowIndex+2;
         hashTable[ZSTD_hashPtr(lowest+3, hBits, mls)] = lowIndex+3;
@@ -956,8 +956,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
     }
 
     /* 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 mlCode;
         size_t offset;
         const size_t h = ZSTD_hashPtr(ip, hBits, mls);
@@ -966,17 +965,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
         const U32 current = (U32)(ip-base);
         hashTable[h] = current;   /* update hash table */
 
-        if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))   /* note : by construction, offset_1 <= current */
-        {
+        if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) {   /* note : by construction, offset_1 <= current */
             mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend);
             ip++;
             offset = 0;
-        }
-        else
-        {
+        } else {
             if ( (matchIndex <= lowIndex) ||
-                 (MEM_read32(match) != MEM_read32(ip)) )
-            {
+                 (MEM_read32(match) != MEM_read32(ip)) ) {
                 ip += ((ip-anchor) >> g_searchStrength) + 1;
                 continue;
             }
@@ -992,15 +987,13 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
         ip += mlCode + MINMATCH;
         anchor = ip;
 
-        if (ip <= ilimit)
-        {
+        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)
-                 && (MEM_read32(ip) == MEM_read32(ip - offset_2)) )
-            {
+                 && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
                 /* store sequence */
                 size_t rlCode = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend);
                 size_t tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff;   /* swap offset_2 <=> offset_1 */
@@ -1009,9 +1002,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
                 ip += rlCode+MINMATCH;
                 anchor = ip;
                 continue;   /* faster when present ... (?) */
-            }
-        }
-    }
+    }   }   }
 
     /* Last Literals */
     {
@@ -1067,18 +1058,15 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
 
     /* init */
     ZSTD_resetSeqStore(seqStorePtr);
-    {
-        /* skip first 4 positions to avoid read overflow during repcode match check */
-        hashTable[ZSTD_hashPtr(ip+0, hBits, mls)] = (U32)(ip-base+0);
-        hashTable[ZSTD_hashPtr(ip+1, hBits, mls)] = (U32)(ip-base+1);
-        hashTable[ZSTD_hashPtr(ip+2, hBits, mls)] = (U32)(ip-base+2);
-        hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3);
-        ip += 4;
-    }
+    /* skip first 4 positions to avoid read overflow during repcode match check */
+    hashTable[ZSTD_hashPtr(ip+0, hBits, mls)] = (U32)(ip-base+0);
+    hashTable[ZSTD_hashPtr(ip+1, hBits, mls)] = (U32)(ip-base+1);
+    hashTable[ZSTD_hashPtr(ip+2, hBits, mls)] = (U32)(ip-base+2);
+    hashTable[ZSTD_hashPtr(ip+3, hBits, mls)] = (U32)(ip-base+3);
+    ip += 4;
 
     /* Main 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;
@@ -1092,15 +1080,12 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
         hashTable[h] = current;   /* update hash table */
 
         if ( ((repIndex <= dictLimit-4) || (repIndex >= dictLimit))
-          && (MEM_read32(repMatch) == MEM_read32(ip+1)) )
-        {
+          && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
             const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
             mlCode = ZSTD_count_2segments(ip+1+MINMATCH, repMatch+MINMATCH, iend, repMatchEnd, lowPrefixPtr);
             ip++;
             offset = 0;
-        }
-        else
-        {
+        } else {
             if ( (matchIndex < lowLimit) ||
                  (MEM_read32(match) != MEM_read32(ip)) )
             { ip += ((ip-anchor) >> g_searchStrength) + 1; continue; }
@@ -1108,32 +1093,28 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
                 const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
                 const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
                 mlCode = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iend, matchEnd, lowPrefixPtr);
-                while ((ip>anchor) && (match>lowMatchPtr) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; }  /* catch up */
+                while ((ip>anchor) && (match>lowMatchPtr) && (ip[-1] == match[-1])) { ip--; match--; mlCode++; }   /* catch up */
                 offset = current - matchIndex;
                 offset_2 = offset_1;
                 offset_1 = offset;
-            }
-        }
+        }   }
 
         /* found a match : store it */
         ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset, mlCode);
         ip += mlCode + MINMATCH;
         anchor = ip;
 
-        if (ip <= ilimit)
-        {
+        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)
-            {
+            while (ip <= ilimit) {
                 U32 current2 = (U32)(ip-base);
                 const U32 repIndex2 = current2 - offset_2;
                 const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
                 if ( ((repIndex2 <= dictLimit-4) || (repIndex2 >= dictLimit))
-                  && (MEM_read32(repMatch2) == MEM_read32(ip)) )
-                {
+                  && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
                     const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
                     size_t repLength2 = ZSTD_count_2segments(ip+MINMATCH, repMatch2+MINMATCH, iend, repEnd2, lowPrefixPtr);
                     U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */
@@ -1144,9 +1125,7 @@ void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
                     continue;
                 }
                 break;
-            }
-        }
-    }
+    }   }   }
 
     /* Last Literals */
     {
@@ -1213,14 +1192,13 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
 
     hashTable[h] = current;   /* Update Hash Table */
 
-    while (nbCompares-- && (matchIndex > windowLow))
-    {
+    while (nbCompares-- && (matchIndex > windowLow)) {
         U32* nextPtr = bt + 2*(matchIndex & btMask);
         const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
 
-        if (matchIndex == predictedSmall)
-        {   /* no need to check length, result known */
+        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 */
@@ -1229,8 +1207,7 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
             continue;
         }
 
-        if (matchIndex == predictedLarge)
-        {
+        if (matchIndex == predictedLarge) {
             *largerPtr = matchIndex;
             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
             largerPtr = nextPtr;
@@ -1239,14 +1216,11 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
             continue;
         }
 
-        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;
-        }
-        else
-        {
+        } else {
             match = dictBase + matchIndex;
             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
             if (matchIndex+matchLength >= dictLimit)
@@ -1259,25 +1233,21 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
         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 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
-        {
+        } 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;
     return (matchEndIdx > current + 8) ? matchEndIdx - current - 8 : 1;
@@ -1326,28 +1296,23 @@ size_t ZSTD_insertBtAndFindBestMatch (
 
     hashTable[h] = current;   /* Update Hash Table */
 
-    while (nbCompares-- && (matchIndex > windowLow))
-    {
+    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))
-        {
+        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
-        {
+        } 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 > bestLength) {
             if (matchLength > matchEndIdx - matchIndex)
                 matchEndIdx = matchIndex + (U32)matchLength;
             if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit(current-matchIndex+1) - ZSTD_highbit((U32)offsetPtr[0]+1)) )
@@ -1356,17 +1321,14 @@ size_t ZSTD_insertBtAndFindBestMatch (
                 break;   /* drop, to guarantee consistency (miss a little bit of compression) */
         }
 
-        if (match[matchLength] < ip[matchLength])
-        {
+        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
-        {
+        } else {
             /* match is larger than current */
             *largerPtr = matchIndex;
             commonLengthLarger = matchLength;
@@ -1472,8 +1434,7 @@ static U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
     const U32 target = (U32)(ip - base);
     U32 idx = zc->nextToUpdate;
 
-    while(idx < target)
-    {
+    while(idx < target) {
         size_t h = ZSTD_hashPtr(base+idx, hashLog, mls);
         NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
         hashTable[h] = idx;
@@ -1511,18 +1472,14 @@ size_t ZSTD_HcFindBestMatch_generic (
     /* HC4 match finder */
     matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
 
-    while ((matchIndex>lowLimit) && (nbAttempts))
-    {
+    while ((matchIndex>lowLimit) && (nbAttempts)) {
         size_t currentMl=0;
         nbAttempts--;
-        if ((!extDict) || matchIndex >= dictLimit)
-        {
+        if ((!extDict) || matchIndex >= dictLimit) {
             match = base + matchIndex;
             if (match[ml] == ip[ml])   /* potentially better */
                 currentMl = ZSTD_count(ip, match, iLimit);
-        }
-        else
-        {
+        } else {
             match = dictBase + matchIndex;
             if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */
                 currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
@@ -1601,15 +1558,13 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
     if ((ip-base) < REPCODE_STARTVALUE) ip = base + REPCODE_STARTVALUE;
 
     /* Match Loop */
-    while (ip < ilimit)
-    {
+    while (ip < ilimit) {
         size_t matchLength=0;
         size_t offset=0;
         const BYTE* start=ip+1;
 
         /* check repCode */
-        if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))
-        {
+        if (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1)) {
             /* repcode : we take it */
             matchLength = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend) + MINMATCH;
             if (depth==0) goto _storeSequence;
@@ -1623,19 +1578,16 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
                 matchLength = ml2, start = ip, offset=offsetFound;
         }
 
-        if (matchLength < MINMATCH)
-        {
+        if (matchLength < MINMATCH) {
             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<ilimit)
-        {
+        while (ip<ilimit) {
             ip ++;
-            if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1)))
-            {
+            if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1))) {
                 size_t mlRep = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
                 int gain2 = (int)(mlRep * 3);
                 int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
@@ -1647,19 +1599,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
                 size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
                 int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1));   /* raw approx */
                 int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
-                if ((ml2 >= MINMATCH) && (gain2 > gain1))
-                {
+                if ((ml2 >= MINMATCH) && (gain2 > gain1)) {
                     matchLength = ml2, offset = offset2, start = ip;
                     continue;   /* search a better one */
-                }
-            }
+            }   }
 
             /* let's find an even better one */
-            if ((depth==2) && (ip<ilimit))
-            {
+            if ((depth==2) && (ip<ilimit)) {
                 ip ++;
-                if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1)))
-                {
+                if ((offset) && (MEM_read32(ip) == MEM_read32(ip - offset_1))) {
                     size_t ml2 = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_1, iend) + MINMATCH;
                     int gain2 = (int)(ml2 * 4);
                     int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
@@ -1671,19 +1619,15 @@ void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
                     size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
                     int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1));   /* raw approx */
                     int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
-                    if ((ml2 >= MINMATCH) && (gain2 > gain1))
-                    {
+                    if ((ml2 >= MINMATCH) && (gain2 > gain1)) {
                         matchLength = ml2, offset = offset2, start = ip;
                         continue;
-                    }
-                }
-            }
+            }   }   }
             break;  /* nothing found : store previous solution */
         }
 
         /* catch up */
-        if (offset)
-        {
+        if (offset) {
             while ((start>anchor) && (start>base+offset) && (start[-1] == start[-1-offset]))   /* only search for offset within prefix */
                 { start--; matchLength++; }
             offset_2 = offset_1; offset_1 = offset;
@@ -1699,8 +1643,7 @@ _storeSequence:
 
         /* check immediate repcode */
         while ( (ip <= ilimit)
-             && (MEM_read32(ip) == MEM_read32(ip - offset_2)) )
-        {
+             && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
             /* store sequence */
             matchLength = ZSTD_count(ip+MINMATCH, ip+MINMATCH-offset_2, iend);
             offset = offset_2;
@@ -1710,8 +1653,7 @@ _storeSequence:
             ip += matchLength+MINMATCH;
             anchor = ip;
             continue;   /* faster when present ... (?) */
-        }
-    }
+    }   }
 
     /* Last Literals */
     {
@@ -1774,8 +1716,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
     if ((ip - prefixStart) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
 
     /* Match Loop */
-    while (ip < ilimit)
-    {
+    while (ip < ilimit) {
         size_t matchLength=0;
         size_t offset=0;
         const BYTE* start=ip+1;
@@ -1787,14 +1728,12 @@ 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)   /* intentional overflow */
-            if (MEM_read32(ip+1) == MEM_read32(repMatch))
-            {
+            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+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
                 if (depth==0) goto _storeSequence;
-            }
-        }
+        }   }
 
         {
             /* first search (depth 0) */
@@ -1804,27 +1743,23 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
                 matchLength = ml2, start = ip, offset=offsetFound;
         }
 
-         if (matchLength < MINMATCH)
-        {
+         if (matchLength < MINMATCH) {
             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<ilimit)
-        {
+        while (ip<ilimit) {
             ip ++;
             current++;
             /* check repCode */
-            if (offset)
-            {
+            if (offset) {
                 const U32 repIndex = (U32)(current - offset_1);
                 const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
                 const BYTE* const repMatch = repBase + repIndex;
                 if ((U32)((dictLimit-1) - repIndex) >= 3)   /* intentional overflow */
-                if (MEM_read32(ip) == MEM_read32(repMatch))
-                {
+                if (MEM_read32(ip) == MEM_read32(repMatch)) {
                     /* repcode detected */
                     const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
                     size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
@@ -1832,8 +1767,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
                     int gain1 = (int)(matchLength*3 - ZSTD_highbit((U32)offset+1) + 1);
                     if ((repLength >= MINMATCH) && (gain2 > gain1))
                         matchLength = repLength, offset = 0, start = ip;
-                }
-            }
+            }   }
 
             /* search match, depth 1 */
             {
@@ -1841,27 +1775,22 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
                 size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
                 int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1));   /* raw approx */
                 int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 4);
-                if ((ml2 >= MINMATCH) && (gain2 > gain1))
-                {
+                if ((ml2 >= MINMATCH) && (gain2 > gain1)) {
                     matchLength = ml2, offset = offset2, start = ip;
                     continue;   /* search a better one */
-                }
-            }
+            }   }
 
             /* let's find an even better one */
-            if ((depth==2) && (ip<ilimit))
-            {
+            if ((depth==2) && (ip<ilimit)) {
                 ip ++;
                 current++;
                 /* check repCode */
-                if (offset)
-                {
+                if (offset) {
                     const U32 repIndex = (U32)(current - offset_1);
                     const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
                     const BYTE* const repMatch = repBase + repIndex;
                     if ((U32)((dictLimit-1) - repIndex) >= 3)   /* intentional overflow */
-                    if (MEM_read32(ip) == MEM_read32(repMatch))
-                    {
+                    if (MEM_read32(ip) == MEM_read32(repMatch)) {
                         /* repcode detected */
                         const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
                         size_t repLength = ZSTD_count_2segments(ip+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
@@ -1869,8 +1798,7 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
                         int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 1);
                         if ((repLength >= MINMATCH) && (gain2 > gain1))
                             matchLength = repLength, offset = 0, start = ip;
-                    }
-                }
+                }   }
 
                 /* search match, depth 2 */
                 {
@@ -1878,19 +1806,15 @@ void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
                     size_t ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
                     int gain2 = (int)(ml2*4 - ZSTD_highbit((U32)offset2+1));   /* raw approx */
                     int gain1 = (int)(matchLength*4 - ZSTD_highbit((U32)offset+1) + 7);
-                    if ((ml2 >= MINMATCH) && (gain2 > gain1))
-                    {
+                    if ((ml2 >= MINMATCH) && (gain2 > gain1)) {
                         matchLength = ml2, offset = offset2, start = ip;
                         continue;
-                    }
-                }
-            }
+            }   }   }
             break;  /* nothing found : store previous solution */
         }
 
         /* catch up */
-        if (offset)
-        {
+        if (offset) {
             U32 matchIndex = (U32)((start-base) - offset);
             const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
             const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
@@ -1907,14 +1831,12 @@ _storeSequence:
         }
 
         /* check immediate repcode */
-        while (ip <= ilimit)
-        {
+        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)   /* intentional overflow */
-            if (MEM_read32(ip) == MEM_read32(repMatch))
-            {
+            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+MINMATCH, repMatch+MINMATCH, iend, repEnd, prefixStart) + MINMATCH;
@@ -1925,8 +1847,7 @@ _storeSequence:
                 continue;   /* faster when present ... (?) */
             }
             break;
-        }
-    }
+    }   }
 
     /* Last Literals */
     {
@@ -2161,12 +2082,43 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
 static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
 {
     /* note : magic number already checked */
+    size_t offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize, errorCode;
+    short offcodeNCount[MaxOff+1];
+    unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
+    short matchlengthNCount[MaxML+1];
+    unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
+    short litlengthNCount[MaxLL+1];
+    unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
+
     const size_t hufHeaderSize = HUF_readCTable(zc->hufTable, 255, dict, dictSize);
     if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
-    zc->flagHufTable = 1;
-    return hufHeaderSize;
+    zc->flagStaticTables = 1;
+    dict = (const char*)dict + hufHeaderSize;
+    dictSize -= hufHeaderSize;
+
+    offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
+    if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildCTable(zc->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+    dict = (const char*)dict + offcodeHeaderSize;
+    dictSize -= offcodeHeaderSize;
+
+    matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
+    if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildCTable(zc->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+    dict = (const char*)dict + matchlengthHeaderSize;
+    dictSize -= matchlengthHeaderSize;
+
+    litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
+    if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildCTable(zc->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+
+    return hufHeaderSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
 }
 
+
 static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
 {
     if (dict && dictSize)
@@ -2240,8 +2192,7 @@ size_t ZSTD_compressEnd(ZSTD_CCtx* zc, void* dst, size_t maxDstSize)
     size_t hbSize = 0;
 
     /* empty frame */
-    if (zc->stage==0)
-    {
+    if (zc->stage==0) {
         hbSize = zc->hbSize;
         if (maxDstSize <= hbSize) return ERROR(dstSize_tooSmall);
         zc->stage = 1;
index 93e82884cf6466e45c38bb67fc109868f569e063..b50e474fbcfc1ae8c7d6987df0de18a6a2b1c146 100644 (file)
@@ -51,7 +51,7 @@
 #endif
 
 
-/* *******************************************************
+/*-*******************************************************
 *  Includes
 *********************************************************/
 #include <stdlib.h>      /* calloc */
@@ -67,7 +67,8 @@
 #  include "zstd_legacy.h"
 #endif
 
-/* *******************************************************
+
+/*-*******************************************************
 *  Compiler specifics
 *********************************************************/
 #ifdef _MSC_VER    /* Visual Studio */
@@ -85,7 +86,7 @@
 #endif
 
 
-/* *************************************
+/*-*************************************
 *  Local types
 ***************************************/
 typedef struct
@@ -123,10 +124,10 @@ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
 
 struct ZSTD_DCtx_s
 {
-    U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
-    U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
-    U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
-    U32 hufTableX4[HUF_DTABLE_SIZE(HufLog)];
+    FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
+    FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
+    FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
+    unsigned   hufTableX4[HUF_DTABLE_SIZE(HufLog)];
     const void* previousDstEnd;
     const void* base;
     const void* vBase;
@@ -134,9 +135,9 @@ struct ZSTD_DCtx_s
     size_t expected;
     size_t headerSize;
     ZSTD_parameters params;
-    blockType_t bType;
+    blockType_t bType;   /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
     ZSTD_dStage stage;
-    U32 flagHufTable;
+    U32 flagStaticTables;
     const BYTE* litPtr;
     size_t litBufSize;
     size_t litSize;
@@ -144,6 +145,8 @@ struct ZSTD_DCtx_s
     BYTE headerBuffer[ZSTD_frameHeaderSize_max];
 };  /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
 
+size_t sizeofDCtx (void) { return sizeof(ZSTD_DCtx); }
+
 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
 {
     dctx->expected = ZSTD_frameHeaderSize_min;
@@ -153,7 +156,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
     dctx->vBase = NULL;
     dctx->dictEnd = NULL;
     dctx->hufTableX4[0] = HufLog;
-    dctx->flagHufTable = 0;
+    dctx->flagStaticTables = 0;
     return 0;
 }
 
@@ -197,27 +200,66 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
 */
 
 /* Block format description
-   Literal Section - Sequences Section
+
+   Block = Literal Section - Sequences Section
+   Prerequisite : size of (compressed) block, maximum size of regenerated data
+
    1) Literal Section
-   1.1) Header : up to 5 bytes
-        flags:
+
+   1.1) Header : 1-5 bytes
+        flags: 2 bits
             00 compressed by Huff0
-            01 is Raw (uncompressed)
-            10 is Rle
-            11 unused
-            Note : using 11 for Huff0 with precomputed table ?
+            01 unused
+            10 is Raw (uncompressed)
+            11 is Rle
+            Note : using 01 => Huff0 with precomputed table ?
             Note : delta map ? => compressed ?
-            Note 2 : 19 bits for sizes, seems a bit larger than necessary
-            Note 3 : RLE blocks ?
+
+   1.1.1) Huff0-compressed literal block : 3-5 bytes
+            srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
+            srcSize < 1 KB => 3 bytes (2-2-10-10)
+            srcSize < 16KB => 4 bytes (2-2-14-14)
+            else           => 5 bytes (2-2-18-18)
+            big endian convention
+
+   1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
+        size :  5 bits: (IS_RAW<<6) + (0<<4) + size
+               12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
+                        size&255
+               20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
+                        size>>8&255
+                        size&255
+
+   1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
+        size :  5 bits: (IS_RLE<<6) + (0<<4) + size
+               12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
+                        size&255
+               20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
+                        size>>8&255
+                        size&255
+
+   1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
+            srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
+            srcSize < 1 KB => 3 bytes (2-2-10-10)
+            srcSize < 16KB => 4 bytes (2-2-14-14)
+            else           => 5 bytes (2-2-18-18)
+            big endian convention
+
+        1- CTable available (stored into workspace ?)
+        2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
+
+
+   1.2) Literal block content
 
    1.2.1) Huff0 block, using sizes from header
         See Huff0 format
 
-   1.2.2) Huff0 block, using precomputed DTable
-        _usingDTable variants
+   1.2.2) Huff0 block, using prepared table
+
+   1.2.3) Raw content
+
+   1.2.4) single byte
 
-   1.2.3) uncompressed blocks
-        as the name says (both 2 or 3 bytes variants)
 
    2) Sequences section
       TO DO
@@ -331,7 +373,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
                 litCSize = ((istart[2] &  3) << 16) + (istart[3] << 8) + istart[4];
                 break;
             }
-            if (litSize > BLOCKSIZE) return ERROR(corruption_detected);;
+            if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
 
             if (HUF_isError(singleStream ?
                             HUF_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) :
@@ -350,7 +392,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
             U32 lhSize = ((istart[0]) >> 4) & 3;
             if (lhSize != 1)  /* only case supported for now : small litSize, single stream */
                 return ERROR(corruption_detected);
-            if (!dctx->flagHufTable)
+            if (!dctx->flagStaticTables)
                 return ERROR(dictionary_corrupted);
 
             /* 2 - 2 - 10 - 10 */
@@ -448,14 +490,11 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
     LLtype  = *ip >> 6;
     Offtype = (*ip >> 4) & 3;
     MLtype  = (*ip >> 2) & 3;
-    if (*ip & 2)
-    {
+    if (*ip & 2) {
         dumpsLength  = ip[2];
         dumpsLength += ip[1] << 8;
         ip += 3;
-    }
-    else
-    {
+    } else {
         dumpsLength  = ip[1];
         dumpsLength += (ip[0] & 1) << 8;
         ip += 2;
@@ -476,13 +515,18 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
         switch(LLtype)
         {
         U32 max;
-        case bt_rle :
+        case FSE_ENCODING_RLE :
             LLlog = 0;
-            FSE_buildDTable_rle(DTableLL, *ip++); break;
-        case bt_raw :
+            FSE_buildDTable_rle(DTableLL, *ip++);
+            break;
+        case FSE_ENCODING_RAW :
             LLlog = LLbits;
-            FSE_buildDTable_raw(DTableLL, LLbits); break;
-        default :
+            FSE_buildDTable_raw(DTableLL, LLbits);
+            break;
+        case FSE_ENCODING_STATIC:
+            break;
+        case FSE_ENCODING_DYNAMIC :
+        default :   /* impossible */
             max = MaxLL;
             headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
             if (FSE_isError(headerSize)) return ERROR(GENERIC);
@@ -494,15 +538,19 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
         switch(Offtype)
         {
         U32 max;
-        case bt_rle :
+        case FSE_ENCODING_RLE :
             Offlog = 0;
             if (ip > iend-2) return ERROR(srcSize_wrong);   /* min : "raw", hence no header, but at least xxLog bits */
             FSE_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */
             break;
-        case bt_raw :
+        case FSE_ENCODING_RAW :
             Offlog = Offbits;
-            FSE_buildDTable_raw(DTableOffb, Offbits); break;
-        default :
+            FSE_buildDTable_raw(DTableOffb, Offbits);
+            break;
+        case FSE_ENCODING_STATIC:
+            break;
+        case FSE_ENCODING_DYNAMIC :
+        default :   /* impossible */
             max = MaxOff;
             headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
             if (FSE_isError(headerSize)) return ERROR(GENERIC);
@@ -514,22 +562,26 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLen
         switch(MLtype)
         {
         U32 max;
-        case bt_rle :
+        case FSE_ENCODING_RLE :
             MLlog = 0;
             if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */
-            FSE_buildDTable_rle(DTableML, *ip++); break;
-        case bt_raw :
+            FSE_buildDTable_rle(DTableML, *ip++);
+            break;
+        case FSE_ENCODING_RAW :
             MLlog = MLbits;
-            FSE_buildDTable_raw(DTableML, MLbits); break;
-        default :
+            FSE_buildDTable_raw(DTableML, MLbits);
+            break;
+        case FSE_ENCODING_STATIC:
+            break;
+        case FSE_ENCODING_DYNAMIC :
+        default :   /* impossible */
             max = MaxML;
             headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
             if (FSE_isError(headerSize)) return ERROR(GENERIC);
             if (MLlog > MLFSELog) return ERROR(corruption_detected);
             ip += headerSize;
             FSE_buildDTable(DTableML, norm, max, MLlog);
-        }
-    }
+    }   }
 
     return ip-istart;
 }
@@ -564,12 +616,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
     /* Literal length */
     litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
     prevOffset = litLength ? seq->offset : seqState->prevOffset;
-    if (litLength == MaxLL)
-    {
+    if (litLength == MaxLL) {
         U32 add = *dumps++;
         if (add < 255) litLength += add;
-        else
-        {
+        else {
             litLength = MEM_readLE32(dumps) & 0xFFFFFF;  /* no pb : dumps is always followed by seq tables > 1 byte */
             dumps += 3;
         }
@@ -595,12 +645,10 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
 
     /* MatchLength */
     matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
-    if (matchLength == MaxML)
-    {
+    if (matchLength == MaxML) {
         U32 add = *dumps++;
         if (add < 255) matchLength += add;
-        else
-        {
+        else {
             matchLength = MEM_readLE32(dumps) & 0xFFFFFF;  /* no pb : dumps is always followed by seq tables > 1 byte */
             dumps += 3;
         }
@@ -613,6 +661,15 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
     seq->offset = offset;
     seq->matchLength = matchLength;
     seqState->dumps = dumps;
+
+#if 0
+    {
+        static U64 totalDecoded = 0;
+        printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n",
+           (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset);
+        totalDecoded += litLength + matchLength;
+    }
+#endif
 }
 
 
@@ -657,8 +714,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
             op = oLitEnd + length1;
             sequence.matchLength -= length1;
             match = base;
-        }
-    }
+    }   }
 
     /* match within prefix */
     if (sequence.offset < 8) {
@@ -671,8 +727,7 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
         match += dec32table[sequence.offset];
         ZSTD_copy4(op+4, match);
         match -= sub2;
-    }
-    else {
+    } else {
         ZSTD_copy8(op, match);
     }
     op += 8; match += 8;
@@ -683,9 +738,9 @@ FORCE_INLINE size_t ZSTD_execSequence(BYTE* op,
             match += oend_8 - op;
             op = oend_8;
         }
-        while (op < oMatchEnd) *op++ = *match++;
-    }
-    else {
+        while (op < oMatchEnd)
+            *op++ = *match++;
+    else {
         ZSTD_wildcopy(op, match, sequence.matchLength-8);   /* works even if matchLength < 8 */
     }
     return sequenceLength;
@@ -718,7 +773,7 @@ static size_t ZSTD_decompressSequences(
     /* Build Decoding Tables */
     errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength,
                                       DTableLL, DTableML, DTableOffb,
-                                      ip, iend-ip);
+                                      ip, seqSize);
     if (ZSTD_isError(errorCode)) return errorCode;
     ip += errorCode;
 
@@ -757,8 +812,7 @@ static size_t ZSTD_decompressSequences(
             if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
             if (op != litPtr) memcpy(op, litPtr, lastLLSize);
             op += lastLLSize;
-        }
-    }
+    }   }
 
     return op-ostart;
 }
@@ -1018,10 +1072,40 @@ static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSi
 
 static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
 {
-    size_t hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
+    size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize;
+    short offcodeNCount[MaxOff+1];
+    U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
+    short matchlengthNCount[MaxML+1];
+    unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
+    short litlengthNCount[MaxLL+1];
+    unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
+
+    hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize);
     if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
-    dctx->flagHufTable = 1;
-    return hSize;
+    dict = (const char*)dict + hSize;
+    dictSize -= hSize;
+
+    offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize);
+    if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+    dict = (const char*)dict + offcodeHeaderSize;
+    dictSize -= offcodeHeaderSize;
+
+    matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize);
+    if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+    dict = (const char*)dict + matchlengthHeaderSize;
+    dictSize -= matchlengthHeaderSize;
+
+    litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize);
+    if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
+    errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
+    if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted);
+
+    dctx->flagStaticTables = 1;
+    return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize;
 }
 
 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
index 38bda786ec4e66f1b83451a7a15c1ad4cdd37028..7eda813669291fe4b30f8d44299800789a89bb88 100644 (file)
@@ -94,6 +94,12 @@ static const size_t ZSTD_frameHeaderSize_min = 5;
 #define OffFSELog   9
 #define MaxSeq MAX(MaxLL, MaxML)
 
+#define FSE_ENCODING_RAW     0
+#define FSE_ENCODING_RLE     1
+#define FSE_ENCODING_STATIC  2
+#define FSE_ENCODING_DYNAMIC 3
+
+
 #define HufLog 12
 
 #define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/)
@@ -104,9 +110,9 @@ static const size_t ZSTD_frameHeaderSize_min = 5;
 typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
 
 
-/* ******************************************
+/*-*******************************************
 *  Shared functions to include for inlining
-********************************************/
+*********************************************/
 static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
 
 #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
index 1f35301f0079ec49b3f06ba2aa4097bbbfcb2003..efb9d69f452973f9c7088553cf8d9567c799ccd3 100644 (file)
@@ -293,11 +293,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
             milliTime = BMK_GetMilliStart();
             while (BMK_GetMilliStart() == milliTime);
             milliTime = BMK_GetMilliStart();
-            while (BMK_GetMilliSpan(milliTime) < TIMELOOP)
-            {
+            while (BMK_GetMilliSpan(milliTime) < TIMELOOP) {
                 ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, dictBufferSize+largestBlockSize));
-                for (blockNb=0; blockNb<nbBlocks; blockNb++)
-                {
+                //ZSTD_compressBegin_advanced(refCtx, dictBuffer, dictBufferSize, ZSTD_getParams(cLevel, 0));
+                for (blockNb=0; blockNb<nbBlocks; blockNb++) {
                     ZSTD_copyCCtx(ctx, refCtx);
                     size_t rSize = ZSTD_compressContinue(ctx,
                                           blockTable[blockNb].cPtr,  blockTable[blockNb].cRoom,
@@ -309,6 +308,10 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                                           blockTable[blockNb].cRoom - rSize);
                     if (ZSTD_isError(rSize)) EXM_THROW(2, "ZSTD_compressEnd() failed : %s", ZSTD_getErrorName(rSize));
                     blockTable[blockNb].cSize += rSize;
+
+                    if (blockNb==999999999)
+                        printf("%4u : %6u => %6u bytes (%08X) \n",
+                               blockNb, (U32)blockTable[blockNb].srcSize, (U32)blockTable[blockNb].cSize, XXH32(blockTable[blockNb].cPtr, blockTable[blockNb].cSize, 0));
                 }
                 nbLoops++;
             }
@@ -340,7 +343,8 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                         blockTable[blockNb].cPtr, blockTable[blockNb].cSize);
 
                     if (ZSTD_isError(regenSize))
-                        EXM_THROW(3, "ZSTD_decompress_usingDict() failed : %s", ZSTD_getErrorName(regenSize));
+                        EXM_THROW(3, "ZSTD_decompress_usingPreparedDCtx() failed on block %u : %s",
+                                  blockNb, ZSTD_getErrorName(regenSize));
                     blockTable[blockNb].resSize = regenSize;
             }   }
 
@@ -364,8 +368,11 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
                         }
                         pos = (U32)(u - bacc);
                         bNb = pos / (128 KB);
-                        printf("(segment %u, block %u, pos %u) \n", segNb, bNb, pos);
+                        printf("(block %u, sub %u, pos %u) \n", segNb, bNb, pos);
                         break;
+                    }
+                    if (u==srcSize-1) {  /* should never happen */
+                        printf("no difference detected\n");
                 }   }
                 break;
             }
@@ -375,7 +382,7 @@ static int BMK_benchMem(const void* srcBuffer, size_t srcSize,
         if (crcOrig == crcCheck)
             DISPLAY("%2i-%-17.17s :%10i ->%10i (%5.3f),%6.1f MB/s ,%6.1f MB/s \n", cLevel, displayName, (int)srcSize, (int)cSize, ratio, (double)srcSize / fastestC / 1000., (double)srcSize / fastestD / 1000.);
         else
-            DISPLAY("\n");
+            DISPLAY("%2i-\n", cLevel);
     }
 
     /* clean up */