extzstd 0.0.3.CONCEPT-x86-mingw32 → 0.1-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja +5 -0
  3. data/LICENSE +6 -6
  4. data/README.md +35 -22
  5. data/contrib/zstd/LICENSE +13 -9
  6. data/contrib/zstd/README.md +37 -44
  7. data/contrib/zstd/common/entropy_common.c +33 -39
  8. data/contrib/zstd/common/error_private.c +43 -0
  9. data/contrib/zstd/common/error_private.h +11 -60
  10. data/contrib/zstd/common/fse.h +11 -5
  11. data/contrib/zstd/common/fse_decompress.c +14 -16
  12. data/contrib/zstd/common/huf.h +1 -1
  13. data/contrib/zstd/common/mem.h +36 -43
  14. data/contrib/zstd/common/xxhash.c +31 -18
  15. data/contrib/zstd/common/xxhash.h +71 -35
  16. data/contrib/zstd/common/zbuff.h +29 -35
  17. data/contrib/zstd/common/zstd_common.c +24 -32
  18. data/contrib/zstd/common/zstd_errors.h +60 -0
  19. data/contrib/zstd/common/zstd_internal.h +109 -80
  20. data/contrib/zstd/compress/fse_compress.c +9 -6
  21. data/contrib/zstd/compress/huf_compress.c +30 -74
  22. data/contrib/zstd/compress/zbuff_compress.c +43 -51
  23. data/contrib/zstd/compress/zstd_compress.c +953 -763
  24. data/contrib/zstd/compress/zstd_opt.h +115 -261
  25. data/contrib/zstd/decompress/huf_decompress.c +29 -40
  26. data/contrib/zstd/decompress/zbuff_decompress.c +36 -78
  27. data/contrib/zstd/decompress/zstd_decompress.c +976 -496
  28. data/contrib/zstd/dictBuilder/divsufsort.h +5 -5
  29. data/contrib/zstd/dictBuilder/zdict.c +194 -229
  30. data/contrib/zstd/dictBuilder/zdict.h +66 -68
  31. data/contrib/zstd/legacy/zstd_legacy.h +168 -49
  32. data/contrib/zstd/legacy/zstd_v01.c +95 -178
  33. data/contrib/zstd/legacy/zstd_v01.h +12 -32
  34. data/contrib/zstd/legacy/zstd_v02.c +48 -274
  35. data/contrib/zstd/legacy/zstd_v02.h +12 -32
  36. data/contrib/zstd/legacy/zstd_v03.c +48 -274
  37. data/contrib/zstd/legacy/zstd_v03.h +12 -32
  38. data/contrib/zstd/legacy/zstd_v04.c +63 -320
  39. data/contrib/zstd/legacy/zstd_v04.h +13 -33
  40. data/contrib/zstd/legacy/zstd_v05.c +80 -345
  41. data/contrib/zstd/legacy/zstd_v05.h +9 -31
  42. data/contrib/zstd/legacy/zstd_v06.c +48 -458
  43. data/contrib/zstd/legacy/zstd_v06.h +41 -67
  44. data/contrib/zstd/legacy/zstd_v07.c +4544 -0
  45. data/contrib/zstd/legacy/zstd_v07.h +173 -0
  46. data/contrib/zstd/zstd.h +640 -0
  47. data/ext/extconf.rb +7 -3
  48. data/ext/extzstd.c +263 -106
  49. data/ext/extzstd.h +8 -6
  50. data/ext/extzstd_nogvls.h +0 -117
  51. data/ext/extzstd_stream.c +347 -0
  52. data/ext/zstd_common.c +8 -0
  53. data/ext/zstd_compress.c +6 -0
  54. data/ext/zstd_decompress.c +5 -0
  55. data/ext/zstd_dictbuilder.c +5 -0
  56. data/ext/zstd_legacy_v07.c +1 -0
  57. data/gemstub.rb +18 -16
  58. data/lib/2.1/extzstd.so +0 -0
  59. data/lib/2.2/extzstd.so +0 -0
  60. data/lib/2.3/extzstd.so +0 -0
  61. data/lib/extzstd/version.rb +1 -1
  62. data/lib/extzstd.rb +77 -43
  63. data/test/test_basic.rb +11 -6
  64. metadata +23 -11
  65. data/contrib/zstd/common/error_public.h +0 -77
  66. data/contrib/zstd/common/zstd.h +0 -475
  67. data/ext/extzstd_buffered.c +0 -265
  68. data/ext/zstd_amalgam.c +0 -18
  69. data/lib/2.0/extzstd.so +0 -0
@@ -1,33 +1,12 @@
1
- /*
2
- zstd - standard compression library
3
- Copyright (C) 2014-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
- * Redistributions of source code must retain the above copyright
11
- notice, this list of conditions and the following disclaimer.
12
- * Redistributions in binary form must reproduce the above
13
- copyright notice, this list of conditions and the following disclaimer
14
- in the documentation and/or other materials provided with the
15
- distribution.
16
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
-
28
- You can contact the author at :
29
- - zstd homepage : http://www.zstd.net
30
- */
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
+
31
10
 
32
11
  /* ***************************************************************
33
12
  * Tuning parameters
@@ -49,12 +28,20 @@
49
28
  # define ZSTD_LEGACY_SUPPORT 0
50
29
  #endif
51
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
+
52
40
 
53
41
  /*-*******************************************************
54
42
  * Dependencies
55
43
  *********************************************************/
56
44
  #include <string.h> /* memcpy, memmove, memset */
57
- #include <stdio.h> /* debug only : printf */
58
45
  #include "mem.h" /* low level memory routines */
59
46
  #define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
60
47
  #include "xxhash.h" /* XXH64_* */
@@ -69,23 +56,6 @@
69
56
  #endif
70
57
 
71
58
 
72
- /*-*******************************************************
73
- * Compiler specifics
74
- *********************************************************/
75
- #ifdef _MSC_VER /* Visual Studio */
76
- # define FORCE_INLINE static __forceinline
77
- # include <intrin.h> /* For Visual 2005 */
78
- # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
79
- # pragma warning(disable : 4324) /* disable: C4324: padded structure */
80
- #else
81
- # ifdef __GNUC__
82
- # define FORCE_INLINE static inline __attribute__((always_inline))
83
- # else
84
- # define FORCE_INLINE static inline
85
- # endif
86
- #endif
87
-
88
-
89
59
  /*-*************************************
90
60
  * Macros
91
61
  ***************************************/
@@ -105,12 +75,17 @@ static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
105
75
  ***************************************************************/
106
76
  typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
107
77
  ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
78
+ ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
108
79
  ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
109
80
 
110
81
  struct ZSTD_DCtx_s
111
82
  {
83
+ const FSE_DTable* LLTptr;
84
+ const FSE_DTable* MLTptr;
85
+ const FSE_DTable* OFTptr;
86
+ const HUF_DTable* HUFptr;
112
87
  FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
113
- FSE_DTable OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
88
+ FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
114
89
  FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
115
90
  HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
116
91
  const void* previousDstEnd;
@@ -118,9 +93,9 @@ struct ZSTD_DCtx_s
118
93
  const void* vBase;
119
94
  const void* dictEnd;
120
95
  size_t expected;
121
- U32 rep[3];
96
+ U32 rep[ZSTD_REP_NUM];
122
97
  ZSTD_frameParams fParams;
123
- blockType_t bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
98
+ blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
124
99
  ZSTD_dStage stage;
125
100
  U32 litEntropy;
126
101
  U32 fseEntropy;
@@ -131,26 +106,32 @@ struct ZSTD_DCtx_s
131
106
  ZSTD_customMem customMem;
132
107
  size_t litBufSize;
133
108
  size_t litSize;
134
- BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
109
+ size_t rleSize;
110
+ BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
135
111
  BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
136
- }; /* typedef'd to ZSTD_DCtx within "zstd_static.h" */
112
+ }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
137
113
 
138
- size_t ZSTD_sizeofDCtx (const ZSTD_DCtx* dctx) { return sizeof(*dctx); }
114
+ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { return (dctx==NULL) ? 0 : sizeof(ZSTD_DCtx); }
139
115
 
140
116
  size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
141
117
 
142
118
  size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
143
119
  {
144
- dctx->expected = ZSTD_frameHeaderSize_min;
120
+ dctx->expected = ZSTD_frameHeaderSize_prefix;
145
121
  dctx->stage = ZSTDds_getFrameHeaderSize;
146
122
  dctx->previousDstEnd = NULL;
147
123
  dctx->base = NULL;
148
124
  dctx->vBase = NULL;
149
125
  dctx->dictEnd = NULL;
150
- dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);
126
+ dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
151
127
  dctx->litEntropy = dctx->fseEntropy = 0;
152
128
  dctx->dictID = 0;
153
- { int i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = repStartValue[i]; }
129
+ MEM_STATIC_ASSERT(sizeof(dctx->rep) == sizeof(repStartValue));
130
+ memcpy(dctx->rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
131
+ dctx->LLTptr = dctx->LLTable;
132
+ dctx->MLTptr = dctx->MLTable;
133
+ dctx->OFTptr = dctx->OFTable;
134
+ dctx->HUFptr = dctx->hufTable;
154
135
  return 0;
155
136
  }
156
137
 
@@ -158,15 +139,12 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
158
139
  {
159
140
  ZSTD_DCtx* dctx;
160
141
 
161
- if (!customMem.customAlloc && !customMem.customFree)
162
- customMem = defaultCustomMem;
142
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
143
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
163
144
 
164
- if (!customMem.customAlloc || !customMem.customFree)
165
- return NULL;
166
-
167
- dctx = (ZSTD_DCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_DCtx));
145
+ dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
168
146
  if (!dctx) return NULL;
169
- memcpy(&dctx->customMem, &customMem, sizeof(ZSTD_customMem));
147
+ memcpy(&dctx->customMem, &customMem, sizeof(customMem));
170
148
  ZSTD_decompressBegin(dctx);
171
149
  return dctx;
172
150
  }
@@ -179,14 +157,35 @@ ZSTD_DCtx* ZSTD_createDCtx(void)
179
157
  size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
