This source file includes following definitions.
- HUF_getDTableDesc
- HUF_readDTableX2_wksp
- HUF_decodeSymbolX2
- HUF_decodeStreamX2
- HUF_decompress1X2_usingDTable_internal
- HUF_decompress1X2_usingDTable
- HUF_decompress1X2_DCtx_wksp
- HUF_decompress4X2_usingDTable_internal
- HUF_decompress4X2_usingDTable
- HUF_decompress4X2_DCtx_wksp
- HUF_fillDTableX4Level2
- HUF_fillDTableX4
- HUF_readDTableX4_wksp
- HUF_decodeSymbolX4
- HUF_decodeLastSymbolX4
- HUF_decodeStreamX4
- HUF_decompress1X4_usingDTable_internal
- HUF_decompress1X4_usingDTable
- HUF_decompress1X4_DCtx_wksp
- HUF_decompress4X4_usingDTable_internal
- HUF_decompress4X4_usingDTable
- HUF_decompress4X4_DCtx_wksp
- HUF_decompress1X_usingDTable
- HUF_decompress4X_usingDTable
- HUF_selectDecoder
- HUF_decompress4X_DCtx_wksp
- HUF_decompress4X_hufOnly_wksp
- HUF_decompress1X_DCtx_wksp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #define FORCE_INLINE static __always_inline
44
45
46
47
48 #include "bitstream.h"
49 #include "fse.h"
50 #include "huf.h"
51 #include <linux/compiler.h>
52 #include <linux/kernel.h>
53 #include <linux/string.h>
54
55
56
57
58 #define HUF_STATIC_ASSERT(c) \
59 { \
60 enum { HUF_static_assert = 1 / (int)(!!(c)) }; \
61 }
62
63
64
65
66
67 typedef struct {
68 BYTE maxTableLog;
69 BYTE tableType;
70 BYTE tableLog;
71 BYTE reserved;
72 } DTableDesc;
73
74 static DTableDesc HUF_getDTableDesc(const HUF_DTable *table)
75 {
76 DTableDesc dtd;
77 memcpy(&dtd, table, sizeof(dtd));
78 return dtd;
79 }
80
81
82
83
84
85 typedef struct {
86 BYTE byte;
87 BYTE nbBits;
88 } HUF_DEltX2;
89
90 size_t HUF_readDTableX2_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize)
91 {
92 U32 tableLog = 0;
93 U32 nbSymbols = 0;
94 size_t iSize;
95 void *const dtPtr = DTable + 1;
96 HUF_DEltX2 *const dt = (HUF_DEltX2 *)dtPtr;
97
98 U32 *rankVal;
99 BYTE *huffWeight;
100 size_t spaceUsed32 = 0;
101
102 rankVal = (U32 *)workspace + spaceUsed32;
103 spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;
104 huffWeight = (BYTE *)((U32 *)workspace + spaceUsed32);
105 spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
106
107 if ((spaceUsed32 << 2) > workspaceSize)
108 return ERROR(tableLog_tooLarge);
109 workspace = (U32 *)workspace + spaceUsed32;
110 workspaceSize -= (spaceUsed32 << 2);
111
112 HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
113
114
115 iSize = HUF_readStats_wksp(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize);
116 if (HUF_isError(iSize))
117 return iSize;
118
119
120 {
121 DTableDesc dtd = HUF_getDTableDesc(DTable);
122 if (tableLog > (U32)(dtd.maxTableLog + 1))
123 return ERROR(tableLog_tooLarge);
124 dtd.tableType = 0;
125 dtd.tableLog = (BYTE)tableLog;
126 memcpy(DTable, &dtd, sizeof(dtd));
127 }
128
129
130 {
131 U32 n, nextRankStart = 0;
132 for (n = 1; n < tableLog + 1; n++) {
133 U32 const curr = nextRankStart;
134 nextRankStart += (rankVal[n] << (n - 1));
135 rankVal[n] = curr;
136 }
137 }
138
139
140 {
141 U32 n;
142 for (n = 0; n < nbSymbols; n++) {
143 U32 const w = huffWeight[n];
144 U32 const length = (1 << w) >> 1;
145 U32 u;
146 HUF_DEltX2 D;
147 D.byte = (BYTE)n;
148 D.nbBits = (BYTE)(tableLog + 1 - w);
149 for (u = rankVal[w]; u < rankVal[w] + length; u++)
150 dt[u] = D;
151 rankVal[w] += length;
152 }
153 }
154
155 return iSize;
156 }
157
158 static BYTE HUF_decodeSymbolX2(BIT_DStream_t *Dstream, const HUF_DEltX2 *dt, const U32 dtLog)
159 {
160 size_t const val = BIT_lookBitsFast(Dstream, dtLog);
161 BYTE const c = dt[val].byte;
162 BIT_skipBits(Dstream, dt[val].nbBits);
163 return c;
164 }
165
166 #define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
167
168 #define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
169 if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
170 HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
171
172 #define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
173 if (ZSTD_64bits()) \
174 HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
175
176 FORCE_INLINE size_t HUF_decodeStreamX2(BYTE *p, BIT_DStream_t *const bitDPtr, BYTE *const pEnd, const HUF_DEltX2 *const dt, const U32 dtLog)
177 {
178 BYTE *const pStart = p;
179
180
181 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd - 4)) {
182 HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
183 HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
184 HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
185 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
186 }
187
188
189 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))
190 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
191
192
193 while (p < pEnd)
194 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
195
196 return pEnd - pStart;
197 }
198
199 static size_t HUF_decompress1X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
200 {
201 BYTE *op = (BYTE *)dst;
202 BYTE *const oend = op + dstSize;
203 const void *dtPtr = DTable + 1;
204 const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;
205 BIT_DStream_t bitD;
206 DTableDesc const dtd = HUF_getDTableDesc(DTable);
207 U32 const dtLog = dtd.tableLog;
208
209 {
210 size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
211 if (HUF_isError(errorCode))
212 return errorCode;
213 }
214
215 HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);
216
217
218 if (!BIT_endOfDStream(&bitD))
219 return ERROR(corruption_detected);
220
221 return dstSize;
222 }
223
224 size_t HUF_decompress1X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
225 {
226 DTableDesc dtd = HUF_getDTableDesc(DTable);
227 if (dtd.tableType != 0)
228 return ERROR(GENERIC);
229 return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
230 }
231
232 size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
233 {
234 const BYTE *ip = (const BYTE *)cSrc;
235
236 size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize);
237 if (HUF_isError(hSize))
238 return hSize;
239 if (hSize >= cSrcSize)
240 return ERROR(srcSize_wrong);
241 ip += hSize;
242 cSrcSize -= hSize;
243
244 return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
245 }
246
247 static size_t HUF_decompress4X2_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
248 {
249
250 if (cSrcSize < 10)
251 return ERROR(corruption_detected);
252
253 {
254 const BYTE *const istart = (const BYTE *)cSrc;
255 BYTE *const ostart = (BYTE *)dst;
256 BYTE *const oend = ostart + dstSize;
257 const void *const dtPtr = DTable + 1;
258 const HUF_DEltX2 *const dt = (const HUF_DEltX2 *)dtPtr;
259
260
261 BIT_DStream_t bitD1;
262 BIT_DStream_t bitD2;
263 BIT_DStream_t bitD3;
264 BIT_DStream_t bitD4;
265 size_t const length1 = ZSTD_readLE16(istart);
266 size_t const length2 = ZSTD_readLE16(istart + 2);
267 size_t const length3 = ZSTD_readLE16(istart + 4);
268 size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
269 const BYTE *const istart1 = istart + 6;
270 const BYTE *const istart2 = istart1 + length1;
271 const BYTE *const istart3 = istart2 + length2;
272 const BYTE *const istart4 = istart3 + length3;
273 const size_t segmentSize = (dstSize + 3) / 4;
274 BYTE *const opStart2 = ostart + segmentSize;
275 BYTE *const opStart3 = opStart2 + segmentSize;
276 BYTE *const opStart4 = opStart3 + segmentSize;
277 BYTE *op1 = ostart;
278 BYTE *op2 = opStart2;
279 BYTE *op3 = opStart3;
280 BYTE *op4 = opStart4;
281 U32 endSignal;
282 DTableDesc const dtd = HUF_getDTableDesc(DTable);
283 U32 const dtLog = dtd.tableLog;
284
285 if (length4 > cSrcSize)
286 return ERROR(corruption_detected);
287 {
288 size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
289 if (HUF_isError(errorCode))
290 return errorCode;
291 }
292 {
293 size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
294 if (HUF_isError(errorCode))
295 return errorCode;
296 }
297 {
298 size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
299 if (HUF_isError(errorCode))
300 return errorCode;
301 }
302 {
303 size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
304 if (HUF_isError(errorCode))
305 return errorCode;
306 }
307
308
309 endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
310 for (; (endSignal == BIT_DStream_unfinished) && (op4 < (oend - 7));) {
311 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
312 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
313 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
314 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
315 HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
316 HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
317 HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
318 HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
319 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
320 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
321 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
322 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
323 HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
324 HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
325 HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
326 HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
327 endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
328 }
329
330
331 if (op1 > opStart2)
332 return ERROR(corruption_detected);
333 if (op2 > opStart3)
334 return ERROR(corruption_detected);
335 if (op3 > opStart4)
336 return ERROR(corruption_detected);
337
338
339
340 HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
341 HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
342 HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
343 HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
344
345
346 endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
347 if (!endSignal)
348 return ERROR(corruption_detected);
349
350
351 return dstSize;
352 }
353 }
354
355 size_t HUF_decompress4X2_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
356 {
357 DTableDesc dtd = HUF_getDTableDesc(DTable);
358 if (dtd.tableType != 0)
359 return ERROR(GENERIC);
360 return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
361 }
362
363 size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
364 {
365 const BYTE *ip = (const BYTE *)cSrc;
366
367 size_t const hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize);
368 if (HUF_isError(hSize))
369 return hSize;
370 if (hSize >= cSrcSize)
371 return ERROR(srcSize_wrong);
372 ip += hSize;
373 cSrcSize -= hSize;
374
375 return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
376 }
377
378
379
380
381 typedef struct {
382 U16 sequence;
383 BYTE nbBits;
384 BYTE length;
385 } HUF_DEltX4;
386
387 typedef struct {
388 BYTE symbol;
389 BYTE weight;
390 } sortedSymbol_t;
391
392
393
394 static void HUF_fillDTableX4Level2(HUF_DEltX4 *DTable, U32 sizeLog, const U32 consumed, const U32 *rankValOrigin, const int minWeight,
395 const sortedSymbol_t *sortedSymbols, const U32 sortedListSize, U32 nbBitsBaseline, U16 baseSeq)
396 {
397 HUF_DEltX4 DElt;
398 U32 rankVal[HUF_TABLELOG_MAX + 1];
399
400
401 memcpy(rankVal, rankValOrigin, sizeof(rankVal));
402
403
404 if (minWeight > 1) {
405 U32 i, skipSize = rankVal[minWeight];
406 ZSTD_writeLE16(&(DElt.sequence), baseSeq);
407 DElt.nbBits = (BYTE)(consumed);
408 DElt.length = 1;
409 for (i = 0; i < skipSize; i++)
410 DTable[i] = DElt;
411 }
412
413
414 {
415 U32 s;
416 for (s = 0; s < sortedListSize; s++) {
417 const U32 symbol = sortedSymbols[s].symbol;
418 const U32 weight = sortedSymbols[s].weight;
419 const U32 nbBits = nbBitsBaseline - weight;
420 const U32 length = 1 << (sizeLog - nbBits);
421 const U32 start = rankVal[weight];
422 U32 i = start;
423 const U32 end = start + length;
424
425 ZSTD_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
426 DElt.nbBits = (BYTE)(nbBits + consumed);
427 DElt.length = 2;
428 do {
429 DTable[i++] = DElt;
430 } while (i < end);
431
432 rankVal[weight] += length;
433 }
434 }
435 }
436
437 typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
438 typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];
439
440 static void HUF_fillDTableX4(HUF_DEltX4 *DTable, const U32 targetLog, const sortedSymbol_t *sortedList, const U32 sortedListSize, const U32 *rankStart,
441 rankVal_t rankValOrigin, const U32 maxWeight, const U32 nbBitsBaseline)
442 {
443 U32 rankVal[HUF_TABLELOG_MAX + 1];
444 const int scaleLog = nbBitsBaseline - targetLog;
445 const U32 minBits = nbBitsBaseline - maxWeight;
446 U32 s;
447
448 memcpy(rankVal, rankValOrigin, sizeof(rankVal));
449
450
451 for (s = 0; s < sortedListSize; s++) {
452 const U16 symbol = sortedList[s].symbol;
453 const U32 weight = sortedList[s].weight;
454 const U32 nbBits = nbBitsBaseline - weight;
455 const U32 start = rankVal[weight];
456 const U32 length = 1 << (targetLog - nbBits);
457
458 if (targetLog - nbBits >= minBits) {
459 U32 sortedRank;
460 int minWeight = nbBits + scaleLog;
461 if (minWeight < 1)
462 minWeight = 1;
463 sortedRank = rankStart[minWeight];
464 HUF_fillDTableX4Level2(DTable + start, targetLog - nbBits, nbBits, rankValOrigin[nbBits], minWeight, sortedList + sortedRank,
465 sortedListSize - sortedRank, nbBitsBaseline, symbol);
466 } else {
467 HUF_DEltX4 DElt;
468 ZSTD_writeLE16(&(DElt.sequence), symbol);
469 DElt.nbBits = (BYTE)(nbBits);
470 DElt.length = 1;
471 {
472 U32 const end = start + length;
473 U32 u;
474 for (u = start; u < end; u++)
475 DTable[u] = DElt;
476 }
477 }
478 rankVal[weight] += length;
479 }
480 }
481
482 size_t HUF_readDTableX4_wksp(HUF_DTable *DTable, const void *src, size_t srcSize, void *workspace, size_t workspaceSize)
483 {
484 U32 tableLog, maxW, sizeOfSort, nbSymbols;
485 DTableDesc dtd = HUF_getDTableDesc(DTable);
486 U32 const maxTableLog = dtd.maxTableLog;
487 size_t iSize;
488 void *dtPtr = DTable + 1;
489 HUF_DEltX4 *const dt = (HUF_DEltX4 *)dtPtr;
490 U32 *rankStart;
491
492 rankValCol_t *rankVal;
493 U32 *rankStats;
494 U32 *rankStart0;
495 sortedSymbol_t *sortedSymbol;
496 BYTE *weightList;
497 size_t spaceUsed32 = 0;
498
499 HUF_STATIC_ASSERT((sizeof(rankValCol_t) & 3) == 0);
500
501 rankVal = (rankValCol_t *)((U32 *)workspace + spaceUsed32);
502 spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;
503 rankStats = (U32 *)workspace + spaceUsed32;
504 spaceUsed32 += HUF_TABLELOG_MAX + 1;
505 rankStart0 = (U32 *)workspace + spaceUsed32;
506 spaceUsed32 += HUF_TABLELOG_MAX + 2;
507 sortedSymbol = (sortedSymbol_t *)((U32 *)workspace + spaceUsed32);
508 spaceUsed32 += ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;
509 weightList = (BYTE *)((U32 *)workspace + spaceUsed32);
510 spaceUsed32 += ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;
511
512 if ((spaceUsed32 << 2) > workspaceSize)
513 return ERROR(tableLog_tooLarge);
514 workspace = (U32 *)workspace + spaceUsed32;
515 workspaceSize -= (spaceUsed32 << 2);
516
517 rankStart = rankStart0 + 1;
518 memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));
519
520 HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable));
521 if (maxTableLog > HUF_TABLELOG_MAX)
522 return ERROR(tableLog_tooLarge);
523
524
525 iSize = HUF_readStats_wksp(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize, workspace, workspaceSize);
526 if (HUF_isError(iSize))
527 return iSize;
528
529
530 if (tableLog > maxTableLog)
531 return ERROR(tableLog_tooLarge);
532
533
534 for (maxW = tableLog; rankStats[maxW] == 0; maxW--) {
535 }
536
537
538 {
539 U32 w, nextRankStart = 0;
540 for (w = 1; w < maxW + 1; w++) {
541 U32 curr = nextRankStart;
542 nextRankStart += rankStats[w];
543 rankStart[w] = curr;
544 }
545 rankStart[0] = nextRankStart;
546 sizeOfSort = nextRankStart;
547 }
548
549
550 {
551 U32 s;
552 for (s = 0; s < nbSymbols; s++) {
553 U32 const w = weightList[s];
554 U32 const r = rankStart[w]++;
555 sortedSymbol[r].symbol = (BYTE)s;
556 sortedSymbol[r].weight = (BYTE)w;
557 }
558 rankStart[0] = 0;
559 }
560
561
562 {
563 U32 *const rankVal0 = rankVal[0];
564 {
565 int const rescale = (maxTableLog - tableLog) - 1;
566 U32 nextRankVal = 0;
567 U32 w;
568 for (w = 1; w < maxW + 1; w++) {
569 U32 curr = nextRankVal;
570 nextRankVal += rankStats[w] << (w + rescale);
571 rankVal0[w] = curr;
572 }
573 }
574 {
575 U32 const minBits = tableLog + 1 - maxW;
576 U32 consumed;
577 for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
578 U32 *const rankValPtr = rankVal[consumed];
579 U32 w;
580 for (w = 1; w < maxW + 1; w++) {
581 rankValPtr[w] = rankVal0[w] >> consumed;
582 }
583 }
584 }
585 }
586
587 HUF_fillDTableX4(dt, maxTableLog, sortedSymbol, sizeOfSort, rankStart0, rankVal, maxW, tableLog + 1);
588
589 dtd.tableLog = (BYTE)maxTableLog;
590 dtd.tableType = 1;
591 memcpy(DTable, &dtd, sizeof(dtd));
592 return iSize;
593 }
594
595 static U32 HUF_decodeSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
596 {
597 size_t const val = BIT_lookBitsFast(DStream, dtLog);
598 memcpy(op, dt + val, 2);
599 BIT_skipBits(DStream, dt[val].nbBits);
600 return dt[val].length;
601 }
602
603 static U32 HUF_decodeLastSymbolX4(void *op, BIT_DStream_t *DStream, const HUF_DEltX4 *dt, const U32 dtLog)
604 {
605 size_t const val = BIT_lookBitsFast(DStream, dtLog);
606 memcpy(op, dt + val, 1);
607 if (dt[val].length == 1)
608 BIT_skipBits(DStream, dt[val].nbBits);
609 else {
610 if (DStream->bitsConsumed < (sizeof(DStream->bitContainer) * 8)) {
611 BIT_skipBits(DStream, dt[val].nbBits);
612 if (DStream->bitsConsumed > (sizeof(DStream->bitContainer) * 8))
613
614 DStream->bitsConsumed = (sizeof(DStream->bitContainer) * 8);
615 }
616 }
617 return 1;
618 }
619
620 #define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
621
622 #define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
623 if (ZSTD_64bits() || (HUF_TABLELOG_MAX <= 12)) \
624 ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
625
626 #define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
627 if (ZSTD_64bits()) \
628 ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
629
630 FORCE_INLINE size_t HUF_decodeStreamX4(BYTE *p, BIT_DStream_t *bitDPtr, BYTE *const pEnd, const HUF_DEltX4 *const dt, const U32 dtLog)
631 {
632 BYTE *const pStart = p;
633
634
635 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd - (sizeof(bitDPtr->bitContainer) - 1))) {
636 HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
637 HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
638 HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
639 HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
640 }
641
642
643 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd - 2))
644 HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
645
646 while (p <= pEnd - 2)
647 HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
648
649 if (p < pEnd)
650 p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
651
652 return p - pStart;
653 }
654
655 static size_t HUF_decompress1X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
656 {
657 BIT_DStream_t bitD;
658
659
660 {
661 size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
662 if (HUF_isError(errorCode))
663 return errorCode;
664 }
665
666
667 {
668 BYTE *const ostart = (BYTE *)dst;
669 BYTE *const oend = ostart + dstSize;
670 const void *const dtPtr = DTable + 1;
671 const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;
672 DTableDesc const dtd = HUF_getDTableDesc(DTable);
673 HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
674 }
675
676
677 if (!BIT_endOfDStream(&bitD))
678 return ERROR(corruption_detected);
679
680
681 return dstSize;
682 }
683
684 size_t HUF_decompress1X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
685 {
686 DTableDesc dtd = HUF_getDTableDesc(DTable);
687 if (dtd.tableType != 1)
688 return ERROR(GENERIC);
689 return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
690 }
691
692 size_t HUF_decompress1X4_DCtx_wksp(HUF_DTable *DCtx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
693 {
694 const BYTE *ip = (const BYTE *)cSrc;
695
696 size_t const hSize = HUF_readDTableX4_wksp(DCtx, cSrc, cSrcSize, workspace, workspaceSize);
697 if (HUF_isError(hSize))
698 return hSize;
699 if (hSize >= cSrcSize)
700 return ERROR(srcSize_wrong);
701 ip += hSize;
702 cSrcSize -= hSize;
703
704 return HUF_decompress1X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx);
705 }
706
707 static size_t HUF_decompress4X4_usingDTable_internal(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
708 {
709 if (cSrcSize < 10)
710 return ERROR(corruption_detected);
711
712 {
713 const BYTE *const istart = (const BYTE *)cSrc;
714 BYTE *const ostart = (BYTE *)dst;
715 BYTE *const oend = ostart + dstSize;
716 const void *const dtPtr = DTable + 1;
717 const HUF_DEltX4 *const dt = (const HUF_DEltX4 *)dtPtr;
718
719
720 BIT_DStream_t bitD1;
721 BIT_DStream_t bitD2;
722 BIT_DStream_t bitD3;
723 BIT_DStream_t bitD4;
724 size_t const length1 = ZSTD_readLE16(istart);
725 size_t const length2 = ZSTD_readLE16(istart + 2);
726 size_t const length3 = ZSTD_readLE16(istart + 4);
727 size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
728 const BYTE *const istart1 = istart + 6;
729 const BYTE *const istart2 = istart1 + length1;
730 const BYTE *const istart3 = istart2 + length2;
731 const BYTE *const istart4 = istart3 + length3;
732 size_t const segmentSize = (dstSize + 3) / 4;
733 BYTE *const opStart2 = ostart + segmentSize;
734 BYTE *const opStart3 = opStart2 + segmentSize;
735 BYTE *const opStart4 = opStart3 + segmentSize;
736 BYTE *op1 = ostart;
737 BYTE *op2 = opStart2;
738 BYTE *op3 = opStart3;
739 BYTE *op4 = opStart4;
740 U32 endSignal;
741 DTableDesc const dtd = HUF_getDTableDesc(DTable);
742 U32 const dtLog = dtd.tableLog;
743
744 if (length4 > cSrcSize)
745 return ERROR(corruption_detected);
746 {
747 size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
748 if (HUF_isError(errorCode))
749 return errorCode;
750 }
751 {
752 size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
753 if (HUF_isError(errorCode))
754 return errorCode;
755 }
756 {
757 size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
758 if (HUF_isError(errorCode))
759 return errorCode;
760 }
761 {
762 size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
763 if (HUF_isError(errorCode))
764 return errorCode;
765 }
766
767
768 endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
769 for (; (endSignal == BIT_DStream_unfinished) & (op4 < (oend - (sizeof(bitD4.bitContainer) - 1)));) {
770 HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
771 HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
772 HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
773 HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
774 HUF_DECODE_SYMBOLX4_1(op1, &bitD1);
775 HUF_DECODE_SYMBOLX4_1(op2, &bitD2);
776 HUF_DECODE_SYMBOLX4_1(op3, &bitD3);
777 HUF_DECODE_SYMBOLX4_1(op4, &bitD4);
778 HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
779 HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
780 HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
781 HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
782 HUF_DECODE_SYMBOLX4_0(op1, &bitD1);
783 HUF_DECODE_SYMBOLX4_0(op2, &bitD2);
784 HUF_DECODE_SYMBOLX4_0(op3, &bitD3);
785 HUF_DECODE_SYMBOLX4_0(op4, &bitD4);
786
787 endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
788 }
789
790
791 if (op1 > opStart2)
792 return ERROR(corruption_detected);
793 if (op2 > opStart3)
794 return ERROR(corruption_detected);
795 if (op3 > opStart4)
796 return ERROR(corruption_detected);
797
798
799
800 HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
801 HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
802 HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
803 HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
804
805
806 {
807 U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
808 if (!endCheck)
809 return ERROR(corruption_detected);
810 }
811
812
813 return dstSize;
814 }
815 }
816
817 size_t HUF_decompress4X4_usingDTable(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
818 {
819 DTableDesc dtd = HUF_getDTableDesc(DTable);
820 if (dtd.tableType != 1)
821 return ERROR(GENERIC);
822 return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
823 }
824
825 size_t HUF_decompress4X4_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
826 {
827 const BYTE *ip = (const BYTE *)cSrc;
828
829 size_t hSize = HUF_readDTableX4_wksp(dctx, cSrc, cSrcSize, workspace, workspaceSize);
830 if (HUF_isError(hSize))
831 return hSize;
832 if (hSize >= cSrcSize)
833 return ERROR(srcSize_wrong);
834 ip += hSize;
835 cSrcSize -= hSize;
836
837 return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
838 }
839
840
841
842
843
844 size_t HUF_decompress1X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
845 {
846 DTableDesc const dtd = HUF_getDTableDesc(DTable);
847 return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
848 : HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
849 }
850
851 size_t HUF_decompress4X_usingDTable(void *dst, size_t maxDstSize, const void *cSrc, size_t cSrcSize, const HUF_DTable *DTable)
852 {
853 DTableDesc const dtd = HUF_getDTableDesc(DTable);
854 return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable)
855 : HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
856 }
857
858 typedef struct {
859 U32 tableTime;
860 U32 decode256Time;
861 } algo_time_t;
862 static const algo_time_t algoTime[16 ][3 ] = {
863
864 {{0, 0}, {1, 1}, {2, 2}},
865 {{0, 0}, {1, 1}, {2, 2}},
866 {{38, 130}, {1313, 74}, {2151, 38}},
867 {{448, 128}, {1353, 74}, {2238, 41}},
868 {{556, 128}, {1353, 74}, {2238, 47}},
869 {{714, 128}, {1418, 74}, {2436, 53}},
870 {{883, 128}, {1437, 74}, {2464, 61}},
871 {{897, 128}, {1515, 75}, {2622, 68}},
872 {{926, 128}, {1613, 75}, {2730, 75}},
873 {{947, 128}, {1729, 77}, {3359, 77}},
874 {{1107, 128}, {2083, 81}, {4006, 84}},
875 {{1177, 128}, {2379, 87}, {4785, 88}},
876 {{1242, 128}, {2415, 93}, {5155, 84}},
877 {{1349, 128}, {2644, 106}, {5260, 106}},
878 {{1455, 128}, {2422, 124}, {4174, 124}},
879 {{722, 128}, {1891, 145}, {1936, 146}},
880 };
881
882
883
884
885
886
887 U32 HUF_selectDecoder(size_t dstSize, size_t cSrcSize)
888 {
889
890 U32 const Q = (U32)(cSrcSize * 16 / dstSize);
891 U32 const D256 = (U32)(dstSize >> 8);
892 U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
893 U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
894 DTime1 += DTime1 >> 3;
895
896 return DTime1 < DTime0;
897 }
898
899 typedef size_t (*decompressionAlgo)(void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize);
900
901 size_t HUF_decompress4X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
902 {
903
904 if (dstSize == 0)
905 return ERROR(dstSize_tooSmall);
906 if (cSrcSize > dstSize)
907 return ERROR(corruption_detected);
908 if (cSrcSize == dstSize) {
909 memcpy(dst, cSrc, dstSize);
910 return dstSize;
911 }
912 if (cSrcSize == 1) {
913 memset(dst, *(const BYTE *)cSrc, dstSize);
914 return dstSize;
915 }
916
917 {
918 U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
919 return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
920 : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
921 }
922 }
923
924 size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
925 {
926
927 if (dstSize == 0)
928 return ERROR(dstSize_tooSmall);
929 if ((cSrcSize >= dstSize) || (cSrcSize <= 1))
930 return ERROR(corruption_detected);
931
932 {
933 U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
934 return algoNb ? HUF_decompress4X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
935 : HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
936 }
937 }
938
939 size_t HUF_decompress1X_DCtx_wksp(HUF_DTable *dctx, void *dst, size_t dstSize, const void *cSrc, size_t cSrcSize, void *workspace, size_t workspaceSize)
940 {
941
942 if (dstSize == 0)
943 return ERROR(dstSize_tooSmall);
944 if (cSrcSize > dstSize)
945 return ERROR(corruption_detected);
946 if (cSrcSize == dstSize) {
947 memcpy(dst, cSrc, dstSize);
948 return dstSize;
949 }
950 if (cSrcSize == 1) {
951 memset(dst, *(const BYTE *)cSrc, dstSize);
952 return dstSize;
953 }
954
955 {
956 U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
957 return algoNb ? HUF_decompress1X4_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize)
958 : HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workspace, workspaceSize);
959 }
960 }