contrib/python-zstandard/zstd/compress/fse_compress.c
changeset 37495 b1fb341d8a61
parent 30822 b54a2984cdd4
child 40121 73fef626dae3
equal deleted inserted replaced
37494:1ce7a55b09d1 37495:b1fb341d8a61
    31     - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    31     - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
    32     - Public forum : https://groups.google.com/forum/#!forum/lz4c
    32     - Public forum : https://groups.google.com/forum/#!forum/lz4c
    33 ****************************************************************** */
    33 ****************************************************************** */
    34 
    34 
    35 /* **************************************************************
    35 /* **************************************************************
    36 *  Compiler specifics
       
    37 ****************************************************************/
       
    38 #ifdef _MSC_VER    /* Visual Studio */
       
    39 #  define FORCE_INLINE static __forceinline
       
    40 #  include <intrin.h>                    /* For Visual 2005 */
       
    41 #  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
       
    42 #  pragma warning(disable : 4214)        /* disable: C4214: non-int bitfields */
       
    43 #else
       
    44 #  if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
       
    45 #    ifdef __GNUC__
       
    46 #      define FORCE_INLINE static inline __attribute__((always_inline))
       
    47 #    else
       
    48 #      define FORCE_INLINE static inline
       
    49 #    endif
       
    50 #  else
       
    51 #    define FORCE_INLINE static
       
    52 #  endif /* __STDC_VERSION__ */
       
    53 #endif
       
    54 
       
    55 
       
    56 /* **************************************************************
       
    57 *  Includes
    36 *  Includes
    58 ****************************************************************/
    37 ****************************************************************/
    59 #include <stdlib.h>     /* malloc, free, qsort */
    38 #include <stdlib.h>     /* malloc, free, qsort */
    60 #include <string.h>     /* memcpy, memset */
    39 #include <string.h>     /* memcpy, memset */
    61 #include <stdio.h>      /* printf (debug) */
    40 #include <stdio.h>      /* printf (debug) */
    62 #include "bitstream.h"
    41 #include "bitstream.h"
       
    42 #include "compiler.h"
    63 #define FSE_STATIC_LINKING_ONLY
    43 #define FSE_STATIC_LINKING_ONLY
    64 #include "fse.h"
    44 #include "fse.h"
       
    45 #include "error_private.h"
    65 
    46 
    66 
    47 
    67 /* **************************************************************
    48 /* **************************************************************
    68 *  Error Management
    49 *  Error Management
    69 ****************************************************************/
    50 ****************************************************************/
       
    51 #define FSE_isError ERR_isError
    70 #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    52 #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
    71 
    53 
    72 
    54 
    73 /* **************************************************************
    55 /* **************************************************************
    74 *  Templates
    56 *  Templates
   198 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
   180 size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
   199 {
   181 {
   200     size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
   182     size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
   201     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
   183     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
   202 }
   184 }
   203 
       
   204 static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
       
   205 
   185 
   206 static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
   186 static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
   207                                        const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
   187                                        const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
   208                                        unsigned writeIsSafe)
   188                                        unsigned writeIsSafe)
   209 {
   189 {
   256                 out[1] = (BYTE)(bitStream>>8);
   236                 out[1] = (BYTE)(bitStream>>8);
   257                 out += 2;
   237                 out += 2;
   258                 bitStream >>= 16;
   238                 bitStream >>= 16;
   259                 bitCount -= 16;
   239                 bitCount -= 16;
   260         }   }
   240         }   }
   261         {   short count = normalizedCounter[charnum++];
   241         {   int count = normalizedCounter[charnum++];
   262             const short max = (short)((2*threshold-1)-remaining);
   242             int const max = (2*threshold-1)-remaining;
   263             remaining -= FSE_abs(count);
   243             remaining -= count < 0 ? -count : count;
   264             if (remaining<1) return ERROR(GENERIC);
       
   265             count++;   /* +1 for extra accuracy */
   244             count++;   /* +1 for extra accuracy */
   266             if (count>=threshold) count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
   245             if (count>=threshold) count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
   267             bitStream += count << bitCount;
   246             bitStream += count << bitCount;
   268             bitCount  += nbBits;
   247             bitCount  += nbBits;
   269             bitCount  -= (count<max);
   248             bitCount  -= (count<max);
   270             previous0  = (count==1);
   249             previous0  = (count==1);
   271             while (remaining<threshold) nbBits--, threshold>>=1;
   250             if (remaining<1) return ERROR(GENERIC);
       
   251             while (remaining<threshold) { nbBits--; threshold>>=1; }
   272         }
   252         }
   273         if (bitCount>16) {
   253         if (bitCount>16) {
   274             if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
   254             if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
   275             out[0] = (BYTE)bitStream;
   255             out[0] = (BYTE)bitStream;
   276             out[1] = (BYTE)(bitStream>>8);
   256             out[1] = (BYTE)(bitStream>>8);
   291 }
   271 }
   292 
   272 
   293 
   273 
   294 size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
   274 size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
   295 {
   275 {
   296     if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
   276     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported */
   297     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
   277     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
   298 
   278 
   299     if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
   279     if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
   300         return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
   280         return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
   301 
   281 
   310 /*! FSE_count_simple
   290 /*! FSE_count_simple
   311     This function counts byte values within `src`, and store the histogram into table `count`.
   291     This function counts byte values within `src`, and store the histogram into table `count`.
   312     It doesn't use any additional memory.
   292     It doesn't use any additional memory.
   313     But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
   293     But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
   314     For this reason, prefer using a table `count` with 256 elements.
   294     For this reason, prefer using a table `count` with 256 elements.
   315     @return : count of most numerous element
   295     @return : count of most numerous element.
   316 */
   296 */
   317 size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
   297 size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
   318                         const void* src, size_t srcSize)
   298                         const void* src, size_t srcSize)
   319 {
   299 {
   320     const BYTE* ip = (const BYTE*)src;
   300     const BYTE* ip = (const BYTE*)src;
   323     unsigned max=0;
   303     unsigned max=0;
   324 
   304 
   325     memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
   305     memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
   326     if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
   306     if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
   327 
   307 
   328     while (ip<end) count[*ip++]++;
   308     while (ip<end) {
       
   309         assert(*ip <= maxSymbolValue);
       
   310         count[*ip++]++;
       
   311     }
   329 
   312 
   330     while (!count[maxSymbolValue]) maxSymbolValue--;
   313     while (!count[maxSymbolValue]) maxSymbolValue--;
   331     *maxSymbolValuePtr = maxSymbolValue;
   314     *maxSymbolValuePtr = maxSymbolValue;
   332 
   315 
   333     { U32 s; for (s=0; s<=maxSymbolValue; s++) if (count[s] > max) max = count[s]; }
   316     { U32 s; for (s=0; s<=maxSymbolValue; s++) if (count[s] > max) max = count[s]; }
   336 }
   319 }
   337 
   320 
   338 
   321 
   339 /* FSE_count_parallel_wksp() :
   322 /* FSE_count_parallel_wksp() :
   340  * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
   323  * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
   341  * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
   324  * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`.
       
   325  * @return : largest histogram frequency, or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */
   342 static size_t FSE_count_parallel_wksp(
   326 static size_t FSE_count_parallel_wksp(
   343                                 unsigned* count, unsigned* maxSymbolValuePtr,
   327                                 unsigned* count, unsigned* maxSymbolValuePtr,
   344                                 const void* source, size_t sourceSize,
   328                                 const void* source, size_t sourceSize,
   345                                 unsigned checkMax, unsigned* const workSpace)
   329                                 unsigned checkMax, unsigned* const workSpace)
   346 {
   330 {
   351     U32* const Counting1 = workSpace;
   335     U32* const Counting1 = workSpace;
   352     U32* const Counting2 = Counting1 + 256;
   336     U32* const Counting2 = Counting1 + 256;
   353     U32* const Counting3 = Counting2 + 256;
   337     U32* const Counting3 = Counting2 + 256;
   354     U32* const Counting4 = Counting3 + 256;
   338     U32* const Counting4 = Counting3 + 256;
   355 
   339 
   356     memset(Counting1, 0, 4*256*sizeof(unsigned));
   340     memset(workSpace, 0, 4*256*sizeof(unsigned));
   357 
   341 
   358     /* safety checks */
   342     /* safety checks */
   359     if (!sourceSize) {
   343     if (!sourceSize) {
   360         memset(count, 0, maxSymbolValue + 1);
   344         memset(count, 0, maxSymbolValue + 1);
   361         *maxSymbolValuePtr = 0;
   345         *maxSymbolValuePtr = 0;
   397         U32 s; for (s=255; s>maxSymbolValue; s--) {
   381         U32 s; for (s=255; s>maxSymbolValue; s--) {
   398             Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
   382             Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
   399             if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
   383             if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
   400     }   }
   384     }   }
   401 
   385 
   402     {   U32 s; for (s=0; s<=maxSymbolValue; s++) {
   386     {   U32 s;
       
   387         if (maxSymbolValue > 255) maxSymbolValue = 255;
       
   388         for (s=0; s<=maxSymbolValue; s++) {
   403             count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
   389             count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
   404             if (count[s] > max) max = count[s];
   390             if (count[s] > max) max = count[s];
   405     }   }
   391     }   }
   406 
   392 
   407     while (!count[maxSymbolValue]) maxSymbolValue--;
   393     while (!count[maxSymbolValue]) maxSymbolValue--;
   411 
   397 
   412 /* FSE_countFast_wksp() :
   398 /* FSE_countFast_wksp() :
   413  * Same as FSE_countFast(), but using an externally provided scratch buffer.
   399  * Same as FSE_countFast(), but using an externally provided scratch buffer.
   414  * `workSpace` size must be table of >= `1024` unsigned */
   400  * `workSpace` size must be table of >= `1024` unsigned */
   415 size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
   401 size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
   416                      const void* source, size_t sourceSize, unsigned* workSpace)
   402                           const void* source, size_t sourceSize,
   417 {
   403                           unsigned* workSpace)
   418     if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
   404 {
       
   405     if (sourceSize < 1500) /* heuristic threshold */
       
   406         return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
   419     return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
   407     return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
   420 }
   408 }
   421 
   409 
   422 /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
   410 /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
   423 size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
   411 size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
   476 void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
   464 void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
   477 
   465 
   478 /* provides the minimum logSize to safely represent a distribution */
   466 /* provides the minimum logSize to safely represent a distribution */
   479 static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
   467 static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
   480 {
   468 {
   481 	U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
   469     U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
   482 	U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
   470     U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
   483 	U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
   471     U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
   484 	return minBits;
   472     assert(srcSize > 1); /* Not supported, RLE should be used instead */
       
   473     return minBits;
   485 }
   474 }
   486 
   475 
   487 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
   476 unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
   488 {
   477 {
   489 	U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
   478     U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
   490     U32 tableLog = maxTableLog;
   479     U32 tableLog = maxTableLog;
   491 	U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
   480     U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
       
   481     assert(srcSize > 1); /* Not supported, RLE should be used instead */
   492     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
   482     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
   493 	if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
   483     if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
   494 	if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
   484     if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
   495     if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
   485     if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
   496     if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
   486     if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
   497     return tableLog;
   487     return tableLog;
   498 }
   488 }
   499 
   489 
   506 /* Secondary normalization method.
   496 /* Secondary normalization method.
   507    To be used when primary method fails. */
   497    To be used when primary method fails. */
   508 
   498 
   509 static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
   499 static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
   510 {
   500 {
       
   501     short const NOT_YET_ASSIGNED = -2;
   511     U32 s;
   502     U32 s;
   512     U32 distributed = 0;
   503     U32 distributed = 0;
   513     U32 ToDistribute;
   504     U32 ToDistribute;
   514 
   505 
   515     /* Init */
   506     /* Init */
   531             norm[s] = 1;
   522             norm[s] = 1;
   532             distributed++;
   523             distributed++;
   533             total -= count[s];
   524             total -= count[s];
   534             continue;
   525             continue;
   535         }
   526         }
   536         norm[s]=-2;
   527 
       
   528         norm[s]=NOT_YET_ASSIGNED;
   537     }
   529     }
   538     ToDistribute = (1 << tableLog) - distributed;
   530     ToDistribute = (1 << tableLog) - distributed;
   539 
   531 
   540     if ((total / ToDistribute) > lowOne) {
   532     if ((total / ToDistribute) > lowOne) {
   541         /* risk of rounding to zero */
   533         /* risk of rounding to zero */
   542         lowOne = (U32)((total * 3) / (ToDistribute * 2));
   534         lowOne = (U32)((total * 3) / (ToDistribute * 2));
   543         for (s=0; s<=maxSymbolValue; s++) {
   535         for (s=0; s<=maxSymbolValue; s++) {
   544             if ((norm[s] == -2) && (count[s] <= lowOne)) {
   536             if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
   545                 norm[s] = 1;
   537                 norm[s] = 1;
   546                 distributed++;
   538                 distributed++;
   547                 total -= count[s];
   539                 total -= count[s];
   548                 continue;
   540                 continue;
   549         }   }
   541         }   }
   554         /* all values are pretty poor;
   546         /* all values are pretty poor;
   555            probably incompressible data (should have already been detected);
   547            probably incompressible data (should have already been detected);
   556            find max, then give all remaining points to max */
   548            find max, then give all remaining points to max */
   557         U32 maxV = 0, maxC = 0;
   549         U32 maxV = 0, maxC = 0;
   558         for (s=0; s<=maxSymbolValue; s++)
   550         for (s=0; s<=maxSymbolValue; s++)
   559             if (count[s] > maxC) maxV=s, maxC=count[s];
   551             if (count[s] > maxC) { maxV=s; maxC=count[s]; }
   560         norm[maxV] += (short)ToDistribute;
   552         norm[maxV] += (short)ToDistribute;
       
   553         return 0;
       
   554     }
       
   555 
       
   556     if (total == 0) {
       
   557         /* all of the symbols were low enough for the lowOne or lowThreshold */
       
   558         for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
       
   559             if (norm[s] > 0) { ToDistribute--; norm[s]++; }
   561         return 0;
   560         return 0;
   562     }
   561     }
   563 
   562 
   564     {   U64 const vStepLog = 62 - tableLog;
   563     {   U64 const vStepLog = 62 - tableLog;
   565         U64 const mid = (1ULL << (vStepLog-1)) - 1;
   564         U64 const mid = (1ULL << (vStepLog-1)) - 1;
   566         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
   565         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
   567         U64 tmpTotal = mid;
   566         U64 tmpTotal = mid;
   568         for (s=0; s<=maxSymbolValue; s++) {
   567         for (s=0; s<=maxSymbolValue; s++) {
   569             if (norm[s]==-2) {
   568             if (norm[s]==NOT_YET_ASSIGNED) {
   570                 U64 const end = tmpTotal + (count[s] * rStep);
   569                 U64 const end = tmpTotal + (count[s] * rStep);
   571                 U32 const sStart = (U32)(tmpTotal >> vStepLog);
   570                 U32 const sStart = (U32)(tmpTotal >> vStepLog);
   572                 U32 const sEnd = (U32)(end >> vStepLog);
   571                 U32 const sEnd = (U32)(end >> vStepLog);
   573                 U32 const weight = sEnd - sStart;
   572                 U32 const weight = sEnd - sStart;
   574                 if (weight < 1)
   573                 if (weight < 1)
   589     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
   588     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
   590     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
   589     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
   591     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
   590     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
   592     if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
   591     if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
   593 
   592 
   594     {   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
   593     {   static U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
   595         U64 const scale = 62 - tableLog;
   594         U64 const scale = 62 - tableLog;
   596         U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
   595         U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
   597         U64 const vStep = 1ULL<<(scale-20);
   596         U64 const vStep = 1ULL<<(scale-20);
   598         int stillToDistribute = 1<<tableLog;
   597         int stillToDistribute = 1<<tableLog;
   599         unsigned s;
   598         unsigned s;
   611                 short proba = (short)((count[s]*step) >> scale);
   610                 short proba = (short)((count[s]*step) >> scale);
   612                 if (proba<8) {
   611                 if (proba<8) {
   613                     U64 restToBeat = vStep * rtbTable[proba];
   612                     U64 restToBeat = vStep * rtbTable[proba];
   614                     proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
   613                     proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
   615                 }
   614                 }
   616                 if (proba > largestP) largestP=proba, largest=s;
   615                 if (proba > largestP) { largestP=proba; largest=s; }
   617                 normalizedCounter[s] = proba;
   616                 normalizedCounter[s] = proba;
   618                 stillToDistribute -= proba;
   617                 stillToDistribute -= proba;
   619         }   }
   618         }   }
   620         if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
   619         if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
   621             /* corner case, need another normalization method */
   620             /* corner case, need another normalization method */
   772 }
   771 }
   773 
   772 
   774 
   773 
   775 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
   774 size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
   776 
   775 
   777 #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
   776 #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
   778 #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
   777 #define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }
   779 
   778 
   780 /* FSE_compress_wksp() :
   779 /* FSE_compress_wksp() :
   781  * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
   780  * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
   782  * `wkspSize` size must be `(1<<tableLog)`.
   781  * `wkspSize` size must be `(1<<tableLog)`.
   799     if (srcSize <= 1) return 0;  /* Not compressible */
   798     if (srcSize <= 1) return 0;  /* Not compressible */
   800     if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
   799     if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
   801     if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
   800     if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
   802 
   801 
   803     /* Scan input and build symbol stats */
   802     /* Scan input and build symbol stats */
   804     {   CHECK_V_F(maxCount, FSE_count(count, &maxSymbolValue, src, srcSize) );
   803     {   CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) );
   805         if (maxCount == srcSize) return 1;   /* only a single symbol in src : rle */
   804         if (maxCount == srcSize) return 1;   /* only a single symbol in src : rle */
   806         if (maxCount == 1) return 0;         /* each symbol present maximum once => not compressible */
   805         if (maxCount == 1) return 0;         /* each symbol present maximum once => not compressible */
   807         if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
   806         if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
   808     }
   807     }
   809 
   808