180
158
  {
181
159
  if (dctx==NULL) return 0; /* support free on NULL */
182
- dctx->customMem.customFree(dctx->customMem.opaque, dctx);
160
+ ZSTD_free(dctx, dctx->customMem);
183
161
  return 0; /* reserved as a potential error code in the future */
184
162
  }
185
163
 
186
164
  void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
187
165
  {
188
- memcpy(dstDCtx, srcDCtx,
189
- sizeof(ZSTD_DCtx) - (ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH + ZSTD_frameHeaderSize_max)); /* no need to copy workspace */
166
+ size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
167
+ memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
168
+ }
169
+
170
+ static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
171
+ {
172
+ ZSTD_decompressBegin(dstDCtx); /* init */
173
+ if (srcDCtx) { /* support refDCtx on NULL */
174
+ dstDCtx->dictEnd = srcDCtx->dictEnd;
175
+ dstDCtx->vBase = srcDCtx->vBase;
176
+ dstDCtx->base = srcDCtx->base;
177
+ dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
178
+ dstDCtx->dictID = srcDCtx->dictID;
179
+ dstDCtx->litEntropy = srcDCtx->litEntropy;
180
+ dstDCtx->fseEntropy = srcDCtx->fseEntropy;
181
+ dstDCtx->LLTptr = srcDCtx->LLTable;
182
+ dstDCtx->MLTptr = srcDCtx->MLTable;
183
+ dstDCtx->OFTptr = srcDCtx->OFTable;
184
+ dstDCtx->HUFptr = srcDCtx->hufTable;
185
+ dstDCtx->rep[0] = srcDCtx->rep[0];
186
+ dstDCtx->rep[1] = srcDCtx->rep[1];
187
+ dstDCtx->rep[2] = srcDCtx->rep[2];
188
+ }
190
189
  }
191
190
 
192
191
 
@@ -194,130 +193,20 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
194
193
  * Decompression section
195
194
  ***************************************************************/
196
195
 
197
- /* Frame format description
198
- Frame Header - [ Block Header - Block ] - Frame End
199
- 1) Frame Header
200
- - 4 bytes - Magic Number : ZSTD_MAGICNUMBER (defined within zstd.h)
201
- - 1 byte - Frame Descriptor
202
- 2) Block Header
203
- - 3 bytes, starting with a 2-bits descriptor
204
- Uncompressed, Compressed, Frame End, unused
205
- 3) Block
206
- See Block Format Description
207
- 4) Frame End
208
- - 3 bytes, compatible with Block Header
209
- */
210
-
211
-
212
- /* Frame Header :
213
-
214
- 1 byte - FrameHeaderDescription :
215
- bit 0-1 : dictID (0, 1, 2 or 4 bytes)
216
- bit 2 : checksumFlag
217
- bit 3 : reserved (must be zero)
218
- bit 4 : reserved (unused, can be any value)
219
- bit 5 : Single Segment (if 1, WindowLog byte is not present)
220
- bit 6-7 : FrameContentFieldSize (0, 2, 4, or 8)
221
- if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
222
-
223
- Optional : WindowLog (0 or 1 byte)
224
- bit 0-2 : octal Fractional (1/8th)
225
- bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
226
-
227
- Optional : dictID (0, 1, 2 or 4 bytes)
228
- Automatic adaptation
229
- 0 : no dictID
230
- 1 : 1 - 255
231
- 2 : 256 - 65535
232
- 4 : all other values
233
-
234
- Optional : content size (0, 1, 2, 4 or 8 bytes)
235
- 0 : unknown (fcfs==0 and swl==0)
236
- 1 : 0-255 bytes (fcfs==0 and swl==1)
237
- 2 : 256 - 65535+256 (fcfs==1)
238
- 4 : 0 - 4GB-1 (fcfs==2)
239
- 8 : 0 - 16EB-1 (fcfs==3)
240
- */
241
-
242
-
243
- /* Compressed Block, format description
244
-
245
- Block = Literal Section - Sequences Section
246
- Prerequisite : size of (compressed) block, maximum size of regenerated data
247
-
248
- 1) Literal Section
249
-
250
- 1.1) Header : 1-5 bytes
251
- flags: 2 bits
252
- 00 compressed by Huff0
253
- 01 unused
254
- 10 is Raw (uncompressed)
255
- 11 is Rle
256
- Note : using 01 => Huff0 with precomputed table ?
257
- Note : delta map ? => compressed ?
258
-
259
- 1.1.1) Huff0-compressed literal block : 3-5 bytes
260
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
261
- srcSize < 1 KB => 3 bytes (2-2-10-10)
262
- srcSize < 16KB => 4 bytes (2-2-14-14)
263
- else => 5 bytes (2-2-18-18)
264
- big endian convention
265
-
266
- 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
267
- size : 5 bits: (IS_RAW<<6) + (0<<4) + size
268
- 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
269
- size&255
270
- 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
271
- size>>8&255
272
- size&255
273
-
274
- 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
275
- size : 5 bits: (IS_RLE<<6) + (0<<4) + size
276
- 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
277
- size&255
278
- 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
279
- size>>8&255
280
- size&255
281
-
282
- 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
283
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
284
- srcSize < 1 KB => 3 bytes (2-2-10-10)
285
- srcSize < 16KB => 4 bytes (2-2-14-14)
286
- else => 5 bytes (2-2-18-18)
287
- big endian convention
288
-
289
- 1- CTable available (stored into workspace ?)
290
- 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
291
-
292
-
293
- 1.2) Literal block content
294
-
295
- 1.2.1) Huff0 block, using sizes from header
296
- See Huff0 format
297
-
298
- 1.2.2) Huff0 block, using prepared table
299
-
300
- 1.2.3) Raw content
301
-
302
- 1.2.4) single byte
303
-
304
-
305
- 2) Sequences section
306
- TO DO
307
- */
196
+ /* See compression format details in : doc/zstd_compression_format.md */
308
197
 
309
198
  /** ZSTD_frameHeaderSize() :
310
- * srcSize must be >= ZSTD_frameHeaderSize_min.
199
+ * srcSize must be >= ZSTD_frameHeaderSize_prefix.
311
200
  * @return : size of the Frame Header */
312
201
  static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
313
202
  {
314
- if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
203
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
315
204
  { BYTE const fhd = ((const BYTE*)src)[4];
316
205
  U32 const dictID= fhd & 3;
317
- U32 const directMode = (fhd >> 5) & 1;
206
+ U32 const singleSegment = (fhd >> 5) & 1;
318
207
  U32 const fcsId = fhd >> 6;
319
- return ZSTD_frameHeaderSize_min + !directMode + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
320
- + (directMode && !ZSTD_fcs_fieldSize[fcsId]);
208
+ return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
209
+ + (singleSegment && !fcsId);
321
210
  }
322
211
  }
323
212
 
@@ -331,7 +220,7 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
331
220
  {
332
221
  const BYTE* ip = (const BYTE*)src;
333
222
 
334
- if (srcSize < ZSTD_frameHeaderSize_min) return ZSTD_frameHeaderSize_min;
223
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
335
224
  if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
336
225
  if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
337
226
  if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
@@ -351,17 +240,17 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
351
240
  size_t pos = 5;
352
241
  U32 const dictIDSizeCode = fhdByte&3;
353
242
  U32 const checksumFlag = (fhdByte>>2)&1;
354
- U32 const directMode = (fhdByte>>5)&1;
243
+ U32 const singleSegment = (fhdByte>>5)&1;
355
244
  U32 const fcsID = fhdByte>>6;
356
245
  U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
357
246
  U32 windowSize = 0;
358
247
  U32 dictID = 0;
359
248
  U64 frameContentSize = 0;
360
249
  if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
361
- if (!directMode) {
250
+ if (!singleSegment) {
362
251
  BYTE const wlByte = ip[pos++];
363
252
  U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
364
- if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_unsupported);
253
+ if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */
365
254
  windowSize = (1U << windowLog);
366
255
  windowSize += (windowSize >> 3) * (wlByte&7);
367
256
  }
@@ -377,13 +266,13 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
377
266
  switch(fcsID)
378
267
  {
379
268
  default: /* impossible */
380
- case 0 : if (directMode) frameContentSize = ip[pos]; break;
269
+ case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
381
270
  case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
382
271
  case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
383
272
  case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
384
273
  }
385
274
  if (!windowSize) windowSize = (U32)frameContentSize;
386
- if (windowSize > windowSizeMax) return ERROR(frameParameter_unsupported);
275
+ if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
387
276
  fparamsPtr->frameContentSize = frameContentSize;
388
277
  fparamsPtr->windowSize = windowSize;
389
278
  fparamsPtr->dictID = dictID;
@@ -397,9 +286,9 @@ size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t
397
286
  * compatible with legacy mode
398
287
  * @return : decompressed size if known, 0 otherwise
399
288
  note : 0 can mean any of the following :
400
- - decompressed size is not provided within frame header
289
+ - decompressed size is not present within frame header
401
290
  - frame header unknown / not supported
402
- - frame header not completely provided (`srcSize` too small) */
291
+ - frame header not complete (`srcSize` too small) */
403
292
  unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
404
293
  {
405
294
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
@@ -414,20 +303,23 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
414
303
 
415
304
 
416
305
  /** ZSTD_decodeFrameHeader() :
417
- * `srcSize` must be the size provided by ZSTD_frameHeaderSize().
306
+ * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
418
307
  * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
419
- static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t srcSize)
308
+ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
420
309
  {
421
- size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, srcSize);
310
+ size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
311
+ if (ZSTD_isError(result)) return result; /* invalid header */
312
+ if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
422
313
  if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
423
314
  if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
424
- return result;
315
+ return 0;
425
316
  }
426
317
 
427
318
 
428
319
  typedef struct
429
320
  {
430
- blockType_t blockType;
321
+ blockType_e blockType;
322
+ U32 lastBlock;
431
323
  U32 origSize;
432
324
  } blockProperties_t;
433
325
 
@@ -435,18 +327,16 @@ typedef struct
435
327
  * Provides the size of compressed block from block header `src` */
436
328
  size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
437
329
  {
438
- const BYTE* const in = (const BYTE* const)src;
439
- U32 cSize;
440
-
441
330
  if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
442
-
443
- bpPtr->blockType = (blockType_t)((*in) >> 6);
444
- cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16);
445
- bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0;
446
-
447
- if (bpPtr->blockType == bt_end) return 0;
448
- if (bpPtr->blockType == bt_rle) return 1;
449
- return cSize;
331
+ { U32 const cBlockHeader = MEM_readLE24(src);
332
+ U32 const cSize = cBlockHeader >> 3;
333
+ bpPtr->lastBlock = cBlockHeader & 1;
334
+ bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
335
+ bpPtr->origSize = cSize; /* only useful for RLE */
336
+ if (bpPtr->blockType == bt_rle) return 1;
337
+ if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
338
+ return cSize;
339
+ }
450
340
  }
