contrib/python-zstandard/zstd/compress/fse_compress.c
changeset 30822 b54a2984cdd4
parent 30434 2e484bdea8c4
child 37495 b1fb341d8a61
equal deleted inserted replaced
30821:7005c03f7387 30822:b54a2984cdd4
    69 ****************************************************************/
    69 ****************************************************************/
    70 #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    70 #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    71 
    71 
    72 
    72 
    73 /* **************************************************************
    73 /* **************************************************************
    74 *  Complex types
       
    75 ****************************************************************/
       
    76 typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
       
    77 
       
    78 
       
    79 /* **************************************************************
       
    80 *  Templates
    74 *  Templates
    81 ****************************************************************/
    75 ****************************************************************/
    82 /*
    76 /*
    83   designed to be included
    77   designed to be included
    84   for type-specific functions (template emulation in C)
    78   for type-specific functions (template emulation in C)
    98 #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    92 #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
    99 #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
    93 #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
   100 
    94 
   101 
    95 
   102 /* Function templates */
    96 /* Function templates */
   103 size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
    97 
       
    98 /* FSE_buildCTable_wksp() :
       
    99  * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
       
   100  * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
       
   101  * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
       
   102  */
       
   103 size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
   104 {
   104 {
   105     U32 const tableSize = 1 << tableLog;
   105     U32 const tableSize = 1 << tableLog;
   106     U32 const tableMask = tableSize - 1;
   106     U32 const tableMask = tableSize - 1;
   107     void* const ptr = ct;
   107     void* const ptr = ct;
   108     U16* const tableU16 = ( (U16*) ptr) + 2;
   108     U16* const tableU16 = ( (U16*) ptr) + 2;
   109     void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
   109     void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
   110     FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
   110     FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
   111     U32 const step = FSE_TABLESTEP(tableSize);
   111     U32 const step = FSE_TABLESTEP(tableSize);
   112     U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
   112     U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
   113 
   113 
   114     FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
   114     FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
   115     U32 highThreshold = tableSize-1;
   115     U32 highThreshold = tableSize-1;
   116 
   116 
   117     /* CTable header */
   117     /* CTable header */
       
   118     if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
   118     tableU16[-2] = (U16) tableLog;
   119     tableU16[-2] = (U16) tableLog;
   119     tableU16[-1] = (U16) maxSymbolValue;
   120     tableU16[-1] = (U16) maxSymbolValue;
   120 
   121 
   121     /* For explanations on how to distribute symbol values over the table :
   122     /* For explanations on how to distribute symbol values over the table :
   122     *  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
   123     *  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
   179 
   180 
   180     return 0;
   181     return 0;
   181 }
   182 }
   182 
   183 
   183 
   184 
       
   185 size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
       
   186 {
       
   187     FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE];   /* memset() is not necessary, even if static analyzer complain about it */
       
   188     return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
       
   189 }
       
   190 
       
   191 
   184 
   192 
   185 #ifndef FSE_COMMONDEFS_ONLY
   193 #ifndef FSE_COMMONDEFS_ONLY
   186 
   194 
   187 /*-**************************************************************
   195 /*-**************************************************************
   188 *  FSE NCount encoding-decoding
   196 *  FSE NCount encoding-decoding
   189 ****************************************************************/
   197 ****************************************************************/
   190 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
   198 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
   191 {
   199 {
   192     size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
   200     size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
   193     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
   201     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
   194 }
   202 }
   195 
   203 
   196 static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
   204 static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
   197 
   205 
   298 
   306 
   299 /*-**************************************************************
   307 /*-**************************************************************
   300 *  Counting histogram
   308 *  Counting histogram
   301 ****************************************************************/
   309 ****************************************************************/
   302 /*! FSE_count_simple
   310 /*! FSE_count_simple
   303     This function just counts byte values within `src`,
   311     This function counts byte values within `src`, and store the histogram into table `count`.
   304     and store the histogram into table `count`.
   312     It doesn't use any additional memory.
   305     This function is unsafe : it doesn't check that all values within `src` can fit into `count`.
   313     But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
   306     For this reason, prefer using a table `count` with 256 elements.
   314     For this reason, prefer using a table `count` with 256 elements.
   307     @return : count of most numerous element
   315     @return : count of most numerous element
   308 */
   316 */
   309 static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
   317 size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
   310                                const void* src, size_t srcSize)
   318                         const void* src, size_t srcSize)
   311 {
   319 {
   312     const BYTE* ip = (const BYTE*)src;
   320     const BYTE* ip = (const BYTE*)src;
   313     const BYTE* const end = ip + srcSize;
   321     const BYTE* const end = ip + srcSize;
   314     unsigned maxSymbolValue = *maxSymbolValuePtr;
   322     unsigned maxSymbolValue = *maxSymbolValuePtr;
   315     unsigned max=0;
   323     unsigned max=0;
   316 
   324 
   317 
       
   318     memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
   325     memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
   319     if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
   326     if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
   320 
   327 
   321     while (ip<end) count[*ip++]++;
   328     while (ip<end) count[*ip++]++;
   322 
   329 
   327 
   334 
   328     return (size_t)max;
   335     return (size_t)max;
   329 }
   336 }
   330 
   337 
   331 
   338 
   332 static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr,
   339 /* FSE_count_parallel_wksp() :
       
   340  * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
       
   341  * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
       
   342 static size_t FSE_count_parallel_wksp(
       
   343                                 unsigned* count, unsigned* maxSymbolValuePtr,
   333                                 const void* source, size_t sourceSize,
   344                                 const void* source, size_t sourceSize,
   334                                 unsigned checkMax)
   345                                 unsigned checkMax, unsigned* const workSpace)
   335 {
   346 {
   336     const BYTE* ip = (const BYTE*)source;
   347     const BYTE* ip = (const BYTE*)source;
   337     const BYTE* const iend = ip+sourceSize;
   348     const BYTE* const iend = ip+sourceSize;
   338     unsigned maxSymbolValue = *maxSymbolValuePtr;
   349     unsigned maxSymbolValue = *maxSymbolValuePtr;
   339     unsigned max=0;
   350     unsigned max=0;
   340 
   351     U32* const Counting1 = workSpace;
   341 
   352     U32* const Counting2 = Counting1 + 256;
   342     U32 Counting1[256] = { 0 };
   353     U32* const Counting3 = Counting2 + 256;
   343     U32 Counting2[256] = { 0 };
   354     U32* const Counting4 = Counting3 + 256;
   344     U32 Counting3[256] = { 0 };
   355 
   345     U32 Counting4[256] = { 0 };
   356     memset(Counting1, 0, 4*256*sizeof(unsigned));
   346 
   357 
   347     /* safety checks */
   358     /* safety checks */
   348     if (!sourceSize) {
   359     if (!sourceSize) {
   349         memset(count, 0, maxSymbolValue + 1);
   360         memset(count, 0, maxSymbolValue + 1);
   350         *maxSymbolValuePtr = 0;
   361         *maxSymbolValuePtr = 0;
   386         U32 s; for (s=255; s>maxSymbolValue; s--) {
   397         U32 s; for (s=255; s>maxSymbolValue; s--) {
   387             Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
   398             Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
   388             if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
   399             if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
   389     }   }
   400     }   }
   390 
   401 
   391     { U32 s; for (s=0; s<=maxSymbolValue; s++) {
   402     {   U32 s; for (s=0; s<=maxSymbolValue; s++) {
   392         count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
   403             count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
   393         if (count[s] > max) max = count[s];
   404             if (count[s] > max) max = count[s];
   394     }}
   405     }   }
   395 
   406 
   396     while (!count[maxSymbolValue]) maxSymbolValue--;
   407     while (!count[maxSymbolValue]) maxSymbolValue--;
   397     *maxSymbolValuePtr = maxSymbolValue;
   408     *maxSymbolValuePtr = maxSymbolValue;
   398     return (size_t)max;
   409     return (size_t)max;
   399 }
   410 }
   400 
   411 
       
   412 /* FSE_countFast_wksp() :
       
   413  * Same as FSE_countFast(), but using an externally provided scratch buffer.
       
   414  * `workSpace` size must be table of >= `1024` unsigned */
       
   415 size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
       
   416                      const void* source, size_t sourceSize, unsigned* workSpace)
       
   417 {
       
   418     if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
       
   419     return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
       
   420 }
       
   421 
   401 /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
   422 /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
   402 size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
   423 size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
   403                      const void* source, size_t sourceSize)
   424                      const void* source, size_t sourceSize)
   404 {
   425 {
   405     if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
   426     unsigned tmpCounters[1024];
   406     return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 0);
   427     return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters);
       
   428 }
       
   429 
       
   430 /* FSE_count_wksp() :
       
   431  * Same as FSE_count(), but using an externally provided scratch buffer.
       
   432  * `workSpace` size must be table of >= `1024` unsigned */
       
   433 size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
       
   434                  const void* source, size_t sourceSize, unsigned* workSpace)
       
   435 {
       
   436     if (*maxSymbolValuePtr < 255)
       
   437         return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
       
   438     *maxSymbolValuePtr = 255;
       
   439     return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
   407 }
   440 }
   408 
   441 
   409 size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
   442 size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
   410                  const void* source, size_t sourceSize)
   443                  const void* src, size_t srcSize)
   411 {
   444 {
   412     if (*maxSymbolValuePtr <255)
   445     unsigned tmpCounters[1024];
   413         return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1);
   446     return FSE_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters);
   414     *maxSymbolValuePtr = 255;
       
   415     return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize);
       
   416 }
   447 }
   417 
   448 
   418 
   449 
   419 
   450 
   420 /*-**************************************************************
   451 /*-**************************************************************
   426     `U16 maxSymbolValue;`
   457     `U16 maxSymbolValue;`
   427     `U16 nextStateNumber[1 << tableLog];`                         // This size is variable
   458     `U16 nextStateNumber[1 << tableLog];`                         // This size is variable
   428     `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
   459     `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
   429 Allocation is manual (C standard does not support variable-size structures).
   460 Allocation is manual (C standard does not support variable-size structures).
   430 */
   461 */
   431 
       
   432 size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
   462 size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
   433 {
   463 {
   434     size_t size;
   464     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
   435     FSE_STATIC_ASSERT((size_t)FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)*4 >= sizeof(CTable_max_t));   /* A compilation error here means FSE_CTABLE_SIZE_U32 is not large enough */
   465     return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
   436     if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);
       
   437     size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
       
   438     return size;
       
   439 }
   466 }
   440 
   467 
   441 FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
   468 FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
   442 {
   469 {
   443     size_t size;
   470     size_t size;
   484     U32 s;
   511     U32 s;
   485     U32 distributed = 0;
   512     U32 distributed = 0;
   486     U32 ToDistribute;
   513     U32 ToDistribute;
   487 
   514 
   488     /* Init */
   515     /* Init */
   489     U32 lowThreshold = (U32)(total >> tableLog);
   516     U32 const lowThreshold = (U32)(total >> tableLog);
   490     U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
   517     U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
   491 
   518 
   492     for (s=0; s<=maxSymbolValue; s++) {
   519     for (s=0; s<=maxSymbolValue; s++) {
   493         if (count[s] == 0) {
   520         if (count[s] == 0) {
   494             norm[s]=0;
   521             norm[s]=0;
   532             if (count[s] > maxC) maxV=s, maxC=count[s];
   559             if (count[s] > maxC) maxV=s, maxC=count[s];
   533         norm[maxV] += (short)ToDistribute;
   560         norm[maxV] += (short)ToDistribute;
   534         return 0;
   561         return 0;
   535     }
   562     }
   536 
   563 
   537     {
   564     {   U64 const vStepLog = 62 - tableLog;
   538         U64 const vStepLog = 62 - tableLog;
       
   539         U64 const mid = (1ULL << (vStepLog-1)) - 1;
   565         U64 const mid = (1ULL << (vStepLog-1)) - 1;
   540         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
   566         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
   541         U64 tmpTotal = mid;
   567         U64 tmpTotal = mid;
   542         for (s=0; s<=maxSymbolValue; s++) {
   568         for (s=0; s<=maxSymbolValue; s++) {
   543             if (norm[s]==-2) {
   569             if (norm[s]==-2) {
   544                 U64 end = tmpTotal + (count[s] * rStep);
   570                 U64 const end = tmpTotal + (count[s] * rStep);
   545                 U32 sStart = (U32)(tmpTotal >> vStepLog);
   571                 U32 const sStart = (U32)(tmpTotal >> vStepLog);
   546                 U32 sEnd = (U32)(end >> vStepLog);
   572                 U32 const sEnd = (U32)(end >> vStepLog);
   547                 U32 weight = sEnd - sStart;
   573                 U32 const weight = sEnd - sStart;
   548                 if (weight < 1)
   574                 if (weight < 1)
   549                     return ERROR(GENERIC);
   575                     return ERROR(GENERIC);
   550                 norm[s] = (short)weight;
   576                 norm[s] = (short)weight;
   551                 tmpTotal = end;
   577                 tmpTotal = end;
   552     }   }   }
   578     }   }   }
   564     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
   590     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
   565     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
   591     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
   566     if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
   592     if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
   567 
   593 
   568     {   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
   594     {   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
   569 
       
   570         U64 const scale = 62 - tableLog;
   595         U64 const scale = 62 - tableLog;
   571         U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
   596         U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
   572         U64 const vStep = 1ULL<<(scale-20);
   597         U64 const vStep = 1ULL<<(scale-20);
   573         int stillToDistribute = 1<<tableLog;
   598         int stillToDistribute = 1<<tableLog;
   574         unsigned s;
   599         unsigned s;
   592                 normalizedCounter[s] = proba;
   617                 normalizedCounter[s] = proba;
   593                 stillToDistribute -= proba;
   618                 stillToDistribute -= proba;
   594         }   }
   619         }   }
   595         if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
   620         if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
   596             /* corner case, need another normalization method */
   621             /* corner case, need another normalization method */
   597             size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
   622             size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
   598             if (FSE_isError(errorCode)) return errorCode;
   623             if (FSE_isError(errorCode)) return errorCode;
   599         }
   624         }
   600         else normalizedCounter[largest] += (short)stillToDistribute;
   625         else normalizedCounter[largest] += (short)stillToDistribute;
   601     }
   626     }
   602 
   627 
   641     for (s=0; s<tableSize; s++)
   666     for (s=0; s<tableSize; s++)
   642         tableU16[s] = (U16)(tableSize + s);
   667         tableU16[s] = (U16)(tableSize + s);
   643 
   668 
   644     /* Build Symbol Transformation Table */
   669     /* Build Symbol Transformation Table */
   645     {   const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
   670     {   const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
   646 
       
   647         for (s=0; s<=maxSymbolValue; s++) {
   671         for (s=0; s<=maxSymbolValue; s++) {
   648             symbolTT[s].deltaNbBits = deltaNbBits;
   672             symbolTT[s].deltaNbBits = deltaNbBits;
   649             symbolTT[s].deltaFindState = s-1;
   673             symbolTT[s].deltaFindState = s-1;
   650     }   }
   674     }   }
   651 
   675 
   652 
       
   653     return 0;
   676     return 0;
   654 }
   677 }
   655 
   678 
   656 /* fake FSE_CTable, for rle (100% always same symbol) input */
   679 /* fake FSE_CTable, for rle input (always same symbol) */
   657 size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
   680 size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
   658 {
   681 {
   659     void* ptr = ct;
   682     void* ptr = ct;
   660     U16* tableU16 = ( (U16*) ptr) + 2;
   683     U16* tableU16 = ( (U16*) ptr) + 2;
   661     void* FSCTptr = (U32*)ptr + 2;
   684     void* FSCTptr = (U32*)ptr + 2;
   683 {
   706 {
   684     const BYTE* const istart = (const BYTE*) src;
   707     const BYTE* const istart = (const BYTE*) src;
   685     const BYTE* const iend = istart + srcSize;
   708     const BYTE* const iend = istart + srcSize;
   686     const BYTE* ip=iend;
   709     const BYTE* ip=iend;
   687 
   710 
   688 
       
   689     BIT_CStream_t bitC;
   711     BIT_CStream_t bitC;
   690     FSE_CState_t CState1, CState2;
   712     FSE_CState_t CState1, CState2;
   691 
   713 
   692     /* init */
   714     /* init */
   693     if (srcSize <= 2) return 0;
   715     if (srcSize <= 2) return 0;
   694     { size_t const errorCode = BIT_initCStream(&bitC, dst, dstSize);
   716     { size_t const initError = BIT_initCStream(&bitC, dst, dstSize);
   695       if (FSE_isError(errorCode)) return 0; }
   717       if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ }
   696 
   718 
   697 #define FSE_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
   719 #define FSE_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
   698 
   720 
   699     if (srcSize & 1) {
   721     if (srcSize & 1) {
   700         FSE_initCState2(&CState1, ct, *--ip);
   722         FSE_initCState2(&CState1, ct, *--ip);
   713         FSE_encodeSymbol(&bitC, &CState1, *--ip);
   735         FSE_encodeSymbol(&bitC, &CState1, *--ip);
   714         FSE_FLUSHBITS(&bitC);
   736         FSE_FLUSHBITS(&bitC);
   715     }
   737     }
   716 
   738 
   717     /* 2 or 4 encoding per loop */
   739     /* 2 or 4 encoding per loop */
   718     for ( ; ip>istart ; ) {
   740     while ( ip>istart ) {
   719 
   741 
   720         FSE_encodeSymbol(&bitC, &CState2, *--ip);
   742         FSE_encodeSymbol(&bitC, &CState2, *--ip);
   721 
   743 
   722         if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */
   744         if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */
   723             FSE_FLUSHBITS(&bitC);
   745             FSE_FLUSHBITS(&bitC);
   739 
   761 
   740 size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
   762 size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
   741                            const void* src, size_t srcSize,
   763                            const void* src, size_t srcSize,
   742                            const FSE_CTable* ct)
   764                            const FSE_CTable* ct)
   743 {
   765 {
   744     const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
   766     unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
   745 
   767 
   746     if (fast)
   768     if (fast)
   747         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
   769         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
   748     else
   770     else
   749         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
   771         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
   750 }
   772 }
   751 
   773 
   752 
   774 
   753 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
   775 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
   754 
   776 
   755 size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
   777 #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
   756 {
   778 #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
   757     const BYTE* const istart = (const BYTE*) src;
   779 
   758     const BYTE* ip = istart;
   780 /* FSE_compress_wksp() :
   759 
   781  * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
       
   782  * `wkspSize` size must be `(1<<tableLog)`.
       
   783  */
       
   784 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)
       
   785 {
   760     BYTE* const ostart = (BYTE*) dst;
   786     BYTE* const ostart = (BYTE*) dst;
   761     BYTE* op = ostart;
   787     BYTE* op = ostart;
   762     BYTE* const oend = ostart + dstSize;
   788     BYTE* const oend = ostart + dstSize;
   763 
   789 
   764     U32   count[FSE_MAX_SYMBOL_VALUE+1];
   790     U32   count[FSE_MAX_SYMBOL_VALUE+1];
   765     S16   norm[FSE_MAX_SYMBOL_VALUE+1];
   791     S16   norm[FSE_MAX_SYMBOL_VALUE+1];
   766     CTable_max_t ct;
   792     FSE_CTable* CTable = (FSE_CTable*)workSpace;
   767     size_t errorCode;
   793     size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
       
   794     void* scratchBuffer = (void*)(CTable + CTableSize);
       
   795     size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
   768 
   796 
   769     /* init conditions */
   797     /* init conditions */
   770     if (srcSize <= 1) return 0;  /* Uncompressible */
   798     if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
       
   799     if (srcSize <= 1) return 0;  /* Not compressible */
   771     if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
   800     if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
   772     if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
   801     if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
   773 
   802 
   774     /* Scan input and build symbol stats */
   803     /* Scan input and build symbol stats */
   775     errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
   804     {   CHECK_V_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) );
   776     if (FSE_isError(errorCode)) return errorCode;
   805         if (maxCount == srcSize) return 1;   /* only a single symbol in src : rle */
   777     if (errorCode == srcSize) return 1;
   806         if (maxCount == 1) return 0;         /* each symbol present maximum once => not compressible */
   778     if (errorCode == 1) return 0;   /* each symbol only present once */
   807         if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
   779     if (errorCode < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
   808     }
   780 
   809 
   781     tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
   810     tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
   782     errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
   811     CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
   783     if (FSE_isError(errorCode)) return errorCode;
       
   784 
   812 
   785     /* Write table description header */
   813     /* Write table description header */
   786     errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog);
   814     {   CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
   787     if (FSE_isError(errorCode)) return errorCode;
   815         op += nc_err;
   788     op += errorCode;
   816     }
   789 
   817 
   790     /* Compress */
   818     /* Compress */
   791     errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
   819     CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
   792     if (FSE_isError(errorCode)) return errorCode;
   820     {   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
   793     errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
   821         if (cSize == 0) return 0;   /* not enough space for compressed data */
   794     if (errorCode == 0) return 0;   /* not enough space for compressed data */
   822         op += cSize;
   795     op += errorCode;
   823     }
   796 
   824 
   797     /* check compressibility */
   825     /* check compressibility */
   798     if ( (size_t)(op-ostart) >= srcSize-1 )
   826     if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
   799         return 0;
       
   800 
   827 
   801     return op-ostart;
   828     return op-ostart;
   802 }
   829 }
   803 
   830 
   804 size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
   831 typedef struct {
   805 {
   832     FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
   806     return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
   833     BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
       
   834 } fseWkspMax_t;
       
   835 
       
   836 size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
       
   837 {
       
   838     fseWkspMax_t scratchBuffer;
       
   839     FSE_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE));   /* compilation failures here means scratchBuffer is not large enough */
       
   840     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
       
   841     return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
       
   842 }
       
   843 
       
   844 size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
       
   845 {
       
   846     return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
   807 }
   847 }
   808 
   848 
   809 
   849 
   810 #endif   /* FSE_COMMONDEFS_ONLY */
   850 #endif   /* FSE_COMMONDEFS_ONLY */