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,2154 @@
1
+ /**
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+
11
+ /* ***************************************************************
12
+ * Tuning parameters
13
+ *****************************************************************/
14
+ /*!
15
+ * HEAPMODE :
16
+ * Select how default decompression function ZSTD_decompress() will allocate memory,
17
+ * in memory stack (0), or in memory heap (1, requires malloc())
18
+ */
19
+ #ifndef ZSTD_HEAPMODE
20
+ # define ZSTD_HEAPMODE 1
21
+ #endif
22
+
23
+ /*!
24
+ * LEGACY_SUPPORT :
25
+ * if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
26
+ */
27
+ #ifndef ZSTD_LEGACY_SUPPORT
28
+ # define ZSTD_LEGACY_SUPPORT 0
29
+ #endif
30
+
31
+ /*!
32
+ * MAXWINDOWSIZE_DEFAULT :
33
+ * maximum window size accepted by DStream, by default.
34
+ * Frames requiring more memory will be rejected.
35
+ */
36
+ #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
37
+ # define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
38
+ #endif
39
+
40
+
41
+ /*-*******************************************************
42
+ * Dependencies
43
+ *********************************************************/
44
+ #include <string.h> /* memcpy, memmove, memset */
45
+ #include "mem.h" /* low level memory routines */
46
+ #define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
47
+ #include "xxhash.h" /* XXH64_* */
48
+ #define FSE_STATIC_LINKING_ONLY
49
+ #include "fse.h"
50
+ #define HUF_STATIC_LINKING_ONLY
51
+ #include "huf.h"
52
+ #include "zstd_internal.h"
53
+
54
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
55
+ # include "zstd_legacy.h"
56
+ #endif
57
+
58
+
59
+ #if defined(_MSC_VER)
60
+ # include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
61
+ # define ZSTD_PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0)
62
+ #elif defined(__GNUC__)
63
+ # define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
64
+ #else
65
+ # define ZSTD_PREFETCH(ptr) /* disabled */
66
+ #endif
67
+
68
+ /*-*************************************
69
+ * Macros
70
+ ***************************************/
71
+ #define ZSTD_isError ERR_isError /* for inlining */
72
+ #define FSE_isError ERR_isError
73
+ #define HUF_isError ERR_isError
74
+
75
+
76
+ /*_*******************************************************
77
+ * Memory operations
78
+ **********************************************************/
79
+ static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
80
+
81
+
82
+ /*-*************************************************************
83
+ * Context management
84
+ ***************************************************************/
85
+ typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
86
+ ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
87
+ ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
88
+ ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
89
+
90
+ struct ZSTD_DCtx_s
91
+ {
92
+ const FSE_DTable* LLTptr;
93
+ const FSE_DTable* MLTptr;
94
+ const FSE_DTable* OFTptr;
95
+ const HUF_DTable* HUFptr;
96
+ FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
97
+ FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
98
+ FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
99
+ HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
100
+ const void* previousDstEnd;
101
+ const void* base;
102
+ const void* vBase;
103
+ const void* dictEnd;
104
+ size_t expected;
105
+ U32 rep[ZSTD_REP_NUM];
106
+ ZSTD_frameParams fParams;
107
+ blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
108
+ ZSTD_dStage stage;
109
+ U32 litEntropy;
110
+ U32 fseEntropy;
111
+ XXH64_state_t xxhState;
112
+ size_t headerSize;
113
+ U32 dictID;
114
+ const BYTE* litPtr;
115
+ ZSTD_customMem customMem;
116
+ size_t litSize;
117
+ size_t rleSize;
118
+ BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
119
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
120
+ }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
121
+
122
+ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { return (dctx==NULL) ? 0 : sizeof(ZSTD_DCtx); }
123
+
124
+ size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
125
+
126
+ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
127
+ {
128
+ dctx->expected = ZSTD_frameHeaderSize_prefix;
129
+ dctx->stage = ZSTDds_getFrameHeaderSize;
130
+ dctx->previousDstEnd = NULL;
131
+ dctx->base = NULL;
132
+ dctx->vBase = NULL;
133
+ dctx->dictEnd = NULL;
134
+ dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
135
+ dctx->litEntropy = dctx->fseEntropy = 0;
136
+ dctx->dictID = 0;
137
+ MEM_STATIC_ASSERT(sizeof(dctx->rep) == sizeof(repStartValue));
138
+ memcpy(dctx->rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
139
+ dctx->LLTptr = dctx->LLTable;
140
+ dctx->MLTptr = dctx->MLTable;
141
+ dctx->OFTptr = dctx->OFTable;
142
+ dctx->HUFptr = dctx->hufTable;
143
+ return 0;
144
+ }
145
+
146
+ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
147
+ {
148
+ ZSTD_DCtx* dctx;
149
+
150
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
151
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
152
+
153
+ dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
154
+ if (!dctx) return NULL;
155
+ memcpy(&dctx->customMem, &customMem, sizeof(customMem));
156
+ ZSTD_decompressBegin(dctx);
157
+ return dctx;
158
+ }
159
+
160
+ ZSTD_DCtx* ZSTD_createDCtx(void)
161
+ {
162
+ return ZSTD_createDCtx_advanced(defaultCustomMem);
163
+ }
164
+
165
+ size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
166
+ {
167
+ if (dctx==NULL) return 0; /* support free on NULL */
168
+ ZSTD_free(dctx, dctx->customMem);
169
+ return 0; /* reserved as a potential error code in the future */
170
+ }
171
+
172
+ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
173
+ {
174
+ size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
175
+ memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
176
+ }
177
+
178
+ static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
179
+ {
180
+ ZSTD_decompressBegin(dstDCtx); /* init */
181
+ if (srcDCtx) { /* support refDCtx on NULL */
182
+ dstDCtx->dictEnd = srcDCtx->dictEnd;
183
+ dstDCtx->vBase = srcDCtx->vBase;
184
+ dstDCtx->base = srcDCtx->base;
185
+ dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
186
+ dstDCtx->dictID = srcDCtx->dictID;
187
+ dstDCtx->litEntropy = srcDCtx->litEntropy;
188
+ dstDCtx->fseEntropy = srcDCtx->fseEntropy;
189
+ dstDCtx->LLTptr = srcDCtx->LLTable;
190
+ dstDCtx->MLTptr = srcDCtx->MLTable;
191
+ dstDCtx->OFTptr = srcDCtx->OFTable;
192
+ dstDCtx->HUFptr = srcDCtx->hufTable;
193
+ dstDCtx->rep[0] = srcDCtx->rep[0];
194
+ dstDCtx->rep[1] = srcDCtx->rep[1];
195
+ dstDCtx->rep[2] = srcDCtx->rep[2];
196
+ }
197
+ }
198
+
199
+
200
+ /*-*************************************************************
201
+ * Decompression section
202
+ ***************************************************************/
203
+
204
+ /*! ZSTD_isFrame() :
205
+ * Tells if the content of `buffer` starts with a valid Frame Identifier.
206
+ * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
207
+ * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
208
+ * Note 3 : Skippable Frame Identifiers are considered valid. */
209
+ unsigned ZSTD_isFrame(const void* buffer, size_t size)
210
+ {
211
+ if (size < 4) return 0;
212
+ { U32 const magic = MEM_readLE32(buffer);
213
+ if (magic == ZSTD_MAGICNUMBER) return 1;
214
+ if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
215
+ }
216
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
217
+ if (ZSTD_isLegacy(buffer, size)) return 1;
218
+ #endif
219
+ return 0;
220
+ }
221
+
222
+
223
+ /** ZSTD_frameHeaderSize() :
224
+ * srcSize must be >= ZSTD_frameHeaderSize_prefix.
225
+ * @return : size of the Frame Header */
226
+ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
227
+ {
228
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
229
+ { BYTE const fhd = ((const BYTE*)src)[4];
230
+ U32 const dictID= fhd & 3;
231
+ U32 const singleSegment = (fhd >> 5) & 1;
232
+ U32 const fcsId = fhd >> 6;
233
+ return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
234
+ + (singleSegment && !fcsId);
235
+ }
236
+ }
237
+
238
+
239
+ /** ZSTD_getFrameParams() :
240
+ * decode Frame Header, or require larger `srcSize`.
241
+ * @return : 0, `fparamsPtr` is correctly filled,
242
+ * >0, `srcSize` is too small, result is expected `srcSize`,
243
+ * or an error code, which can be tested using ZSTD_isError() */
244
+ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
245
+ {
246
+ const BYTE* ip = (const BYTE*)src;
247
+
248
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
249
+ if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
250
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
251
+ if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
252
+ memset(fparamsPtr, 0, sizeof(*fparamsPtr));
253
+ fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
254
+ fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
255
+ return 0;
256
+ }
257
+ return ERROR(prefix_unknown);
258
+ }
259
+
260
+ /* ensure there is enough `srcSize` to fully read/decode frame header */
261
+ { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
262
+ if (srcSize < fhsize) return fhsize; }
263
+
264
+ { BYTE const fhdByte = ip[4];
265
+ size_t pos = 5;
266
+ U32 const dictIDSizeCode = fhdByte&3;
267
+ U32 const checksumFlag = (fhdByte>>2)&1;
268
+ U32 const singleSegment = (fhdByte>>5)&1;
269
+ U32 const fcsID = fhdByte>>6;
270
+ U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
271
+ U32 windowSize = 0;
272
+ U32 dictID = 0;
273
+ U64 frameContentSize = 0;
274
+ if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
275
+ if (!singleSegment) {
276
+ BYTE const wlByte = ip[pos++];
277
+ U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
278
+ if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */
279
+ windowSize = (1U << windowLog);
280
+ windowSize += (windowSize >> 3) * (wlByte&7);
281
+ }
282
+
283
+ switch(dictIDSizeCode)
284
+ {
285
+ default: /* impossible */
286
+ case 0 : break;
287
+ case 1 : dictID = ip[pos]; pos++; break;
288
+ case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
289
+ case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
290
+ }
291
+ switch(fcsID)
292
+ {
293
+ default: /* impossible */
294
+ case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
295
+ case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
296
+ case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
297
+ case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
298
+ }
299
+ if (!windowSize) windowSize = (U32)frameContentSize;
300
+ if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
301
+ fparamsPtr->frameContentSize = frameContentSize;
302
+ fparamsPtr->windowSize = windowSize;
303
+ fparamsPtr->dictID = dictID;
304
+ fparamsPtr->checksumFlag = checksumFlag;
305
+ }
306
+ return 0;
307
+ }
308
+
309
+
310
+ /** ZSTD_getDecompressedSize() :
311
+ * compatible with legacy mode
312
+ * @return : decompressed size if known, 0 otherwise
313
+ note : 0 can mean any of the following :
314
+ - decompressed size is not present within frame header
315
+ - frame header unknown / not supported
316
+ - frame header not complete (`srcSize` too small) */
317
+ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
318
+ {
319
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
320
+ if (ZSTD_isLegacy(src, srcSize)) return ZSTD_getDecompressedSize_legacy(src, srcSize);
321
+ #endif
322
+ { ZSTD_frameParams fparams;
323
+ size_t const frResult = ZSTD_getFrameParams(&fparams, src, srcSize);
324
+ if (frResult!=0) return 0;
325
+ return fparams.frameContentSize;
326
+ }
327
+ }
328
+
329
+
330
+ /** ZSTD_decodeFrameHeader() :
331
+ * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
332
+ * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
333
+ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
334
+ {
335
+ size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
336
+ if (ZSTD_isError(result)) return result; /* invalid header */
337
+ if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
338
+ if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
339
+ if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
340
+ return 0;
341
+ }
342
+
343
+
344
+ typedef struct
345
+ {
346
+ blockType_e blockType;
347
+ U32 lastBlock;
348
+ U32 origSize;
349
+ } blockProperties_t;
350
+
351
+ /*! ZSTD_getcBlockSize() :
352
+ * Provides the size of compressed block from block header `src` */
353
+ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
354
+ {
355
+ if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
356
+ { U32 const cBlockHeader = MEM_readLE24(src);
357
+ U32 const cSize = cBlockHeader >> 3;
358
+ bpPtr->lastBlock = cBlockHeader & 1;
359
+ bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
360
+ bpPtr->origSize = cSize; /* only useful for RLE */
361
+ if (bpPtr->blockType == bt_rle) return 1;
362
+ if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
363
+ return cSize;
364
+ }
365
+ }
366
+
367
+
368
+ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
369
+ {
370
+ if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
371
+ memcpy(dst, src, srcSize);
372
+ return srcSize;
373
+ }
374
+
375
+
376
+ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
377
+ {
378
+ if (srcSize != 1) return ERROR(srcSize_wrong);
379
+ if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
380
+ memset(dst, *(const BYTE*)src, regenSize);
381
+ return regenSize;
382
+ }
383
+
384
+ /*! ZSTD_decodeLiteralsBlock() :
385
+ @return : nb of bytes read from src (< srcSize ) */
386
+ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
387
+ const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
388
+ {
389
+ if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
390
+
391
+ { const BYTE* const istart = (const BYTE*) src;
392
+ symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
393
+
394
+ switch(litEncType)
395
+ {
396
+ case set_repeat:
397
+ if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
398
+ /* fall-through */
399
+ case set_compressed:
400
+ if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
401
+ { size_t lhSize, litSize, litCSize;
402
+ U32 singleStream=0;
403
+ U32 const lhlCode = (istart[0] >> 2) & 3;
404
+ U32 const lhc = MEM_readLE32(istart);
405
+ switch(lhlCode)
406
+ {
407
+ case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
408
+ /* 2 - 2 - 10 - 10 */
409
+ singleStream = !lhlCode;
410
+ lhSize = 3;
411
+ litSize = (lhc >> 4) & 0x3FF;
412
+ litCSize = (lhc >> 14) & 0x3FF;
413
+ break;
414
+ case 2:
415
+ /* 2 - 2 - 14 - 14 */
416
+ lhSize = 4;
417
+ litSize = (lhc >> 4) & 0x3FFF;
418
+ litCSize = lhc >> 18;
419
+ break;
420
+ case 3:
421
+ /* 2 - 2 - 18 - 18 */
422
+ lhSize = 5;
423
+ litSize = (lhc >> 4) & 0x3FFFF;
424
+ litCSize = (lhc >> 22) + (istart[4] << 10);
425
+ break;
426
+ }
427
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
428
+ if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
429
+
430
+ if (HUF_isError((litEncType==set_repeat) ?
431
+ ( singleStream ?
432
+ HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
433
+ HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
434
+ ( singleStream ?
435
+ HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
436
+ HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
437
+ return ERROR(corruption_detected);
438
+
439
+ dctx->litPtr = dctx->litBuffer;
440
+ dctx->litSize = litSize;
441
+ dctx->litEntropy = 1;
442
+ if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable;
443
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
444
+ return litCSize + lhSize;
445
+ }
446
+
447
+ case set_basic:
448
+ { size_t litSize, lhSize;
449
+ U32 const lhlCode = ((istart[0]) >> 2) & 3;
450
+ switch(lhlCode)
451
+ {
452
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
453
+ lhSize = 1;
454
+ litSize = istart[0] >> 3;
455
+ break;
456
+ case 1:
457
+ lhSize = 2;
458
+ litSize = MEM_readLE16(istart) >> 4;
459
+ break;
460
+ case 3:
461
+ lhSize = 3;
462
+ litSize = MEM_readLE24(istart) >> 4;
463
+ break;
464
+ }
465
+
466
+ if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
467
+ if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
468
+ memcpy(dctx->litBuffer, istart+lhSize, litSize);
469
+ dctx->litPtr = dctx->litBuffer;
470
+ dctx->litSize = litSize;
471
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
472
+ return lhSize+litSize;
473
+ }
474
+ /* direct reference into compressed stream */
475
+ dctx->litPtr = istart+lhSize;
476
+ dctx->litSize = litSize;
477
+ return lhSize+litSize;
478
+ }
479
+
480
+ case set_rle:
481
+ { U32 const lhlCode = ((istart[0]) >> 2) & 3;
482
+ size_t litSize, lhSize;
483
+ switch(lhlCode)
484
+ {
485
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
486
+ lhSize = 1;
487
+ litSize = istart[0] >> 3;
488
+ break;
489
+ case 1:
490
+ lhSize = 2;
491
+ litSize = MEM_readLE16(istart) >> 4;
492
+ break;
493
+ case 3:
494
+ lhSize = 3;
495
+ litSize = MEM_readLE24(istart) >> 4;
496
+ if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
497
+ break;
498
+ }
499
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
500
+ memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
501
+ dctx->litPtr = dctx->litBuffer;
502
+ dctx->litSize = litSize;
503
+ return lhSize+1;
504
+ }
505
+ default:
506
+ return ERROR(corruption_detected); /* impossible */
507
+ }
508
+ }
509
+ }
510
+
511
+
512
+ typedef union {
513
+ FSE_decode_t realData;
514
+ U32 alignedBy4;
515
+ } FSE_decode_t4;
516
+
517
+ static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
518
+ { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
519
+ { { 0, 0, 4 } }, /* 0 : base, symbol, bits */
520
+ { { 16, 0, 4 } },
521
+ { { 32, 1, 5 } },
522
+ { { 0, 3, 5 } },
523
+ { { 0, 4, 5 } },
524
+ { { 0, 6, 5 } },
525
+ { { 0, 7, 5 } },
526
+ { { 0, 9, 5 } },
527
+ { { 0, 10, 5 } },
528
+ { { 0, 12, 5 } },
529
+ { { 0, 14, 6 } },
530
+ { { 0, 16, 5 } },
531
+ { { 0, 18, 5 } },
532
+ { { 0, 19, 5 } },
533
+ { { 0, 21, 5 } },
534
+ { { 0, 22, 5 } },
535
+ { { 0, 24, 5 } },
536
+ { { 32, 25, 5 } },
537
+ { { 0, 26, 5 } },
538
+ { { 0, 27, 6 } },
539
+ { { 0, 29, 6 } },
540
+ { { 0, 31, 6 } },
541
+ { { 32, 0, 4 } },
542
+ { { 0, 1, 4 } },
543
+ { { 0, 2, 5 } },
544
+ { { 32, 4, 5 } },
545
+ { { 0, 5, 5 } },
546
+ { { 32, 7, 5 } },
547
+ { { 0, 8, 5 } },
548
+ { { 32, 10, 5 } },
549
+ { { 0, 11, 5 } },
550
+ { { 0, 13, 6 } },
551
+ { { 32, 16, 5 } },
552
+ { { 0, 17, 5 } },
553
+ { { 32, 19, 5 } },
554
+ { { 0, 20, 5 } },
555
+ { { 32, 22, 5 } },
556
+ { { 0, 23, 5 } },
557
+ { { 0, 25, 4 } },
558
+ { { 16, 25, 4 } },
559
+ { { 32, 26, 5 } },
560
+ { { 0, 28, 6 } },
561
+ { { 0, 30, 6 } },
562
+ { { 48, 0, 4 } },
563
+ { { 16, 1, 4 } },
564
+ { { 32, 2, 5 } },
565
+ { { 32, 3, 5 } },
566
+ { { 32, 5, 5 } },
567
+ { { 32, 6, 5 } },
568
+ { { 32, 8, 5 } },
569
+ { { 32, 9, 5 } },
570
+ { { 32, 11, 5 } },
571
+ { { 32, 12, 5 } },
572
+ { { 0, 15, 6 } },
573
+ { { 32, 17, 5 } },
574
+ { { 32, 18, 5 } },
575
+ { { 32, 20, 5 } },
576
+ { { 32, 21, 5 } },
577
+ { { 32, 23, 5 } },
578
+ { { 32, 24, 5 } },
579
+ { { 0, 35, 6 } },
580
+ { { 0, 34, 6 } },
581
+ { { 0, 33, 6 } },
582
+ { { 0, 32, 6 } },
583
+ }; /* LL_defaultDTable */
584
+
585
+ static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
586
+ { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
587
+ { { 0, 0, 6 } }, /* 0 : base, symbol, bits */
588
+ { { 0, 1, 4 } },
589
+ { { 32, 2, 5 } },
590
+ { { 0, 3, 5 } },
591
+ { { 0, 5, 5 } },
592
+ { { 0, 6, 5 } },
593
+ { { 0, 8, 5 } },
594
+ { { 0, 10, 6 } },
595
+ { { 0, 13, 6 } },
596
+ { { 0, 16, 6 } },
597
+ { { 0, 19, 6 } },
598
+ { { 0, 22, 6 } },
599
+ { { 0, 25, 6 } },
600
+ { { 0, 28, 6 } },
601
+ { { 0, 31, 6 } },
602
+ { { 0, 33, 6 } },
603
+ { { 0, 35, 6 } },
604
+ { { 0, 37, 6 } },
605
+ { { 0, 39, 6 } },
606
+ { { 0, 41, 6 } },
607
+ { { 0, 43, 6 } },
608
+ { { 0, 45, 6 } },
609
+ { { 16, 1, 4 } },
610
+ { { 0, 2, 4 } },
611
+ { { 32, 3, 5 } },
612
+ { { 0, 4, 5 } },
613
+ { { 32, 6, 5 } },
614
+ { { 0, 7, 5 } },
615
+ { { 0, 9, 6 } },
616
+ { { 0, 12, 6 } },
617
+ { { 0, 15, 6 } },
618
+ { { 0, 18, 6 } },
619
+ { { 0, 21, 6 } },
620
+ { { 0, 24, 6 } },
621
+ { { 0, 27, 6 } },
622
+ { { 0, 30, 6 } },
623
+ { { 0, 32, 6 } },
624
+ { { 0, 34, 6 } },
625
+ { { 0, 36, 6 } },
626
+ { { 0, 38, 6 } },
627
+ { { 0, 40, 6 } },
628
+ { { 0, 42, 6 } },
629
+ { { 0, 44, 6 } },
630
+ { { 32, 1, 4 } },
631
+ { { 48, 1, 4 } },
632
+ { { 16, 2, 4 } },
633
+ { { 32, 4, 5 } },
634
+ { { 32, 5, 5 } },
635
+ { { 32, 7, 5 } },
636
+ { { 32, 8, 5 } },
637
+ { { 0, 11, 6 } },
638
+ { { 0, 14, 6 } },
639
+ { { 0, 17, 6 } },
640
+ { { 0, 20, 6 } },
641
+ { { 0, 23, 6 } },
642
+ { { 0, 26, 6 } },
643
+ { { 0, 29, 6 } },
644
+ { { 0, 52, 6 } },
645
+ { { 0, 51, 6 } },
646
+ { { 0, 50, 6 } },
647
+ { { 0, 49, 6 } },
648
+ { { 0, 48, 6 } },
649
+ { { 0, 47, 6 } },
650
+ { { 0, 46, 6 } },
651
+ }; /* ML_defaultDTable */
652
+
653
+ static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
654
+ { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
655
+ { { 0, 0, 5 } }, /* 0 : base, symbol, bits */
656
+ { { 0, 6, 4 } },
657
+ { { 0, 9, 5 } },
658
+ { { 0, 15, 5 } },
659
+ { { 0, 21, 5 } },
660
+ { { 0, 3, 5 } },
661
+ { { 0, 7, 4 } },
662
+ { { 0, 12, 5 } },
663
+ { { 0, 18, 5 } },
664
+ { { 0, 23, 5 } },
665
+ { { 0, 5, 5 } },
666
+ { { 0, 8, 4 } },
667
+ { { 0, 14, 5 } },
668
+ { { 0, 20, 5 } },
669
+ { { 0, 2, 5 } },
670
+ { { 16, 7, 4 } },
671
+ { { 0, 11, 5 } },
672
+ { { 0, 17, 5 } },
673
+ { { 0, 22, 5 } },
674
+ { { 0, 4, 5 } },
675
+ { { 16, 8, 4 } },
676
+ { { 0, 13, 5 } },
677
+ { { 0, 19, 5 } },
678
+ { { 0, 1, 5 } },
679
+ { { 16, 6, 4 } },
680
+ { { 0, 10, 5 } },
681
+ { { 0, 16, 5 } },
682
+ { { 0, 28, 5 } },
683
+ { { 0, 27, 5 } },
684
+ { { 0, 26, 5 } },
685
+ { { 0, 25, 5 } },
686
+ { { 0, 24, 5 } },
687
+ }; /* OF_defaultDTable */
688
+
689
+ /*! ZSTD_buildSeqTable() :
690
+ @return : nb bytes read from src,
691
+ or an error code if it fails, testable with ZSTD_isError()
692
+ */
693
+ static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
694
+ symbolEncodingType_e type, U32 max, U32 maxLog,
695
+ const void* src, size_t srcSize,
696
+ const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
697
+ {
698
+ const void* const tmpPtr = defaultTable; /* bypass strict aliasing */
699
+ switch(type)
700
+ {
701
+ case set_rle :
702
+ if (!srcSize) return ERROR(srcSize_wrong);
703
+ if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
704
+ FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
705
+ *DTablePtr = DTableSpace;
706
+ return 1;
707
+ case set_basic :
708
+ *DTablePtr = (const FSE_DTable*)tmpPtr;
709
+ return 0;
710
+ case set_repeat:
711
+ if (!flagRepeatTable) return ERROR(corruption_detected);
712
+ return 0;
713
+ default : /* impossible */
714
+ case set_compressed :
715
+ { U32 tableLog;
716
+ S16 norm[MaxSeq+1];
717
+ size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
718
+ if (FSE_isError(headerSize)) return ERROR(corruption_detected);
719
+ if (tableLog > maxLog) return ERROR(corruption_detected);
720
+ FSE_buildDTable(DTableSpace, norm, max, tableLog);
721
+ *DTablePtr = DTableSpace;
722
+ return headerSize;
723
+ } }
724
+ }
725
+
726
+ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
727
+ const void* src, size_t srcSize)
728
+ {
729
+ const BYTE* const istart = (const BYTE* const)src;
730
+ const BYTE* const iend = istart + srcSize;
731
+ const BYTE* ip = istart;
732
+
733
+ /* check */
734
+ if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
735
+
736
+ /* SeqHead */
737
+ { int nbSeq = *ip++;
738
+ if (!nbSeq) { *nbSeqPtr=0; return 1; }
739
+ if (nbSeq > 0x7F) {
740
+ if (nbSeq == 0xFF) {
741
+ if (ip+2 > iend) return ERROR(srcSize_wrong);
742
+ nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
743
+ } else {
744
+ if (ip >= iend) return ERROR(srcSize_wrong);
745
+ nbSeq = ((nbSeq-0x80)<<8) + *ip++;
746
+ }
747
+ }
748
+ *nbSeqPtr = nbSeq;
749
+ }
750
+
751
+ /* FSE table descriptors */
752
+ if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
753
+ { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
754
+ symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
755
+ symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
756
+ ip++;
757
+
758
+ /* Build DTables */
759
+ { size_t const llhSize = ZSTD_buildSeqTable(dctx->LLTable, &dctx->LLTptr,
760
+ LLtype, MaxLL, LLFSELog,
761
+ ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
762
+ if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
763
+ ip += llhSize;
764
+ }
765
+ { size_t const ofhSize = ZSTD_buildSeqTable(dctx->OFTable, &dctx->OFTptr,
766
+ OFtype, MaxOff, OffFSELog,
767
+ ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
768
+ if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
769
+ ip += ofhSize;
770
+ }
771
+ { size_t const mlhSize = ZSTD_buildSeqTable(dctx->MLTable, &dctx->MLTptr,
772
+ MLtype, MaxML, MLFSELog,
773
+ ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
774
+ if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
775
+ ip += mlhSize;
776
+ }
777
+ }
778
+
779
+ return ip-istart;
780
+ }
781
+
782
+
783
+ typedef struct {
784
+ size_t litLength;
785
+ size_t matchLength;
786
+ size_t offset;
787
+ const BYTE* match;
788
+ } seq_t;
789
+
790
+ typedef struct {
791
+ BIT_DStream_t DStream;
792
+ FSE_DState_t stateLL;
793
+ FSE_DState_t stateOffb;
794
+ FSE_DState_t stateML;
795
+ size_t prevOffset[ZSTD_REP_NUM];
796
+ const BYTE* base;
797
+ size_t pos;
798
+ iPtrDiff gotoDict;
799
+ } seqState_t;
800
+
801
+
802
+ FORCE_NOINLINE
803
+ size_t ZSTD_execSequenceLast7(BYTE* op,
804
+ BYTE* const oend, seq_t sequence,
805
+ const BYTE** litPtr, const BYTE* const litLimit,
806
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
807
+ {
808
+ BYTE* const oLitEnd = op + sequence.litLength;
809
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
810
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
811
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
812
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
813
+ const BYTE* match = oLitEnd - sequence.offset;
814
+
815
+ /* check */
816
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
817
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
818
+ if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */
819
+
820
+ /* copy literals */
821
+ if (op < oend_w) {
822
+ ZSTD_wildcopy(op, *litPtr, oend_w - op);
823
+ *litPtr += oend_w - op;
824
+ op = oend_w;
825
+ }
826
+ while (op < oLitEnd) *op++ = *(*litPtr)++;
827
+
828
+ /* copy Match */
829
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
830
+ /* offset beyond prefix */
831
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
832
+ match = dictEnd - (base-match);
833
+ if (match + sequence.matchLength <= dictEnd) {
834
+ memmove(oLitEnd, match, sequence.matchLength);
835
+ return sequenceLength;
836
+ }
837
+ /* span extDict & currentPrefixSegment */
838
+ { size_t const length1 = dictEnd - match;
839
+ memmove(oLitEnd, match, length1);
840
+ op = oLitEnd + length1;
841
+ sequence.matchLength -= length1;
842
+ match = base;
843
+ } }
844
+ while (op < oMatchEnd) *op++ = *match++;
845
+ return sequenceLength;
846
+ }
847
+
848
+
849
+
850
+
851
+ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
852
+ {
853
+ seq_t seq;
854
+
855
+ U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
856
+ U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
857
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
858
+
859
+ U32 const llBits = LL_bits[llCode];
860
+ U32 const mlBits = ML_bits[mlCode];
861
+ U32 const ofBits = ofCode;
862
+ U32 const totalBits = llBits+mlBits+ofBits;
863
+
864
+ static const U32 LL_base[MaxLL+1] = {
865
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
866
+ 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
867
+ 0x2000, 0x4000, 0x8000, 0x10000 };
868
+
869
+ static const U32 ML_base[MaxML+1] = {
870
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
871
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
872
+ 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
873
+ 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
874
+
875
+ static const U32 OF_base[MaxOff+1] = {
876
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
877
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
878
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
879
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
880
+
881
+ /* sequence */
882
+ { size_t offset;
883
+ if (!ofCode)
884
+ offset = 0;
885
+ else {
886
+ offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
887
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
888
+ }
889
+
890
+ if (ofCode <= 1) {
891
+ offset += (llCode==0);
892
+ if (offset) {
893
+ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
894
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
895
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
896
+ seqState->prevOffset[1] = seqState->prevOffset[0];
897
+ seqState->prevOffset[0] = offset = temp;
898
+ } else {
899
+ offset = seqState->prevOffset[0];
900
+ }
901
+ } else {
902
+ seqState->prevOffset[2] = seqState->prevOffset[1];
903
+ seqState->prevOffset[1] = seqState->prevOffset[0];
904
+ seqState->prevOffset[0] = offset;
905
+ }
906
+ seq.offset = offset;
907
+ }
908
+
909
+ seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
910
+ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
911
+
912
+ seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
913
+ if (MEM_32bits() ||
914
+ (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
915
+
916
+ /* ANS state update */
917
+ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
918
+ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
919
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
920
+ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
921
+
922
+ return seq;
923
+ }
924
+
925
+
926
+ FORCE_INLINE
927
+ size_t ZSTD_execSequence(BYTE* op,
928
+ BYTE* const oend, seq_t sequence,
929
+ const BYTE** litPtr, const BYTE* const litLimit,
930
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
931
+ {
932
+ BYTE* const oLitEnd = op + sequence.litLength;
933
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
934
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
935
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
936
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
937
+ const BYTE* match = oLitEnd - sequence.offset;
938
+
939
+ /* check */
940
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
941
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
942
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
943
+
944
+ /* copy Literals */
945
+ ZSTD_copy8(op, *litPtr);
946
+ if (sequence.litLength > 8)
947
+ ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
948
+ op = oLitEnd;
949
+ *litPtr = iLitEnd; /* update for next sequence */
950
+
951
+ /* copy Match */
952
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
953
+ /* offset beyond prefix */
954
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
955
+ match += (dictEnd-base);
956
+ if (match + sequence.matchLength <= dictEnd) {
957
+ memmove(oLitEnd, match, sequence.matchLength);
958
+ return sequenceLength;
959
+ }
960
+ /* span extDict & currentPrefixSegment */
961
+ { size_t const length1 = dictEnd - match;
962
+ memmove(oLitEnd, match, length1);
963
+ op = oLitEnd + length1;
964
+ sequence.matchLength -= length1;
965
+ match = base;
966
+ if (op > oend_w || sequence.matchLength < MINMATCH) {
967
+ U32 i;
968
+ for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
969
+ return sequenceLength;
970
+ }
971
+ } }
972
+ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
973
+
974
+ /* match within prefix */
975
+ if (sequence.offset < 8) {
976
+ /* close range match, overlap */
977
+ static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
978
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
979
+ int const sub2 = dec64table[sequence.offset];
980
+ op[0] = match[0];
981
+ op[1] = match[1];
982
+ op[2] = match[2];
983
+ op[3] = match[3];
984
+ match += dec32table[sequence.offset];
985
+ ZSTD_copy4(op+4, match);
986
+ match -= sub2;
987
+ } else {
988
+ ZSTD_copy8(op, match);
989
+ }
990
+ op += 8; match += 8;
991
+
992
+ if (oMatchEnd > oend-(16-MINMATCH)) {
993
+ if (op < oend_w) {
994
+ ZSTD_wildcopy(op, match, oend_w - op);
995
+ match += oend_w - op;
996
+ op = oend_w;
997
+ }
998
+ while (op < oMatchEnd) *op++ = *match++;
999
+ } else {
1000
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
1001
+ }
1002
+ return sequenceLength;
1003
+ }
1004
+
1005
+
1006
+ static size_t ZSTD_decompressSequences(
1007
+ ZSTD_DCtx* dctx,
1008
+ void* dst, size_t maxDstSize,
1009
+ const void* seqStart, size_t seqSize)
1010
+ {
1011
+ const BYTE* ip = (const BYTE*)seqStart;
1012
+ const BYTE* const iend = ip + seqSize;
1013
+ BYTE* const ostart = (BYTE* const)dst;
1014
+ BYTE* const oend = ostart + maxDstSize;
1015
+ BYTE* op = ostart;
1016
+ const BYTE* litPtr = dctx->litPtr;
1017
+ const BYTE* const litEnd = litPtr + dctx->litSize;
1018
+ const BYTE* const base = (const BYTE*) (dctx->base);
1019
+ const BYTE* const vBase = (const BYTE*) (dctx->vBase);
1020
+ const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1021
+ int nbSeq;
1022
+
1023
+ /* Build Decoding Tables */
1024
+ { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1025
+ if (ZSTD_isError(seqHSize)) return seqHSize;
1026
+ ip += seqHSize;
1027
+ }
1028
+
1029
+ /* Regen sequences */
1030
+ if (nbSeq) {
1031
+ seqState_t seqState;
1032
+ dctx->fseEntropy = 1;
1033
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
1034
+ CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
1035
+ FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1036
+ FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1037
+ FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1038
+
1039
+ for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
1040
+ nbSeq--;
1041
+ { seq_t const sequence = ZSTD_decodeSequence(&seqState);
1042
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
1043
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1044
+ op += oneSeqSize;
1045
+ } }
1046
+
1047
+ /* check if reached exact end */
1048
+ if (nbSeq) return ERROR(corruption_detected);
1049
+ /* save reps for next block */
1050
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
1051
+ }
1052
+
1053
+ /* last literal segment */
1054
+ { size_t const lastLLSize = litEnd - litPtr;
1055
+ if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
1056
+ memcpy(op, litPtr, lastLLSize);
1057
+ op += lastLLSize;
1058
+ }
1059
+
1060
+ return op-ostart;
1061
+ }
1062
+
1063
+
1064
+ static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState)
1065
+ {
1066
+ seq_t seq;
1067
+
1068
+ U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
1069
+ U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
1070
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
1071
+
1072
+ U32 const llBits = LL_bits[llCode];
1073
+ U32 const mlBits = ML_bits[mlCode];
1074
+ U32 const ofBits = ofCode;
1075
+ U32 const totalBits = llBits+mlBits+ofBits;
1076
+
1077
+ static const U32 LL_base[MaxLL+1] = {
1078
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1079
+ 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1080
+ 0x2000, 0x4000, 0x8000, 0x10000 };
1081
+
1082
+ static const U32 ML_base[MaxML+1] = {
1083
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
1084
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
1085
+ 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
1086
+ 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
1087
+
1088
+ static const U32 OF_base[MaxOff+1] = {
1089
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
1090
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
1091
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
1092
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
1093
+
1094
+ /* sequence */
1095
+ { size_t offset;
1096
+ if (!ofCode)
1097
+ offset = 0;
1098
+ else {
1099
+ offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1100
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
1101
+ }
1102
+
1103
+ if (ofCode <= 1) {
1104
+ offset += (llCode==0);
1105
+ if (offset) {
1106
+ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1107
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
1108
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
1109
+ seqState->prevOffset[1] = seqState->prevOffset[0];
1110
+ seqState->prevOffset[0] = offset = temp;
1111
+ } else {
1112
+ offset = seqState->prevOffset[0];
1113
+ }
1114
+ } else {
1115
+ seqState->prevOffset[2] = seqState->prevOffset[1];
1116
+ seqState->prevOffset[1] = seqState->prevOffset[0];
1117
+ seqState->prevOffset[0] = offset;
1118
+ }
1119
+ seq.offset = offset;
1120
+ }
1121
+
1122
+ seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
1123
+ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
1124
+
1125
+ seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
1126
+ if (MEM_32bits() ||
1127
+ (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
1128
+
1129
+ { size_t const pos = seqState->pos + seq.litLength;
1130
+ seq.match = seqState->base + pos - seq.offset; /* single memory segment */
1131
+ if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */
1132
+ seqState->pos = pos + seq.matchLength;
1133
+ }
1134
+
1135
+ /* ANS state update */
1136
+ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
1137
+ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
1138
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1139
+ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
1140
+
1141
+ return seq;
1142
+ }
1143
+
1144
+ FORCE_INLINE
1145
+ size_t ZSTD_execSequenceLong(BYTE* op,
1146
+ BYTE* const oend, seq_t sequence,
1147
+ const BYTE** litPtr, const BYTE* const litLimit,
1148
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
1149
+ {
1150
+ BYTE* const oLitEnd = op + sequence.litLength;
1151
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1152
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1153
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
1154
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
1155
+ const BYTE* match = sequence.match;
1156
+
1157
+ /* check */
1158
+ #if 1
1159
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1160
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
1161
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1162
+ #endif
1163
+
1164
+ /* copy Literals */
1165
+ ZSTD_copy8(op, *litPtr);
1166
+ if (sequence.litLength > 8)
1167
+ ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1168
+ op = oLitEnd;
1169
+ *litPtr = iLitEnd; /* update for next sequence */
1170
+
1171
+ /* copy Match */
1172
+ #if 1
1173
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
1174
+ /* offset beyond prefix */
1175
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
1176
+ if (match + sequence.matchLength <= dictEnd) {
1177
+ memmove(oLitEnd, match, sequence.matchLength);
1178
+ return sequenceLength;
1179
+ }
1180
+ /* span extDict & currentPrefixSegment */
1181
+ { size_t const length1 = dictEnd - match;
1182
+ memmove(oLitEnd, match, length1);
1183
+ op = oLitEnd + length1;
1184
+ sequence.matchLength -= length1;
1185
+ match = base;
1186
+ if (op > oend_w || sequence.matchLength < MINMATCH) {
1187
+ U32 i;
1188
+ for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
1189
+ return sequenceLength;
1190
+ }
1191
+ } }
1192
+ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1193
+ #endif
1194
+
1195
+ /* match within prefix */
1196
+ if (sequence.offset < 8) {
1197
+ /* close range match, overlap */
1198
+ static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
1199
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
1200
+ int const sub2 = dec64table[sequence.offset];
1201
+ op[0] = match[0];
1202
+ op[1] = match[1];
1203
+ op[2] = match[2];
1204
+ op[3] = match[3];
1205
+ match += dec32table[sequence.offset];
1206
+ ZSTD_copy4(op+4, match);
1207
+ match -= sub2;
1208
+ } else {
1209
+ ZSTD_copy8(op, match);
1210
+ }
1211
+ op += 8; match += 8;
1212
+
1213
+ if (oMatchEnd > oend-(16-MINMATCH)) {
1214
+ if (op < oend_w) {
1215
+ ZSTD_wildcopy(op, match, oend_w - op);
1216
+ match += oend_w - op;
1217
+ op = oend_w;
1218
+ }
1219
+ while (op < oMatchEnd) *op++ = *match++;
1220
+ } else {
1221
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
1222
+ }
1223
+ return sequenceLength;
1224
+ }
1225
+
1226
+ static size_t ZSTD_decompressSequencesLong(
1227
+ ZSTD_DCtx* dctx,
1228
+ void* dst, size_t maxDstSize,
1229
+ const void* seqStart, size_t seqSize)
1230
+ {
1231
+ const BYTE* ip = (const BYTE*)seqStart;
1232
+ const BYTE* const iend = ip + seqSize;
1233
+ BYTE* const ostart = (BYTE* const)dst;
1234
+ BYTE* const oend = ostart + maxDstSize;
1235
+ BYTE* op = ostart;
1236
+ const BYTE* litPtr = dctx->litPtr;
1237
+ const BYTE* const litEnd = litPtr + dctx->litSize;
1238
+ const BYTE* const base = (const BYTE*) (dctx->base);
1239
+ const BYTE* const vBase = (const BYTE*) (dctx->vBase);
1240
+ const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1241
+ int nbSeq;
1242
+
1243
+ /* Build Decoding Tables */
1244
+ { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1245
+ if (ZSTD_isError(seqHSize)) return seqHSize;
1246
+ ip += seqHSize;
1247
+ }
1248
+
1249
+ /* Regen sequences */
1250
+ if (nbSeq) {
1251
+ #define STORED_SEQS 4
1252
+ #define STOSEQ_MASK (STORED_SEQS-1)
1253
+ #define ADVANCED_SEQS 4
1254
+ seq_t sequences[STORED_SEQS];
1255
+ int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
1256
+ seqState_t seqState;
1257
+ int seqNb;
1258
+ dctx->fseEntropy = 1;
1259
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
1260
+ seqState.base = base;
1261
+ seqState.pos = (size_t)(op-base);
1262
+ seqState.gotoDict = (iPtrDiff)(dictEnd - base);
1263
+ CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
1264
+ FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1265
+ FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1266
+ FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1267
+
1268
+ /* prepare in advance */
1269
+ for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) {
1270
+ sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState);
1271
+ }
1272
+ if (seqNb<seqAdvance) return ERROR(corruption_detected);
1273
+
1274
+ /* decode and decompress */
1275
+ for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) {
1276
+ seq_t const sequence = ZSTD_decodeSequenceLong(&seqState);
1277
+ size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
1278
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1279
+ ZSTD_PREFETCH(sequence.match);
1280
+ sequences[seqNb&STOSEQ_MASK] = sequence;
1281
+ op += oneSeqSize;
1282
+ }
1283
+ if (seqNb<nbSeq) return ERROR(corruption_detected);
1284
+
1285
+ /* finish queue */
1286
+ seqNb -= seqAdvance;
1287
+ for ( ; seqNb<nbSeq ; seqNb++) {
1288
+ size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb&STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
1289
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1290
+ op += oneSeqSize;
1291
+ }
1292
+
1293
+ /* save reps for next block */
1294
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
1295
+ }
1296
+
1297
+ /* last literal segment */
1298
+ { size_t const lastLLSize = litEnd - litPtr;
1299
+ if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
1300
+ memcpy(op, litPtr, lastLLSize);
1301
+ op += lastLLSize;
1302
+ }
1303
+
1304
+ return op-ostart;
1305
+ }
1306
+
1307
+
1308
+ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1309
+ void* dst, size_t dstCapacity,
1310
+ const void* src, size_t srcSize)
1311
+ { /* blockType == blockCompressed */
1312
+ const BYTE* ip = (const BYTE*)src;
1313
+
1314
+ if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
1315
+
1316
+ /* Decode literals sub-block */
1317
+ { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
1318
+ if (ZSTD_isError(litCSize)) return litCSize;
1319
+ ip += litCSize;
1320
+ srcSize -= litCSize;
1321
+ }
1322
+ if (dctx->fParams.windowSize > (1<<23)) return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
1323
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
1324
+ }
1325
+
1326
+
1327
+ static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
1328
+ {
1329
+ if (dst != dctx->previousDstEnd) { /* not contiguous */
1330
+ dctx->dictEnd = dctx->previousDstEnd;
1331
+ dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1332
+ dctx->base = dst;
1333
+ dctx->previousDstEnd = dst;
1334
+ }
1335
+ }
1336
+
1337
+ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
1338
+ void* dst, size_t dstCapacity,
1339
+ const void* src, size_t srcSize)
1340
+ {
1341
+ size_t dSize;
1342
+ ZSTD_checkContinuity(dctx, dst);
1343
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
1344
+ dctx->previousDstEnd = (char*)dst + dSize;
1345
+ return dSize;
1346
+ }
1347
+
1348
+
1349
+ /** ZSTD_insertBlock() :
1350
+ insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
1351
+ ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
1352
+ {
1353
+ ZSTD_checkContinuity(dctx, blockStart);
1354
+ dctx->previousDstEnd = (const char*)blockStart + blockSize;
1355
+ return blockSize;
1356
+ }
1357
+
1358
+
1359
+ size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
1360
+ {
1361
+ if (length > dstCapacity) return ERROR(dstSize_tooSmall);
1362
+ memset(dst, byte, length);
1363
+ return length;
1364
+ }
1365
+
1366
+
1367
+ /*! ZSTD_decompressFrame() :
1368
+ * `dctx` must be properly initialized */
1369
+ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1370
+ void* dst, size_t dstCapacity,
1371
+ const void* src, size_t srcSize)
1372
+ {
1373
+ const BYTE* ip = (const BYTE*)src;
1374
+ BYTE* const ostart = (BYTE* const)dst;
1375
+ BYTE* const oend = ostart + dstCapacity;
1376
+ BYTE* op = ostart;
1377
+ size_t remainingSize = srcSize;
1378
+
1379
+ /* check */
1380
+ if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
1381
+
1382
+ /* Frame Header */
1383
+ { size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
1384
+ if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
1385
+ if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
1386
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize));
1387
+ ip += frameHeaderSize; remainingSize -= frameHeaderSize;
1388
+ }
1389
+
1390
+ /* Loop on each block */
1391
+ while (1) {
1392
+ size_t decodedSize;
1393
+ blockProperties_t blockProperties;
1394
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
1395
+ if (ZSTD_isError(cBlockSize)) return cBlockSize;
1396
+
1397
+ ip += ZSTD_blockHeaderSize;
1398
+ remainingSize -= ZSTD_blockHeaderSize;
1399
+ if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
1400
+
1401
+ switch(blockProperties.blockType)
1402
+ {
1403
+ case bt_compressed:
1404
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
1405
+ break;
1406
+ case bt_raw :
1407
+ decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
1408
+ break;
1409
+ case bt_rle :
1410
+ decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
1411
+ break;
1412
+ case bt_reserved :
1413
+ default:
1414
+ return ERROR(corruption_detected);
1415
+ }
1416
+
1417
+ if (ZSTD_isError(decodedSize)) return decodedSize;
1418
+ if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
1419
+ op += decodedSize;
1420
+ ip += cBlockSize;
1421
+ remainingSize -= cBlockSize;
1422
+ if (blockProperties.lastBlock) break;
1423
+ }
1424
+
1425
+ if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1426
+ U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
1427
+ U32 checkRead;
1428
+ if (remainingSize<4) return ERROR(checksum_wrong);
1429
+ checkRead = MEM_readLE32(ip);
1430
+ if (checkRead != checkCalc) return ERROR(checksum_wrong);
1431
+ remainingSize -= 4;
1432
+ }
1433
+
1434
+ if (remainingSize) return ERROR(srcSize_wrong);
1435
+ return op-ostart;
1436
+ }
1437
+
1438
+
1439
+ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1440
+ void* dst, size_t dstCapacity,
1441
+ const void* src, size_t srcSize,
1442
+ const void* dict, size_t dictSize)
1443
+ {
1444
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
1445
+ if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize);
1446
+ #endif
1447
+ ZSTD_decompressBegin_usingDict(dctx, dict, dictSize);
1448
+ ZSTD_checkContinuity(dctx, dst);
1449
+ return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
1450
+ }
1451
+
1452
+
1453
+ size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1454
+ {
1455
+ return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
1456
+ }
1457
+
1458
+
1459
+ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1460
+ {
1461
+ #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
1462
+ size_t regenSize;
1463
+ ZSTD_DCtx* const dctx = ZSTD_createDCtx();
1464
+ if (dctx==NULL) return ERROR(memory_allocation);
1465
+ regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
1466
+ ZSTD_freeDCtx(dctx);
1467
+ return regenSize;
1468
+ #else /* stack mode */
1469
+ ZSTD_DCtx dctx;
1470
+ return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
1471
+ #endif
1472
+ }
1473
+
1474
+
1475
+ /*-**************************************
1476
+ * Advanced Streaming Decompression API
1477
+ * Bufferless and synchronous
1478
+ ****************************************/
1479
+ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
1480
+
1481
+ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
1482
+ switch(dctx->stage)
1483
+ {
1484
+ default: /* should not happen */
1485
+ case ZSTDds_getFrameHeaderSize:
1486
+ case ZSTDds_decodeFrameHeader:
1487
+ return ZSTDnit_frameHeader;
1488
+ case ZSTDds_decodeBlockHeader:
1489
+ return ZSTDnit_blockHeader;
1490
+ case ZSTDds_decompressBlock:
1491
+ return ZSTDnit_block;
1492
+ case ZSTDds_decompressLastBlock:
1493
+ return ZSTDnit_lastBlock;
1494
+ case ZSTDds_checkChecksum:
1495
+ return ZSTDnit_checksum;
1496
+ case ZSTDds_decodeSkippableHeader:
1497
+ case ZSTDds_skipFrame:
1498
+ return ZSTDnit_skippableFrame;
1499
+ }
1500
+ }
1501
+
1502
+ int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
1503
+
1504
+ /** ZSTD_decompressContinue() :
1505
+ * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1506
+ * or an error code, which can be tested using ZSTD_isError() */
1507
+ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1508
+ {
1509
+ /* Sanity check */
1510
+ if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
1511
+ if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
1512
+
1513
+ switch (dctx->stage)
1514
+ {
1515
+ case ZSTDds_getFrameHeaderSize :
1516
+ if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* impossible */
1517
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1518
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1519
+ dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
1520
+ dctx->stage = ZSTDds_decodeSkippableHeader;
1521
+ return 0;
1522
+ }
1523
+ dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
1524
+ if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1525
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1526
+ if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
1527
+ dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
1528
+ dctx->stage = ZSTDds_decodeFrameHeader;
1529
+ return 0;
1530
+ }
1531
+ dctx->expected = 0; /* not necessary to copy more */
1532
+
1533
+ case ZSTDds_decodeFrameHeader:
1534
+ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1535
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
1536
+ dctx->expected = ZSTD_blockHeaderSize;
1537
+ dctx->stage = ZSTDds_decodeBlockHeader;
1538
+ return 0;
1539
+
1540
+ case ZSTDds_decodeBlockHeader:
1541
+ { blockProperties_t bp;
1542
+ size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1543
+ if (ZSTD_isError(cBlockSize)) return cBlockSize;
1544
+ dctx->expected = cBlockSize;
1545
+ dctx->bType = bp.blockType;
1546
+ dctx->rleSize = bp.origSize;
1547
+ if (cBlockSize) {
1548
+ dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
1549
+ return 0;
1550
+ }
1551
+ /* empty block */
1552
+ if (bp.lastBlock) {
1553
+ if (dctx->fParams.checksumFlag) {
1554
+ dctx->expected = 4;
1555
+ dctx->stage = ZSTDds_checkChecksum;
1556
+ } else {
1557
+ dctx->expected = 0; /* end of frame */
1558
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1559
+ }
1560
+ } else {
1561
+ dctx->expected = 3; /* go directly to next header */
1562
+ dctx->stage = ZSTDds_decodeBlockHeader;
1563
+ }
1564
+ return 0;
1565
+ }
1566
+ case ZSTDds_decompressLastBlock:
1567
+ case ZSTDds_decompressBlock:
1568
+ { size_t rSize;
1569
+ switch(dctx->bType)
1570
+ {
1571
+ case bt_compressed:
1572
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
1573
+ break;
1574
+ case bt_raw :
1575
+ rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
1576
+ break;
1577
+ case bt_rle :
1578
+ rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
1579
+ break;
1580
+ case bt_reserved : /* should never happen */
1581
+ default:
1582
+ return ERROR(corruption_detected);
1583
+ }
1584
+ if (ZSTD_isError(rSize)) return rSize;
1585
+ if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
1586
+
1587
+ if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1588
+ if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1589
+ dctx->expected = 4;
1590
+ dctx->stage = ZSTDds_checkChecksum;
1591
+ } else {
1592
+ dctx->expected = 0; /* ends here */
1593
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1594
+ }
1595
+ } else {
1596
+ dctx->stage = ZSTDds_decodeBlockHeader;
1597
+ dctx->expected = ZSTD_blockHeaderSize;
1598
+ dctx->previousDstEnd = (char*)dst + rSize;
1599
+ }
1600
+ return rSize;
1601
+ }
1602
+ case ZSTDds_checkChecksum:
1603
+ { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1604
+ U32 const check32 = MEM_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
1605
+ if (check32 != h32) return ERROR(checksum_wrong);
1606
+ dctx->expected = 0;
1607
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1608
+ return 0;
1609
+ }
1610
+ case ZSTDds_decodeSkippableHeader:
1611
+ { memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1612
+ dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
1613
+ dctx->stage = ZSTDds_skipFrame;
1614
+ return 0;
1615
+ }
1616
+ case ZSTDds_skipFrame:
1617
+ { dctx->expected = 0;
1618
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1619
+ return 0;
1620
+ }
1621
+ default:
1622
+ return ERROR(GENERIC); /* impossible */
1623
+ }
1624
+ }
1625
+
1626
+
1627
+ static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1628
+ {
1629
+ dctx->dictEnd = dctx->previousDstEnd;
1630
+ dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1631
+ dctx->base = dict;
1632
+ dctx->previousDstEnd = (const char*)dict + dictSize;
1633
+ return 0;
1634
+ }
1635
+
1636
+ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t const dictSize)
1637
+ {
1638
+ const BYTE* dictPtr = (const BYTE*)dict;
1639
+ const BYTE* const dictEnd = dictPtr + dictSize;
1640
+
1641
+ { size_t const hSize = HUF_readDTableX4(dctx->hufTable, dict, dictSize);
1642
+ if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
1643
+ dictPtr += hSize;
1644
+ }
1645
+
1646
+ { short offcodeNCount[MaxOff+1];
1647
+ U32 offcodeMaxValue=MaxOff, offcodeLog;
1648
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
1649
+ if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1650
+ if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
1651
+ CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
1652
+ dictPtr += offcodeHeaderSize;
1653
+ }
1654
+
1655
+ { short matchlengthNCount[MaxML+1];
1656
+ unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1657
+ size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
1658
+ if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1659
+ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
1660
+ CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
1661
+ dictPtr += matchlengthHeaderSize;
1662
+ }
1663
+
1664
+ { short litlengthNCount[MaxLL+1];
1665
+ unsigned litlengthMaxValue = MaxLL, litlengthLog;
1666
+ size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
1667
+ if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1668
+ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
1669
+ CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
1670
+ dictPtr += litlengthHeaderSize;
1671
+ }
1672
+
1673
+ if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
1674
+ dctx->rep[0] = MEM_readLE32(dictPtr+0); if (dctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
1675
+ dctx->rep[1] = MEM_readLE32(dictPtr+4); if (dctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
1676
+ dctx->rep[2] = MEM_readLE32(dictPtr+8); if (dctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
1677
+ dictPtr += 12;
1678
+
1679
+ dctx->litEntropy = dctx->fseEntropy = 1;
1680
+ return dictPtr - (const BYTE*)dict;
1681
+ }
1682
+
1683
+ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1684
+ {
1685
+ if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
1686
+ { U32 const magic = MEM_readLE32(dict);
1687
+ if (magic != ZSTD_DICT_MAGIC) {
1688
+ return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
1689
+ } }
1690
+ dctx->dictID = MEM_readLE32((const char*)dict + 4);
1691
+
1692
+ /* load entropy tables */
1693
+ dict = (const char*)dict + 8;
1694
+ dictSize -= 8;
1695
+ { size_t const eSize = ZSTD_loadEntropy(dctx, dict, dictSize);
1696
+ if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1697
+ dict = (const char*)dict + eSize;
1698
+ dictSize -= eSize;
1699
+ }
1700
+
1701
+ /* reference dictionary content */
1702
+ return ZSTD_refDictContent(dctx, dict, dictSize);
1703
+ }
1704
+
1705
+ size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1706
+ {
1707
+ CHECK_F(ZSTD_decompressBegin(dctx));
1708
+ if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
1709
+ return 0;
1710
+ }
1711
+
1712
+
1713
+ /* ====== ZSTD_DDict ====== */
1714
+
1715
+ struct ZSTD_DDict_s {
1716
+ void* dict;
1717
+ size_t dictSize;
1718
+ ZSTD_DCtx* refContext;
1719
+ }; /* typedef'd to ZSTD_DDict within "zstd.h" */
1720
+
1721
+ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_customMem customMem)
1722
+ {
1723
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
1724
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
1725
+
1726
+ { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
1727
+ void* const dictContent = ZSTD_malloc(dictSize, customMem);
1728
+ ZSTD_DCtx* const dctx = ZSTD_createDCtx_advanced(customMem);
1729
+
1730
+ if (!dictContent || !ddict || !dctx) {
1731
+ ZSTD_free(dictContent, customMem);
1732
+ ZSTD_free(ddict, customMem);
1733
+ ZSTD_free(dctx, customMem);
1734
+ return NULL;
1735
+ }
1736
+
1737
+ if (dictSize) {
1738
+ memcpy(dictContent, dict, dictSize);
1739
+ }
1740
+ { size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dictContent, dictSize);
1741
+ if (ZSTD_isError(errorCode)) {
1742
+ ZSTD_free(dictContent, customMem);
1743
+ ZSTD_free(ddict, customMem);
1744
+ ZSTD_free(dctx, customMem);
1745
+ return NULL;
1746
+ } }
1747
+
1748
+ ddict->dict = dictContent;
1749
+ ddict->dictSize = dictSize;
1750
+ ddict->refContext = dctx;
1751
+ return ddict;
1752
+ }
1753
+ }
1754
+
1755
+ /*! ZSTD_createDDict() :
1756
+ * Create a digested dictionary, ready to start decompression without startup delay.
1757
+ * `dict` can be released after `ZSTD_DDict` creation */
1758
+ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
1759
+ {
1760
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
1761
+ return ZSTD_createDDict_advanced(dict, dictSize, allocator);
1762
+ }
1763
+
1764
+ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
1765
+ {
1766
+ if (ddict==NULL) return 0; /* support free on NULL */
1767
+ { ZSTD_customMem const cMem = ddict->refContext->customMem;
1768
+ ZSTD_freeDCtx(ddict->refContext);
1769
+ ZSTD_free(ddict->dict, cMem);
1770
+ ZSTD_free(ddict, cMem);
1771
+ return 0;
1772
+ }
1773
+ }
1774
+
1775
+ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
1776
+ {
1777
+ if (ddict==NULL) return 0; /* support sizeof on NULL */
1778
+ return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize;
1779
+ }
1780
+
1781
+ /*! ZSTD_getDictID_fromDict() :
1782
+ * Provides the dictID stored within dictionary.
1783
+ * if @return == 0, the dictionary is not conformant with Zstandard specification.
1784
+ * It can still be loaded, but as a content-only dictionary. */
1785
+ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
1786
+ {
1787
+ if (dictSize < 8) return 0;
1788
+ if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
1789
+ return MEM_readLE32((const char*)dict + 4);
1790
+ }
1791
+
1792
+ /*! ZSTD_getDictID_fromDDict() :
1793
+ * Provides the dictID of the dictionary loaded into `ddict`.
1794
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
1795
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
1796
+ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
1797
+ {
1798
+ if (ddict==NULL) return 0;
1799
+ return ZSTD_getDictID_fromDict(ddict->dict, ddict->dictSize);
1800
+ }
1801
+
1802
+ /*! ZSTD_getDictID_fromFrame() :
1803
+ * Provides the dictID required to decompressed the frame stored within `src`.
1804
+ * If @return == 0, the dictID could not be decoded.
1805
+ * This could for one of the following reasons :
1806
+ * - The frame does not require a dictionary to be decoded (most common case).
1807
+ * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
1808
+ * Note : this use case also happens when using a non-conformant dictionary.
1809
+ * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
1810
+ * - This is not a Zstandard frame.
1811
+ * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
1812
+ unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
1813
+ {
1814
+ ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
1815
+ size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
1816
+ if (ZSTD_isError(hError)) return 0;
1817
+ return zfp.dictID;
1818
+ }
1819
+
1820
+
1821
+ /*! ZSTD_decompress_usingDDict() :
1822
+ * Decompression using a pre-digested Dictionary
1823
+ * Use dictionary without significant overhead. */
1824
+ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
1825
+ void* dst, size_t dstCapacity,
1826
+ const void* src, size_t srcSize,
1827
+ const ZSTD_DDict* ddict)
1828
+ {
1829
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
1830
+ if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, ddict->dict, ddict->dictSize);
1831
+ #endif
1832
+ ZSTD_refDCtx(dctx, ddict->refContext);
1833
+ ZSTD_checkContinuity(dctx, dst);
1834
+ return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
1835
+ }
1836
+
1837
+
1838
+ /*=====================================
1839
+ * Streaming decompression
1840
+ *====================================*/
1841
+
1842
+ typedef enum { zdss_init, zdss_loadHeader,
1843
+ zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
1844
+
1845
+ /* *** Resource management *** */
1846
+ struct ZSTD_DStream_s {
1847
+ ZSTD_DCtx* dctx;
1848
+ ZSTD_DDict* ddictLocal;
1849
+ const ZSTD_DDict* ddict;
1850
+ ZSTD_frameParams fParams;
1851
+ ZSTD_dStreamStage stage;
1852
+ char* inBuff;
1853
+ size_t inBuffSize;
1854
+ size_t inPos;
1855
+ size_t maxWindowSize;
1856
+ char* outBuff;
1857
+ size_t outBuffSize;
1858
+ size_t outStart;
1859
+ size_t outEnd;
1860
+ size_t blockSize;
1861
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
1862
+ size_t lhSize;
1863
+ ZSTD_customMem customMem;
1864
+ void* legacyContext;
1865
+ U32 previousLegacyVersion;
1866
+ U32 legacyVersion;
1867
+ U32 hostageByte;
1868
+ }; /* typedef'd to ZSTD_DStream within "zstd.h" */
1869
+
1870
+
1871
+ ZSTD_DStream* ZSTD_createDStream(void)
1872
+ {
1873
+ return ZSTD_createDStream_advanced(defaultCustomMem);
1874
+ }
1875
+
1876
+ ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
1877
+ {
1878
+ ZSTD_DStream* zds;
1879
+
1880
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
1881
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
1882
+
1883
+ zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
1884
+ if (zds==NULL) return NULL;
1885
+ memset(zds, 0, sizeof(ZSTD_DStream));
1886
+ memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
1887
+ zds->dctx = ZSTD_createDCtx_advanced(customMem);
1888
+ if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
1889
+ zds->stage = zdss_init;
1890
+ zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
1891
+ return zds;
1892
+ }
1893
+
1894
+ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
1895
+ {
1896
+ if (zds==NULL) return 0; /* support free on null */
1897
+ { ZSTD_customMem const cMem = zds->customMem;
1898
+ ZSTD_freeDCtx(zds->dctx);
1899
+ ZSTD_freeDDict(zds->ddictLocal);
1900
+ ZSTD_free(zds->inBuff, cMem);
1901
+ ZSTD_free(zds->outBuff, cMem);
1902
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1903
+ if (zds->legacyContext)
1904
+ ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
1905
+ #endif
1906
+ ZSTD_free(zds, cMem);
1907
+ return 0;
1908
+ }
1909
+ }
1910
+
1911
+
1912
+ /* *** Initialization *** */
1913
+
1914
+ size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
1915
+ size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
1916
+
1917
+ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1918
+ {
1919
+ zds->stage = zdss_loadHeader;
1920
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1921
+ ZSTD_freeDDict(zds->ddictLocal);
1922
+ if (dict) {
1923
+ zds->ddictLocal = ZSTD_createDDict(dict, dictSize);
1924
+ if (zds->ddictLocal == NULL) return ERROR(memory_allocation);
1925
+ } else zds->ddictLocal = NULL;
1926
+ zds->ddict = zds->ddictLocal;
1927
+ zds->legacyVersion = 0;
1928
+ zds->hostageByte = 0;
1929
+ return ZSTD_frameHeaderSize_prefix;
1930
+ }
1931
+
1932
+ size_t ZSTD_initDStream(ZSTD_DStream* zds)
1933
+ {
1934
+ return ZSTD_initDStream_usingDict(zds, NULL, 0);
1935
+ }
1936
+
1937
+ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict) /**< note : ddict will just be referenced, and must outlive decompression session */
1938
+ {
1939
+ size_t const initResult = ZSTD_initDStream(zds);
1940
+ zds->ddict = ddict;
1941
+ return initResult;
1942
+ }
1943
+
1944
+ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
1945
+ {
1946
+ zds->stage = zdss_loadHeader;
1947
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1948
+ zds->legacyVersion = 0;
1949
+ zds->hostageByte = 0;
1950
+ return ZSTD_frameHeaderSize_prefix;
1951
+ }
1952
+
1953
+ size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
1954
+ ZSTD_DStreamParameter_e paramType, unsigned paramValue)
1955
+ {
1956
+ switch(paramType)
1957
+ {
1958
+ default : return ERROR(parameter_unknown);
1959
+ case ZSTDdsp_maxWindowSize : zds->maxWindowSize = paramValue ? paramValue : (U32)(-1); break;
1960
+ }
1961
+ return 0;
1962
+ }
1963
+
1964
+
1965
+ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
1966
+ {
1967
+ if (zds==NULL) return 0; /* support sizeof on NULL */
1968
+ return sizeof(*zds) + ZSTD_sizeof_DCtx(zds->dctx) + ZSTD_sizeof_DDict(zds->ddictLocal) + zds->inBuffSize + zds->outBuffSize;
1969
+ }
1970
+
1971
+
1972
+ /* ***** Decompression ***** */
1973
+
1974
+ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1975
+ {
1976
+ size_t const length = MIN(dstCapacity, srcSize);
1977
+ memcpy(dst, src, length);
1978
+ return length;
1979
+ }
1980
+
1981
+
1982
+ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
1983
+ {
1984
+ const char* const istart = (const char*)(input->src) + input->pos;
1985
+ const char* const iend = (const char*)(input->src) + input->size;
1986
+ const char* ip = istart;
1987
+ char* const ostart = (char*)(output->dst) + output->pos;
1988
+ char* const oend = (char*)(output->dst) + output->size;
1989
+ char* op = ostart;
1990
+ U32 someMoreWork = 1;
1991
+
1992
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1993
+ if (zds->legacyVersion)
1994
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
1995
+ #endif
1996
+
1997
+ while (someMoreWork) {
1998
+ switch(zds->stage)
1999
+ {
2000
+ case zdss_init :
2001
+ ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
2002
+ /* fall-through */
2003
+
2004
+ case zdss_loadHeader :
2005
+ { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
2006
+ if (ZSTD_isError(hSize))
2007
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2008
+ { U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
2009
+ if (legacyVersion) {
2010
+ const void* const dict = zds->ddict ? zds->ddict->dict : NULL;
2011
+ size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
2012
+ CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
2013
+ dict, dictSize));
2014
+ zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
2015
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
2016
+ } else {
2017
+ return hSize; /* error */
2018
+ } }
2019
+ #else
2020
+ return hSize;
2021
+ #endif
2022
+ if (hSize != 0) { /* need more input */
2023
+ size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
2024
+ if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
2025
+ memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
2026
+ zds->lhSize += iend-ip;
2027
+ input->pos = input->size;
2028
+ return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
2029
+ }
2030
+ memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
2031
+ break;
2032
+ } }
2033
+
2034
+ /* Consume header */
2035
+ { const ZSTD_DCtx* refContext = zds->ddict ? zds->ddict->refContext : NULL;
2036
+ ZSTD_refDCtx(zds->dctx, refContext);
2037
+ }
2038
+ { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
2039
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
2040
+ { size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2041
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
2042
+ } }
2043
+
2044
+ zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2045
+ if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
2046
+
2047
+ /* Adapt buffer sizes to frame header instructions */
2048
+ { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
2049
+ size_t const neededOutSize = zds->fParams.windowSize + blockSize;
2050
+ zds->blockSize = blockSize;
2051
+ if (zds->inBuffSize < blockSize) {
2052
+ ZSTD_free(zds->inBuff, zds->customMem);
2053
+ zds->inBuffSize = blockSize;
2054
+ zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
2055
+ if (zds->inBuff == NULL) return ERROR(memory_allocation);
2056
+ }
2057
+ if (zds->outBuffSize < neededOutSize) {
2058
+ ZSTD_free(zds->outBuff, zds->customMem);
2059
+ zds->outBuffSize = neededOutSize;
2060
+ zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
2061
+ if (zds->outBuff == NULL) return ERROR(memory_allocation);
2062
+ } }
2063
+ zds->stage = zdss_read;
2064
+ /* pass-through */
2065
+
2066
+ case zdss_read:
2067
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2068
+ if (neededInSize==0) { /* end of frame */
2069
+ zds->stage = zdss_init;
2070
+ someMoreWork = 0;
2071
+ break;
2072
+ }
2073
+ if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
2074
+ const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
2075
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
2076
+ zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
2077
+ ip, neededInSize);
2078
+ if (ZSTD_isError(decodedSize)) return decodedSize;
2079
+ ip += neededInSize;
2080
+ if (!decodedSize && !isSkipFrame) break; /* this was just a header */
2081
+ zds->outEnd = zds->outStart + decodedSize;
2082
+ zds->stage = zdss_flush;
2083
+ break;
2084
+ }
2085
+ if (ip==iend) { someMoreWork = 0; break; } /* no more input */
2086
+ zds->stage = zdss_load;
2087
+ /* pass-through */
2088
+ }
2089
+
2090
+ case zdss_load:
2091
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2092
+ size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
2093
+ size_t loadedSize;
2094
+ if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
2095
+ loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
2096
+ ip += loadedSize;
2097
+ zds->inPos += loadedSize;
2098
+ if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
2099
+
2100
+ /* decode loaded input */
2101
+ { const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
2102
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
2103
+ zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
2104
+ zds->inBuff, neededInSize);
2105
+ if (ZSTD_isError(decodedSize)) return decodedSize;
2106
+ zds->inPos = 0; /* input is consumed */
2107
+ if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; } /* this was just a header */
2108
+ zds->outEnd = zds->outStart + decodedSize;
2109
+ zds->stage = zdss_flush;
2110
+ /* pass-through */
2111
+ } }
2112
+
2113
+ case zdss_flush:
2114
+ { size_t const toFlushSize = zds->outEnd - zds->outStart;
2115
+ size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
2116
+ op += flushedSize;
2117
+ zds->outStart += flushedSize;
2118
+ if (flushedSize == toFlushSize) { /* flush completed */
2119
+ zds->stage = zdss_read;
2120
+ if (zds->outStart + zds->blockSize > zds->outBuffSize)
2121
+ zds->outStart = zds->outEnd = 0;
2122
+ break;
2123
+ }
2124
+ /* cannot complete flush */
2125
+ someMoreWork = 0;
2126
+ break;
2127
+ }
2128
+ default: return ERROR(GENERIC); /* impossible */
2129
+ } }
2130
+
2131
+ /* result */
2132
+ input->pos += (size_t)(ip-istart);
2133
+ output->pos += (size_t)(op-ostart);
2134
+ { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2135
+ if (!nextSrcSizeHint) { /* frame fully decoded */
2136
+ if (zds->outEnd == zds->outStart) { /* output fully flushed */
2137
+ if (zds->hostageByte) {
2138
+ if (input->pos >= input->size) { zds->stage = zdss_read; return 1; } /* can't release hostage (not present) */
2139
+ input->pos++; /* release hostage */
2140
+ }
2141
+ return 0;
2142
+ }
2143
+ if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
2144
+ input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
2145
+ zds->hostageByte=1;
2146
+ }
2147
+ return 1;
2148
+ }
2149
+ nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
2150
+ if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
2151
+ nextSrcSizeHint -= zds->inPos; /* already loaded*/
2152
+ return nextSrcSizeHint;
2153
+ }
2154
+ }