451
341
 
452
342
 
@@ -458,176 +348,359 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src,
458
348
  }
459
349
 
460
350
 
351
+ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
352
+ {
353
+ if (srcSize != 1) return ERROR(srcSize_wrong);
354
+ if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
355
+ memset(dst, *(const BYTE*)src, regenSize);
356
+ return regenSize;
357
+ }
358
+
461
359
  /*! ZSTD_decodeLiteralsBlock() :
462
360
  @return : nb of bytes read from src (< srcSize ) */
463
361
  size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
464
362
  const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
465
363
  {
466
- const BYTE* const istart = (const BYTE*) src;
467
-
468
364
  if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
469
365
 
470
- switch((litBlockType_t)(istart[0]>> 6))
471
- {
472
- case lbt_huffman:
473
- { size_t litSize, litCSize, singleStream=0;
474
- U32 lhSize = (istart[0] >> 4) & 3;
475
- if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for lhSize, + cSize (+nbSeq) */
476
- switch(lhSize)
477
- {
478
- case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
479
- /* 2 - 2 - 10 - 10 */
480
- lhSize=3;
481
- singleStream = istart[0] & 16;
482
- litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
483
- litCSize = ((istart[1] & 3) << 8) + istart[2];
484
- break;
485
- case 2:
486
- /* 2 - 2 - 14 - 14 */
487
- lhSize=4;
488
- litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6);
489
- litCSize = ((istart[2] & 63) << 8) + istart[3];
490
- break;
491
- case 3:
492
- /* 2 - 2 - 18 - 18 */
493
- lhSize=5;
494
- litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2);
495
- litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4];
496
- break;
497
- }
498
- if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
499
- if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
366
+ { const BYTE* const istart = (const BYTE*) src;
367
+ symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
500
368
 
501
- if (HUF_isError(singleStream ?
502
- HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
503
- HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) ))
504
- return ERROR(corruption_detected);
369
+ switch(litEncType)
370
+ {
371
+ case set_repeat:
372
+ if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
373
+ /* fall-through */
374
+ case set_compressed:
375
+ if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
376
+ { size_t lhSize, litSize, litCSize;
377
+ U32 singleStream=0;
378
+ U32 const lhlCode = (istart[0] >> 2) & 3;
379
+ U32 const lhc = MEM_readLE32(istart);
380
+ switch(lhlCode)
381
+ {
382
+ case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
383
+ /* 2 - 2 - 10 - 10 */
384
+ singleStream = !lhlCode;
385
+ lhSize = 3;
386
+ litSize = (lhc >> 4) & 0x3FF;
387
+ litCSize = (lhc >> 14) & 0x3FF;
388
+ break;
389
+ case 2:
390
+ /* 2 - 2 - 14 - 14 */
391
+ lhSize = 4;
392
+ litSize = (lhc >> 4) & 0x3FFF;
393
+ litCSize = lhc >> 18;
394
+ break;
395
+ case 3:
396
+ /* 2 - 2 - 18 - 18 */
397
+ lhSize = 5;
398
+ litSize = (lhc >> 4) & 0x3FFFF;
399
+ litCSize = (lhc >> 22) + (istart[4] << 10);
400
+ break;
401
+ }
402
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
403
+ if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
404
+
405
+ if (HUF_isError((litEncType==set_repeat) ?
406
+ ( singleStream ?
407
+ HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
408
+ HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
409
+ ( singleStream ?
410
+ HUF_decompress1X2_DCtx(dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
411
+ HUF_decompress4X_hufOnly (dctx->hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
412
+ return ERROR(corruption_detected);
505
413
 
506
- dctx->litPtr = dctx->litBuffer;
507
- dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
508
- dctx->litSize = litSize;
509
- dctx->litEntropy = 1;
510
- return litCSize + lhSize;
511
- }
512
- case lbt_repeat:
513
- { size_t litSize, litCSize;
514
- U32 lhSize = ((istart[0]) >> 4) & 3;
515
- if (lhSize != 1) /* only case supported for now : small litSize, single stream */
516
- return ERROR(corruption_detected);
517
- if (dctx->litEntropy==0)
518
- return ERROR(dictionary_corrupted);
414
+ dctx->litPtr = dctx->litBuffer;
415
+ dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
416
+ dctx->litSize = litSize;
417
+ dctx->litEntropy = 1;
418
+ if (litEncType==set_compressed) dctx->HUFptr = dctx->hufTable;
419
+ return litCSize + lhSize;
420
+ }
519
421
 
520
- /* 2 - 2 - 10 - 10 */
521
- lhSize=3;
522
- litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
523
- litCSize = ((istart[1] & 3) << 8) + istart[2];
524
- if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
422
+ case set_basic:
423
+ { size_t litSize, lhSize;
424
+ U32 const lhlCode = ((istart[0]) >> 2) & 3;
425
+ switch(lhlCode)
426
+ {
427
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
428
+ lhSize = 1;
429
+ litSize = istart[0] >> 3;
430
+ break;
431
+ case 1:
432
+ lhSize = 2;
433
+ litSize = MEM_readLE16(istart) >> 4;
434
+ break;
435
+ case 3:
436
+ lhSize = 3;
437
+ litSize = MEM_readLE24(istart) >> 4;
438
+ break;
439
+ }
525
440
 
526
- { size_t const errorCode = HUF_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTable);
527
- if (HUF_isError(errorCode)) return ERROR(corruption_detected);
528
- }
529
- dctx->litPtr = dctx->litBuffer;
530
- dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
531
- dctx->litSize = litSize;
532
- return litCSize + lhSize;
533
- }
534
- case lbt_raw:
535
- { size_t litSize;
536
- U32 lhSize = ((istart[0]) >> 4) & 3;
537
- switch(lhSize)
538
- {
539
- case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
540
- lhSize=1;
541
- litSize = istart[0] & 31;
542
- break;
543
- case 2:
544
- litSize = ((istart[0] & 15) << 8) + istart[1];
545
- break;
546
- case 3:
547
- litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
548
- break;
441
+ if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
442
+ if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
443
+ memcpy(dctx->litBuffer, istart+lhSize, litSize);
444
+ dctx->litPtr = dctx->litBuffer;
445
+ dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+8;
446
+ dctx->litSize = litSize;
447
+ return lhSize+litSize;
448
+ }
449
+ /* direct reference into compressed stream */
450
+ dctx->litPtr = istart+lhSize;
451
+ dctx->litBufSize = srcSize-lhSize;
452
+ dctx->litSize = litSize;
453
+ return lhSize+litSize;
549
454
  }
550
455
 
551
- if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
552
- if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
553
- memcpy(dctx->litBuffer, istart+lhSize, litSize);
456
+ case set_rle:
457
+ { U32 const lhlCode = ((istart[0]) >> 2) & 3;
458
+ size_t litSize, lhSize;
459
+ switch(lhlCode)
460
+ {
461
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
462
+ lhSize = 1;
463
+ litSize = istart[0] >> 3;
464
+ break;
465
+ case 1:
466
+ lhSize = 2;
467
+ litSize = MEM_readLE16(istart) >> 4;
468
+ break;
469
+ case 3:
470
+ lhSize = 3;
471
+ litSize = MEM_readLE24(istart) >> 4;
472
+ if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
473
+ break;
474
+ }
475
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
476
+ memset(dctx->litBuffer, istart[lhSize], litSize);
554
477
  dctx->litPtr = dctx->litBuffer;
555
- dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+8;
478
+ dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
556
479
  dctx->litSize = litSize;
557
- return lhSize+litSize;
558
- }
559
- /* direct reference into compressed stream */
560
- dctx->litPtr = istart+lhSize;
561
- dctx->litBufSize = srcSize-lhSize;
562
- dctx->litSize = litSize;
563
- return lhSize+litSize;
564
- }
565
- case lbt_rle:
566
- { size_t litSize;
567
- U32 lhSize = ((istart[0]) >> 4) & 3;
568
- switch(lhSize)
569
- {
570
- case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */
571
- lhSize = 1;
572
- litSize = istart[0] & 31;
573
- break;
574
- case 2:
575
- litSize = ((istart[0] & 15) << 8) + istart[1];
576
- break;
577
- case 3:
578
- litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2];
579
- if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
580
- break;
480
+ return lhSize+1;
581
481
  }
582
- if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
583
- memset(dctx->litBuffer, istart[lhSize], litSize);
584
- dctx->litPtr = dctx->litBuffer;
585
- dctx->litBufSize = ZSTD_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
586
- dctx->litSize = litSize;
587
- return lhSize+1;
482
+ default:
483
+ return ERROR(corruption_detected); /* impossible */
588
484
  }
589
- default:
590
- return ERROR(corruption_detected); /* impossible */
591
485
  }
592
486
  }
593
487
 
594
488
 
489
+ typedef union {
490
+ FSE_decode_t realData;
491
+ U32 alignedBy4;
492
+ } FSE_decode_t4;
493
+
494
+ static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
495
+ { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
496
+ { { 0, 0, 4 } }, /* 0 : base, symbol, bits */
497
+ { { 16, 0, 4 } },
498
+ { { 32, 1, 5 } },
499
+ { { 0, 3, 5 } },
500
+ { { 0, 4, 5 } },
501
+ { { 0, 6, 5 } },
502
+ { { 0, 7, 5 } },
503
+ { { 0, 9, 5 } },
504
+ { { 0, 10, 5 } },
505
+ { { 0, 12, 5 } },
506
+ { { 0, 14, 6 } },
507
+ { { 0, 16, 5 } },
508
+ { { 0, 18, 5 } },
509
+ { { 0, 19, 5 } },
510
+ { { 0, 21, 5 } },
511
+ { { 0, 22, 5 } },
512
+ { { 0, 24, 5 } },
513
+ { { 32, 25, 5 } },
514
+ { { 0, 26, 5 } },
515
+ { { 0, 27, 6 } },
516
+ { { 0, 29, 6 } },
517
+ { { 0, 31, 6 } },
518
+ { { 32, 0, 4 } },
519
+ { { 0, 1, 4 } },
520
+ { { 0, 2, 5 } },
521
+ { { 32, 4, 5 } },
522
+ { { 0, 5, 5 } },
523
+ { { 32, 7, 5 } },
524
+ { { 0, 8, 5 } },
525
+ { { 32, 10, 5 } },
526
+ { { 0, 11, 5 } },
527
+ { { 0, 13, 6 } },
528
+ { { 32, 16, 5 } },
529
+ { { 0, 17, 5 } },
530
+ { { 32, 19, 5 } },
531
+ { { 0, 20, 5 } },
532
+ { { 32, 22, 5 } },
533
+ { { 0, 23, 5 } },
534
+ { { 0, 25, 4 } },
535
+ { { 16, 25, 4 } },
536
+ { { 32, 26, 5 } },
537
+ { { 0, 28, 6 } },
538
+ { { 0, 30, 6 } },
539
+ { { 48, 0, 4 } },
540
+ { { 16, 1, 4 } },
541
+ { { 32, 2, 5 } },
542
+ { { 32, 3, 5 } },
543
+ { { 32, 5, 5 } },
544
+ { { 32, 6, 5 } },
545
+ { { 32, 8, 5 } },
546
+ { { 32, 9, 5 } },
547
+ { { 32, 11, 5 } },
548
+ { { 32, 12, 5 } },
549
+ { { 0, 15, 6 } },
550
+ { { 32, 17, 5 } },
551
+ { { 32, 18, 5 } },
552
+ { { 32, 20, 5 } },
553
+ { { 32, 21, 5 } },
554
+ { { 32, 23, 5 } },
555
+ { { 32, 24, 5 } },
556
+ { { 0, 35, 6 } },
557
+ { { 0, 34, 6 } },
558
+ { { 0, 33, 6 } },
559
+ { { 0, 32, 6 } },
560
+ }; /* LL_defaultDTable */
561
+
562
+ static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
563
+ { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
564
+ { { 0, 0, 6 } }, /* 0 : base, symbol, bits */
565
+ { { 0, 1, 4 } },
566
+ { { 32, 2, 5 } },
567
+ { { 0, 3, 5 } },
568
+ { { 0, 5, 5 } },
569
+ { { 0, 6, 5 } },
570
+ { { 0, 8, 5 } },
571
+ { { 0, 10, 6 } },
572
+ { { 0, 13, 6 } },
573
+ { { 0, 16, 6 } },
574
+ { { 0, 19, 6 } },
575
+ { { 0, 22, 6 } },
576
+ { { 0, 25, 6 } },
577
+ { { 0, 28, 6 } },
578
+ { { 0, 31, 6 } },
579
+ { { 0, 33, 6 } },
580
+ { { 0, 35, 6 } },
581
+ { { 0, 37, 6 } },
582
+ { { 0, 39, 6 } },
583
+ { { 0, 41, 6 } },
584
+ { { 0, 43, 6 } },
585
+ { { 0, 45, 6 } },
586
+ { { 16, 1, 4 } },
587
+ { { 0, 2, 4 } },
588
+ { { 32, 3, 5 } },
589
+ { { 0, 4, 5 } },
590
+ { { 32, 6, 5 } },
591
+ { { 0, 7, 5 } },
592
+ { { 0, 9, 6 } },
593
+ { { 0, 12, 6 } },
594
+ { { 0, 15, 6 } },
595
+ { { 0, 18, 6 } },
596
+ { { 0, 21, 6 } },
597
+ { { 0, 24, 6 } },
598
+ { { 0, 27, 6 } },
599
+ { { 0, 30, 6 } },
600
+ { { 0, 32, 6 } },
601
+ { { 0, 34, 6 } },
602
+ { { 0, 36, 6 } },
603
+ { { 0, 38, 6 } },
604
+ { { 0, 40, 6 } },
605
+ { { 0, 42, 6 } },
606
+ { { 0, 44, 6 } },
607
+ { { 32, 1, 4 } },
608
+ { { 48, 1, 4 } },
609
+ { { 16, 2, 4 } },
610
+ { { 32, 4, 5 } },
611
+ { { 32, 5, 5 } },
612
+ { { 32, 7, 5 } },
613
+ { { 32, 8, 5 } },
614
+ { { 0, 11, 6 } },
615
+ { { 0, 14, 6 } },
616
+ { { 0, 17, 6 } },
617
+ { { 0, 20, 6 } },
618
+ { { 0, 23, 6 } },
619
+ { { 0, 26, 6 } },
620
+ { { 0, 29, 6 } },
621
+ { { 0, 52, 6 } },
622
+ { { 0, 51, 6 } },
623
+ { { 0, 50, 6 } },
624
+ { { 0, 49, 6 } },
625
+ { { 0, 48, 6 } },
626
+ { { 0, 47, 6 } },
627
+ { { 0, 46, 6 } },
628
+ }; /* ML_defaultDTable */
629
+
630
+ static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
631
+ { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
632
+ { { 0, 0, 5 } }, /* 0 : base, symbol, bits */
633
+ { { 0, 6, 4 } },
634
+ { { 0, 9, 5 } },
635
+ { { 0, 15, 5 } },
636
+ { { 0, 21, 5 } },
637
+ { { 0, 3, 5 } },
638
+ { { 0, 7, 4 } },
639
+ { { 0, 12, 5 } },
640
+ { { 0, 18, 5 } },
641
+ { { 0, 23, 5 } },
642
+ { { 0, 5, 5 } },
643
+ { { 0, 8, 4 } },
644
+ { { 0, 14, 5 } },
645
+ { { 0, 20, 5 } },
646
+ { { 0, 2, 5 } },
647
+ { { 16, 7, 4 } },
648
+ { { 0, 11, 5 } },
649
+ { { 0, 17, 5 } },
650
+ { { 0, 22, 5 } },
651
+ { { 0, 4, 5 } },
652
+ { { 16, 8, 4 } },
653
+ { { 0, 13, 5 } },
654
+ { { 0, 19, 5 } },
655
+ { { 0, 1, 5 } },
656
+ { { 16, 6, 4 } },
657
+ { { 0, 10, 5 } },
658
+ { { 0, 16, 5 } },
659
+ { { 0, 28, 5 } },
660
+ { { 0, 27, 5 } },
661
+ { { 0, 26, 5 } },
662
+ { { 0, 25, 5 } },
663
+ { { 0, 24, 5 } },
664
+ }; /* OF_defaultDTable */
665
+
595
666
  /*! ZSTD_buildSeqTable() :
596
667
  @return : nb bytes read from src,
597
668
  or an error code if it fails, testable with ZSTD_isError()
598
669
  */
599
- FORCE_INLINE size_t ZSTD_buildSeqTable(FSE_DTable* DTable, U32 type, U32 max, U32 maxLog,
670
+ static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
671
+ symbolEncodingType_e type, U32 max, U32 maxLog,
600
672
  const void* src, size_t srcSize,
601
- const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
673
+ const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
602
674
  {
675
+ const void* const tmpPtr = defaultTable; /* bypass strict aliasing */
603
676
  switch(type)
604
677
  {
605
- case FSE_ENCODING_RLE :
678
+ case set_rle :
606
679
  if (!srcSize) return ERROR(srcSize_wrong);
607
680
  if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
608
- FSE_buildDTable_rle(DTable, *(const BYTE*)src); /* if *src > max, data is corrupted */
681
+ FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
682
+ *DTablePtr = DTableSpace;
609
683
  return 1;
610
- case FSE_ENCODING_RAW :
611
- FSE_buildDTable(DTable, defaultNorm, max, defaultLog);
684
+ case set_basic :
685
+ *DTablePtr = (const FSE_DTable*)tmpPtr;
612
686
  return 0;
613
- case FSE_ENCODING_STATIC:
687
+ case set_repeat:
614
688
  if (!flagRepeatTable) return ERROR(corruption_detected);
615
689
  return 0;
616
690
  default : /* impossible */
617
- case FSE_ENCODING_DYNAMIC :
691
+ case set_compressed :
618
692
  { U32 tableLog;
619
693
  S16 norm[MaxSeq+1];
620
694
  size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
621
695
  if (FSE_isError(headerSize)) return ERROR(corruption_detected);
622
696
  if (tableLog > maxLog) return ERROR(corruption_detected);
623
- FSE_buildDTable(DTable, norm, max, tableLog);
697
+ FSE_buildDTable(DTableSpace, norm, max, tableLog);
698
+ *DTablePtr = DTableSpace;
624
699
  return headerSize;
625
700
  } }
626
701
  }
627
702
 
628
-
629
- size_t ZSTD_decodeSeqHeaders(int* nbSeqPtr,
630
- FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, U32 flagRepeatTable,
703
+ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
631
704
  const void* src, size_t srcSize)
632
705
  {
633
706
  const BYTE* const istart = (const BYTE* const)src;
@@ -641,36 +714,44 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeqPtr,
641
714
  { int nbSeq = *ip++;
642
715
  if (!nbSeq) { *nbSeqPtr=0; return 1; }
643
716
  if (nbSeq > 0x7F) {
644
- if (nbSeq == 0xFF)
717
+ if (nbSeq == 0xFF) {
718
+ if (ip+2 > iend) return ERROR(srcSize_wrong);
645
719
  nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
646
- else
720
+ } else {
721
+ if (ip >= iend) return ERROR(srcSize_wrong);
647
722
  nbSeq = ((nbSeq-0x80)<<8) + *ip++;
723
+ }
648
724
  }
649
725
  *nbSeqPtr = nbSeq;
650
726
  }
651
727
 
652
728
  /* FSE table descriptors */
653
- { U32 const LLtype = *ip >> 6;
654
- U32 const OFtype = (*ip >> 4) & 3;
655
- U32 const MLtype = (*ip >> 2) & 3;
729
+ if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
730
+ { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
731
+ symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
732
+ symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
656
733
  ip++;
657
734
 
658
- /* check */
659
- if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
660
-
661
735
  /* Build DTables */
662
- { size_t const llhSize = ZSTD_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
736
+ { size_t const llhSize = ZSTD_buildSeqTable(dctx->LLTable, &dctx->LLTptr,
737
+ LLtype, MaxLL, LLFSELog,
738
+ ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
663
739
  if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
664
740
  ip += llhSize;
665
741
  }
666
- { size_t const ofhSize = ZSTD_buildSeqTable(DTableOffb, OFtype, MaxOff, OffFSELog, ip, iend-ip, OF_defaultNorm, OF_defaultNormLog, flagRepeatTable);
742
+ { size_t const ofhSize = ZSTD_buildSeqTable(dctx->OFTable, &dctx->OFTptr,
743
+ OFtype, MaxOff, OffFSELog,
744
+ ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
667
745
  if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
668
746
  ip += ofhSize;
669
747
  }
670
- { size_t const mlhSize = ZSTD_buildSeqTable(DTableML, MLtype, MaxML, MLFSELog, ip, iend-ip, ML_defaultNorm, ML_defaultNormLog, flagRepeatTable);
748
+ { size_t const mlhSize = ZSTD_buildSeqTable(dctx->MLTable, &dctx->MLTptr,
749
+ MLtype, MaxML, MLFSELog,
750
+ ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
671
751
  if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
672
752
  ip += mlhSize;
673
- } }
753
+ }
754
+ }
674
755
 
675
756
  return ip-istart;
676
757
  }
@@ -687,7 +768,7 @@ typedef struct {
687
768
  FSE_DState_t stateLL;
688
769
  FSE_DState_t stateOffb;
689
770
  FSE_DState_t stateML;
690
- size_t prevOffset[ZSTD_REP_INIT];
771
+ size_t prevOffset[ZSTD_REP_NUM];
691
772
  } seqState_t;
692
773
 
693
774
 
@@ -695,9 +776,9 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
695
776
  {
696
777
  seq_t seq;
697
778
 
698
- U32 const llCode = FSE_peekSymbol(&(seqState->stateLL));
699
- U32 const mlCode = FSE_peekSymbol(&(seqState->stateML));
700
- U32 const ofCode = FSE_peekSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */
779
+ U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
780
+ U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
781
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
701
782
 
702
783
  U32 const llBits = LL_bits[llCode];
703
784
  U32 const mlBits = ML_bits[mlCode];
@@ -726,14 +807,15 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
726
807
  if (!ofCode)
727
808
  offset = 0;
728
809
  else {
729
- offset = OF_base[ofCode] + BIT_readBits(&(seqState->DStream), ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
730
- if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream));
810
+ offset = OF_base[ofCode] + BIT_readBits(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
811
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
731
812
  }
732
813
 
733
814
  if (ofCode <= 1) {
734
- if ((llCode == 0) & (offset <= 1)) offset = 1-offset;
815
+ offset += (llCode==0);
735
816
  if (offset) {
736
- size_t const temp = seqState->prevOffset[offset];
817
+ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
818
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
737
819
  if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
738
820
  seqState->prevOffset[1] = seqState->prevOffset[0];
739
821
  seqState->prevOffset[0] = offset = temp;
@@ -748,23 +830,70 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
748
830
  seq.offset = offset;
749
831
  }
750
832
 
751
- seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&(seqState->DStream), mlBits) : 0); /* <= 16 bits */
752
- if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&(seqState->DStream));
833
+ seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBits(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
834
+ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
753
835
 
754
- seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&(seqState->DStream), llBits) : 0); /* <= 16 bits */
836
+ seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBits(&seqState->DStream, llBits) : 0); /* <= 16 bits */
755
837
  if (MEM_32bits() ||
756
- (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&(seqState->DStream));
838
+ (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
757
839
 
758
840
  /* ANS state update */
759
- FSE_updateState(&(seqState->stateLL), &(seqState->DStream)); /* <= 9 bits */
760
- FSE_updateState(&(seqState->stateML), &(seqState->DStream)); /* <= 9 bits */
761
- if (MEM_32bits()) BIT_reloadDStream(&(seqState->DStream)); /* <= 18 bits */
762
- FSE_updateState(&(seqState->stateOffb), &(seqState->DStream)); /* <= 8 bits */
841
+ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
842
+ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
843
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
844
+ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
763
845
 
764
846
  return seq;
765
847
  }
766
848
 
767
849
 
850
+ FORCE_NOINLINE
851
+ size_t ZSTD_execSequenceLast7(BYTE* op,
852
+ BYTE* const oend, seq_t sequence,
853
+ const BYTE** litPtr, const BYTE* const litLimit_w,
854
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
855
+ {
856
+ BYTE* const oLitEnd = op + sequence.litLength;
857
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
858
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
859
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
860
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
861
+ const BYTE* match = oLitEnd - sequence.offset;
862
+
863
+ /* check */
864
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
865
+ if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */
866
+ if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */
867
+
868
+ /* copy literals */
869
+ if (op < oend_w) {
870
+ ZSTD_wildcopy(op, *litPtr, oend_w - op);
871
+ *litPtr += oend_w - op;
872
+ op = oend_w;
873
+ }
874
+ while (op < oLitEnd) *op++ = *(*litPtr)++;
875
+
876
+ /* copy Match */
877
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
878
+ /* offset beyond prefix */
879
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
880
+ match = dictEnd - (base-match);
881
+ if (match + sequence.matchLength <= dictEnd) {
882
+ memmove(oLitEnd, match, sequence.matchLength);
883
+ return sequenceLength;
884
+ }
885
+ /* span extDict & currentPrefixSegment */
886
+ { size_t const length1 = dictEnd - match;
887
+ memmove(oLitEnd, match, length1);
888
+ op = oLitEnd + length1;
889
+ sequence.matchLength -= length1;
890
+ match = base;
891
+ } }
892
+ while (op < oMatchEnd) *op++ = *match++;
893
+ return sequenceLength;
894
+ }
895
+
896
+
768
897
  FORCE_INLINE
769
898
  size_t ZSTD_execSequence(BYTE* op,
770
899
  BYTE* const oend, seq_t sequence,
@@ -774,16 +903,19 @@ size_t ZSTD_execSequence(BYTE* op,
774
903
  BYTE* const oLitEnd = op + sequence.litLength;
775
904
  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
776
905
  BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
777
- BYTE* const oend_w = oend-WILDCOPY_OVERLENGTH;
906
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
778
907
  const BYTE* const iLitEnd = *litPtr + sequence.litLength;
779
908
  const BYTE* match = oLitEnd - sequence.offset;
780
909
 
781
910
  /* check */
782
- if ((oLitEnd>oend_w) | (oMatchEnd>oend)) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
911
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
783
912
  if (iLitEnd > litLimit_w) return ERROR(corruption_detected); /* over-read beyond lit buffer */
913
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit_w, base, vBase, dictEnd);
784
914
 
785
915
  /* copy Literals */
786
- ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
916
+ ZSTD_copy8(op, *litPtr);
917
+ if (sequence.litLength > 8)
918
+ ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
787
919
  op = oLitEnd;
788
920
  *litPtr = iLitEnd; /* update for next sequence */
789
921
 
@@ -802,7 +934,13 @@ size_t ZSTD_execSequence(BYTE* op,
802
934
  op = oLitEnd + length1;
803
935
  sequence.matchLength -= length1;
804
936
  match = base;
937
+ if (op > oend_w) {
938
+ U32 i;
939
+ for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
940
+ return sequenceLength;
941
+ }
805
942
  } }
943
+ /* Requirement: op <= oend_w */
806
944
 
807
945
  /* match within prefix */
808
946
  if (sequence.offset < 8) {
@@ -849,16 +987,13 @@ static size_t ZSTD_decompressSequences(
849
987
  const BYTE* litPtr = dctx->litPtr;
850
988
  const BYTE* const litLimit_w = litPtr + dctx->litBufSize - WILDCOPY_OVERLENGTH;
851
989
  const BYTE* const litEnd = litPtr + dctx->litSize;
852
- FSE_DTable* DTableLL = dctx->LLTable;
853
- FSE_DTable* DTableML = dctx->MLTable;
854
- FSE_DTable* DTableOffb = dctx->OffTable;
855
990
  const BYTE* const base = (const BYTE*) (dctx->base);
856
991
  const BYTE* const vBase = (const BYTE*) (dctx->vBase);
857
992
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
858
993
  int nbSeq;
859
994
 
860
995
  /* Build Decoding Tables */
861
- { size_t const seqHSize = ZSTD_decodeSeqHeaders(&nbSeq, DTableLL, DTableML, DTableOffb, dctx->fseEntropy, ip, seqSize);
996
+ { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
862
997
  if (ZSTD_isError(seqHSize)) return seqHSize;
863
998
  ip += seqHSize;
864
999
  }
@@ -867,12 +1002,11 @@ static size_t ZSTD_decompressSequences(
867
1002
  if (nbSeq) {
868
1003
  seqState_t seqState;
869
1004
  dctx->fseEntropy = 1;
870
- { U32 i; for (i=0; i<ZSTD_REP_INIT; i++) seqState.prevOffset[i] = dctx->rep[i]; }
871
- { size_t const errorCode = BIT_initDStream(&(seqState.DStream), ip, iend-ip);
872
- if (ERR_isError(errorCode)) return ERROR(corruption_detected); }
873
- FSE_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL);
874
- FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
875
- FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
1005
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; }
1006
+ CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
1007
+ FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1008
+ FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1009
+ FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
876
1010
 
877
1011
  for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
878
1012
  nbSeq--;
@@ -885,12 +1019,11 @@ static size_t ZSTD_decompressSequences(
885
1019
  /* check if reached exact end */
886
1020
  if (nbSeq) return ERROR(corruption_detected);
887
1021
  /* save reps for next block */
888
- { U32 i; for (i=0; i<ZSTD_REP_INIT; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
1022
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); }
889
1023
  }
890
1024
 
891
1025
  /* last literal segment */
892
1026
  { size_t const lastLLSize = litEnd - litPtr;
893
- //if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
894
1027
  if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
895
1028
  memcpy(op, litPtr, lastLLSize);
896
1029
  op += lastLLSize;
@@ -917,7 +1050,7 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
917
1050
  { /* blockType == blockCompressed */
918
1051
  const BYTE* ip = (const BYTE*)src;
919
1052
 
920
- if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
1053
+ if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
921
1054
 
922
1055
  /* Decode literals sub-block */
923
1056
  { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
@@ -966,7 +1099,6 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
966
1099
  const void* src, size_t srcSize)
967
1100
  {
968
1101
  const BYTE* ip = (const BYTE*)src;
969
- const BYTE* const iend = ip + srcSize;
970
1102
  BYTE* const ostart = (BYTE* const)dst;
971
1103
  BYTE* const oend = ostart + dstCapacity;
972
1104
  BYTE* op = ostart;
@@ -976,10 +1108,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
976
1108
  if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
977
1109
 
978
1110
  /* Frame Header */
979
- { size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
1111
+ { size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
980
1112
  if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
981
1113
  if (srcSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
982
- if (ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize)) return ERROR(corruption_detected);
1114
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, src, frameHeaderSize));
983
1115
  ip += frameHeaderSize; remainingSize -= frameHeaderSize;
984
1116
  }
985
1117
 
@@ -987,7 +1119,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
987
1119
  while (1) {
988
1120
  size_t decodedSize;
989
1121
  blockProperties_t blockProperties;
990
- size_t const cBlockSize = ZSTD_getcBlockSize(ip, iend-ip, &blockProperties);
1122
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
991
1123
  if (ZSTD_isError(cBlockSize)) return cBlockSize;
992
1124
 
993
1125
  ip += ZSTD_blockHeaderSize;
@@ -1005,46 +1137,37 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1005
1137
  case bt_rle :
1006
1138
  decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
1007
1139
  break;
1008
- case bt_end :
1009
- /* end of frame */
1010
- if (remainingSize) return ERROR(srcSize_wrong);
1011
- decodedSize = 0;
1012
- break;
1140
+ case bt_reserved :
1013
1141
  default:
1014
- return ERROR(GENERIC); /* impossible */
1142
+ return ERROR(corruption_detected);
1015
1143
  }
1016
- if (cBlockSize == 0) break; /* bt_end */
1017
1144
 
1018
1145
  if (ZSTD_isError(decodedSize)) return decodedSize;
1019
1146
  if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
1020
1147
  op += decodedSize;
1021
1148
  ip += cBlockSize;
1022
1149
  remainingSize -= cBlockSize;
1150
+ if (blockProperties.lastBlock) break;
1023
1151
  }
1024
1152
 
1025
- return op-ostart;
1026
- }
1027
-
1153
+ if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1154
+ U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
1155
+ U32 checkRead;
1156
+ if (remainingSize<4) return ERROR(checksum_wrong);
1157
+ checkRead = MEM_readLE32(ip);
1158
+ if (checkRead != checkCalc) return ERROR(checksum_wrong);
1159
+ remainingSize -= 4;
1160
+ }
1028
1161
 
1029
- /*! ZSTD_decompress_usingPreparedDCtx() :
1030
- * Same as ZSTD_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded.
1031
- * It avoids reloading the dictionary each time.
1032
- * `preparedDCtx` must have been properly initialized using ZSTD_decompressBegin_usingDict().
1033
- * Requires 2 contexts : 1 for reference (preparedDCtx), which will not be modified, and 1 to run the decompression operation (dctx) */
1034
- size_t ZSTD_decompress_usingPreparedDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* refDCtx,
1035
- void* dst, size_t dstCapacity,
1036
- const void* src, size_t srcSize)
1037
- {
1038
- ZSTD_copyDCtx(dctx, refDCtx);
1039
- ZSTD_checkContinuity(dctx, dst);
1040
- return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
1162
+ if (remainingSize) return ERROR(srcSize_wrong);
1163
+ return op-ostart;
1041
1164
  }
1042
1165
 
1043
1166
 
1044
1167
  size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1045
1168
  void* dst, size_t dstCapacity,
1046
- const void* src, size_t srcSize,
1047
- const void* dict, size_t dictSize)
1169
+ const void* src, size_t srcSize,
1170
+ const void* dict, size_t dictSize)
1048
1171
  {
1049
1172
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
1050
1173
  if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize);
@@ -1077,19 +1200,35 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
1077
1200
  }
1078
1201
 
1079
1202
 
1080
- /*_******************************
1081
- * Streaming Decompression API
1082
- ********************************/
1083
- size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx)
1084
- {
1085
- return dctx->expected;
1086
- }
1203
+ /*-**************************************
1204
+ * Advanced Streaming Decompression API
1205
+ * Bufferless and synchronous
1206
+ ****************************************/
1207
+ size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
1087
1208
 
1088
- int ZSTD_isSkipFrame(ZSTD_DCtx* dctx)
1089
- {
1090
- return dctx->stage == ZSTDds_skipFrame;
1209
+ ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
1210
+ switch(dctx->stage)
1211
+ {
1212
+ default: /* should not happen */
1213
+ case ZSTDds_getFrameHeaderSize:
1214
+ case ZSTDds_decodeFrameHeader:
1215
+ return ZSTDnit_frameHeader;
1216
+ case ZSTDds_decodeBlockHeader:
1217
+ return ZSTDnit_blockHeader;
1218
+ case ZSTDds_decompressBlock:
1219
+ return ZSTDnit_block;
1220
+ case ZSTDds_decompressLastBlock:
1221
+ return ZSTDnit_lastBlock;
1222
+ case ZSTDds_checkChecksum:
1223
+ return ZSTDnit_checksum;
1224
+ case ZSTDds_decodeSkippableHeader:
1225
+ case ZSTDds_skipFrame:
1226
+ return ZSTDnit_skippableFrame;
1227
+ }
1091
1228
  }
1092
1229
 
1230
+ int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
1231
+
1093
1232
  /** ZSTD_decompressContinue() :
1094
1233
  * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1095
1234
  * or an error code, which can be tested using ZSTD_isError() */
@@ -1102,53 +1241,57 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1102
1241
  switch (dctx->stage)
1103
1242
  {
1104
1243
  case ZSTDds_getFrameHeaderSize :
1105
- if (srcSize != ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */
1106
- if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1107
- memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
1108
- dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_min; /* magic number + skippable frame length */
1244
+ if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* impossible */
1245
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1246
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1247
+ dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
1109
1248
  dctx->stage = ZSTDds_decodeSkippableHeader;
1110
1249
  return 0;
1111
1250
  }
1112
- dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min);
1251
+ dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
1113
1252
  if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1114
- memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_min);
1115
- if (dctx->headerSize > ZSTD_frameHeaderSize_min) {
1116
- dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_min;
1253
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1254
+ if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
1255
+ dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
1117
1256
  dctx->stage = ZSTDds_decodeFrameHeader;
1118
1257
  return 0;
1119
1258
  }
1120
1259
  dctx->expected = 0; /* not necessary to copy more */
1121
1260
 
1122
1261
  case ZSTDds_decodeFrameHeader:
1123
- { size_t result;
1124
- memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1125
- result = ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize);
1126
- if (ZSTD_isError(result)) return result;
1127
- dctx->expected = ZSTD_blockHeaderSize;
1128
- dctx->stage = ZSTDds_decodeBlockHeader;
1129
- return 0;
1130
- }
1262
+ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1263
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
1264
+ dctx->expected = ZSTD_blockHeaderSize;
1265
+ dctx->stage = ZSTDds_decodeBlockHeader;
1266
+ return 0;
1267
+
1131
1268
  case ZSTDds_decodeBlockHeader:
1132
1269
  { blockProperties_t bp;
1133
1270
  size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1134
1271
  if (ZSTD_isError(cBlockSize)) return cBlockSize;
1135
- if (bp.blockType == bt_end) {
1272
+ dctx->expected = cBlockSize;
1273
+ dctx->bType = bp.blockType;
1274
+ dctx->rleSize = bp.origSize;
1275
+ if (cBlockSize) {
1276
+ dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
1277
+ return 0;
1278
+ }
1279
+ /* empty block */
1280
+ if (bp.lastBlock) {
1136
1281
  if (dctx->fParams.checksumFlag) {
1137
- U64 const h64 = XXH64_digest(&dctx->xxhState);
1138
- U32 const h32 = (U32)(h64>>11) & ((1<<22)-1);
1139
- const BYTE* const ip = (const BYTE*)src;
1140
- U32 const check32 = ip[2] + (ip[1] << 8) + ((ip[0] & 0x3F) << 16);
1141
- if (check32 != h32) return ERROR(checksum_wrong);
1282
+ dctx->expected = 4;
1283
+ dctx->stage = ZSTDds_checkChecksum;
1284
+ } else {
1285
+ dctx->expected = 0; /* end of frame */
1286
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1142
1287
  }
1143
- dctx->expected = 0;
1144
- dctx->stage = ZSTDds_getFrameHeaderSize;
1145
1288
  } else {
1146
- dctx->expected = cBlockSize;
1147
- dctx->bType = bp.blockType;
1148
- dctx->stage = ZSTDds_decompressBlock;
1289
+ dctx->expected = 3; /* go directly to next header */
1290
+ dctx->stage = ZSTDds_decodeBlockHeader;
1149
1291
  }
1150
1292
  return 0;
1151
1293
  }
1294
+ case ZSTDds_decompressLastBlock:
1152
1295
  case ZSTDds_decompressBlock:
1153
1296
  { size_t rSize;
1154
1297
  switch(dctx->bType)
@@ -1160,23 +1303,40 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1160
1303
  rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
1161
1304
  break;
1162
1305
  case bt_rle :
1163
- return ERROR(GENERIC); /* not yet handled */
1164
- break;
1165
- case bt_end : /* should never happen (filtered at phase 1) */
1166
- rSize = 0;
1306
+ rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
1167
1307
  break;
1308
+ case bt_reserved : /* should never happen */
1168
1309
  default:
1169
- return ERROR(GENERIC); /* impossible */
1310
+ return ERROR(corruption_detected);
1170
1311
  }
1171
- dctx->stage = ZSTDds_decodeBlockHeader;
1172
- dctx->expected = ZSTD_blockHeaderSize;
1173
- dctx->previousDstEnd = (char*)dst + rSize;
1174
1312
  if (ZSTD_isError(rSize)) return rSize;
1175
1313
  if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
1314
+
1315
+ if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1316
+ if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1317
+ dctx->expected = 4;
1318
+ dctx->stage = ZSTDds_checkChecksum;
1319
+ } else {
1320
+ dctx->expected = 0; /* ends here */
1321
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1322
+ }
1323
+ } else {
1324
+ dctx->stage = ZSTDds_decodeBlockHeader;
1325
+ dctx->expected = ZSTD_blockHeaderSize;
1326
+ dctx->previousDstEnd = (char*)dst + rSize;
1327
+ }
1176
1328
  return rSize;
