extzstd 0.0.2.CONCEPT → 0.0.3.CONCEPT

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