LCOV - code coverage report
Current view: top level - pression/compressor/zstd/lib/compress - fse_compress.c (source / functions) Hit Total Coverage
Test: Pression Lines: 333 384 86.7 %
Date: 2016-12-06 05:44:58 Functions: 20 24 83.3 %

          Line data    Source code
       1             : /* ******************************************************************
       2             :    FSE : Finite State Entropy encoder
       3             :    Copyright (C) 2013-2015, Yann Collet.
       4             : 
       5             :    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
       6             : 
       7             :    Redistribution and use in source and binary forms, with or without
       8             :    modification, are permitted provided that the following conditions are
       9             :    met:
      10             : 
      11             :        * Redistributions of source code must retain the above copyright
      12             :    notice, this list of conditions and the following disclaimer.
      13             :        * Redistributions in binary form must reproduce the above
      14             :    copyright notice, this list of conditions and the following disclaimer
      15             :    in the documentation and/or other materials provided with the
      16             :    distribution.
      17             : 
      18             :    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      19             :    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      20             :    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      21             :    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      22             :    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      23             :    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      24             :    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      25             :    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      26             :    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      27             :    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      28             :    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      29             : 
      30             :     You can contact the author at :
      31             :     - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
      32             :     - Public forum : https://groups.google.com/forum/#!forum/lz4c
      33             : ****************************************************************** */
      34             : 
      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
      58             : ****************************************************************/
      59             : #include <stdlib.h>     /* malloc, free, qsort */
      60             : #include <string.h>     /* memcpy, memset */
      61             : #include <stdio.h>      /* printf (debug) */
      62             : #include "bitstream.h"
      63             : #define FSE_STATIC_LINKING_ONLY
      64             : #include "fse.h"
      65             : 
      66             : 
      67             : /* **************************************************************
      68             : *  Error Management
      69             : ****************************************************************/
      70             : #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
      71             : 
      72             : 
      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
      81             : ****************************************************************/
      82             : /*
      83             :   designed to be included
      84             :   for type-specific functions (template emulation in C)
      85             :   Objective is to write these functions only once, for improved maintenance
      86             : */
      87             : 
      88             : /* safety checks */
      89             : #ifndef FSE_FUNCTION_EXTENSION
      90             : #  error "FSE_FUNCTION_EXTENSION must be defined"
      91             : #endif
      92             : #ifndef FSE_FUNCTION_TYPE
      93             : #  error "FSE_FUNCTION_TYPE must be defined"
      94             : #endif
      95             : 
      96             : /* Function names */
      97             : #define FSE_CAT(X,Y) X##Y
      98             : #define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
      99             : #define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
     100             : 
     101             : 
     102             : /* Function templates */
     103        6244 : size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
     104             : {
     105        6244 :     U32 const tableSize = 1 << tableLog;
     106        6244 :     U32 const tableMask = tableSize - 1;
     107        6244 :     void* const ptr = ct;
     108        6244 :     U16* const tableU16 = ( (U16*) ptr) + 2;
     109        6244 :     void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
     110        6244 :     FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
     111        6244 :     U32 const step = FSE_TABLESTEP(tableSize);
     112             :     U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
     113             : 
     114             :     FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
     115        6244 :     U32 highThreshold = tableSize-1;
     116             : 
     117             :     /* CTable header */
     118        6244 :     tableU16[-2] = (U16) tableLog;
     119        6244 :     tableU16[-1] = (U16) maxSymbolValue;
     120             : 
     121             :     /* For explanations on how to distribute symbol values over the table :
     122             :     *  http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
     123             : 
     124             :     /* symbol start positions */
     125             :     {   U32 u;
     126        6244 :         cumul[0] = 0;
     127      137218 :         for (u=1; u<=maxSymbolValue+1; u++) {
     128      130974 :             if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */
     129       32864 :                 cumul[u] = cumul[u-1] + 1;
     130       32864 :                 tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
     131             :             } else {
     132       98110 :                 cumul[u] = cumul[u-1] + normalizedCounter[u-1];
     133             :         }   }
     134        6244 :         cumul[maxSymbolValue+1] = tableSize+1;
     135             :     }
     136             : 
     137             :     /* Spread symbols */
     138        6244 :     {   U32 position = 0;
     139             :         U32 symbol;
     140      137218 :         for (symbol=0; symbol<=maxSymbolValue; symbol++) {
     141             :             int nbOccurences;
     142     1732030 :             for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++) {
     143     1601056 :                 tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
     144     1601056 :                 position = (position + step) & tableMask;
     145     1601056 :                 while (position > highThreshold) position = (position + step) & tableMask;   /* Low proba area */
     146             :         }   }
     147             : 
     148        6244 :         if (position!=0) return ERROR(GENERIC);   /* Must have gone through all positions */
     149             :     }
     150             : 
     151             :     /* Build table */
     152     1640164 :     {   U32 u; for (u=0; u<tableSize; u++) {
     153     1633920 :         FSE_FUNCTION_TYPE s = tableSymbol[u];   /* note : static analyzer may not understand tableSymbol is properly initialized */
     154     1633920 :         tableU16[cumul[s]++] = (U16) (tableSize+u);   /* TableU16 : sorted by symbol order; gives next state value */
     155             :     }   }
     156             : 
     157             :     /* Build Symbol Transformation Table */
     158        6244 :     {   unsigned total = 0;
     159             :         unsigned s;
     160      137218 :         for (s=0; s<=maxSymbolValue; s++) {
     161      130974 :             switch (normalizedCounter[s])
     162             :             {
     163       14754 :             case  0: break;
     164             : 
     165             :             case -1:
     166             :             case  1:
     167       46180 :                 symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
     168       46180 :                 symbolTT[s].deltaFindState = total - 1;
     169       46180 :                 total ++;
     170       46180 :                 break;
     171             :             default :
     172             :                 {
     173       70040 :                     U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
     174       70040 :                     U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;
     175       70040 :                     symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
     176       70040 :                     symbolTT[s].deltaFindState = total - normalizedCounter[s];
     177       70040 :                     total +=  normalizedCounter[s];
     178             :     }   }   }   }
     179             : 
     180        6244 :     return 0;
     181             : }
     182             : 
     183             : 
     184             : 
     185             : #ifndef FSE_COMMONDEFS_ONLY
     186             : 
     187             : /*-**************************************************************
     188             : *  FSE NCount encoding-decoding
     189             : ****************************************************************/
     190        5940 : size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
     191             : {
     192        5940 :     size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
     193        5940 :     return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */
     194             : }
     195             : 
     196      113946 : static short FSE_abs(short a) { return (short)(a<0 ? -a : a); }
     197             : 
     198        5940 : static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
     199             :                                        const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
     200             :                                        unsigned writeIsSafe)
     201             : {
     202        5940 :     BYTE* const ostart = (BYTE*) header;
     203        5940 :     BYTE* out = ostart;
     204        5940 :     BYTE* const oend = ostart + headerBufferSize;
     205             :     int nbBits;
     206        5940 :     const int tableSize = 1 << tableLog;
     207             :     int remaining;
     208             :     int threshold;
     209             :     U32 bitStream;
     210             :     int bitCount;
     211        5940 :     unsigned charnum = 0;
     212        5940 :     int previous0 = 0;
     213             : 
     214        5940 :     bitStream = 0;
     215        5940 :     bitCount  = 0;
     216             :     /* Table Size */
     217        5940 :     bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
     218        5940 :     bitCount  += 4;
     219             : 
     220             :     /* Init */
     221        5940 :     remaining = tableSize+1;   /* +1 for extra accuracy */
     222        5940 :     threshold = tableSize;
     223        5940 :     nbBits = tableLog+1;
     224             : 
     225      125826 :     while (remaining>1) {  /* stops at 1 */
     226      113946 :         if (previous0) {
     227        9732 :             unsigned start = charnum;
     228        9732 :             while (!normalizedCounter[charnum]) charnum++;
     229       19478 :             while (charnum >= start+24) {
     230          14 :                 start+=24;
     231          14 :                 bitStream += 0xFFFFU << bitCount;
     232          14 :                 if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
     233          14 :                 out[0] = (BYTE) bitStream;
     234          14 :                 out[1] = (BYTE)(bitStream>>8);
     235          14 :                 out+=2;
     236          14 :                 bitStream>>=16;
     237             :             }
     238       20122 :             while (charnum >= start+3) {
     239         658 :                 start+=3;
     240         658 :                 bitStream += 3 << bitCount;
     241         658 :                 bitCount += 2;
     242             :             }
     243        9732 :             bitStream += (charnum-start) << bitCount;
     244        9732 :             bitCount += 2;
     245        9732 :             if (bitCount>16) {
     246         998 :                 if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
     247         998 :                 out[0] = (BYTE)bitStream;
     248         998 :                 out[1] = (BYTE)(bitStream>>8);
     249         998 :                 out += 2;
     250         998 :                 bitStream >>= 16;
     251         998 :                 bitCount -= 16;
     252             :         }   }
     253      113946 :         {   short count = normalizedCounter[charnum++];
     254      113946 :             const short max = (short)((2*threshold-1)-remaining);
     255      113946 :             remaining -= FSE_abs(count);
     256      113946 :             if (remaining<1) return ERROR(GENERIC);
     257      113946 :             count++;   /* +1 for extra accuracy */
     258      113946 :             if (count>=threshold) count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
     259      113946 :             bitStream += count << bitCount;
     260      113946 :             bitCount  += nbBits;
     261      113946 :             bitCount  -= (count<max);
     262      113946 :             previous0  = (count==1);
     263      113946 :             while (remaining<threshold) nbBits--, threshold>>=1;
     264             :         }
     265      113946 :         if (bitCount>16) {
     266       32800 :             if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
     267       32800 :             out[0] = (BYTE)bitStream;
     268       32800 :             out[1] = (BYTE)(bitStream>>8);
     269       32800 :             out += 2;
     270       32800 :             bitStream >>= 16;
     271       32800 :             bitCount -= 16;
     272             :     }   }
     273             : 
     274             :     /* flush remaining bitStream */
     275        5940 :     if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall);   /* Buffer overflow */
     276        5940 :     out[0] = (BYTE)bitStream;
     277        5940 :     out[1] = (BYTE)(bitStream>>8);
     278        5940 :     out+= (bitCount+7) /8;
     279             : 
     280        5940 :     if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
     281             : 
     282        5940 :     return (out-ostart);
     283             : }
     284             : 
     285             : 
     286        5940 : size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
     287             : {
     288        5940 :     if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
     289        5940 :     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */
     290             : 
     291        5940 :     if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
     292           0 :         return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
     293             : 
     294        5940 :     return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
     295             : }
     296             : 
     297             : 
     298             : 
     299             : /*-**************************************************************
     300             : *  Counting histogram
     301             : ****************************************************************/
     302             : /*! FSE_count_simple
     303             :     This function just counts byte values within `src`,
     304             :     and store the histogram into table `count`.
     305             :     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.
     307             :     @return : count of most numerous element
     308             : */
     309        2756 : static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
     310             :                                const void* src, size_t srcSize)
     311             : {
     312        2756 :     const BYTE* ip = (const BYTE*)src;
     313        2756 :     const BYTE* const end = ip + srcSize;
     314        2756 :     unsigned maxSymbolValue = *maxSymbolValuePtr;
     315        2756 :     unsigned max=0;
     316             : 
     317             : 
     318        2756 :     memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
     319        2756 :     if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
     320             : 
     321        2756 :     while (ip<end) count[*ip++]++;
     322             : 
     323        2756 :     while (!count[maxSymbolValue]) maxSymbolValue--;
     324        2756 :     *maxSymbolValuePtr = maxSymbolValue;
     325             : 
     326        2756 :     { U32 s; for (s=0; s<=maxSymbolValue; s++) if (count[s] > max) max = count[s]; }
     327             : 
     328        2756 :     return (size_t)max;
     329             : }
     330             : 
     331             : 
     332        6830 : static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr,
     333             :                                 const void* source, size_t sourceSize,
     334             :                                 unsigned checkMax)
     335             : {
     336        6830 :     const BYTE* ip = (const BYTE*)source;
     337        6830 :     const BYTE* const iend = ip+sourceSize;
     338        6830 :     unsigned maxSymbolValue = *maxSymbolValuePtr;
     339        6830 :     unsigned max=0;
     340             : 
     341             : 
     342        6830 :     U32 Counting1[256] = { 0 };
     343        6830 :     U32 Counting2[256] = { 0 };
     344        6830 :     U32 Counting3[256] = { 0 };
     345        6830 :     U32 Counting4[256] = { 0 };
     346             : 
     347             :     /* safety checks */
     348        6830 :     if (!sourceSize) {
     349           0 :         memset(count, 0, maxSymbolValue + 1);
     350           0 :         *maxSymbolValuePtr = 0;
     351           0 :         return 0;
     352             :     }
     353        6830 :     if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */
     354             : 
     355             :     /* by stripes of 16 bytes */
     356        6830 :     {   U32 cached = MEM_read32(ip); ip += 4;
     357    21290798 :         while (ip < iend-15) {
     358    21277138 :             U32 c = cached; cached = MEM_read32(ip); ip += 4;
     359    21277138 :             Counting1[(BYTE) c     ]++;
     360    21277138 :             Counting2[(BYTE)(c>>8) ]++;
     361    21277138 :             Counting3[(BYTE)(c>>16)]++;
     362    21277138 :             Counting4[       c>>24 ]++;
     363    21277138 :             c = cached; cached = MEM_read32(ip); ip += 4;
     364    21277138 :             Counting1[(BYTE) c     ]++;
     365    21277138 :             Counting2[(BYTE)(c>>8) ]++;
     366    21277138 :             Counting3[(BYTE)(c>>16)]++;
     367    21277138 :             Counting4[       c>>24 ]++;
     368    21277138 :             c = cached; cached = MEM_read32(ip); ip += 4;
     369    21277138 :             Counting1[(BYTE) c     ]++;
     370    21277138 :             Counting2[(BYTE)(c>>8) ]++;
     371    21277138 :             Counting3[(BYTE)(c>>16)]++;
     372    21277138 :             Counting4[       c>>24 ]++;
     373    21277138 :             c = cached; cached = MEM_read32(ip); ip += 4;
     374    21277138 :             Counting1[(BYTE) c     ]++;
     375    21277138 :             Counting2[(BYTE)(c>>8) ]++;
     376    21277138 :             Counting3[(BYTE)(c>>16)]++;
     377    21277138 :             Counting4[       c>>24 ]++;
     378             :         }
     379        6830 :         ip-=4;
     380             :     }
     381             : 
     382             :     /* finish last symbols */
     383        6830 :     while (ip<iend) Counting1[*ip++]++;
     384             : 
     385        6830 :     if (checkMax) {   /* verify stats will fit into destination table */
     386           0 :         U32 s; for (s=255; s>maxSymbolValue; s--) {
     387           0 :             Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
     388           0 :             if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
     389             :     }   }
     390             : 
     391      987010 :     { U32 s; for (s=0; s<=maxSymbolValue; s++) {
     392      980180 :         count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
     393      980180 :         if (count[s] > max) max = count[s];
     394             :     }}
     395             : 
     396        6830 :     while (!count[maxSymbolValue]) maxSymbolValue--;
     397        6830 :     *maxSymbolValuePtr = maxSymbolValue;
     398        6830 :     return (size_t)max;
     399             : }
     400             : 
     401             : /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
     402        9586 : size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
     403             :                      const void* source, size_t sourceSize)
     404             : {
     405        9586 :     if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
     406        6830 :     return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 0);
     407             : }
     408             : 
     409        5362 : size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
     410             :                  const void* source, size_t sourceSize)
     411             : {
     412        5362 :     if (*maxSymbolValuePtr <255)
     413           0 :         return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1);
     414        5362 :     *maxSymbolValuePtr = 255;
     415        5362 :     return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize);
     416             : }
     417             : 
     418             : 
     419             : 
     420             : /*-**************************************************************
     421             : *  FSE Compression Code
     422             : ****************************************************************/
     423             : /*! FSE_sizeof_CTable() :
     424             :     FSE_CTable is a variable size structure which contains :
     425             :     `U16 tableLog;`
     426             :     `U16 maxSymbolValue;`
     427             :     `U16 nextStateNumber[1 << tableLog];`                         // This size is variable
     428             :     `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];`  // This size is variable
     429             : Allocation is manual (C standard does not support variable-size structures).
     430             : */
     431             : 
     432           0 : size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
     433             : {
     434             :     size_t size;
     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 */
     436           0 :     if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);
     437           0 :     size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
     438           0 :     return size;
     439             : }
     440             : 
     441           0 : FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
     442             : {
     443             :     size_t size;
     444           0 :     if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
     445           0 :     size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
     446           0 :     return (FSE_CTable*)malloc(size);
     447             : }
     448             : 
     449           0 : void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
     450             : 
     451             : /* provides the minimum logSize to safely represent a distribution */
     452       13916 : static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
     453             : {
     454       13916 :         U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
     455       13916 :         U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
     456       13916 :         U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
     457       13916 :         return minBits;
     458             : }
     459             : 
     460        7976 : unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
     461             : {
     462        7976 :         U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
     463        7976 :     U32 tableLog = maxTableLog;
     464        7976 :         U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
     465        7976 :     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
     466        7976 :         if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */
     467        7976 :         if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */
     468        7976 :     if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
     469        7976 :     if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
     470        7976 :     return tableLog;
     471             : }
     472             : 
     473        5940 : unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
     474             : {
     475        5940 :     return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
     476             : }
     477             : 
     478             : 
     479             : /* Secondary normalization method.
     480             :    To be used when primary method fails. */
     481             : 
     482           6 : static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
     483             : {
     484             :     U32 s;
     485           6 :     U32 distributed = 0;
     486             :     U32 ToDistribute;
     487             : 
     488             :     /* Init */
     489           6 :     U32 lowThreshold = (U32)(total >> tableLog);
     490           6 :     U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
     491             : 
     492         272 :     for (s=0; s<=maxSymbolValue; s++) {
     493         266 :         if (count[s] == 0) {
     494          52 :             norm[s]=0;
     495          52 :             continue;
     496             :         }
     497         214 :         if (count[s] <= lowThreshold) {
     498         130 :             norm[s] = -1;
     499         130 :             distributed++;
     500         130 :             total -= count[s];
     501         130 :             continue;
     502             :         }
     503          84 :         if (count[s] <= lowOne) {
     504           8 :             norm[s] = 1;
     505           8 :             distributed++;
     506           8 :             total -= count[s];
     507           8 :             continue;
     508             :         }
     509          76 :         norm[s]=-2;
     510             :     }
     511           6 :     ToDistribute = (1 << tableLog) - distributed;
     512             : 
     513           6 :     if ((total / ToDistribute) > lowOne) {
     514             :         /* risk of rounding to zero */
     515           0 :         lowOne = (U32)((total * 3) / (ToDistribute * 2));
     516           0 :         for (s=0; s<=maxSymbolValue; s++) {
     517           0 :             if ((norm[s] == -2) && (count[s] <= lowOne)) {
     518           0 :                 norm[s] = 1;
     519           0 :                 distributed++;
     520           0 :                 total -= count[s];
     521           0 :                 continue;
     522             :         }   }
     523           0 :         ToDistribute = (1 << tableLog) - distributed;
     524             :     }
     525             : 
     526           6 :     if (distributed == maxSymbolValue+1) {
     527             :         /* all values are pretty poor;
     528             :            probably incompressible data (should have already been detected);
     529             :            find max, then give all remaining points to max */
     530           0 :         U32 maxV = 0, maxC = 0;
     531           0 :         for (s=0; s<=maxSymbolValue; s++)
     532           0 :             if (count[s] > maxC) maxV=s, maxC=count[s];
     533           0 :         norm[maxV] += (short)ToDistribute;
     534           0 :         return 0;
     535             :     }
     536             : 
     537             :     {
     538           6 :         U64 const vStepLog = 62 - tableLog;
     539           6 :         U64 const mid = (1ULL << (vStepLog-1)) - 1;
     540           6 :         U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */
     541           6 :         U64 tmpTotal = mid;
     542         272 :         for (s=0; s<=maxSymbolValue; s++) {
     543         266 :             if (norm[s]==-2) {
     544          76 :                 U64 end = tmpTotal + (count[s] * rStep);
     545          76 :                 U32 sStart = (U32)(tmpTotal >> vStepLog);
     546          76 :                 U32 sEnd = (U32)(end >> vStepLog);
     547          76 :                 U32 weight = sEnd - sStart;
     548          76 :                 if (weight < 1)
     549           0 :                     return ERROR(GENERIC);
     550          76 :                 norm[s] = (short)weight;
     551          76 :                 tmpTotal = end;
     552             :     }   }   }
     553             : 
     554           6 :     return 0;
     555             : }
     556             : 
     557             : 
     558        5940 : size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
     559             :                            const unsigned* count, size_t total,
     560             :                            unsigned maxSymbolValue)
     561             : {
     562             :     /* Sanity checks */
     563        5940 :     if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
     564        5940 :     if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */
     565        5940 :     if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */
     566        5940 :     if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */
     567             : 
     568        5940 :     {   U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
     569             : 
     570        5940 :         U64 const scale = 62 - tableLog;
     571        5940 :         U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */
     572        5940 :         U64 const vStep = 1ULL<<(scale-20);
     573        5940 :         int stillToDistribute = 1<<tableLog;
     574             :         unsigned s;
     575        5940 :         unsigned largest=0;
     576        5940 :         short largestP=0;
     577        5940 :         U32 lowThreshold = (U32)(total >> tableLog);
     578             : 
     579      124908 :         for (s=0; s<=maxSymbolValue; s++) {
     580      118968 :             if (count[s] == total) return 0;   /* rle special case */
     581      118968 :             if (count[s] == 0) { normalizedCounter[s]=0; continue; }
     582      104214 :             if (count[s] <= lowThreshold) {
     583       31246 :                 normalizedCounter[s] = -1;
     584       31246 :                 stillToDistribute--;
     585             :             } else {
     586       72968 :                 short proba = (short)((count[s]*step) >> scale);
     587       72968 :                 if (proba<8) {
     588       39974 :                     U64 restToBeat = vStep * rtbTable[proba];
     589       39974 :                     proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
     590             :                 }
     591       72968 :                 if (proba > largestP) largestP=proba, largest=s;
     592       72968 :                 normalizedCounter[s] = proba;
     593       72968 :                 stillToDistribute -= proba;
     594             :         }   }
     595        5940 :         if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
     596             :             /* corner case, need another normalization method */
     597           6 :             size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
     598           6 :             if (FSE_isError(errorCode)) return errorCode;
     599             :         }
     600        5934 :         else normalizedCounter[largest] += (short)stillToDistribute;
     601             :     }
     602             : 
     603             : #if 0
     604             :     {   /* Print Table (debug) */
     605             :         U32 s;
     606             :         U32 nTotal = 0;
     607             :         for (s=0; s<=maxSymbolValue; s++)
     608             :             printf("%3i: %4i \n", s, normalizedCounter[s]);
     609             :         for (s=0; s<=maxSymbolValue; s++)
     610             :             nTotal += abs(normalizedCounter[s]);
     611             :         if (nTotal != (1U<<tableLog))
     612             :             printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
     613             :         getchar();
     614             :     }
     615             : #endif
     616             : 
     617        5940 :     return tableLog;
     618             : }
     619             : 
     620             : 
     621             : /* fake FSE_CTable, for raw (uncompressed) input */
     622           0 : size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
     623             : {
     624           0 :     const unsigned tableSize = 1 << nbBits;
     625           0 :     const unsigned tableMask = tableSize - 1;
     626           0 :     const unsigned maxSymbolValue = tableMask;
     627           0 :     void* const ptr = ct;
     628           0 :     U16* const tableU16 = ( (U16*) ptr) + 2;
     629           0 :     void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1);   /* assumption : tableLog >= 1 */
     630           0 :     FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
     631             :     unsigned s;
     632             : 
     633             :     /* Sanity checks */
     634           0 :     if (nbBits < 1) return ERROR(GENERIC);             /* min size */
     635             : 
     636             :     /* header */
     637           0 :     tableU16[-2] = (U16) nbBits;
     638           0 :     tableU16[-1] = (U16) maxSymbolValue;
     639             : 
     640             :     /* Build table */
     641           0 :     for (s=0; s<tableSize; s++)
     642           0 :         tableU16[s] = (U16)(tableSize + s);
     643             : 
     644             :     /* Build Symbol Transformation Table */
     645           0 :     {   const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
     646             : 
     647           0 :         for (s=0; s<=maxSymbolValue; s++) {
     648           0 :             symbolTT[s].deltaNbBits = deltaNbBits;
     649           0 :             symbolTT[s].deltaFindState = s-1;
     650             :     }   }
     651             : 
     652             : 
     653           0 :     return 0;
     654             : }
     655             : 
     656             : /* fake FSE_CTable, for rle (100% always same symbol) input */
     657          16 : size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
     658             : {
     659          16 :     void* ptr = ct;
     660          16 :     U16* tableU16 = ( (U16*) ptr) + 2;
     661          16 :     void* FSCTptr = (U32*)ptr + 2;
     662          16 :     FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) FSCTptr;
     663             : 
     664             :     /* header */
     665          16 :     tableU16[-2] = (U16) 0;
     666          16 :     tableU16[-1] = (U16) symbolValue;
     667             : 
     668             :     /* Build table */
     669          16 :     tableU16[0] = 0;
     670          16 :     tableU16[1] = 0;   /* just in case */
     671             : 
     672             :     /* Build Symbol Transformation Table */
     673          16 :     symbolTT[symbolValue].deltaNbBits = 0;
     674          16 :     symbolTT[symbolValue].deltaFindState = 0;
     675             : 
     676          16 :     return 0;
     677             : }
     678             : 
     679             : 
     680        2036 : static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
     681             :                            const void* src, size_t srcSize,
     682             :                            const FSE_CTable* ct, const unsigned fast)
     683             : {
     684        2036 :     const BYTE* const istart = (const BYTE*) src;
     685        2036 :     const BYTE* const iend = istart + srcSize;
     686        2036 :     const BYTE* ip=iend;
     687             : 
     688             : 
     689             :     BIT_CStream_t bitC;
     690             :     FSE_CState_t CState1, CState2;
     691             : 
     692             :     /* init */
     693        2036 :     if (srcSize <= 2) return 0;
     694        2036 :     { size_t const errorCode = BIT_initCStream(&bitC, dst, dstSize);
     695        2036 :       if (FSE_isError(errorCode)) return 0; }
     696             : 
     697             : #define FSE_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
     698             : 
     699        2036 :     if (srcSize & 1) {
     700        1996 :         FSE_initCState2(&CState1, ct, *--ip);
     701        1996 :         FSE_initCState2(&CState2, ct, *--ip);
     702        1996 :         FSE_encodeSymbol(&bitC, &CState1, *--ip);
     703        1996 :         FSE_FLUSHBITS(&bitC);
     704             :     } else {
     705          40 :         FSE_initCState2(&CState2, ct, *--ip);
     706          40 :         FSE_initCState2(&CState1, ct, *--ip);
     707             :     }
     708             : 
     709             :     /* join to mod 4 */
     710        2036 :     srcSize -= 2;
     711        2036 :     if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) {  /* test bit 2 */
     712          28 :         FSE_encodeSymbol(&bitC, &CState2, *--ip);
     713          28 :         FSE_encodeSymbol(&bitC, &CState1, *--ip);
     714          28 :         FSE_FLUSHBITS(&bitC);
     715             :     }
     716             : 
     717             :     /* 2 or 4 encoding per loop */
     718      131142 :     for ( ; ip>istart ; ) {
     719             : 
     720      127070 :         FSE_encodeSymbol(&bitC, &CState2, *--ip);
     721             : 
     722             :         if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */
     723             :             FSE_FLUSHBITS(&bitC);
     724             : 
     725      127070 :         FSE_encodeSymbol(&bitC, &CState1, *--ip);
     726             : 
     727             :         if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) {  /* this test must be static */
     728      127070 :             FSE_encodeSymbol(&bitC, &CState2, *--ip);
     729      127070 :             FSE_encodeSymbol(&bitC, &CState1, *--ip);
     730             :         }
     731             : 
     732      127070 :         FSE_FLUSHBITS(&bitC);
     733             :     }
     734             : 
     735        2036 :     FSE_flushCState(&bitC, &CState2);
     736        2036 :     FSE_flushCState(&bitC, &CState1);
     737        2036 :     return BIT_closeCStream(&bitC);
     738             : }
     739             : 
     740        2036 : size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
     741             :                            const void* src, size_t srcSize,
     742             :                            const FSE_CTable* ct)
     743             : {
     744        2036 :     const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
     745             : 
     746        2036 :     if (fast)
     747        2036 :         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
     748             :     else
     749           0 :         return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
     750             : }
     751             : 
     752             : 
     753          74 : size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
     754             : 
     755        2036 : size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
     756             : {
     757        2036 :     const BYTE* const istart = (const BYTE*) src;
     758        2036 :     const BYTE* ip = istart;
     759             : 
     760        2036 :     BYTE* const ostart = (BYTE*) dst;
     761        2036 :     BYTE* op = ostart;
     762        2036 :     BYTE* const oend = ostart + dstSize;
     763             : 
     764             :     U32   count[FSE_MAX_SYMBOL_VALUE+1];
     765             :     S16   norm[FSE_MAX_SYMBOL_VALUE+1];
     766             :     CTable_max_t ct;
     767             :     size_t errorCode;
     768             : 
     769             :     /* init conditions */
     770        2036 :     if (srcSize <= 1) return 0;  /* Uncompressible */
     771        2036 :     if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
     772        2036 :     if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
     773             : 
     774             :     /* Scan input and build symbol stats */
     775        2036 :     errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
     776        2036 :     if (FSE_isError(errorCode)) return errorCode;
     777        2036 :     if (errorCode == srcSize) return 1;
     778        2036 :     if (errorCode == 1) return 0;   /* each symbol only present once */
     779        2036 :     if (errorCode < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */
     780             : 
     781        2036 :     tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
     782        2036 :     errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
     783        2036 :     if (FSE_isError(errorCode)) return errorCode;
     784             : 
     785             :     /* Write table description header */
     786        2036 :     errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog);
     787        2036 :     if (FSE_isError(errorCode)) return errorCode;
     788        2036 :     op += errorCode;
     789             : 
     790             :     /* Compress */
     791        2036 :     errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
     792        2036 :     if (FSE_isError(errorCode)) return errorCode;
     793        2036 :     errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
     794        2036 :     if (errorCode == 0) return 0;   /* not enough space for compressed data */
     795        2036 :     op += errorCode;
     796             : 
     797             :     /* check compressibility */
     798        2036 :     if ( (size_t)(op-ostart) >= srcSize-1 )
     799           0 :         return 0;
     800             : 
     801        2036 :     return op-ostart;
     802             : }
     803             : 
     804        2036 : size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
     805             : {
     806        2036 :     return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
     807             : }
     808             : 
     809             : 
     810             : #endif   /* FSE_COMMONDEFS_ONLY */

Generated by: LCOV version 1.11