1177
1329
  }
1330
+ case ZSTDds_checkChecksum:
1331
+ { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1332
+ U32 const check32 = MEM_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
1333
+ if (check32 != h32) return ERROR(checksum_wrong);
1334
+ dctx->expected = 0;
1335
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1336
+ return 0;
1337
+ }
1178
1338
  case ZSTDds_decodeSkippableHeader:
1179
- { memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_min, src, dctx->expected);
1339
+ { memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1180
1340
  dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
1181
1341
  dctx->stage = ZSTDds_skipFrame;
1182
1342
  return 0;
@@ -1212,29 +1372,29 @@ static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t c
1212
1372
  }
1213
1373
 
1214
1374
  { short offcodeNCount[MaxOff+1];
1215
- U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog;
1375
+ U32 offcodeMaxValue=MaxOff, offcodeLog;
1216
1376
  size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
1217
1377
  if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1218
- { size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog);
1219
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
1378
+ if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
1379
+ CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
1220
1380
  dictPtr += offcodeHeaderSize;
1221
1381
  }
1222
1382
 
1223
1383
  { short matchlengthNCount[MaxML+1];
1224
- unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
1384
+ unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1225
1385
  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
1226
1386
  if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1227
- { size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
1228
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
1387
+ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
1388
+ CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
1229
1389
  dictPtr += matchlengthHeaderSize;
1230
1390
  }
1231
1391
 
1232
1392
  { short litlengthNCount[MaxLL+1];
1233
- unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
1393
+ unsigned litlengthMaxValue = MaxLL, litlengthLog;
1234
1394
  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
1235
1395
  if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1236
- { size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog);
1237
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
1396
+ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
1397
+ CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
1238
1398
  dictPtr += litlengthHeaderSize;
1239
1399
  }
1240
1400
 
@@ -1270,52 +1430,46 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
1270
1430
  return ZSTD_refDictContent(dctx, dict, dictSize);
1271
1431
  }
