LCOV - code coverage report
Current view: top level - pression/compressor/zstd/lib/decompress - huf_decompress.c (source / functions) Hit Total Coverage
Test: Pression Lines: 332 407 81.6 %
Date: 2016-12-06 05:44:58 Functions: 18 33 54.5 %

          Line data    Source code
       1             : /* ******************************************************************
       2             :    Huffman decoder, part of New Generation Entropy library
       3             :    Copyright (C) 2013-2016, 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+HUF 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             : #if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
      39             : /* inline is defined */
      40             : #elif defined(_MSC_VER) || defined(__GNUC__)
      41             : #  define inline __inline
      42             : #else
      43             : #  define inline /* disable inline */
      44             : #endif
      45             : 
      46             : #ifdef _MSC_VER    /* Visual Studio */
      47             : #  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
      48             : #endif
      49             : 
      50             : 
      51             : /* **************************************************************
      52             : *  Dependencies
      53             : ****************************************************************/
      54             : #include <string.h>     /* memcpy, memset */
      55             : #include "bitstream.h"  /* BIT_* */
      56             : #include "fse.h"        /* header compression */
      57             : #define HUF_STATIC_LINKING_ONLY
      58             : #include "huf.h"
      59             : 
      60             : 
      61             : /* **************************************************************
      62             : *  Error Management
      63             : ****************************************************************/
      64             : #define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
      65             : 
      66             : 
      67             : /*-***************************/
      68             : /*  generic DTableDesc       */
      69             : /*-***************************/
      70             : 
      71             : typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
      72             : 
      73        4008 : static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
      74             : {
      75             :     DTableDesc dtd;
      76        4008 :     memcpy(&dtd, table, sizeof(dtd));
      77        4008 :     return dtd;
      78             : }
      79             : 
      80             : 
      81             : /*-***************************/
      82             : /*  single-symbol decoding   */
      83             : /*-***************************/
      84             : 
      85             : typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2;   /* single-symbol decoding */
      86             : 
      87        1212 : size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
      88             : {
      89             :     BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
      90             :     U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */
      91        1212 :     U32 tableLog = 0;
      92        1212 :     U32 nbSymbols = 0;
      93             :     size_t iSize;
      94        1212 :     void* const dtPtr = DTable + 1;
      95        1212 :     HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
      96             : 
      97             :     HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
      98             :     /* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */
      99             : 
     100        1212 :     iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
     101        1212 :     if (HUF_isError(iSize)) return iSize;
     102             : 
     103             :     /* Table header */
     104        1212 :     {   DTableDesc dtd = HUF_getDTableDesc(DTable);
     105        1212 :         if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, huffman tree cannot fit in */
     106        1212 :         dtd.tableType = 0;
     107        1212 :         dtd.tableLog = (BYTE)tableLog;
     108        1212 :         memcpy(DTable, &dtd, sizeof(dtd));
     109             :     }
     110             : 
     111             :     /* Prepare ranks */
     112        1212 :     {   U32 n, nextRankStart = 0;
     113       13288 :         for (n=1; n<tableLog+1; n++) {
     114       12076 :             U32 current = nextRankStart;
     115       12076 :             nextRankStart += (rankVal[n] << (n-1));
     116       12076 :             rankVal[n] = current;
     117             :     }   }
     118             : 
     119             :     /* fill DTable */
     120             :     {   U32 n;
     121      306712 :         for (n=0; n<nbSymbols; n++) {
     122      305500 :             U32 const w = huffWeight[n];
     123      305500 :             U32 const length = (1 << w) >> 1;
     124             :             U32 i;
     125             :             HUF_DEltX2 D;
     126      305500 :             D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
     127     1749852 :             for (i = rankVal[w]; i < rankVal[w] + length; i++)
     128     1444352 :                 dt[i] = D;
     129      305500 :             rankVal[w] += length;
     130             :     }   }
     131             : 
     132        1212 :     return iSize;
     133             : }
     134             : 
     135             : 
     136    49301334 : static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
     137             : {
     138    49301334 :     size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
     139    49301334 :     BYTE const c = dt[val].byte;
     140    49301334 :     BIT_skipBits(Dstream, dt[val].nbBits);
     141    49301334 :     return c;
     142             : }
     143             : 
     144             : #define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
     145             :     *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
     146             : 
     147             : #define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
     148             :     if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
     149             :         HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     150             : 
     151             : #define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
     152             :     if (MEM_64bits()) \
     153             :         HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
     154             : 
     155        4836 : static inline size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)
     156             : {
     157        4836 :     BYTE* const pStart = p;
     158             : 
     159             :     /* up to 4 symbols at a time */
     160       11060 :     while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4)) {
     161        1388 :         HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
     162        1388 :         HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
     163        1388 :         HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
     164        1388 :         HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
     165             :     }
     166             : 
     167             :     /* closer to the end */
     168        9672 :     while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))
     169           0 :         HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
     170             : 
     171             :     /* no more data to retrieve from bitstream, hence no need to reload */
     172       43342 :     while (p < pEnd)
     173       33670 :         HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
     174             : 
     175        4836 :     return pEnd-pStart;
     176             : }
     177             : 
     178           4 : static size_t HUF_decompress1X2_usingDTable_internal(
     179             :           void* dst,  size_t dstSize,
     180             :     const void* cSrc, size_t cSrcSize,
     181             :     const HUF_DTable* DTable)
     182             : {
     183           4 :     BYTE* op = (BYTE*)dst;
     184           4 :     BYTE* const oend = op + dstSize;
     185           4 :     const void* dtPtr = DTable + 1;
     186           4 :     const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
     187             :     BIT_DStream_t bitD;
     188           4 :     DTableDesc const dtd = HUF_getDTableDesc(DTable);
     189           4 :     U32 const dtLog = dtd.tableLog;
     190             : 
     191           4 :     { size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
     192           4 :       if (HUF_isError(errorCode)) return errorCode; }
     193             : 
     194           4 :     HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);
     195             : 
     196             :     /* check */
     197           4 :     if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
     198             : 
     199           4 :     return dstSize;
     200             : }
     201             : 
     202           0 : size_t HUF_decompress1X2_usingDTable(
     203             :           void* dst,  size_t dstSize,
     204             :     const void* cSrc, size_t cSrcSize,
     205             :     const HUF_DTable* DTable)
     206             : {
     207           0 :     DTableDesc dtd = HUF_getDTableDesc(DTable);
     208           0 :     if (dtd.tableType != 0) return ERROR(GENERIC);
     209           0 :     return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     210             : }
     211             : 
     212           4 : size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     213             : {
     214           4 :     const BYTE* ip = (const BYTE*) cSrc;
     215             : 
     216           4 :     size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize);
     217           4 :     if (HUF_isError(hSize)) return hSize;
     218           4 :     if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
     219           4 :     ip += hSize; cSrcSize -= hSize;
     220             : 
     221           4 :     return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
     222             : }
     223             : 
     224           0 : size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     225             : {
     226           0 :     HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
     227           0 :     return HUF_decompress1X2_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
     228             : }
     229             : 
     230             : 
     231        1208 : static size_t HUF_decompress4X2_usingDTable_internal(
     232             :           void* dst,  size_t dstSize,
     233             :     const void* cSrc, size_t cSrcSize,
     234             :     const HUF_DTable* DTable)
     235             : {
     236             :     /* Check */
     237        1208 :     if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */
     238             : 
     239        1208 :     {   const BYTE* const istart = (const BYTE*) cSrc;
     240        1208 :         BYTE* const ostart = (BYTE*) dst;
     241        1208 :         BYTE* const oend = ostart + dstSize;
     242        1208 :         const void* const dtPtr = DTable + 1;
     243        1208 :         const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
     244             : 
     245             :         /* Init */
     246             :         BIT_DStream_t bitD1;
     247             :         BIT_DStream_t bitD2;
     248             :         BIT_DStream_t bitD3;
     249             :         BIT_DStream_t bitD4;
     250        1208 :         size_t const length1 = MEM_readLE16(istart);
     251        1208 :         size_t const length2 = MEM_readLE16(istart+2);
     252        1208 :         size_t const length3 = MEM_readLE16(istart+4);
     253        1208 :         size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
     254        1208 :         const BYTE* const istart1 = istart + 6;  /* jumpTable */
     255        1208 :         const BYTE* const istart2 = istart1 + length1;
     256        1208 :         const BYTE* const istart3 = istart2 + length2;
     257        1208 :         const BYTE* const istart4 = istart3 + length3;
     258        1208 :         const size_t segmentSize = (dstSize+3) / 4;
     259        1208 :         BYTE* const opStart2 = ostart + segmentSize;
     260        1208 :         BYTE* const opStart3 = opStart2 + segmentSize;
     261        1208 :         BYTE* const opStart4 = opStart3 + segmentSize;
     262        1208 :         BYTE* op1 = ostart;
     263        1208 :         BYTE* op2 = opStart2;
     264        1208 :         BYTE* op3 = opStart3;
     265        1208 :         BYTE* op4 = opStart4;
     266             :         U32 endSignal;
     267        1208 :         DTableDesc const dtd = HUF_getDTableDesc(DTable);
     268        1208 :         U32 const dtLog = dtd.tableLog;
     269             : 
     270        1208 :         if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
     271        1208 :         { size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
     272        1208 :           if (HUF_isError(errorCode)) return errorCode; }
     273        1208 :         { size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
     274        1208 :           if (HUF_isError(errorCode)) return errorCode; }
     275        1208 :         { size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
     276        1208 :           if (HUF_isError(errorCode)) return errorCode; }
     277        1208 :         { size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
     278        1208 :           if (HUF_isError(errorCode)) return errorCode; }
     279             : 
     280             :         /* 16-32 symbols per loop (4-8 symbols per stream) */
     281        1208 :         endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
     282     3081298 :         for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) {
     283     3078882 :             HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
     284     3078882 :             HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
     285     3078882 :             HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
     286     3078882 :             HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
     287     3078882 :             HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
     288     3078882 :             HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
     289     3078882 :             HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
     290     3078882 :             HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
     291     3078882 :             HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
     292     3078882 :             HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
     293     3078882 :             HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
     294     3078882 :             HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
     295     3078882 :             HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
     296     3078882 :             HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
     297     3078882 :             HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
     298     3078882 :             HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
     299     3078882 :             endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
     300             :         }
     301             : 
     302             :         /* check corruption */
     303        1208 :         if (op1 > opStart2) return ERROR(corruption_detected);
     304        1208 :         if (op2 > opStart3) return ERROR(corruption_detected);
     305        1208 :         if (op3 > opStart4) return ERROR(corruption_detected);
     306             :         /* note : op4 supposed already verified within main loop */
     307             : 
     308             :         /* finish bitStreams one by one */
     309        1208 :         HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
     310        1208 :         HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
     311        1208 :         HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
     312        1208 :         HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);
     313             : 
     314             :         /* check */
     315        1208 :         endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
     316        1208 :         if (!endSignal) return ERROR(corruption_detected);
     317             : 
     318             :         /* decoded size */
     319        1208 :         return dstSize;
     320             :     }
     321             : }
     322             : 
     323             : 
     324           0 : size_t HUF_decompress4X2_usingDTable(
     325             :           void* dst,  size_t dstSize,
     326             :     const void* cSrc, size_t cSrcSize,
     327             :     const HUF_DTable* DTable)
     328             : {
     329           0 :     DTableDesc dtd = HUF_getDTableDesc(DTable);
     330           0 :     if (dtd.tableType != 0) return ERROR(GENERIC);
     331           0 :     return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     332             : }
     333             : 
     334             : 
     335        1208 : size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     336             : {
     337        1208 :     const BYTE* ip = (const BYTE*) cSrc;
     338             : 
     339        1208 :     size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize);
     340        1208 :     if (HUF_isError(hSize)) return hSize;
     341        1208 :     if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
     342        1208 :     ip += hSize; cSrcSize -= hSize;
     343             : 
     344        1208 :     return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
     345             : }
     346             : 
     347           0 : size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     348             : {
     349           0 :     HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
     350           0 :     return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
     351             : }
     352             : 
     353             : 
     354             : /* *************************/
     355             : /* double-symbols decoding */
     356             : /* *************************/
     357             : typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4;  /* double-symbols decoding */
     358             : 
     359             : typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
     360             : 
     361      189808 : static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
     362             :                            const U32* rankValOrigin, const int minWeight,
     363             :                            const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
     364             :                            U32 nbBitsBaseline, U16 baseSeq)
     365             : {
     366             :     HUF_DEltX4 DElt;
     367             :     U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
     368             : 
     369             :     /* get pre-calculated rankVal */
     370      189808 :     memcpy(rankVal, rankValOrigin, sizeof(rankVal));
     371             : 
     372             :     /* fill skipped values */
     373      189808 :     if (minWeight>1) {
     374      189116 :         U32 i, skipSize = rankVal[minWeight];
     375      189116 :         MEM_writeLE16(&(DElt.sequence), baseSeq);
     376      189116 :         DElt.nbBits   = (BYTE)(consumed);
     377      189116 :         DElt.length   = 1;
     378     1880390 :         for (i = 0; i < skipSize; i++)
     379     1691274 :             DTable[i] = DElt;
     380             :     }
     381             : 
     382             :     /* fill DTable */
     383      691818 :     {   U32 s; for (s=0; s<sortedListSize; s++) {   /* note : sortedSymbols already skipped */
     384      502010 :             const U32 symbol = sortedSymbols[s].symbol;
     385      502010 :             const U32 weight = sortedSymbols[s].weight;
     386      502010 :             const U32 nbBits = nbBitsBaseline - weight;
     387      502010 :             const U32 length = 1 << (sizeLog-nbBits);
     388      502010 :             const U32 start = rankVal[weight];
     389      502010 :             U32 i = start;
     390      502010 :             const U32 end = start + length;
     391             : 
     392      502010 :             MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
     393      502010 :             DElt.nbBits = (BYTE)(nbBits + consumed);
     394      502010 :             DElt.length = 2;
     395     1491726 :             do { DTable[i++] = DElt; } while (i<end);   /* since length >= 1 */
     396             : 
     397      502010 :             rankVal[weight] += length;
     398             :     }   }
     399      189808 : }
     400             : 
     401             : typedef U32 rankVal_t[HUF_TABLELOG_ABSOLUTEMAX][HUF_TABLELOG_ABSOLUTEMAX + 1];
     402             : 
     403         792 : static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
     404             :                            const sortedSymbol_t* sortedList, const U32 sortedListSize,
     405             :                            const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
     406             :                            const U32 nbBitsBaseline)
     407             : {
     408             :     U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
     409         792 :     const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */
     410         792 :     const U32 minBits  = nbBitsBaseline - maxWeight;
     411             :     U32 s;
     412             : 
     413         792 :     memcpy(rankVal, rankValOrigin, sizeof(rankVal));
     414             : 
     415             :     /* fill DTable */
     416      203544 :     for (s=0; s<sortedListSize; s++) {
     417      202752 :         const U16 symbol = sortedList[s].symbol;
     418      202752 :         const U32 weight = sortedList[s].weight;
     419      202752 :         const U32 nbBits = nbBitsBaseline - weight;
     420      202752 :         const U32 start = rankVal[weight];
     421      202752 :         const U32 length = 1 << (targetLog-nbBits);
     422             : 
     423      202752 :         if (targetLog-nbBits >= minBits) {   /* enough room for a second symbol */
     424             :             U32 sortedRank;
     425      189808 :             int minWeight = nbBits + scaleLog;
     426      189808 :             if (minWeight < 1) minWeight = 1;
     427      189808 :             sortedRank = rankStart[minWeight];
     428      569424 :             HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
     429      189808 :                            rankValOrigin[nbBits], minWeight,
     430      189808 :                            sortedList+sortedRank, sortedListSize-sortedRank,
     431             :                            nbBitsBaseline, symbol);
     432             :         } else {
     433             :             HUF_DEltX4 DElt;
     434       12944 :             MEM_writeLE16(&(DElt.sequence), symbol);
     435       12944 :             DElt.nbBits = (BYTE)(nbBits);
     436       12944 :             DElt.length = 1;
     437       12944 :             {   U32 const end = start + length;
     438             :                 U32 u;
     439       12944 :                 for (u = start; u < end; u++) DTable[u] = DElt;
     440             :         }   }
     441      202752 :         rankVal[weight] += length;
     442             :     }
     443         792 : }
     444             : 
     445         792 : size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
     446             : {
     447             :     BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
     448             :     sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
     449         792 :     U32 rankStats[HUF_TABLELOG_ABSOLUTEMAX + 1] = { 0 };
     450         792 :     U32 rankStart0[HUF_TABLELOG_ABSOLUTEMAX + 2] = { 0 };
     451         792 :     U32* const rankStart = rankStart0+1;
     452             :     rankVal_t rankVal;
     453             :     U32 tableLog, maxW, sizeOfSort, nbSymbols;
     454         792 :     DTableDesc dtd = HUF_getDTableDesc(DTable);
     455         792 :     U32 const maxTableLog = dtd.maxTableLog;
     456             :     size_t iSize;
     457         792 :     void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */
     458         792 :     HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
     459             : 
     460             :     HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable));   /* if compilation fails here, assertion is false */
     461         792 :     if (maxTableLog > HUF_TABLELOG_ABSOLUTEMAX) return ERROR(tableLog_tooLarge);
     462             :     /* memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */
     463             : 
     464         792 :     iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
     465         792 :     if (HUF_isError(iSize)) return iSize;
     466             : 
     467             :     /* check result */
     468         792 :     if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */
     469             : 
     470             :     /* find maxWeight */
     471         792 :     for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */
     472             : 
     473             :     /* Get start index of each weight */
     474         792 :     {   U32 w, nextRankStart = 0;
     475        7222 :         for (w=1; w<maxW+1; w++) {
     476        6430 :             U32 current = nextRankStart;
     477        6430 :             nextRankStart += rankStats[w];
     478        6430 :             rankStart[w] = current;
     479             :         }
     480         792 :         rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/
     481         792 :         sizeOfSort = nextRankStart;
     482             :     }
     483             : 
     484             :     /* sort symbols by weight */
     485             :     {   U32 s;
     486      203544 :         for (s=0; s<nbSymbols; s++) {
     487      202752 :             U32 const w = weightList[s];
     488      202752 :             U32 const r = rankStart[w]++;
     489      202752 :             sortedSymbol[r].symbol = (BYTE)s;
     490      202752 :             sortedSymbol[r].weight = (BYTE)w;
     491             :         }
     492         792 :         rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */
     493             :     }
     494             : 
     495             :     /* Build rankVal */
     496         792 :     {   U32* const rankVal0 = rankVal[0];
     497         792 :         {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */
     498         792 :             U32 nextRankVal = 0;
     499             :             U32 w;
     500        7222 :             for (w=1; w<maxW+1; w++) {
     501        6430 :                 U32 current = nextRankVal;
     502        6430 :                 nextRankVal += rankStats[w] << (w+rescale);
     503        6430 :                 rankVal0[w] = current;
     504             :         }   }
     505         792 :         {   U32 const minBits = tableLog+1 - maxW;
     506             :             U32 consumed;
     507        7636 :             for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
     508        6844 :                 U32* const rankValPtr = rankVal[consumed];
     509             :                 U32 w;
     510       62410 :                 for (w = 1; w < maxW+1; w++) {
     511       55566 :                     rankValPtr[w] = rankVal0[w] >> consumed;
     512             :     }   }   }   }
     513             : 
     514         792 :     HUF_fillDTableX4(dt, maxTableLog,
     515             :                    sortedSymbol, sizeOfSort,
     516             :                    rankStart0, rankVal, maxW,
     517             :                    tableLog+1);
     518             : 
     519         792 :     dtd.tableLog = (BYTE)maxTableLog;
     520         792 :     dtd.tableType = 1;
     521         792 :     memcpy(DTable, &dtd, sizeof(dtd));
     522         792 :     return iSize;
     523             : }
     524             : 
     525             : 
     526    66990482 : static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
     527             : {
     528    66990482 :     size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
     529    66990482 :     memcpy(op, dt+val, 2);
     530    66990482 :     BIT_skipBits(DStream, dt[val].nbBits);
     531    66990482 :     return dt[val].length;
     532             : }
     533             : 
     534        2894 : static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
     535             : {
     536        2894 :     size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */
     537        2894 :     memcpy(op, dt+val, 1);
     538        2894 :     if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
     539             :     else {
     540          98 :         if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
     541          98 :             BIT_skipBits(DStream, dt[val].nbBits);
     542          98 :             if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
     543          98 :                 DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);   /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
     544             :     }   }
     545        2894 :     return 1;
     546             : }
     547             : 
     548             : 
     549             : #define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
     550             :     ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     551             : 
     552             : #define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
     553             :     if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
     554             :         ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     555             : 
     556             : #define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
     557             :     if (MEM_64bits()) \
     558             :         ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
     559             : 
     560        3168 : static inline size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)
     561             : {
     562        3168 :     BYTE* const pStart = p;
     563             : 
     564             :     /* up to 8 symbols at a time */
     565       56264 :     while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
     566       49928 :         HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
     567       49928 :         HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
     568       49928 :         HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
     569       49928 :         HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
     570             :     }
     571             : 
     572             :     /* closer to end : up to 2 symbols at a time */
     573        6336 :     while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
     574           0 :         HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
     575             : 
     576       17842 :     while (p <= pEnd-2)
     577       11506 :         HUF_DECODE_SYMBOLX4_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */
     578             : 
     579        3168 :     if (p < pEnd)
     580        2894 :         p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
     581             : 
     582        3168 :     return p-pStart;
     583             : }
     584             : 
     585             : 
     586           0 : static size_t HUF_decompress1X4_usingDTable_internal(
     587             :           void* dst,  size_t dstSize,
     588             :     const void* cSrc, size_t cSrcSize,
     589             :     const HUF_DTable* DTable)
     590             : {
     591             :     BIT_DStream_t bitD;
     592             : 
     593             :     /* Init */
     594           0 :     {   size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
     595           0 :         if (HUF_isError(errorCode)) return errorCode;
     596             :     }
     597             : 
     598             :     /* decode */
     599           0 :     {   BYTE* const ostart = (BYTE*) dst;
     600           0 :         BYTE* const oend = ostart + dstSize;
     601           0 :         const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */
     602           0 :         const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
     603           0 :         DTableDesc const dtd = HUF_getDTableDesc(DTable);
     604           0 :         HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
     605             :     }
     606             : 
     607             :     /* check */
     608           0 :     if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
     609             : 
     610             :     /* decoded size */
     611           0 :     return dstSize;
     612             : }
     613             : 
     614           0 : size_t HUF_decompress1X4_usingDTable(
     615             :           void* dst,  size_t dstSize,
     616             :     const void* cSrc, size_t cSrcSize,
     617             :     const HUF_DTable* DTable)
     618             : {
     619           0 :     DTableDesc dtd = HUF_getDTableDesc(DTable);
     620           0 :     if (dtd.tableType != 1) return ERROR(GENERIC);
     621           0 :     return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     622             : }
     623             : 
     624           0 : size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     625             : {
     626           0 :     const BYTE* ip = (const BYTE*) cSrc;
     627             : 
     628           0 :     size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize);
     629           0 :     if (HUF_isError(hSize)) return hSize;
     630           0 :     if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
     631           0 :     ip += hSize; cSrcSize -= hSize;
     632             : 
     633           0 :     return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
     634             : }
     635             : 
     636           0 : size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     637             : {
     638           0 :     HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
     639           0 :     return HUF_decompress1X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
     640             : }
     641             : 
     642         792 : static size_t HUF_decompress4X4_usingDTable_internal(
     643             :           void* dst,  size_t dstSize,
     644             :     const void* cSrc, size_t cSrcSize,
     645             :     const HUF_DTable* DTable)
     646             : {
     647         792 :     if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */
     648             : 
     649         792 :     {   const BYTE* const istart = (const BYTE*) cSrc;
     650         792 :         BYTE* const ostart = (BYTE*) dst;
     651         792 :         BYTE* const oend = ostart + dstSize;
     652         792 :         const void* const dtPtr = DTable+1;
     653         792 :         const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
     654             : 
     655             :         /* Init */
     656             :         BIT_DStream_t bitD1;
     657             :         BIT_DStream_t bitD2;
     658             :         BIT_DStream_t bitD3;
     659             :         BIT_DStream_t bitD4;
     660         792 :         size_t const length1 = MEM_readLE16(istart);
     661         792 :         size_t const length2 = MEM_readLE16(istart+2);
     662         792 :         size_t const length3 = MEM_readLE16(istart+4);
     663         792 :         size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
     664         792 :         const BYTE* const istart1 = istart + 6;  /* jumpTable */
     665         792 :         const BYTE* const istart2 = istart1 + length1;
     666         792 :         const BYTE* const istart3 = istart2 + length2;
     667         792 :         const BYTE* const istart4 = istart3 + length3;
     668         792 :         size_t const segmentSize = (dstSize+3) / 4;
     669         792 :         BYTE* const opStart2 = ostart + segmentSize;
     670         792 :         BYTE* const opStart3 = opStart2 + segmentSize;
     671         792 :         BYTE* const opStart4 = opStart3 + segmentSize;
     672         792 :         BYTE* op1 = ostart;
     673         792 :         BYTE* op2 = opStart2;
     674         792 :         BYTE* op3 = opStart3;
     675         792 :         BYTE* op4 = opStart4;
     676             :         U32 endSignal;
     677         792 :         DTableDesc const dtd = HUF_getDTableDesc(DTable);
     678         792 :         U32 const dtLog = dtd.tableLog;
     679             : 
     680         792 :         if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */
     681         792 :         { size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
     682         792 :           if (HUF_isError(errorCode)) return errorCode; }
     683         792 :         { size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
     684         792 :           if (HUF_isError(errorCode)) return errorCode; }
     685         792 :         { size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
     686         792 :           if (HUF_isError(errorCode)) return errorCode; }
     687         792 :         { size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
     688         792 :           if (HUF_isError(errorCode)) return errorCode; }
     689             : 
     690             :         /* 16-32 symbols per loop (4-8 symbols per stream) */
     691         792 :         endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
     692     4175288 :         for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
     693     4173704 :             HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
     694     4173704 :             HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
     695     4173704 :             HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
     696     4173704 :             HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
     697     4173704 :             HUF_DECODE_SYMBOLX4_1(op1, &bitD1);
     698     4173704 :             HUF_DECODE_SYMBOLX4_1(op2, &bitD2);
     699     4173704 :             HUF_DECODE_SYMBOLX4_1(op3, &bitD3);
     700     4173704 :             HUF_DECODE_SYMBOLX4_1(op4, &bitD4);
     701     4173704 :             HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
     702     4173704 :             HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
     703     4173704 :             HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
     704     4173704 :             HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
     705     4173704 :             HUF_DECODE_SYMBOLX4_0(op1, &bitD1);
     706     4173704 :             HUF_DECODE_SYMBOLX4_0(op2, &bitD2);
     707     4173704 :             HUF_DECODE_SYMBOLX4_0(op3, &bitD3);
     708     4173704 :             HUF_DECODE_SYMBOLX4_0(op4, &bitD4);
     709             : 
     710     4173704 :             endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
     711             :         }
     712             : 
     713             :         /* check corruption */
     714         792 :         if (op1 > opStart2) return ERROR(corruption_detected);
     715         792 :         if (op2 > opStart3) return ERROR(corruption_detected);
     716         792 :         if (op3 > opStart4) return ERROR(corruption_detected);
     717             :         /* note : op4 already verified within main loop */
     718             : 
     719             :         /* finish bitStreams one by one */
     720         792 :         HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
     721         792 :         HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
     722         792 :         HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
     723         792 :         HUF_decodeStreamX4(op4, &bitD4, oend,     dt, dtLog);
     724             : 
     725             :         /* check */
     726         792 :         { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
     727         792 :           if (!endCheck) return ERROR(corruption_detected); }
     728             : 
     729             :         /* decoded size */
     730         792 :         return dstSize;
     731             :     }
     732             : }
     733             : 
     734             : 
     735           0 : size_t HUF_decompress4X4_usingDTable(
     736             :           void* dst,  size_t dstSize,
     737             :     const void* cSrc, size_t cSrcSize,
     738             :     const HUF_DTable* DTable)
     739             : {
     740           0 :     DTableDesc dtd = HUF_getDTableDesc(DTable);
     741           0 :     if (dtd.tableType != 1) return ERROR(GENERIC);
     742           0 :     return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
     743             : }
     744             : 
     745             : 
     746         792 : size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     747             : {
     748         792 :     const BYTE* ip = (const BYTE*) cSrc;
     749             : 
     750         792 :     size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize);
     751         792 :     if (HUF_isError(hSize)) return hSize;
     752         792 :     if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
     753         792 :     ip += hSize; cSrcSize -= hSize;
     754             : 
     755         792 :     return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
     756             : }
     757             : 
     758           0 : size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     759             : {
     760           0 :     HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
     761           0 :     return HUF_decompress4X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
     762             : }
     763             : 
     764             : 
     765             : /* ********************************/
     766             : /* Generic decompression selector */
     767             : /* ********************************/
     768             : 
     769           0 : size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
     770             :                                     const void* cSrc, size_t cSrcSize,
     771             :                                     const HUF_DTable* DTable)
     772             : {
     773           0 :     DTableDesc const dtd = HUF_getDTableDesc(DTable);
     774           0 :     return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
     775             :                            HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
     776             : }
     777             : 
     778           0 : size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
     779             :                                     const void* cSrc, size_t cSrcSize,
     780             :                                     const HUF_DTable* DTable)
     781             : {
     782           0 :     DTableDesc const dtd = HUF_getDTableDesc(DTable);
     783           0 :     return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
     784             :                            HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
     785             : }
     786             : 
     787             : 
     788             : typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
     789             : static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
     790             : {
     791             :     /* single, double, quad */
     792             :     {{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */
     793             :     {{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */
     794             :     {{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */
     795             :     {{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */
     796             :     {{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */
     797             :     {{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */
     798             :     {{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */
     799             :     {{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */
     800             :     {{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */
     801             :     {{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */
     802             :     {{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */
     803             :     {{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */
     804             :     {{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */
     805             :     {{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */
     806             :     {{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */
     807             :     {{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */
     808             : };
     809             : 
     810             : /** HUF_selectDecoder() :
     811             : *   Tells which decoder is likely to decode faster,
     812             : *   based on a set of pre-determined metrics.
     813             : *   @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
     814             : *   Assumption : 0 < cSrcSize < dstSize <= 128 KB */
     815        2000 : U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
     816             : {
     817             :     /* decoder timing evaluation */
     818        2000 :     U32 const Q = (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 since dstSize > cSrcSize */
     819        2000 :     U32 const D256 = (U32)(dstSize >> 8);
     820        2000 :     U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
     821        2000 :     U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
     822        2000 :     DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, for cache eviction */
     823             : 
     824        2000 :     return DTime1 < DTime0;
     825             : }
     826             : 
     827             : 
     828             : typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
     829             : 
     830           0 : size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     831             : {
     832             :     static const decompressionAlgo decompress[2] = { HUF_decompress4X2, HUF_decompress4X4 };
     833             : 
     834             :     /* validation checks */
     835           0 :     if (dstSize == 0) return ERROR(dstSize_tooSmall);
     836           0 :     if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
     837           0 :     if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
     838           0 :     if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
     839             : 
     840           0 :     {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     841           0 :         return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
     842             :     }
     843             : }
     844             : 
     845           0 : size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     846             : {
     847             :     /* validation checks */
     848           0 :     if (dstSize == 0) return ERROR(dstSize_tooSmall);
     849           0 :     if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
     850           0 :     if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
     851           0 :     if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
     852             : 
     853           0 :     {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     854           0 :         return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     855             :                         HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     856             :     }
     857             : }
     858             : 
     859        2000 : size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     860             : {
     861             :     /* validation checks */
     862        2000 :     if (dstSize == 0) return ERROR(dstSize_tooSmall);
     863        2000 :     if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected);   /* invalid */
     864             : 
     865        2000 :     {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     866        2000 :         return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     867             :                         HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     868             :     }
     869             : }
     870             : 
     871           0 : size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
     872             : {
     873             :     /* validation checks */
     874           0 :     if (dstSize == 0) return ERROR(dstSize_tooSmall);
     875           0 :     if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */
     876           0 :     if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */
     877           0 :     if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */
     878             : 
     879           0 :     {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
     880           0 :         return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
     881             :                         HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
     882             :     }
     883             : }

Generated by: LCOV version 1.11