extzstd 0.0.3.CONCEPT → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) 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/extzstd/version.rb +1 -1
  59. data/lib/extzstd.rb +77 -43
  60. data/test/test_basic.rb +11 -6
  61. metadata +23 -10
  62. data/contrib/zstd/common/error_public.h +0 -77
  63. data/contrib/zstd/common/zstd.h +0 -475
  64. data/ext/extzstd_buffered.c +0 -265
  65. data/ext/zstd_amalgam.c +0 -18
@@ -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
  }