1272
1432
 
1273
-
1274
1433
  size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1275
1434
  {
1276
- { size_t const errorCode = ZSTD_decompressBegin(dctx);
1277
- if (ZSTD_isError(errorCode)) return errorCode; }
1278
-
1279
- if (dict && dictSize) {
1280
- size_t const errorCode = ZSTD_decompress_insertDictionary(dctx, dict, dictSize);
1281
- if (ZSTD_isError(errorCode)) return ERROR(dictionary_corrupted);
1282
- }
1283
-
1435
+ CHECK_F(ZSTD_decompressBegin(dctx));
1436
+ if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
1284
1437
  return 0;
1285
1438
  }
1286
1439
 
1287
1440
 
1441
+ /* ====== ZSTD_DDict ====== */
1442
+
1288
1443
  struct ZSTD_DDict_s {
1289
1444
  void* dict;
1290
1445
  size_t dictSize;
1291
1446
  ZSTD_DCtx* refContext;
1292
- }; /* typedef'd tp ZSTD_CDict within zstd.h */
1447
+ }; /* typedef'd to ZSTD_DDict within "zstd.h" */
1293
1448
 
1294
1449
  ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_customMem customMem)
1295
1450
  {
1296
- if (!customMem.customAlloc && !customMem.customFree)
1297
- customMem = defaultCustomMem;
1298
-
1299
- if (!customMem.customAlloc || !customMem.customFree)
1300
- return NULL;
1451
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
1452
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
1301
1453
 
1302
- { ZSTD_DDict* const ddict = (ZSTD_DDict*) customMem.customAlloc(customMem.opaque, sizeof(*ddict));
1303
- void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
1454
+ { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
1455
+ void* const dictContent = ZSTD_malloc(dictSize, customMem);
1304
1456
  ZSTD_DCtx* const dctx = ZSTD_createDCtx_advanced(customMem);
1305
1457
 
1306
1458
  if (!dictContent || !ddict || !dctx) {
1307
- customMem.customFree(customMem.opaque, dictContent);
1308
- customMem.customFree(customMem.opaque, ddict);
1309
- customMem.customFree(customMem.opaque, dctx);
1459
+ ZSTD_free(dictContent, customMem);
1460
+ ZSTD_free(ddict, customMem);
1461
+ ZSTD_free(dctx, customMem);
1310
1462
  return NULL;
1311
1463
  }
1312
1464
 
1313
- memcpy(dictContent, dict, dictSize);
1465
+ if (dictSize) {
1466
+ memcpy(dictContent, dict, dictSize);
1467
+ }
1314
1468
  { size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, dictContent, dictSize);
1315
1469
  if (ZSTD_isError(errorCode)) {
1316
- customMem.customFree(customMem.opaque, dictContent);
1317
- customMem.customFree(customMem.opaque, ddict);
1318
- customMem.customFree(customMem.opaque, dctx);
1470
+ ZSTD_free(dictContent, customMem);
1471
+ ZSTD_free(ddict, customMem);
1472
+ ZSTD_free(dctx, customMem);
1319
1473
  return NULL;
1320
1474
  } }
1321
1475
 
@@ -1337,26 +1491,352 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
1337
1491
 
1338
1492
  size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
1339
1493
  {
1340
- ZSTD_freeFunction const cFree = ddict->refContext->customMem.customFree;
1341
- void* const opaque = ddict->refContext->customMem.opaque;
1342
- ZSTD_freeDCtx(ddict->refContext);
1343
- cFree(opaque, ddict->dict);
1344
- cFree(opaque, ddict);
1345
- return 0;
1494
+ if (ddict==NULL) return 0; /* support free on NULL */
1495
+ { ZSTD_customMem const cMem = ddict->refContext->customMem;
1496
+ ZSTD_freeDCtx(ddict->refContext);
1497
+ ZSTD_free(ddict->dict, cMem);
1498
+ ZSTD_free(ddict, cMem);
1499
+ return 0;
1500
+ }
1501
+ }
1502
+
1503
+ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
1504
+ {
1505
+ if (ddict==NULL) return 0; /* support sizeof on NULL */
1506
+ return sizeof(*ddict) + sizeof(ddict->refContext) + ddict->dictSize;
1346
1507
  }
1347
1508
 
1509
+
1348
1510
  /*! ZSTD_decompress_usingDDict() :
1349
1511
  * Decompression using a pre-digested Dictionary
1350
1512
  * Use dictionary without significant overhead. */
1351
- ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
1352
- void* dst, size_t dstCapacity,
1353
- const void* src, size_t srcSize,
1354
- const ZSTD_DDict* ddict)
1513
+ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
1514
+ void* dst, size_t dstCapacity,
1515
+ const void* src, size_t srcSize,
1516
+ const ZSTD_DDict* ddict)
1355
1517
  {
1356
1518
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1)
1357
1519
  if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, ddict->dict, ddict->dictSize);
