zstd-ruby 0.1.0

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