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.
- checksums.yaml +4 -4
- data/HISTORY.ja +5 -0
- data/LICENSE +6 -6
- data/README.md +35 -22
- data/contrib/zstd/LICENSE +13 -9
- data/contrib/zstd/README.md +37 -44
- data/contrib/zstd/common/entropy_common.c +33 -39
- data/contrib/zstd/common/error_private.c +43 -0
- data/contrib/zstd/common/error_private.h +11 -60
- data/contrib/zstd/common/fse.h +11 -5
- data/contrib/zstd/common/fse_decompress.c +14 -16
- data/contrib/zstd/common/huf.h +1 -1
- data/contrib/zstd/common/mem.h +36 -43
- data/contrib/zstd/common/xxhash.c +31 -18
- data/contrib/zstd/common/xxhash.h +71 -35
- data/contrib/zstd/common/zbuff.h +29 -35
- data/contrib/zstd/common/zstd_common.c +24 -32
- data/contrib/zstd/common/zstd_errors.h +60 -0
- data/contrib/zstd/common/zstd_internal.h +109 -80
- data/contrib/zstd/compress/fse_compress.c +9 -6
- data/contrib/zstd/compress/huf_compress.c +30 -74
- data/contrib/zstd/compress/zbuff_compress.c +43 -51
- data/contrib/zstd/compress/zstd_compress.c +953 -763
- data/contrib/zstd/compress/zstd_opt.h +115 -261
- data/contrib/zstd/decompress/huf_decompress.c +29 -40
- data/contrib/zstd/decompress/zbuff_decompress.c +36 -78
- data/contrib/zstd/decompress/zstd_decompress.c +976 -496
- data/contrib/zstd/dictBuilder/divsufsort.h +5 -5
- data/contrib/zstd/dictBuilder/zdict.c +194 -229
- data/contrib/zstd/dictBuilder/zdict.h +66 -68
- data/contrib/zstd/legacy/zstd_legacy.h +168 -49
- data/contrib/zstd/legacy/zstd_v01.c +95 -178
- data/contrib/zstd/legacy/zstd_v01.h +12 -32
- data/contrib/zstd/legacy/zstd_v02.c +48 -274
- data/contrib/zstd/legacy/zstd_v02.h +12 -32
- data/contrib/zstd/legacy/zstd_v03.c +48 -274
- data/contrib/zstd/legacy/zstd_v03.h +12 -32
- data/contrib/zstd/legacy/zstd_v04.c +63 -320
- data/contrib/zstd/legacy/zstd_v04.h +13 -33
- data/contrib/zstd/legacy/zstd_v05.c +80 -345
- data/contrib/zstd/legacy/zstd_v05.h +9 -31
- data/contrib/zstd/legacy/zstd_v06.c +48 -458
- data/contrib/zstd/legacy/zstd_v06.h +41 -67
- data/contrib/zstd/legacy/zstd_v07.c +4544 -0
- data/contrib/zstd/legacy/zstd_v07.h +173 -0
- data/contrib/zstd/zstd.h +640 -0
- data/ext/extconf.rb +7 -3
- data/ext/extzstd.c +263 -106
- data/ext/extzstd.h +8 -6
- data/ext/extzstd_nogvls.h +0 -117
- data/ext/extzstd_stream.c +347 -0
- data/ext/zstd_common.c +8 -0
- data/ext/zstd_compress.c +6 -0
- data/ext/zstd_decompress.c +5 -0
- data/ext/zstd_dictbuilder.c +5 -0
- data/ext/zstd_legacy_v07.c +1 -0
- data/gemstub.rb +18 -16
- data/lib/2.1/extzstd.so +0 -0
- data/lib/2.2/extzstd.so +0 -0
- data/lib/2.3/extzstd.so +0 -0
- data/lib/extzstd/version.rb +1 -1
- data/lib/extzstd.rb +77 -43
- data/test/test_basic.rb +11 -6
- metadata +23 -11
- data/contrib/zstd/common/error_public.h +0 -77
- data/contrib/zstd/common/zstd.h +0 -475
- data/ext/extzstd_buffered.c +0 -265
- data/ext/zstd_amalgam.c +0 -18
- data/lib/2.0/extzstd.so +0 -0
@@ -1,33 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
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[
|
96
|
+
U32 rep[ZSTD_REP_NUM];
|
122
97
|
ZSTD_frameParams fParams;
|
123
|
-
|
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
|
-
|
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 "
|
112
|
+
}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
|
137
113
|
|
138
|
-
size_t
|
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 =
|
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
|
-
|
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
|
-
|
142
|
+
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
143
|
+
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
163
144
|
|
164
|
-
|
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(
|
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
|
-
|
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
|
-
|
189
|
-
|
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
|
-
/*
|
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 >=
|
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 <
|
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
|
206
|
+
U32 const singleSegment = (fhd >> 5) & 1;
|
318
207
|
U32 const fcsId = fhd >> 6;
|
319
|
-
return
|
320
|
-
+ (
|
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 <
|
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
|
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 (!
|
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(
|
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 (
|
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(
|
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
|
289
|
+
- decompressed size is not present within frame header
|
401
290
|
- frame header unknown / not supported
|
402
|
-
- frame header not
|
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
|
-
* `
|
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
|
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,
|
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
|
315
|
+
return 0;
|
425
316
|
}
|
426
317
|
|
427
318
|
|
428
319
|
typedef struct
|
429
320
|
{
|
430
|
-
|
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
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
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
|
-
|
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
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
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
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
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
|
-
|
521
|
-
lhSize
|
522
|
-
|
523
|
-
|
524
|
-
|
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
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
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
|
-
|
552
|
-
|
553
|
-
|
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 =
|
478
|
+
dctx->litBufSize = ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH;
|
556
479
|
dctx->litSize = litSize;
|
557
|
-
return lhSize+
|
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
|
-
|
583
|
-
|
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
|
-
|
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
|
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
|
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(
|
681
|
+
FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
|
682
|
+
*DTablePtr = DTableSpace;
|
609
683
|
return 1;
|
610
|
-
case
|
611
|
-
|
684
|
+
case set_basic :
|
685
|
+
*DTablePtr = (const FSE_DTable*)tmpPtr;
|
612
686
|
return 0;
|
613
|
-
case
|
687
|
+
case set_repeat:
|
614
688
|
if (!flagRepeatTable) return ERROR(corruption_detected);
|
615
689
|
return 0;
|
616
690
|
default : /* impossible */
|
617
|
-
case
|
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(
|
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
|
-
|
654
|
-
|
655
|
-
|
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(
|
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(
|
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(
|
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[
|
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(&
|
699
|
-
U32 const mlCode = FSE_peekSymbol(&
|
700
|
-
U32 const ofCode = FSE_peekSymbol(&
|
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(&
|
730
|
-
if (MEM_32bits()) BIT_reloadDStream(&
|
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
|
-
|
815
|
+
offset += (llCode==0);
|
735
816
|
if (offset) {
|
736
|
-
size_t
|
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(&
|
752
|
-
if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&
|
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(&
|
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(&
|
838
|
+
(totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
|
757
839
|
|
758
840
|
/* ANS state update */
|
759
|
-
FSE_updateState(&
|
760
|
-
FSE_updateState(&
|
761
|
-
if (MEM_32bits()) BIT_reloadDStream(&
|
762
|
-
FSE_updateState(&
|
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 (
|
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
|
-
|
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,
|
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<
|
871
|
-
|
872
|
-
|
873
|
-
FSE_initDState(&
|
874
|
-
FSE_initDState(&
|
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<
|
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 >=
|
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,
|
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
|
-
|
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,
|
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
|
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(
|
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
|
-
|
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
|
-
|
1030
|
-
|
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
|
-
|
1047
|
-
|
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
|
-
*
|
1082
|
-
|
1083
|
-
|
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
|
-
|
1089
|
-
|
1090
|
-
|
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 !=
|
1106
|
-
if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
|
1107
|
-
memcpy(dctx->headerBuffer, src,
|
1108
|
-
dctx->expected = ZSTD_skippableHeaderSize -
|
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,
|
1251
|
+
dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
|
1113
1252
|
if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
|
1114
|
-
memcpy(dctx->headerBuffer, src,
|
1115
|
-
if (dctx->headerSize >
|
1116
|
-
dctx->expected = dctx->headerSize -
|
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
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
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
|
-
|
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
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
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 =
|
1147
|
-
dctx->
|
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
|
-
|
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(
|
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 +
|
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
|
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
|
-
|
1219
|
-
|
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
|
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
|
-
|
1228
|
-
|
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
|
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
|
-
|
1237
|
-
|
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
|
-
|
1277
|
-
|
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
|
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
|
-
|
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*)
|
1303
|
-
void* const dictContent =
|
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
|
-
|
1308
|
-
|
1309
|
-
|
1459
|
+
ZSTD_free(dictContent, customMem);
|
1460
|
+
ZSTD_free(ddict, customMem);
|
1461
|
+
ZSTD_free(dctx, customMem);
|
1310
1462
|
return NULL;
|
1311
1463
|
}
|
1312
1464
|
|
1313
|
-
|
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
|
-
|
1317
|
-
|
1318
|
-
|
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
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
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
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
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
|
-
|
1360
|
-
|
1361
|
-
|
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
|
}
|