1358
1520
  #endif
1359
- return ZSTD_decompress_usingPreparedDCtx(dctx, ddict->refContext,
1360
- dst, dstCapacity,
1361
- src, srcSize);
1521
+ ZSTD_refDCtx(dctx, ddict->refContext);
1522
+ ZSTD_checkContinuity(dctx, dst);
1523
+ return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize);
1524
+ }
1525
+
1526
+
1527
+ /*=====================================
1528
+ * Streaming decompression
1529
+ *====================================*/
1530
+
1531
+ typedef enum { zdss_init, zdss_loadHeader,
1532
+ zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
1533
+
1534
+ /* *** Resource management *** */
1535
+ struct ZSTD_DStream_s {
1536
+ ZSTD_DCtx* dctx;
1537
+ ZSTD_DDict* ddictLocal;
1538
+ const ZSTD_DDict* ddict;
1539
+ ZSTD_frameParams fParams;
1540
+ ZSTD_dStreamStage stage;
1541
+ char* inBuff;
1542
+ size_t inBuffSize;
1543
+ size_t inPos;
1544
+ size_t maxWindowSize;
1545
+ char* outBuff;
1546
+ size_t outBuffSize;
1547
+ size_t outStart;
1548
+ size_t outEnd;
1549
+ size_t blockSize;
1550
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
1551
+ size_t lhSize;
1552
+ ZSTD_customMem customMem;
1553
+ void* legacyContext;
1554
+ U32 previousLegacyVersion;
1555
+ U32 legacyVersion;
1556
+ U32 hostageByte;
1557
+ }; /* typedef'd to ZSTD_DStream within "zstd.h" */
1558
+
1559
+
1560
+ ZSTD_DStream* ZSTD_createDStream(void)
1561
+ {
1562
+ return ZSTD_createDStream_advanced(defaultCustomMem);
1563
+ }
1564
+
1565
+ ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
1566
+ {
1567
+ ZSTD_DStream* zds;
1568
+
1569
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
1570
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
1571
+
1572
+ zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
1573
+ if (zds==NULL) return NULL;
1574
+ memset(zds, 0, sizeof(ZSTD_DStream));
1575
+ memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
1576
+ zds->dctx = ZSTD_createDCtx_advanced(customMem);
1577
+ if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
1578
+ zds->stage = zdss_init;
1579
+ zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
1580
+ return zds;
1581
+ }
1582
+
1583
+ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
1584
+ {
1585
+ if (zds==NULL) return 0; /* support free on null */
1586
+ { ZSTD_customMem const cMem = zds->customMem;
1587
+ ZSTD_freeDCtx(zds->dctx);
1588
+ ZSTD_freeDDict(zds->ddictLocal);
1589
+ ZSTD_free(zds->inBuff, cMem);
1590
+ ZSTD_free(zds->outBuff, cMem);
1591
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1592
+ if (zds->legacyContext)
1593
+ ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
1594
+ #endif
1595
+ ZSTD_free(zds, cMem);
1596
+ return 0;
1597
+ }
1598
+ }
1599
+
1600
+
1601
+ /* *** Initialization *** */
1602
+
1603
+ size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
1604
+ size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
1605
+
1606
+ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1607
+ {
1608
+ zds->stage = zdss_loadHeader;
1609
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1610
+ ZSTD_freeDDict(zds->ddictLocal);
1611
+ if (dict) {
1612
+ zds->ddictLocal = ZSTD_createDDict(dict, dictSize);
1613
+ if (zds->ddictLocal == NULL) return ERROR(memory_allocation);
1614
+ } else zds->ddictLocal = NULL;
1615
+ zds->ddict = zds->ddictLocal;
1616
+ zds->legacyVersion = 0;
1617
+ zds->hostageByte = 0;
1618
+ return ZSTD_frameHeaderSize_prefix;
1619
+ }
1620
+
1621
+ size_t ZSTD_initDStream(ZSTD_DStream* zds)
1622
+ {
1623
+ return ZSTD_initDStream_usingDict(zds, NULL, 0);
1624
+ }
1625
+
1626
+ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict) /**< note : ddict will just be referenced, and must outlive decompression session */
1627
+ {
1628
+ size_t const initResult = ZSTD_initDStream(zds);
1629
+ zds->ddict = ddict;
1630
+ return initResult;
1631
+ }
1632
+
1633
+ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
1634
+ {
1635
+ zds->stage = zdss_loadHeader;
1636
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1637
+ zds->legacyVersion = 0;
1638
+ zds->hostageByte = 0;
1639
+ return ZSTD_frameHeaderSize_prefix;
1640
+ }
1641
+
1642
+ size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
1643
+ ZSTD_DStreamParameter_e paramType, unsigned paramValue)
1644
+ {
1645
+ switch(paramType)
1646
+ {
1647
+ default : return ERROR(parameter_unknown);
1648
+ case ZSTDdsp_maxWindowSize : zds->maxWindowSize = paramValue ? paramValue : (U32)(-1); break;
1649
+ }
1650
+ return 0;
1651
+ }
1652
+
1653
+
1654
+ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
1655
+ {
1656
+ if (zds==NULL) return 0; /* support sizeof on NULL */
1657
+ return sizeof(*zds) + ZSTD_sizeof_DCtx(zds->dctx) + ZSTD_sizeof_DDict(zds->ddictLocal) + zds->inBuffSize + zds->outBuffSize;
1658
+ }
1659
+
1660
+
1661
+ /* ***** Decompression ***** */
1662
+
1663
+ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1664
+ {
1665
+ size_t const length = MIN(dstCapacity, srcSize);
1666
+ memcpy(dst, src, length);
1667
+ return length;
1668
+ }
1669
+
1670
+
1671
+ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
1672
+ {
1673
+ const char* const istart = (const char*)(input->src) + input->pos;
1674
+ const char* const iend = (const char*)(input->src) + input->size;
1675
+ const char* ip = istart;
1676
+ char* const ostart = (char*)(output->dst) + output->pos;
1677
+ char* const oend = (char*)(output->dst) + output->size;
1678
+ char* op = ostart;
1679
+ U32 someMoreWork = 1;
1680
+
1681
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1682
+ if (zds->legacyVersion)
1683
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
1684
+ #endif
1685
+
1686
+ while (someMoreWork) {
1687
+ switch(zds->stage)
1688
+ {
1689
+ case zdss_init :
1690
+ return ERROR(init_missing);
1691
+
1692
+ case zdss_loadHeader :
1693
+ { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
1694
+ if (ZSTD_isError(hSize))
1695
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1696
+ { U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
1697
+ if (legacyVersion) {
1698
+ const void* const dict = zds->ddict ? zds->ddict->dict : NULL;
1699
+ size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
1700
+ CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
1701
+ dict, dictSize));
1702
+ zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
1703
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
1704
+ } else {
1705
+ return hSize; /* error */
1706
+ } }
1707
+ #else
1708
+ return hSize;
1709
+ #endif
1710
+ if (hSize != 0) { /* need more input */
1711
+ size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
1712
+ if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
1713
+ memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
1714
+ zds->lhSize += iend-ip;
1715
+ input->pos = input->size;
1716
+ return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
1717
+ }
1718
+ memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
1719
+ break;
1720
+ } }
1721
+
1722
+ /* Consume header */
1723
+ { const ZSTD_DCtx* refContext = zds->ddict ? zds->ddict->refContext : NULL;
1724
+ ZSTD_refDCtx(zds->dctx, refContext);
1725
+ }
1726
+ { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
1727
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
1728
+ { size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
1729
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
1730
+ } }
1731
+
1732
+ zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
1733
+ if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
1734
+
1735
+ /* Adapt buffer sizes to frame header instructions */
1736
+ { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
1737
+ size_t const neededOutSize = zds->fParams.windowSize + blockSize;
1738
+ zds->blockSize = blockSize;
1739
+ if (zds->inBuffSize < blockSize) {
1740
+ ZSTD_free(zds->inBuff, zds->customMem);
1741
+ zds->inBuffSize = blockSize;
1742
+ zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
1743
+ if (zds->inBuff == NULL) return ERROR(memory_allocation);
1744
+ }
1745
+ if (zds->outBuffSize < neededOutSize) {
1746
+ ZSTD_free(zds->outBuff, zds->customMem);
1747
+ zds->outBuffSize = neededOutSize;
1748
+ zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
1749
+ if (zds->outBuff == NULL) return ERROR(memory_allocation);
1750
+ } }
1751
+ zds->stage = zdss_read;
1752
+ /* pass-through */
1753
+
1754
+ case zdss_read:
1755
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
1756
+ if (neededInSize==0) { /* end of frame */
1757
+ zds->stage = zdss_init;
1758
+ someMoreWork = 0;
1759
+ break;
1760
+ }
1761
+ if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
1762
+ const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
1763
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
1764
+ zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
1765
+ ip, neededInSize);
1766
+ if (ZSTD_isError(decodedSize)) return decodedSize;
1767
+ ip += neededInSize;
1768
+ if (!decodedSize && !isSkipFrame) break; /* this was just a header */
1769
+ zds->outEnd = zds->outStart + decodedSize;
1770
+ zds->stage = zdss_flush;
1771
+ break;
1772
+ }
1773
+ if (ip==iend) { someMoreWork = 0; break; } /* no more input */
1774
+ zds->stage = zdss_load;
1775
+ /* pass-through */
1776
+ }
1777
+
1778
+ case zdss_load:
1779
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
1780
+ size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
1781
+ size_t loadedSize;
1782
+ if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
1783
+ loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
1784
+ ip += loadedSize;
1785
+ zds->inPos += loadedSize;
1786
+ if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
1787
+
1788
+ /* decode loaded input */
1789
+ { const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
1790
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
1791
+ zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
1792
+ zds->inBuff, neededInSize);
1793
+ if (ZSTD_isError(decodedSize)) return decodedSize;
1794
+ zds->inPos = 0; /* input is consumed */
1795
+ if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; } /* this was just a header */
1796
+ zds->outEnd = zds->outStart + decodedSize;
1797
+ zds->stage = zdss_flush;
1798
+ /* pass-through */
1799
+ } }
1800
+
1801
+ case zdss_flush:
1802
+ { size_t const toFlushSize = zds->outEnd - zds->outStart;
1803
+ size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
1804
+ op += flushedSize;
1805
+ zds->outStart += flushedSize;
1806
+ if (flushedSize == toFlushSize) { /* flush completed */
1807
+ zds->stage = zdss_read;
1808
+ if (zds->outStart + zds->blockSize > zds->outBuffSize)
1809
+ zds->outStart = zds->outEnd = 0;
1810
+ break;
1811
+ }
1812
+ /* cannot complete flush */
1813
+ someMoreWork = 0;
1814
+ break;
1815
+ }
1816
+ default: return ERROR(GENERIC); /* impossible */
1817
+ } }
1818
+
1819
+ /* result */
1820
+ input->pos += (size_t)(ip-istart);
1821
+ output->pos += (size_t)(op-ostart);
1822
+ { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
1823
+ if (!nextSrcSizeHint) { /* frame fully decoded */
1824
+ if (zds->outEnd == zds->outStart) { /* output fully flushed */
1825
+ if (zds->hostageByte) {
1826
+ if (input->pos >= input->size) { zds->stage = zdss_read; return 1; } /* can't release hostage (not present) */
1827
+ input->pos++; /* release hostage */
1828
+ }
1829
+ return 0;
1830
+ }
1831
+ if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
1832
+ input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
1833
+ zds->hostageByte=1;
1834
+ }
1835
+ return 1;
1836
+ }
1837
+ nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
1838
+ if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
1839
+ nextSrcSizeHint -= zds->inPos; /* already loaded*/
1840
+ return nextSrcSizeHint;
1841
+ }
1362
1842
  }