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 : }
|