85 typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, |
78 typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader, |
86 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, |
79 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock, |
87 ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, |
80 ZSTDds_decompressLastBlock, ZSTDds_checkChecksum, |
88 ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; |
81 ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage; |
89 |
82 |
|
83 typedef enum { zdss_init=0, zdss_loadHeader, |
|
84 zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; |
|
85 |
|
86 |
|
87 typedef struct { |
|
88 U32 fastMode; |
|
89 U32 tableLog; |
|
90 } ZSTD_seqSymbol_header; |
|
91 |
|
92 typedef struct { |
|
93 U16 nextState; |
|
94 BYTE nbAdditionalBits; |
|
95 BYTE nbBits; |
|
96 U32 baseValue; |
|
97 } ZSTD_seqSymbol; |
|
98 |
|
99 #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log))) |
|
100 |
|
101 typedef struct { |
|
102 ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; |
|
103 ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; |
|
104 ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; |
|
105 HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ |
|
106 U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; |
|
107 U32 rep[ZSTD_REP_NUM]; |
|
108 } ZSTD_entropyDTables_t; |
|
109 |
90 struct ZSTD_DCtx_s |
110 struct ZSTD_DCtx_s |
91 { |
111 { |
92 const FSE_DTable* LLTptr; |
112 const ZSTD_seqSymbol* LLTptr; |
93 const FSE_DTable* MLTptr; |
113 const ZSTD_seqSymbol* MLTptr; |
94 const FSE_DTable* OFTptr; |
114 const ZSTD_seqSymbol* OFTptr; |
95 const HUF_DTable* HUFptr; |
115 const HUF_DTable* HUFptr; |
96 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; |
116 ZSTD_entropyDTables_t entropy; |
97 FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; |
117 const void* previousDstEnd; /* detect continuity */ |
98 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; |
118 const void* base; /* start of current segment */ |
99 HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */ |
119 const void* vBase; /* virtual start of previous segment if it was just before current one */ |
100 const void* previousDstEnd; |
120 const void* dictEnd; /* end of previous segment */ |
101 const void* base; |
|
102 const void* vBase; |
|
103 const void* dictEnd; |
|
104 size_t expected; |
121 size_t expected; |
105 U32 rep[ZSTD_REP_NUM]; |
122 ZSTD_frameHeader fParams; |
106 ZSTD_frameParams fParams; |
123 U64 decodedSize; |
107 blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */ |
124 blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */ |
108 ZSTD_dStage stage; |
125 ZSTD_dStage stage; |
109 U32 litEntropy; |
126 U32 litEntropy; |
110 U32 fseEntropy; |
127 U32 fseEntropy; |
111 XXH64_state_t xxhState; |
128 XXH64_state_t xxhState; |
112 size_t headerSize; |
129 size_t headerSize; |
113 U32 dictID; |
130 U32 dictID; |
|
131 ZSTD_format_e format; |
114 const BYTE* litPtr; |
132 const BYTE* litPtr; |
115 ZSTD_customMem customMem; |
133 ZSTD_customMem customMem; |
116 size_t litSize; |
134 size_t litSize; |
117 size_t rleSize; |
135 size_t rleSize; |
118 BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH]; |
136 size_t staticSize; |
|
137 int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */ |
|
138 |
|
139 /* streaming */ |
|
140 ZSTD_DDict* ddictLocal; |
|
141 const ZSTD_DDict* ddict; |
|
142 ZSTD_dStreamStage streamStage; |
|
143 char* inBuff; |
|
144 size_t inBuffSize; |
|
145 size_t inPos; |
|
146 size_t maxWindowSize; |
|
147 char* outBuff; |
|
148 size_t outBuffSize; |
|
149 size_t outStart; |
|
150 size_t outEnd; |
|
151 size_t lhSize; |
|
152 void* legacyContext; |
|
153 U32 previousLegacyVersion; |
|
154 U32 legacyVersion; |
|
155 U32 hostageByte; |
|
156 |
|
157 /* workspace */ |
|
158 BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH]; |
119 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; |
159 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; |
120 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ |
160 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */ |
121 |
161 |
122 size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { return (dctx==NULL) ? 0 : sizeof(ZSTD_DCtx); } |
162 size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) |
|
163 { |
|
164 if (dctx==NULL) return 0; /* support sizeof NULL */ |
|
165 return sizeof(*dctx) |
|
166 + ZSTD_sizeof_DDict(dctx->ddictLocal) |
|
167 + dctx->inBuffSize + dctx->outBuffSize; |
|
168 } |
123 |
169 |
124 size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } |
170 size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); } |
125 |
171 |
126 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) |
172 |
127 { |
173 static size_t ZSTD_startingInputLength(ZSTD_format_e format) |
128 dctx->expected = ZSTD_frameHeaderSize_prefix; |
174 { |
129 dctx->stage = ZSTDds_getFrameHeaderSize; |
175 size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ? |
130 dctx->previousDstEnd = NULL; |
176 ZSTD_frameHeaderSize_prefix - ZSTD_frameIdSize : |
131 dctx->base = NULL; |
177 ZSTD_frameHeaderSize_prefix; |
132 dctx->vBase = NULL; |
178 ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE); |
133 dctx->dictEnd = NULL; |
179 /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */ |
134 dctx->hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ |
180 assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) ); |
135 dctx->litEntropy = dctx->fseEntropy = 0; |
181 return startingInputLength; |
136 dctx->dictID = 0; |
182 } |
137 MEM_STATIC_ASSERT(sizeof(dctx->rep) == sizeof(repStartValue)); |
183 |
138 memcpy(dctx->rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ |
184 static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx) |
139 dctx->LLTptr = dctx->LLTable; |
185 { |
140 dctx->MLTptr = dctx->MLTable; |
186 dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */ |
141 dctx->OFTptr = dctx->OFTable; |
187 dctx->staticSize = 0; |
142 dctx->HUFptr = dctx->hufTable; |
188 dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; |
143 return 0; |
189 dctx->ddict = NULL; |
|
190 dctx->ddictLocal = NULL; |
|
191 dctx->inBuff = NULL; |
|
192 dctx->inBuffSize = 0; |
|
193 dctx->outBuffSize = 0; |
|
194 dctx->streamStage = zdss_init; |
|
195 dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid()); |
|
196 } |
|
197 |
|
198 ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize) |
|
199 { |
|
200 ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace; |
|
201 |
|
202 if ((size_t)workspace & 7) return NULL; /* 8-aligned */ |
|
203 if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */ |
|
204 |
|
205 ZSTD_initDCtx_internal(dctx); |
|
206 dctx->staticSize = workspaceSize; |
|
207 dctx->inBuff = (char*)(dctx+1); |
|
208 return dctx; |
144 } |
209 } |
145 |
210 |
146 ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) |
211 ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem) |
147 { |
212 { |
148 ZSTD_DCtx* dctx; |
213 if (!customMem.customAlloc ^ !customMem.customFree) return NULL; |
149 |
214 |
150 if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem; |
215 { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem); |
151 if (!customMem.customAlloc || !customMem.customFree) return NULL; |
216 if (!dctx) return NULL; |
152 |
217 dctx->customMem = customMem; |
153 dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem); |
218 dctx->legacyContext = NULL; |
154 if (!dctx) return NULL; |
219 dctx->previousLegacyVersion = 0; |
155 memcpy(&dctx->customMem, &customMem, sizeof(customMem)); |
220 ZSTD_initDCtx_internal(dctx); |
156 ZSTD_decompressBegin(dctx); |
221 return dctx; |
157 return dctx; |
222 } |
158 } |
223 } |
159 |
224 |
160 ZSTD_DCtx* ZSTD_createDCtx(void) |
225 ZSTD_DCtx* ZSTD_createDCtx(void) |
161 { |
226 { |
162 return ZSTD_createDCtx_advanced(defaultCustomMem); |
227 DEBUGLOG(3, "ZSTD_createDCtx"); |
|
228 return ZSTD_createDCtx_advanced(ZSTD_defaultCMem); |
163 } |
229 } |
164 |
230 |
165 size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) |
231 size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx) |
166 { |
232 { |
167 if (dctx==NULL) return 0; /* support free on NULL */ |
233 if (dctx==NULL) return 0; /* support free on NULL */ |
168 ZSTD_free(dctx, dctx->customMem); |
234 if (dctx->staticSize) return ERROR(memory_allocation); /* not compatible with static DCtx */ |
169 return 0; /* reserved as a potential error code in the future */ |
235 { ZSTD_customMem const cMem = dctx->customMem; |
170 } |
236 ZSTD_freeDDict(dctx->ddictLocal); |
171 |
237 dctx->ddictLocal = NULL; |
|
238 ZSTD_free(dctx->inBuff, cMem); |
|
239 dctx->inBuff = NULL; |
|
240 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) |
|
241 if (dctx->legacyContext) |
|
242 ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion); |
|
243 #endif |
|
244 ZSTD_free(dctx, cMem); |
|
245 return 0; |
|
246 } |
|
247 } |
|
248 |
|
249 /* no longer useful */ |
172 void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) |
250 void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) |
173 { |
251 { |
174 size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max; |
252 size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx); |
175 memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */ |
253 memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */ |
176 } |
|
177 |
|
178 static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) |
|
179 { |
|
180 ZSTD_decompressBegin(dstDCtx); /* init */ |
|
181 if (srcDCtx) { /* support refDCtx on NULL */ |
|
182 dstDCtx->dictEnd = srcDCtx->dictEnd; |
|
183 dstDCtx->vBase = srcDCtx->vBase; |
|
184 dstDCtx->base = srcDCtx->base; |
|
185 dstDCtx->previousDstEnd = srcDCtx->previousDstEnd; |
|
186 dstDCtx->dictID = srcDCtx->dictID; |
|
187 dstDCtx->litEntropy = srcDCtx->litEntropy; |
|
188 dstDCtx->fseEntropy = srcDCtx->fseEntropy; |
|
189 dstDCtx->LLTptr = srcDCtx->LLTable; |
|
190 dstDCtx->MLTptr = srcDCtx->MLTable; |
|
191 dstDCtx->OFTptr = srcDCtx->OFTable; |
|
192 dstDCtx->HUFptr = srcDCtx->hufTable; |
|
193 dstDCtx->rep[0] = srcDCtx->rep[0]; |
|
194 dstDCtx->rep[1] = srcDCtx->rep[1]; |
|
195 dstDCtx->rep[2] = srcDCtx->rep[2]; |
|
196 } |
|
197 } |
254 } |
198 |
255 |
199 |
256 |
200 /*-************************************************************* |
257 /*-************************************************************* |
201 * Decompression section |
258 * Frame header decoding |
202 ***************************************************************/ |
259 ***************************************************************/ |
203 |
260 |
204 /*! ZSTD_isFrame() : |
261 /*! ZSTD_isFrame() : |
205 * Tells if the content of `buffer` starts with a valid Frame Identifier. |
262 * Tells if the content of `buffer` starts with a valid Frame Identifier. |
206 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. |
263 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0. |
207 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. |
264 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled. |
208 * Note 3 : Skippable Frame Identifiers are considered valid. */ |
265 * Note 3 : Skippable Frame Identifiers are considered valid. */ |
209 unsigned ZSTD_isFrame(const void* buffer, size_t size) |
266 unsigned ZSTD_isFrame(const void* buffer, size_t size) |
210 { |
267 { |
211 if (size < 4) return 0; |
268 if (size < ZSTD_frameIdSize) return 0; |
212 { U32 const magic = MEM_readLE32(buffer); |
269 { U32 const magic = MEM_readLE32(buffer); |
213 if (magic == ZSTD_MAGICNUMBER) return 1; |
270 if (magic == ZSTD_MAGICNUMBER) return 1; |
214 if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; |
271 if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1; |
215 } |
272 } |
216 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) |
273 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) |
217 if (ZSTD_isLegacy(buffer, size)) return 1; |
274 if (ZSTD_isLegacy(buffer, size)) return 1; |
218 #endif |
275 #endif |
219 return 0; |
276 return 0; |
220 } |
277 } |
221 |
278 |
222 |
279 /** ZSTD_frameHeaderSize_internal() : |
223 /** ZSTD_frameHeaderSize() : |
280 * srcSize must be large enough to reach header size fields. |
224 * srcSize must be >= ZSTD_frameHeaderSize_prefix. |
281 * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless. |
225 * @return : size of the Frame Header */ |
282 * @return : size of the Frame Header |
226 static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) |
283 * or an error code, which can be tested with ZSTD_isError() */ |
227 { |
284 static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format) |
228 if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); |
285 { |
229 { BYTE const fhd = ((const BYTE*)src)[4]; |
286 size_t const minInputSize = ZSTD_startingInputLength(format); |
|
287 if (srcSize < minInputSize) return ERROR(srcSize_wrong); |
|
288 |
|
289 { BYTE const fhd = ((const BYTE*)src)[minInputSize-1]; |
230 U32 const dictID= fhd & 3; |
290 U32 const dictID= fhd & 3; |
231 U32 const singleSegment = (fhd >> 5) & 1; |
291 U32 const singleSegment = (fhd >> 5) & 1; |
232 U32 const fcsId = fhd >> 6; |
292 U32 const fcsId = fhd >> 6; |
233 return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] |
293 return minInputSize + !singleSegment |
234 + (singleSegment && !fcsId); |
294 + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] |
235 } |
295 + (singleSegment && !fcsId); |
236 } |
296 } |
237 |
297 } |
238 |
298 |
239 /** ZSTD_getFrameParams() : |
299 /** ZSTD_frameHeaderSize() : |
240 * decode Frame Header, or require larger `srcSize`. |
300 * srcSize must be >= ZSTD_frameHeaderSize_prefix. |
241 * @return : 0, `fparamsPtr` is correctly filled, |
301 * @return : size of the Frame Header */ |
242 * >0, `srcSize` is too small, result is expected `srcSize`, |
302 size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) |
243 * or an error code, which can be tested using ZSTD_isError() */ |
303 { |
244 size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize) |
304 return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1); |
|
305 } |
|
306 |
|
307 |
|
308 /** ZSTD_getFrameHeader_internal() : |
|
309 * decode Frame Header, or require larger `srcSize`. |
|
310 * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless |
|
311 * @return : 0, `zfhPtr` is correctly filled, |
|
312 * >0, `srcSize` is too small, value is wanted `srcSize` amount, |
|
313 * or an error code, which can be tested using ZSTD_isError() */ |
|
314 static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format) |
245 { |
315 { |
246 const BYTE* ip = (const BYTE*)src; |
316 const BYTE* ip = (const BYTE*)src; |
247 |
317 size_t const minInputSize = ZSTD_startingInputLength(format); |
248 if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix; |
318 |
249 if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) { |
319 if (srcSize < minInputSize) return minInputSize; |
|
320 |
|
321 if ( (format != ZSTD_f_zstd1_magicless) |
|
322 && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) { |
250 if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { |
323 if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { |
251 if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */ |
324 /* skippable frame */ |
252 memset(fparamsPtr, 0, sizeof(*fparamsPtr)); |
325 if (srcSize < ZSTD_skippableHeaderSize) |
253 fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4); |
326 return ZSTD_skippableHeaderSize; /* magic number + frame length */ |
254 fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */ |
327 memset(zfhPtr, 0, sizeof(*zfhPtr)); |
|
328 zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_frameIdSize); |
|
329 zfhPtr->frameType = ZSTD_skippableFrame; |
255 return 0; |
330 return 0; |
256 } |
331 } |
257 return ERROR(prefix_unknown); |
332 return ERROR(prefix_unknown); |
258 } |
333 } |
259 |
334 |
260 /* ensure there is enough `srcSize` to fully read/decode frame header */ |
335 /* ensure there is enough `srcSize` to fully read/decode frame header */ |
261 { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize); |
336 { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format); |
262 if (srcSize < fhsize) return fhsize; } |
337 if (srcSize < fhsize) return fhsize; |
263 |
338 zfhPtr->headerSize = (U32)fhsize; |
264 { BYTE const fhdByte = ip[4]; |
339 } |
265 size_t pos = 5; |
340 |
|
341 { BYTE const fhdByte = ip[minInputSize-1]; |
|
342 size_t pos = minInputSize; |
266 U32 const dictIDSizeCode = fhdByte&3; |
343 U32 const dictIDSizeCode = fhdByte&3; |
267 U32 const checksumFlag = (fhdByte>>2)&1; |
344 U32 const checksumFlag = (fhdByte>>2)&1; |
268 U32 const singleSegment = (fhdByte>>5)&1; |
345 U32 const singleSegment = (fhdByte>>5)&1; |
269 U32 const fcsID = fhdByte>>6; |
346 U32 const fcsID = fhdByte>>6; |
270 U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; |
347 U64 windowSize = 0; |
271 U32 windowSize = 0; |
|
272 U32 dictID = 0; |
348 U32 dictID = 0; |
273 U64 frameContentSize = 0; |
349 U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN; |
274 if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */ |
350 if ((fhdByte & 0x08) != 0) |
|
351 return ERROR(frameParameter_unsupported); /* reserved bits, must be zero */ |
|
352 |
275 if (!singleSegment) { |
353 if (!singleSegment) { |
276 BYTE const wlByte = ip[pos++]; |
354 BYTE const wlByte = ip[pos++]; |
277 U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; |
355 U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN; |
278 if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */ |
356 if (windowLog > ZSTD_WINDOWLOG_MAX) |
279 windowSize = (1U << windowLog); |
357 return ERROR(frameParameter_windowTooLarge); |
|
358 windowSize = (1ULL << windowLog); |
280 windowSize += (windowSize >> 3) * (wlByte&7); |
359 windowSize += (windowSize >> 3) * (wlByte&7); |
281 } |
360 } |
282 |
|
283 switch(dictIDSizeCode) |
361 switch(dictIDSizeCode) |
284 { |
362 { |
285 default: /* impossible */ |
363 default: assert(0); /* impossible */ |
286 case 0 : break; |
364 case 0 : break; |
287 case 1 : dictID = ip[pos]; pos++; break; |
365 case 1 : dictID = ip[pos]; pos++; break; |
288 case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; |
366 case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break; |
289 case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; |
367 case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break; |
290 } |
368 } |
291 switch(fcsID) |
369 switch(fcsID) |
292 { |
370 { |
293 default: /* impossible */ |
371 default: assert(0); /* impossible */ |
294 case 0 : if (singleSegment) frameContentSize = ip[pos]; break; |
372 case 0 : if (singleSegment) frameContentSize = ip[pos]; break; |
295 case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; |
373 case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break; |
296 case 2 : frameContentSize = MEM_readLE32(ip+pos); break; |
374 case 2 : frameContentSize = MEM_readLE32(ip+pos); break; |
297 case 3 : frameContentSize = MEM_readLE64(ip+pos); break; |
375 case 3 : frameContentSize = MEM_readLE64(ip+pos); break; |
298 } |
376 } |
299 if (!windowSize) windowSize = (U32)frameContentSize; |
377 if (singleSegment) windowSize = frameContentSize; |
300 if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge); |
378 |
301 fparamsPtr->frameContentSize = frameContentSize; |
379 zfhPtr->frameType = ZSTD_frame; |
302 fparamsPtr->windowSize = windowSize; |
380 zfhPtr->frameContentSize = frameContentSize; |
303 fparamsPtr->dictID = dictID; |
381 zfhPtr->windowSize = windowSize; |
304 fparamsPtr->checksumFlag = checksumFlag; |
382 zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); |
|
383 zfhPtr->dictID = dictID; |
|
384 zfhPtr->checksumFlag = checksumFlag; |
305 } |
385 } |
306 return 0; |
386 return 0; |
307 } |
387 } |
308 |
388 |
|
389 /** ZSTD_getFrameHeader() : |
|
390 * decode Frame Header, or require larger `srcSize`. |
|
391 * note : this function does not consume input, it only reads it. |
|
392 * @return : 0, `zfhPtr` is correctly filled, |
|
393 * >0, `srcSize` is too small, value is wanted `srcSize` amount, |
|
394 * or an error code, which can be tested using ZSTD_isError() */ |
|
395 size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize) |
|
396 { |
|
397 return ZSTD_getFrameHeader_internal(zfhPtr, src, srcSize, ZSTD_f_zstd1); |
|
398 } |
|
399 |
|
400 |
|
401 /** ZSTD_getFrameContentSize() : |
|
402 * compatible with legacy mode |
|
403 * @return : decompressed size of the single frame pointed to be `src` if known, otherwise |
|
404 * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined |
|
405 * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */ |
|
406 unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize) |
|
407 { |
|
408 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) |
|
409 if (ZSTD_isLegacy(src, srcSize)) { |
|
410 unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize); |
|
411 return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret; |
|
412 } |
|
413 #endif |
|
414 { ZSTD_frameHeader zfh; |
|
415 if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0) |
|
416 return ZSTD_CONTENTSIZE_ERROR; |
|
417 if (zfh.frameType == ZSTD_skippableFrame) { |
|
418 return 0; |
|
419 } else { |
|
420 return zfh.frameContentSize; |
|
421 } } |
|
422 } |
|
423 |
|
424 /** ZSTD_findDecompressedSize() : |
|
425 * compatible with legacy mode |
|
426 * `srcSize` must be the exact length of some number of ZSTD compressed and/or |
|
427 * skippable frames |
|
428 * @return : decompressed size of the frames contained */ |
|
429 unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize) |
|
430 { |
|
431 unsigned long long totalDstSize = 0; |
|
432 |
|
433 while (srcSize >= ZSTD_frameHeaderSize_prefix) { |
|
434 U32 const magicNumber = MEM_readLE32(src); |
|
435 |
|
436 if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { |
|
437 size_t skippableSize; |
|
438 if (srcSize < ZSTD_skippableHeaderSize) |
|
439 return ERROR(srcSize_wrong); |
|
440 skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_frameIdSize) |
|
441 + ZSTD_skippableHeaderSize; |
|
442 if (srcSize < skippableSize) { |
|
443 return ZSTD_CONTENTSIZE_ERROR; |
|
444 } |
|
445 |
|
446 src = (const BYTE *)src + skippableSize; |
|
447 srcSize -= skippableSize; |
|
448 continue; |
|
449 } |
|
450 |
|
451 { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); |
|
452 if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret; |
|
453 |
|
454 /* check for overflow */ |
|
455 if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR; |
|
456 totalDstSize += ret; |
|
457 } |
|
458 { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize); |
|
459 if (ZSTD_isError(frameSrcSize)) { |
|
460 return ZSTD_CONTENTSIZE_ERROR; |
|
461 } |
|
462 |
|
463 src = (const BYTE *)src + frameSrcSize; |
|
464 srcSize -= frameSrcSize; |
|
465 } |
|
466 } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */ |
|
467 |
|
468 if (srcSize) return ZSTD_CONTENTSIZE_ERROR; |
|
469 |
|
470 return totalDstSize; |
|
471 } |
309 |
472 |
310 /** ZSTD_getDecompressedSize() : |
473 /** ZSTD_getDecompressedSize() : |
311 * compatible with legacy mode |
474 * compatible with legacy mode |
312 * @return : decompressed size if known, 0 otherwise |
475 * @return : decompressed size if known, 0 otherwise |
313 note : 0 can mean any of the following : |
476 note : 0 can mean any of the following : |
314 - decompressed size is not present within frame header |
477 - frame content is empty |
|
478 - decompressed size field is not present in frame header |
315 - frame header unknown / not supported |
479 - frame header unknown / not supported |
316 - frame header not complete (`srcSize` too small) */ |
480 - frame header not complete (`srcSize` too small) */ |
317 unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) |
481 unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) |
318 { |
482 { |
319 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) |
483 unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize); |
320 if (ZSTD_isLegacy(src, srcSize)) return ZSTD_getDecompressedSize_legacy(src, srcSize); |
484 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN); |
321 #endif |
485 return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret; |
322 { ZSTD_frameParams fparams; |
|
323 size_t const frResult = ZSTD_getFrameParams(&fparams, src, srcSize); |
|
324 if (frResult!=0) return 0; |
|
325 return fparams.frameContentSize; |
|
326 } |
|
327 } |
486 } |
328 |
487 |
329 |
488 |
330 /** ZSTD_decodeFrameHeader() : |
489 /** ZSTD_decodeFrameHeader() : |
331 * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). |
490 * `headerSize` must be the size provided by ZSTD_frameHeaderSize(). |
332 * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ |
491 * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */ |
333 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) |
492 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize) |
334 { |
493 { |
335 size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize); |
494 size_t const result = ZSTD_getFrameHeader_internal(&(dctx->fParams), src, headerSize, dctx->format); |
336 if (ZSTD_isError(result)) return result; /* invalid header */ |
495 if (ZSTD_isError(result)) return result; /* invalid header */ |
337 if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */ |
496 if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */ |
338 if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong); |
497 if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) |
|
498 return ERROR(dictionary_wrong); |
339 if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0); |
499 if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0); |
340 return 0; |
500 return 0; |
341 } |
501 } |
342 |
502 |
343 |
503 |
344 typedef struct |
504 /*-************************************************************* |
345 { |
505 * Block decoding |
346 blockType_e blockType; |
506 ***************************************************************/ |
347 U32 lastBlock; |
|
348 U32 origSize; |
|
349 } blockProperties_t; |
|
350 |
507 |
351 /*! ZSTD_getcBlockSize() : |
508 /*! ZSTD_getcBlockSize() : |
352 * Provides the size of compressed block from block header `src` */ |
509 * Provides the size of compressed block from block header `src` */ |
353 size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr) |
510 size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, |
|
511 blockProperties_t* bpPtr) |
354 { |
512 { |
355 if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); |
513 if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); |
356 { U32 const cBlockHeader = MEM_readLE24(src); |
514 { U32 const cBlockHeader = MEM_readLE24(src); |
357 U32 const cSize = cBlockHeader >> 3; |
515 U32 const cSize = cBlockHeader >> 3; |
358 bpPtr->lastBlock = cBlockHeader & 1; |
516 bpPtr->lastBlock = cBlockHeader & 1; |
506 return ERROR(corruption_detected); /* impossible */ |
670 return ERROR(corruption_detected); /* impossible */ |
507 } |
671 } |
508 } |
672 } |
509 } |
673 } |
510 |
674 |
511 |
675 /* Default FSE distribution tables. |
512 typedef union { |
676 * These are pre-calculated FSE decoding tables using default distributions as defined in specification : |
513 FSE_decode_t realData; |
677 * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions |
514 U32 alignedBy4; |
678 * They were generated programmatically with following method : |
515 } FSE_decode_t4; |
679 * - start from default distributions, present in /lib/common/zstd_internal.h |
516 |
680 * - generate tables normally, using ZSTD_buildFSETable() |
517 static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = { |
681 * - printout the content of tables |
518 { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */ |
682 * - pretify output, report below, test with fuzzer to ensure it's correct */ |
519 { { 0, 0, 4 } }, /* 0 : base, symbol, bits */ |
683 |
520 { { 16, 0, 4 } }, |
684 /* Default FSE distribution table for Literal Lengths */ |
521 { { 32, 1, 5 } }, |
685 static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = { |
522 { { 0, 3, 5 } }, |
686 { 1, 1, 1, LL_DEFAULTNORMLOG}, /* header : fastMode, tableLog */ |
523 { { 0, 4, 5 } }, |
687 /* nextState, nbAddBits, nbBits, baseVal */ |
524 { { 0, 6, 5 } }, |
688 { 0, 0, 4, 0}, { 16, 0, 4, 0}, |
525 { { 0, 7, 5 } }, |
689 { 32, 0, 5, 1}, { 0, 0, 5, 3}, |
526 { { 0, 9, 5 } }, |
690 { 0, 0, 5, 4}, { 0, 0, 5, 6}, |
527 { { 0, 10, 5 } }, |
691 { 0, 0, 5, 7}, { 0, 0, 5, 9}, |
528 { { 0, 12, 5 } }, |
692 { 0, 0, 5, 10}, { 0, 0, 5, 12}, |
529 { { 0, 14, 6 } }, |
693 { 0, 0, 6, 14}, { 0, 1, 5, 16}, |
530 { { 0, 16, 5 } }, |
694 { 0, 1, 5, 20}, { 0, 1, 5, 22}, |
531 { { 0, 18, 5 } }, |
695 { 0, 2, 5, 28}, { 0, 3, 5, 32}, |
532 { { 0, 19, 5 } }, |
696 { 0, 4, 5, 48}, { 32, 6, 5, 64}, |
533 { { 0, 21, 5 } }, |
697 { 0, 7, 5, 128}, { 0, 8, 6, 256}, |
534 { { 0, 22, 5 } }, |
698 { 0, 10, 6, 1024}, { 0, 12, 6, 4096}, |
535 { { 0, 24, 5 } }, |
699 { 32, 0, 4, 0}, { 0, 0, 4, 1}, |
536 { { 32, 25, 5 } }, |
700 { 0, 0, 5, 2}, { 32, 0, 5, 4}, |
537 { { 0, 26, 5 } }, |
701 { 0, 0, 5, 5}, { 32, 0, 5, 7}, |
538 { { 0, 27, 6 } }, |
702 { 0, 0, 5, 8}, { 32, 0, 5, 10}, |
539 { { 0, 29, 6 } }, |
703 { 0, 0, 5, 11}, { 0, 0, 6, 13}, |
540 { { 0, 31, 6 } }, |
704 { 32, 1, 5, 16}, { 0, 1, 5, 18}, |
541 { { 32, 0, 4 } }, |
705 { 32, 1, 5, 22}, { 0, 2, 5, 24}, |
542 { { 0, 1, 4 } }, |
706 { 32, 3, 5, 32}, { 0, 3, 5, 40}, |
543 { { 0, 2, 5 } }, |
707 { 0, 6, 4, 64}, { 16, 6, 4, 64}, |
544 { { 32, 4, 5 } }, |
708 { 32, 7, 5, 128}, { 0, 9, 6, 512}, |
545 { { 0, 5, 5 } }, |
709 { 0, 11, 6, 2048}, { 48, 0, 4, 0}, |
546 { { 32, 7, 5 } }, |
710 { 16, 0, 4, 1}, { 32, 0, 5, 2}, |
547 { { 0, 8, 5 } }, |
711 { 32, 0, 5, 3}, { 32, 0, 5, 5}, |
548 { { 32, 10, 5 } }, |
712 { 32, 0, 5, 6}, { 32, 0, 5, 8}, |
549 { { 0, 11, 5 } }, |
713 { 32, 0, 5, 9}, { 32, 0, 5, 11}, |
550 { { 0, 13, 6 } }, |
714 { 32, 0, 5, 12}, { 0, 0, 6, 15}, |
551 { { 32, 16, 5 } }, |
715 { 32, 1, 5, 18}, { 32, 1, 5, 20}, |
552 { { 0, 17, 5 } }, |
716 { 32, 2, 5, 24}, { 32, 2, 5, 28}, |
553 { { 32, 19, 5 } }, |
717 { 32, 3, 5, 40}, { 32, 4, 5, 48}, |
554 { { 0, 20, 5 } }, |
718 { 0, 16, 6,65536}, { 0, 15, 6,32768}, |
555 { { 32, 22, 5 } }, |
719 { 0, 14, 6,16384}, { 0, 13, 6, 8192}, |
556 { { 0, 23, 5 } }, |
|
557 { { 0, 25, 4 } }, |
|
558 { { 16, 25, 4 } }, |
|
559 { { 32, 26, 5 } }, |
|
560 { { 0, 28, 6 } }, |
|
561 { { 0, 30, 6 } }, |
|
562 { { 48, 0, 4 } }, |
|
563 { { 16, 1, 4 } }, |
|
564 { { 32, 2, 5 } }, |
|
565 { { 32, 3, 5 } }, |
|
566 { { 32, 5, 5 } }, |
|
567 { { 32, 6, 5 } }, |
|
568 { { 32, 8, 5 } }, |
|
569 { { 32, 9, 5 } }, |
|
570 { { 32, 11, 5 } }, |
|
571 { { 32, 12, 5 } }, |
|
572 { { 0, 15, 6 } }, |
|
573 { { 32, 17, 5 } }, |
|
574 { { 32, 18, 5 } }, |
|
575 { { 32, 20, 5 } }, |
|
576 { { 32, 21, 5 } }, |
|
577 { { 32, 23, 5 } }, |
|
578 { { 32, 24, 5 } }, |
|
579 { { 0, 35, 6 } }, |
|
580 { { 0, 34, 6 } }, |
|
581 { { 0, 33, 6 } }, |
|
582 { { 0, 32, 6 } }, |
|
583 }; /* LL_defaultDTable */ |
720 }; /* LL_defaultDTable */ |
584 |
721 |
585 static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = { |
722 /* Default FSE distribution table for Offset Codes */ |
586 { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */ |
723 static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = { |
587 { { 0, 0, 6 } }, /* 0 : base, symbol, bits */ |
724 { 1, 1, 1, OF_DEFAULTNORMLOG}, /* header : fastMode, tableLog */ |
588 { { 0, 1, 4 } }, |
725 /* nextState, nbAddBits, nbBits, baseVal */ |
589 { { 32, 2, 5 } }, |
726 { 0, 0, 5, 0}, { 0, 6, 4, 61}, |
590 { { 0, 3, 5 } }, |
727 { 0, 9, 5, 509}, { 0, 15, 5,32765}, |
591 { { 0, 5, 5 } }, |
728 { 0, 21, 5,2097149}, { 0, 3, 5, 5}, |
592 { { 0, 6, 5 } }, |
729 { 0, 7, 4, 125}, { 0, 12, 5, 4093}, |
593 { { 0, 8, 5 } }, |
730 { 0, 18, 5,262141}, { 0, 23, 5,8388605}, |
594 { { 0, 10, 6 } }, |
731 { 0, 5, 5, 29}, { 0, 8, 4, 253}, |
595 { { 0, 13, 6 } }, |
732 { 0, 14, 5,16381}, { 0, 20, 5,1048573}, |
596 { { 0, 16, 6 } }, |
733 { 0, 2, 5, 1}, { 16, 7, 4, 125}, |
597 { { 0, 19, 6 } }, |
734 { 0, 11, 5, 2045}, { 0, 17, 5,131069}, |
598 { { 0, 22, 6 } }, |
735 { 0, 22, 5,4194301}, { 0, 4, 5, 13}, |
599 { { 0, 25, 6 } }, |
736 { 16, 8, 4, 253}, { 0, 13, 5, 8189}, |
600 { { 0, 28, 6 } }, |
737 { 0, 19, 5,524285}, { 0, 1, 5, 1}, |
601 { { 0, 31, 6 } }, |
738 { 16, 6, 4, 61}, { 0, 10, 5, 1021}, |
602 { { 0, 33, 6 } }, |
739 { 0, 16, 5,65533}, { 0, 28, 5,268435453}, |
603 { { 0, 35, 6 } }, |
740 { 0, 27, 5,134217725}, { 0, 26, 5,67108861}, |
604 { { 0, 37, 6 } }, |
741 { 0, 25, 5,33554429}, { 0, 24, 5,16777213}, |
605 { { 0, 39, 6 } }, |
742 }; /* OF_defaultDTable */ |
606 { { 0, 41, 6 } }, |
743 |
607 { { 0, 43, 6 } }, |
744 |
608 { { 0, 45, 6 } }, |
745 /* Default FSE distribution table for Match Lengths */ |
609 { { 16, 1, 4 } }, |
746 static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = { |
610 { { 0, 2, 4 } }, |
747 { 1, 1, 1, ML_DEFAULTNORMLOG}, /* header : fastMode, tableLog */ |
611 { { 32, 3, 5 } }, |
748 /* nextState, nbAddBits, nbBits, baseVal */ |
612 { { 0, 4, 5 } }, |
749 { 0, 0, 6, 3}, { 0, 0, 4, 4}, |
613 { { 32, 6, 5 } }, |
750 { 32, 0, 5, 5}, { 0, 0, 5, 6}, |
614 { { 0, 7, 5 } }, |
751 { 0, 0, 5, 8}, { 0, 0, 5, 9}, |
615 { { 0, 9, 6 } }, |
752 { 0, 0, 5, 11}, { 0, 0, 6, 13}, |
616 { { 0, 12, 6 } }, |
753 { 0, 0, 6, 16}, { 0, 0, 6, 19}, |
617 { { 0, 15, 6 } }, |
754 { 0, 0, 6, 22}, { 0, 0, 6, 25}, |
618 { { 0, 18, 6 } }, |
755 { 0, 0, 6, 28}, { 0, 0, 6, 31}, |
619 { { 0, 21, 6 } }, |
756 { 0, 0, 6, 34}, { 0, 1, 6, 37}, |
620 { { 0, 24, 6 } }, |
757 { 0, 1, 6, 41}, { 0, 2, 6, 47}, |
621 { { 0, 27, 6 } }, |
758 { 0, 3, 6, 59}, { 0, 4, 6, 83}, |
622 { { 0, 30, 6 } }, |
759 { 0, 7, 6, 131}, { 0, 9, 6, 515}, |
623 { { 0, 32, 6 } }, |
760 { 16, 0, 4, 4}, { 0, 0, 4, 5}, |
624 { { 0, 34, 6 } }, |
761 { 32, 0, 5, 6}, { 0, 0, 5, 7}, |
625 { { 0, 36, 6 } }, |
762 { 32, 0, 5, 9}, { 0, 0, 5, 10}, |
626 { { 0, 38, 6 } }, |
763 { 0, 0, 6, 12}, { 0, 0, 6, 15}, |
627 { { 0, 40, 6 } }, |
764 { 0, 0, 6, 18}, { 0, 0, 6, 21}, |
628 { { 0, 42, 6 } }, |
765 { 0, 0, 6, 24}, { 0, 0, 6, 27}, |
629 { { 0, 44, 6 } }, |
766 { 0, 0, 6, 30}, { 0, 0, 6, 33}, |
630 { { 32, 1, 4 } }, |
767 { 0, 1, 6, 35}, { 0, 1, 6, 39}, |
631 { { 48, 1, 4 } }, |
768 { 0, 2, 6, 43}, { 0, 3, 6, 51}, |
632 { { 16, 2, 4 } }, |
769 { 0, 4, 6, 67}, { 0, 5, 6, 99}, |
633 { { 32, 4, 5 } }, |
770 { 0, 8, 6, 259}, { 32, 0, 4, 4}, |
634 { { 32, 5, 5 } }, |
771 { 48, 0, 4, 4}, { 16, 0, 4, 5}, |
635 { { 32, 7, 5 } }, |
772 { 32, 0, 5, 7}, { 32, 0, 5, 8}, |
636 { { 32, 8, 5 } }, |
773 { 32, 0, 5, 10}, { 32, 0, 5, 11}, |
637 { { 0, 11, 6 } }, |
774 { 0, 0, 6, 14}, { 0, 0, 6, 17}, |
638 { { 0, 14, 6 } }, |
775 { 0, 0, 6, 20}, { 0, 0, 6, 23}, |
639 { { 0, 17, 6 } }, |
776 { 0, 0, 6, 26}, { 0, 0, 6, 29}, |
640 { { 0, 20, 6 } }, |
777 { 0, 0, 6, 32}, { 0, 16, 6,65539}, |
641 { { 0, 23, 6 } }, |
778 { 0, 15, 6,32771}, { 0, 14, 6,16387}, |
642 { { 0, 26, 6 } }, |
779 { 0, 13, 6, 8195}, { 0, 12, 6, 4099}, |
643 { { 0, 29, 6 } }, |
780 { 0, 11, 6, 2051}, { 0, 10, 6, 1027}, |
644 { { 0, 52, 6 } }, |
|
645 { { 0, 51, 6 } }, |
|
646 { { 0, 50, 6 } }, |
|
647 { { 0, 49, 6 } }, |
|
648 { { 0, 48, 6 } }, |
|
649 { { 0, 47, 6 } }, |
|
650 { { 0, 46, 6 } }, |
|
651 }; /* ML_defaultDTable */ |
781 }; /* ML_defaultDTable */ |
652 |
782 |
653 static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = { |
783 |
654 { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */ |
784 static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddBits) |
655 { { 0, 0, 5 } }, /* 0 : base, symbol, bits */ |
785 { |
656 { { 0, 6, 4 } }, |
786 void* ptr = dt; |
657 { { 0, 9, 5 } }, |
787 ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr; |
658 { { 0, 15, 5 } }, |
788 ZSTD_seqSymbol* const cell = dt + 1; |
659 { { 0, 21, 5 } }, |
789 |
660 { { 0, 3, 5 } }, |
790 DTableH->tableLog = 0; |
661 { { 0, 7, 4 } }, |
791 DTableH->fastMode = 0; |
662 { { 0, 12, 5 } }, |
792 |
663 { { 0, 18, 5 } }, |
793 cell->nbBits = 0; |
664 { { 0, 23, 5 } }, |
794 cell->nextState = 0; |
665 { { 0, 5, 5 } }, |
795 assert(nbAddBits < 255); |
666 { { 0, 8, 4 } }, |
796 cell->nbAdditionalBits = (BYTE)nbAddBits; |
667 { { 0, 14, 5 } }, |
797 cell->baseValue = baseValue; |
668 { { 0, 20, 5 } }, |
798 } |
669 { { 0, 2, 5 } }, |
799 |
670 { { 16, 7, 4 } }, |
800 |
671 { { 0, 11, 5 } }, |
801 /* ZSTD_buildFSETable() : |
672 { { 0, 17, 5 } }, |
802 * generate FSE decoding table for one symbol (ll, ml or off) */ |
673 { { 0, 22, 5 } }, |
803 static void |
674 { { 0, 4, 5 } }, |
804 ZSTD_buildFSETable(ZSTD_seqSymbol* dt, |
675 { { 16, 8, 4 } }, |
805 const short* normalizedCounter, unsigned maxSymbolValue, |
676 { { 0, 13, 5 } }, |
806 const U32* baseValue, const U32* nbAdditionalBits, |
677 { { 0, 19, 5 } }, |
807 unsigned tableLog) |
678 { { 0, 1, 5 } }, |
808 { |
679 { { 16, 6, 4 } }, |
809 ZSTD_seqSymbol* const tableDecode = dt+1; |
680 { { 0, 10, 5 } }, |
810 U16 symbolNext[MaxSeq+1]; |
681 { { 0, 16, 5 } }, |
811 |
682 { { 0, 28, 5 } }, |
812 U32 const maxSV1 = maxSymbolValue + 1; |
683 { { 0, 27, 5 } }, |
813 U32 const tableSize = 1 << tableLog; |
684 { { 0, 26, 5 } }, |
814 U32 highThreshold = tableSize-1; |
685 { { 0, 25, 5 } }, |
815 |
686 { { 0, 24, 5 } }, |
816 /* Sanity Checks */ |
687 }; /* OF_defaultDTable */ |
817 assert(maxSymbolValue <= MaxSeq); |
|
818 assert(tableLog <= MaxFSELog); |
|
819 |
|
820 /* Init, lay down lowprob symbols */ |
|
821 { ZSTD_seqSymbol_header DTableH; |
|
822 DTableH.tableLog = tableLog; |
|
823 DTableH.fastMode = 1; |
|
824 { S16 const largeLimit= (S16)(1 << (tableLog-1)); |
|
825 U32 s; |
|
826 for (s=0; s<maxSV1; s++) { |
|
827 if (normalizedCounter[s]==-1) { |
|
828 tableDecode[highThreshold--].baseValue = s; |
|
829 symbolNext[s] = 1; |
|
830 } else { |
|
831 if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0; |
|
832 symbolNext[s] = normalizedCounter[s]; |
|
833 } } } |
|
834 memcpy(dt, &DTableH, sizeof(DTableH)); |
|
835 } |
|
836 |
|
837 /* Spread symbols */ |
|
838 { U32 const tableMask = tableSize-1; |
|
839 U32 const step = FSE_TABLESTEP(tableSize); |
|
840 U32 s, position = 0; |
|
841 for (s=0; s<maxSV1; s++) { |
|
842 int i; |
|
843 for (i=0; i<normalizedCounter[s]; i++) { |
|
844 tableDecode[position].baseValue = s; |
|
845 position = (position + step) & tableMask; |
|
846 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */ |
|
847 } } |
|
848 assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ |
|
849 } |
|
850 |
|
851 /* Build Decoding table */ |
|
852 { U32 u; |
|
853 for (u=0; u<tableSize; u++) { |
|
854 U32 const symbol = tableDecode[u].baseValue; |
|
855 U32 const nextState = symbolNext[symbol]++; |
|
856 tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) ); |
|
857 tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize); |
|
858 assert(nbAdditionalBits[symbol] < 255); |
|
859 tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol]; |
|
860 tableDecode[u].baseValue = baseValue[symbol]; |
|
861 } } |
|
862 } |
|
863 |
688 |
864 |
689 /*! ZSTD_buildSeqTable() : |
865 /*! ZSTD_buildSeqTable() : |
690 @return : nb bytes read from src, |
866 * @return : nb bytes read from src, |
691 or an error code if it fails, testable with ZSTD_isError() |
867 * or an error code if it fails */ |
692 */ |
868 static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr, |
693 static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr, |
|
694 symbolEncodingType_e type, U32 max, U32 maxLog, |
869 symbolEncodingType_e type, U32 max, U32 maxLog, |
695 const void* src, size_t srcSize, |
870 const void* src, size_t srcSize, |
696 const FSE_decode_t4* defaultTable, U32 flagRepeatTable) |
871 const U32* baseValue, const U32* nbAdditionalBits, |
697 { |
872 const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable) |
698 const void* const tmpPtr = defaultTable; /* bypass strict aliasing */ |
873 { |
699 switch(type) |
874 switch(type) |
700 { |
875 { |
701 case set_rle : |
876 case set_rle : |
702 if (!srcSize) return ERROR(srcSize_wrong); |
877 if (!srcSize) return ERROR(srcSize_wrong); |
703 if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected); |
878 if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected); |
704 FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src); |
879 { U32 const symbol = *(const BYTE*)src; |
|
880 U32 const baseline = baseValue[symbol]; |
|
881 U32 const nbBits = nbAdditionalBits[symbol]; |
|
882 ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits); |
|
883 } |
705 *DTablePtr = DTableSpace; |
884 *DTablePtr = DTableSpace; |
706 return 1; |
885 return 1; |
707 case set_basic : |
886 case set_basic : |
708 *DTablePtr = (const FSE_DTable*)tmpPtr; |
887 *DTablePtr = defaultTable; |
709 return 0; |
888 return 0; |
710 case set_repeat: |
889 case set_repeat: |
711 if (!flagRepeatTable) return ERROR(corruption_detected); |
890 if (!flagRepeatTable) return ERROR(corruption_detected); |
712 return 0; |
891 return 0; |
713 default : /* impossible */ |
|
714 case set_compressed : |
892 case set_compressed : |
715 { U32 tableLog; |
893 { U32 tableLog; |
716 S16 norm[MaxSeq+1]; |
894 S16 norm[MaxSeq+1]; |
717 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); |
895 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize); |
718 if (FSE_isError(headerSize)) return ERROR(corruption_detected); |
896 if (FSE_isError(headerSize)) return ERROR(corruption_detected); |
719 if (tableLog > maxLog) return ERROR(corruption_detected); |
897 if (tableLog > maxLog) return ERROR(corruption_detected); |
720 FSE_buildDTable(DTableSpace, norm, max, tableLog); |
898 ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog); |
721 *DTablePtr = DTableSpace; |
899 *DTablePtr = DTableSpace; |
722 return headerSize; |
900 return headerSize; |
723 } } |
901 } |
724 } |
902 default : /* impossible */ |
|
903 assert(0); |
|
904 return ERROR(GENERIC); |
|
905 } |
|
906 } |
|
907 |
|
908 static const U32 LL_base[MaxLL+1] = { |
|
909 0, 1, 2, 3, 4, 5, 6, 7, |
|
910 8, 9, 10, 11, 12, 13, 14, 15, |
|
911 16, 18, 20, 22, 24, 28, 32, 40, |
|
912 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, |
|
913 0x2000, 0x4000, 0x8000, 0x10000 }; |
|
914 |
|
915 static const U32 OF_base[MaxOff+1] = { |
|
916 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, |
|
917 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, |
|
918 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, |
|
919 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD }; |
|
920 |
|
921 static const U32 OF_bits[MaxOff+1] = { |
|
922 0, 1, 2, 3, 4, 5, 6, 7, |
|
923 8, 9, 10, 11, 12, 13, 14, 15, |
|
924 16, 17, 18, 19, 20, 21, 22, 23, |
|
925 24, 25, 26, 27, 28, 29, 30, 31 }; |
|
926 |
|
927 static const U32 ML_base[MaxML+1] = { |
|
928 3, 4, 5, 6, 7, 8, 9, 10, |
|
929 11, 12, 13, 14, 15, 16, 17, 18, |
|
930 19, 20, 21, 22, 23, 24, 25, 26, |
|
931 27, 28, 29, 30, 31, 32, 33, 34, |
|
932 35, 37, 39, 41, 43, 47, 51, 59, |
|
933 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, |
|
934 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; |
|
935 |
725 |
936 |
726 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, |
937 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, |
727 const void* src, size_t srcSize) |
938 const void* src, size_t srcSize) |
728 { |
939 { |
729 const BYTE* const istart = (const BYTE* const)src; |
940 const BYTE* const istart = (const BYTE* const)src; |
730 const BYTE* const iend = istart + srcSize; |
941 const BYTE* const iend = istart + srcSize; |
731 const BYTE* ip = istart; |
942 const BYTE* ip = istart; |
|
943 DEBUGLOG(5, "ZSTD_decodeSeqHeaders"); |
732 |
944 |
733 /* check */ |
945 /* check */ |
734 if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong); |
946 if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong); |
735 |
947 |
736 /* SeqHead */ |
948 /* SeqHead */ |
844 while (op < oMatchEnd) *op++ = *match++; |
1069 while (op < oMatchEnd) *op++ = *match++; |
845 return sequenceLength; |
1070 return sequenceLength; |
846 } |
1071 } |
847 |
1072 |
848 |
1073 |
849 |
1074 HINT_INLINE |
850 |
1075 size_t ZSTD_execSequence(BYTE* op, |
851 static seq_t ZSTD_decodeSequence(seqState_t* seqState) |
1076 BYTE* const oend, seq_t sequence, |
|
1077 const BYTE** litPtr, const BYTE* const litLimit, |
|
1078 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) |
|
1079 { |
|
1080 BYTE* const oLitEnd = op + sequence.litLength; |
|
1081 size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
|
1082 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
|
1083 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; |
|
1084 const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
|
1085 const BYTE* match = oLitEnd - sequence.offset; |
|
1086 |
|
1087 /* check */ |
|
1088 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ |
|
1089 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ |
|
1090 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); |
|
1091 |
|
1092 /* copy Literals */ |
|
1093 ZSTD_copy8(op, *litPtr); |
|
1094 if (sequence.litLength > 8) |
|
1095 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ |
|
1096 op = oLitEnd; |
|
1097 *litPtr = iLitEnd; /* update for next sequence */ |
|
1098 |
|
1099 /* copy Match */ |
|
1100 if (sequence.offset > (size_t)(oLitEnd - base)) { |
|
1101 /* offset beyond prefix -> go into extDict */ |
|
1102 if (sequence.offset > (size_t)(oLitEnd - vBase)) |
|
1103 return ERROR(corruption_detected); |
|
1104 match = dictEnd + (match - base); |
|
1105 if (match + sequence.matchLength <= dictEnd) { |
|
1106 memmove(oLitEnd, match, sequence.matchLength); |
|
1107 return sequenceLength; |
|
1108 } |
|
1109 /* span extDict & currentPrefixSegment */ |
|
1110 { size_t const length1 = dictEnd - match; |
|
1111 memmove(oLitEnd, match, length1); |
|
1112 op = oLitEnd + length1; |
|
1113 sequence.matchLength -= length1; |
|
1114 match = base; |
|
1115 if (op > oend_w || sequence.matchLength < MINMATCH) { |
|
1116 U32 i; |
|
1117 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; |
|
1118 return sequenceLength; |
|
1119 } |
|
1120 } } |
|
1121 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ |
|
1122 |
|
1123 /* match within prefix */ |
|
1124 if (sequence.offset < 8) { |
|
1125 /* close range match, overlap */ |
|
1126 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ |
|
1127 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ |
|
1128 int const sub2 = dec64table[sequence.offset]; |
|
1129 op[0] = match[0]; |
|
1130 op[1] = match[1]; |
|
1131 op[2] = match[2]; |
|
1132 op[3] = match[3]; |
|
1133 match += dec32table[sequence.offset]; |
|
1134 ZSTD_copy4(op+4, match); |
|
1135 match -= sub2; |
|
1136 } else { |
|
1137 ZSTD_copy8(op, match); |
|
1138 } |
|
1139 op += 8; match += 8; |
|
1140 |
|
1141 if (oMatchEnd > oend-(16-MINMATCH)) { |
|
1142 if (op < oend_w) { |
|
1143 ZSTD_wildcopy(op, match, oend_w - op); |
|
1144 match += oend_w - op; |
|
1145 op = oend_w; |
|
1146 } |
|
1147 while (op < oMatchEnd) *op++ = *match++; |
|
1148 } else { |
|
1149 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ |
|
1150 } |
|
1151 return sequenceLength; |
|
1152 } |
|
1153 |
|
1154 |
|
1155 HINT_INLINE |
|
1156 size_t ZSTD_execSequenceLong(BYTE* op, |
|
1157 BYTE* const oend, seq_t sequence, |
|
1158 const BYTE** litPtr, const BYTE* const litLimit, |
|
1159 const BYTE* const prefixStart, const BYTE* const dictStart, const BYTE* const dictEnd) |
|
1160 { |
|
1161 BYTE* const oLitEnd = op + sequence.litLength; |
|
1162 size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
|
1163 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
|
1164 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; |
|
1165 const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
|
1166 const BYTE* match = sequence.match; |
|
1167 |
|
1168 /* check */ |
|
1169 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ |
|
1170 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ |
|
1171 if (oLitEnd > oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, dictStart, dictEnd); |
|
1172 |
|
1173 /* copy Literals */ |
|
1174 ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */ |
|
1175 if (sequence.litLength > 8) |
|
1176 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ |
|
1177 op = oLitEnd; |
|
1178 *litPtr = iLitEnd; /* update for next sequence */ |
|
1179 |
|
1180 /* copy Match */ |
|
1181 if (sequence.offset > (size_t)(oLitEnd - prefixStart)) { |
|
1182 /* offset beyond prefix */ |
|
1183 if (sequence.offset > (size_t)(oLitEnd - dictStart)) return ERROR(corruption_detected); |
|
1184 if (match + sequence.matchLength <= dictEnd) { |
|
1185 memmove(oLitEnd, match, sequence.matchLength); |
|
1186 return sequenceLength; |
|
1187 } |
|
1188 /* span extDict & currentPrefixSegment */ |
|
1189 { size_t const length1 = dictEnd - match; |
|
1190 memmove(oLitEnd, match, length1); |
|
1191 op = oLitEnd + length1; |
|
1192 sequence.matchLength -= length1; |
|
1193 match = prefixStart; |
|
1194 if (op > oend_w || sequence.matchLength < MINMATCH) { |
|
1195 U32 i; |
|
1196 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; |
|
1197 return sequenceLength; |
|
1198 } |
|
1199 } } |
|
1200 assert(op <= oend_w); |
|
1201 assert(sequence.matchLength >= MINMATCH); |
|
1202 |
|
1203 /* match within prefix */ |
|
1204 if (sequence.offset < 8) { |
|
1205 /* close range match, overlap */ |
|
1206 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ |
|
1207 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */ |
|
1208 int const sub2 = dec64table[sequence.offset]; |
|
1209 op[0] = match[0]; |
|
1210 op[1] = match[1]; |
|
1211 op[2] = match[2]; |
|
1212 op[3] = match[3]; |
|
1213 match += dec32table[sequence.offset]; |
|
1214 ZSTD_copy4(op+4, match); |
|
1215 match -= sub2; |
|
1216 } else { |
|
1217 ZSTD_copy8(op, match); |
|
1218 } |
|
1219 op += 8; match += 8; |
|
1220 |
|
1221 if (oMatchEnd > oend-(16-MINMATCH)) { |
|
1222 if (op < oend_w) { |
|
1223 ZSTD_wildcopy(op, match, oend_w - op); |
|
1224 match += oend_w - op; |
|
1225 op = oend_w; |
|
1226 } |
|
1227 while (op < oMatchEnd) *op++ = *match++; |
|
1228 } else { |
|
1229 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ |
|
1230 } |
|
1231 return sequenceLength; |
|
1232 } |
|
1233 |
|
1234 static void |
|
1235 ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt) |
|
1236 { |
|
1237 const void* ptr = dt; |
|
1238 const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr; |
|
1239 DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog); |
|
1240 DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits", |
|
1241 (U32)DStatePtr->state, DTableH->tableLog); |
|
1242 BIT_reloadDStream(bitD); |
|
1243 DStatePtr->table = dt + 1; |
|
1244 } |
|
1245 |
|
1246 FORCE_INLINE_TEMPLATE void |
|
1247 ZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD) |
|
1248 { |
|
1249 ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state]; |
|
1250 U32 const nbBits = DInfo.nbBits; |
|
1251 size_t const lowBits = BIT_readBits(bitD, nbBits); |
|
1252 DStatePtr->state = DInfo.nextState + lowBits; |
|
1253 } |
|
1254 |
|
1255 /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum |
|
1256 * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1) |
|
1257 * bits before reloading. This value is the maximum number of bytes we read |
|
1258 * after reloading when we are decoding long offets. |
|
1259 */ |
|
1260 #define LONG_OFFSETS_MAX_EXTRA_BITS_32 \ |
|
1261 (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \ |
|
1262 ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \ |
|
1263 : 0) |
|
1264 |
|
1265 typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e; |
|
1266 |
|
1267 FORCE_INLINE_TEMPLATE seq_t |
|
1268 ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) |
852 { |
1269 { |
853 seq_t seq; |
1270 seq_t seq; |
854 |
1271 U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; |
855 U32 const llCode = FSE_peekSymbol(&seqState->stateLL); |
1272 U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; |
856 U32 const mlCode = FSE_peekSymbol(&seqState->stateML); |
1273 U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; |
857 U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ |
|
858 |
|
859 U32 const llBits = LL_bits[llCode]; |
|
860 U32 const mlBits = ML_bits[mlCode]; |
|
861 U32 const ofBits = ofCode; |
|
862 U32 const totalBits = llBits+mlBits+ofBits; |
1274 U32 const totalBits = llBits+mlBits+ofBits; |
863 |
1275 U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; |
864 static const U32 LL_base[MaxLL+1] = { |
1276 U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; |
865 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
1277 U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; |
866 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, |
|
867 0x2000, 0x4000, 0x8000, 0x10000 }; |
|
868 |
|
869 static const U32 ML_base[MaxML+1] = { |
|
870 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, |
|
871 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
|
872 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, |
|
873 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; |
|
874 |
|
875 static const U32 OF_base[MaxOff+1] = { |
|
876 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, |
|
877 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, |
|
878 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, |
|
879 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; |
|
880 |
1278 |
881 /* sequence */ |
1279 /* sequence */ |
882 { size_t offset; |
1280 { size_t offset; |
883 if (!ofCode) |
1281 if (!ofBits) |
884 offset = 0; |
1282 offset = 0; |
885 else { |
1283 else { |
886 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ |
1284 ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); |
887 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); |
1285 ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); |
888 } |
1286 assert(ofBits <= MaxOff); |
889 |
1287 if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) { |
890 if (ofCode <= 1) { |
1288 U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed); |
891 offset += (llCode==0); |
1289 offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); |
|
1290 BIT_reloadDStream(&seqState->DStream); |
|
1291 if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); |
|
1292 assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */ |
|
1293 } else { |
|
1294 offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ |
|
1295 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); |
|
1296 } |
|
1297 } |
|
1298 |
|
1299 if (ofBits <= 1) { |
|
1300 offset += (llBase==0); |
|
1301 if (offset) { |
|
1302 size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; |
|
1303 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ |
|
1304 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; |
|
1305 seqState->prevOffset[1] = seqState->prevOffset[0]; |
|
1306 seqState->prevOffset[0] = offset = temp; |
|
1307 } else { /* offset == 0 */ |
|
1308 offset = seqState->prevOffset[0]; |
|
1309 } |
|
1310 } else { |
|
1311 seqState->prevOffset[2] = seqState->prevOffset[1]; |
|
1312 seqState->prevOffset[1] = seqState->prevOffset[0]; |
|
1313 seqState->prevOffset[0] = offset; |
|
1314 } |
|
1315 seq.offset = offset; |
|
1316 } |
|
1317 |
|
1318 seq.matchLength = mlBase |
|
1319 + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0); /* <= 16 bits */ |
|
1320 if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) |
|
1321 BIT_reloadDStream(&seqState->DStream); |
|
1322 if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) |
|
1323 BIT_reloadDStream(&seqState->DStream); |
|
1324 /* Ensure there are enough bits to read the rest of data in 64-bit mode. */ |
|
1325 ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); |
|
1326 |
|
1327 seq.litLength = llBase |
|
1328 + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0); /* <= 16 bits */ |
|
1329 if (MEM_32bits()) |
|
1330 BIT_reloadDStream(&seqState->DStream); |
|
1331 |
|
1332 DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u", |
|
1333 (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset); |
|
1334 |
|
1335 /* ANS state update */ |
|
1336 ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ |
|
1337 ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ |
|
1338 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ |
|
1339 ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ |
|
1340 |
|
1341 return seq; |
|
1342 } |
|
1343 |
|
1344 FORCE_INLINE_TEMPLATE size_t |
|
1345 ZSTD_decompressSequences_body( ZSTD_DCtx* dctx, |
|
1346 void* dst, size_t maxDstSize, |
|
1347 const void* seqStart, size_t seqSize, int nbSeq, |
|
1348 const ZSTD_longOffset_e isLongOffset) |
|
1349 { |
|
1350 const BYTE* ip = (const BYTE*)seqStart; |
|
1351 const BYTE* const iend = ip + seqSize; |
|
1352 BYTE* const ostart = (BYTE* const)dst; |
|
1353 BYTE* const oend = ostart + maxDstSize; |
|
1354 BYTE* op = ostart; |
|
1355 const BYTE* litPtr = dctx->litPtr; |
|
1356 const BYTE* const litEnd = litPtr + dctx->litSize; |
|
1357 const BYTE* const base = (const BYTE*) (dctx->base); |
|
1358 const BYTE* const vBase = (const BYTE*) (dctx->vBase); |
|
1359 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); |
|
1360 DEBUGLOG(5, "ZSTD_decompressSequences"); |
|
1361 |
|
1362 /* Regen sequences */ |
|
1363 if (nbSeq) { |
|
1364 seqState_t seqState; |
|
1365 dctx->fseEntropy = 1; |
|
1366 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; } |
|
1367 CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); |
|
1368 ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); |
|
1369 ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); |
|
1370 ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); |
|
1371 |
|
1372 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { |
|
1373 nbSeq--; |
|
1374 { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset); |
|
1375 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); |
|
1376 DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize); |
|
1377 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; |
|
1378 op += oneSeqSize; |
|
1379 } } |
|
1380 |
|
1381 /* check if reached exact end */ |
|
1382 DEBUGLOG(5, "ZSTD_decompressSequences: after decode loop, remaining nbSeq : %i", nbSeq); |
|
1383 if (nbSeq) return ERROR(corruption_detected); |
|
1384 /* save reps for next block */ |
|
1385 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); } |
|
1386 } |
|
1387 |
|
1388 /* last literal segment */ |
|
1389 { size_t const lastLLSize = litEnd - litPtr; |
|
1390 if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); |
|
1391 memcpy(op, litPtr, lastLLSize); |
|
1392 op += lastLLSize; |
|
1393 } |
|
1394 |
|
1395 return op-ostart; |
|
1396 } |
|
1397 |
|
1398 static size_t |
|
1399 ZSTD_decompressSequences_default(ZSTD_DCtx* dctx, |
|
1400 void* dst, size_t maxDstSize, |
|
1401 const void* seqStart, size_t seqSize, int nbSeq, |
|
1402 const ZSTD_longOffset_e isLongOffset) |
|
1403 { |
|
1404 return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1405 } |
|
1406 |
|
1407 |
|
1408 |
|
1409 FORCE_INLINE_TEMPLATE seq_t |
|
1410 ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets) |
|
1411 { |
|
1412 seq_t seq; |
|
1413 U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits; |
|
1414 U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits; |
|
1415 U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits; |
|
1416 U32 const totalBits = llBits+mlBits+ofBits; |
|
1417 U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue; |
|
1418 U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue; |
|
1419 U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue; |
|
1420 |
|
1421 /* sequence */ |
|
1422 { size_t offset; |
|
1423 if (!ofBits) |
|
1424 offset = 0; |
|
1425 else { |
|
1426 ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1); |
|
1427 ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5); |
|
1428 assert(ofBits <= MaxOff); |
|
1429 if (MEM_32bits() && longOffsets) { |
|
1430 U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1); |
|
1431 offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits); |
|
1432 if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream); |
|
1433 if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits); |
|
1434 } else { |
|
1435 offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ |
|
1436 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); |
|
1437 } |
|
1438 } |
|
1439 |
|
1440 if (ofBits <= 1) { |
|
1441 offset += (llBase==0); |
892 if (offset) { |
1442 if (offset) { |
893 size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; |
1443 size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; |
894 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ |
1444 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ |
895 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; |
1445 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; |
896 seqState->prevOffset[1] = seqState->prevOffset[0]; |
1446 seqState->prevOffset[1] = seqState->prevOffset[0]; |
904 seqState->prevOffset[0] = offset; |
1454 seqState->prevOffset[0] = offset; |
905 } |
1455 } |
906 seq.offset = offset; |
1456 seq.offset = offset; |
907 } |
1457 } |
908 |
1458 |
909 seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ |
1459 seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ |
910 if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); |
1460 if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32)) |
911 |
1461 BIT_reloadDStream(&seqState->DStream); |
912 seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ |
1462 if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog))) |
913 if (MEM_32bits() || |
1463 BIT_reloadDStream(&seqState->DStream); |
914 (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); |
1464 /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */ |
|
1465 ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64); |
|
1466 |
|
1467 seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ |
|
1468 if (MEM_32bits()) |
|
1469 BIT_reloadDStream(&seqState->DStream); |
|
1470 |
|
1471 { size_t const pos = seqState->pos + seq.litLength; |
|
1472 const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart; |
|
1473 seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted. |
|
1474 * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */ |
|
1475 seqState->pos = pos + seq.matchLength; |
|
1476 } |
915 |
1477 |
916 /* ANS state update */ |
1478 /* ANS state update */ |
917 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ |
1479 ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ |
918 FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ |
1480 ZSTD_updateFseState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ |
919 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ |
1481 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ |
920 FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ |
1482 ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ |
921 |
1483 |
922 return seq; |
1484 return seq; |
923 } |
1485 } |
924 |
1486 |
925 |
1487 FORCE_INLINE_TEMPLATE size_t |
926 FORCE_INLINE |
1488 ZSTD_decompressSequencesLong_body( |
927 size_t ZSTD_execSequence(BYTE* op, |
|
928 BYTE* const oend, seq_t sequence, |
|
929 const BYTE** litPtr, const BYTE* const litLimit, |
|
930 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) |
|
931 { |
|
932 BYTE* const oLitEnd = op + sequence.litLength; |
|
933 size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
|
934 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
|
935 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; |
|
936 const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
|
937 const BYTE* match = oLitEnd - sequence.offset; |
|
938 |
|
939 /* check */ |
|
940 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ |
|
941 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ |
|
942 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); |
|
943 |
|
944 /* copy Literals */ |
|
945 ZSTD_copy8(op, *litPtr); |
|
946 if (sequence.litLength > 8) |
|
947 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ |
|
948 op = oLitEnd; |
|
949 *litPtr = iLitEnd; /* update for next sequence */ |
|
950 |
|
951 /* copy Match */ |
|
952 if (sequence.offset > (size_t)(oLitEnd - base)) { |
|
953 /* offset beyond prefix */ |
|
954 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); |
|
955 match += (dictEnd-base); |
|
956 if (match + sequence.matchLength <= dictEnd) { |
|
957 memmove(oLitEnd, match, sequence.matchLength); |
|
958 return sequenceLength; |
|
959 } |
|
960 /* span extDict & currentPrefixSegment */ |
|
961 { size_t const length1 = dictEnd - match; |
|
962 memmove(oLitEnd, match, length1); |
|
963 op = oLitEnd + length1; |
|
964 sequence.matchLength -= length1; |
|
965 match = base; |
|
966 if (op > oend_w || sequence.matchLength < MINMATCH) { |
|
967 U32 i; |
|
968 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; |
|
969 return sequenceLength; |
|
970 } |
|
971 } } |
|
972 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ |
|
973 |
|
974 /* match within prefix */ |
|
975 if (sequence.offset < 8) { |
|
976 /* close range match, overlap */ |
|
977 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ |
|
978 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ |
|
979 int const sub2 = dec64table[sequence.offset]; |
|
980 op[0] = match[0]; |
|
981 op[1] = match[1]; |
|
982 op[2] = match[2]; |
|
983 op[3] = match[3]; |
|
984 match += dec32table[sequence.offset]; |
|
985 ZSTD_copy4(op+4, match); |
|
986 match -= sub2; |
|
987 } else { |
|
988 ZSTD_copy8(op, match); |
|
989 } |
|
990 op += 8; match += 8; |
|
991 |
|
992 if (oMatchEnd > oend-(16-MINMATCH)) { |
|
993 if (op < oend_w) { |
|
994 ZSTD_wildcopy(op, match, oend_w - op); |
|
995 match += oend_w - op; |
|
996 op = oend_w; |
|
997 } |
|
998 while (op < oMatchEnd) *op++ = *match++; |
|
999 } else { |
|
1000 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ |
|
1001 } |
|
1002 return sequenceLength; |
|
1003 } |
|
1004 |
|
1005 |
|
1006 static size_t ZSTD_decompressSequences( |
|
1007 ZSTD_DCtx* dctx, |
1489 ZSTD_DCtx* dctx, |
1008 void* dst, size_t maxDstSize, |
1490 void* dst, size_t maxDstSize, |
1009 const void* seqStart, size_t seqSize) |
1491 const void* seqStart, size_t seqSize, int nbSeq, |
|
1492 const ZSTD_longOffset_e isLongOffset) |
1010 { |
1493 { |
1011 const BYTE* ip = (const BYTE*)seqStart; |
1494 const BYTE* ip = (const BYTE*)seqStart; |
1012 const BYTE* const iend = ip + seqSize; |
1495 const BYTE* const iend = ip + seqSize; |
1013 BYTE* const ostart = (BYTE* const)dst; |
1496 BYTE* const ostart = (BYTE* const)dst; |
1014 BYTE* const oend = ostart + maxDstSize; |
1497 BYTE* const oend = ostart + maxDstSize; |
1015 BYTE* op = ostart; |
1498 BYTE* op = ostart; |
1016 const BYTE* litPtr = dctx->litPtr; |
1499 const BYTE* litPtr = dctx->litPtr; |
1017 const BYTE* const litEnd = litPtr + dctx->litSize; |
1500 const BYTE* const litEnd = litPtr + dctx->litSize; |
1018 const BYTE* const base = (const BYTE*) (dctx->base); |
1501 const BYTE* const prefixStart = (const BYTE*) (dctx->base); |
1019 const BYTE* const vBase = (const BYTE*) (dctx->vBase); |
1502 const BYTE* const dictStart = (const BYTE*) (dctx->vBase); |
1020 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); |
1503 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); |
1021 int nbSeq; |
|
1022 |
|
1023 /* Build Decoding Tables */ |
|
1024 { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); |
|
1025 if (ZSTD_isError(seqHSize)) return seqHSize; |
|
1026 ip += seqHSize; |
|
1027 } |
|
1028 |
|
1029 /* Regen sequences */ |
|
1030 if (nbSeq) { |
|
1031 seqState_t seqState; |
|
1032 dctx->fseEntropy = 1; |
|
1033 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->rep[i]; } |
|
1034 CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected); |
|
1035 FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr); |
|
1036 FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr); |
|
1037 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr); |
|
1038 |
|
1039 for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) { |
|
1040 nbSeq--; |
|
1041 { seq_t const sequence = ZSTD_decodeSequence(&seqState); |
|
1042 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); |
|
1043 if (ZSTD_isError(oneSeqSize)) return oneSeqSize; |
|
1044 op += oneSeqSize; |
|
1045 } } |
|
1046 |
|
1047 /* check if reached exact end */ |
|
1048 if (nbSeq) return ERROR(corruption_detected); |
|
1049 /* save reps for next block */ |
|
1050 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->rep[i] = (U32)(seqState.prevOffset[i]); } |
|
1051 } |
|
1052 |
|
1053 /* last literal segment */ |
|
1054 { size_t const lastLLSize = litEnd - litPtr; |
|
1055 if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall); |
|
1056 memcpy(op, litPtr, lastLLSize); |
|
1057 op += lastLLSize; |
|
1058 } |
|
1059 |
|
1060 return op-ostart; |
|
1061 } |
|
1062 |
|
1063 |
|
1064 static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState) |
|
1065 { |
|
1066 seq_t seq; |
|
1067 |
|
1068 U32 const llCode = FSE_peekSymbol(&seqState->stateLL); |
|
1069 U32 const mlCode = FSE_peekSymbol(&seqState->stateML); |
|
1070 U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */ |
|
1071 |
|
1072 U32 const llBits = LL_bits[llCode]; |
|
1073 U32 const mlBits = ML_bits[mlCode]; |
|
1074 U32 const ofBits = ofCode; |
|
1075 U32 const totalBits = llBits+mlBits+ofBits; |
|
1076 |
|
1077 static const U32 LL_base[MaxLL+1] = { |
|
1078 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
|
1079 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, |
|
1080 0x2000, 0x4000, 0x8000, 0x10000 }; |
|
1081 |
|
1082 static const U32 ML_base[MaxML+1] = { |
|
1083 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, |
|
1084 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, |
|
1085 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, |
|
1086 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 }; |
|
1087 |
|
1088 static const U32 OF_base[MaxOff+1] = { |
|
1089 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, |
|
1090 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, |
|
1091 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, |
|
1092 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD }; |
|
1093 |
|
1094 /* sequence */ |
|
1095 { size_t offset; |
|
1096 if (!ofCode) |
|
1097 offset = 0; |
|
1098 else { |
|
1099 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */ |
|
1100 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); |
|
1101 } |
|
1102 |
|
1103 if (ofCode <= 1) { |
|
1104 offset += (llCode==0); |
|
1105 if (offset) { |
|
1106 size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset]; |
|
1107 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */ |
|
1108 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1]; |
|
1109 seqState->prevOffset[1] = seqState->prevOffset[0]; |
|
1110 seqState->prevOffset[0] = offset = temp; |
|
1111 } else { |
|
1112 offset = seqState->prevOffset[0]; |
|
1113 } |
|
1114 } else { |
|
1115 seqState->prevOffset[2] = seqState->prevOffset[1]; |
|
1116 seqState->prevOffset[1] = seqState->prevOffset[0]; |
|
1117 seqState->prevOffset[0] = offset; |
|
1118 } |
|
1119 seq.offset = offset; |
|
1120 } |
|
1121 |
|
1122 seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */ |
|
1123 if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream); |
|
1124 |
|
1125 seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */ |
|
1126 if (MEM_32bits() || |
|
1127 (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream); |
|
1128 |
|
1129 { size_t const pos = seqState->pos + seq.litLength; |
|
1130 seq.match = seqState->base + pos - seq.offset; /* single memory segment */ |
|
1131 if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */ |
|
1132 seqState->pos = pos + seq.matchLength; |
|
1133 } |
|
1134 |
|
1135 /* ANS state update */ |
|
1136 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */ |
|
1137 FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */ |
|
1138 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */ |
|
1139 FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */ |
|
1140 |
|
1141 return seq; |
|
1142 } |
|
1143 |
|
1144 FORCE_INLINE |
|
1145 size_t ZSTD_execSequenceLong(BYTE* op, |
|
1146 BYTE* const oend, seq_t sequence, |
|
1147 const BYTE** litPtr, const BYTE* const litLimit, |
|
1148 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) |
|
1149 { |
|
1150 BYTE* const oLitEnd = op + sequence.litLength; |
|
1151 size_t const sequenceLength = sequence.litLength + sequence.matchLength; |
|
1152 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ |
|
1153 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; |
|
1154 const BYTE* const iLitEnd = *litPtr + sequence.litLength; |
|
1155 const BYTE* match = sequence.match; |
|
1156 |
|
1157 /* check */ |
|
1158 #if 1 |
|
1159 if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */ |
|
1160 if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */ |
|
1161 if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd); |
|
1162 #endif |
|
1163 |
|
1164 /* copy Literals */ |
|
1165 ZSTD_copy8(op, *litPtr); |
|
1166 if (sequence.litLength > 8) |
|
1167 ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */ |
|
1168 op = oLitEnd; |
|
1169 *litPtr = iLitEnd; /* update for next sequence */ |
|
1170 |
|
1171 /* copy Match */ |
|
1172 #if 1 |
|
1173 if (sequence.offset > (size_t)(oLitEnd - base)) { |
|
1174 /* offset beyond prefix */ |
|
1175 if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected); |
|
1176 if (match + sequence.matchLength <= dictEnd) { |
|
1177 memmove(oLitEnd, match, sequence.matchLength); |
|
1178 return sequenceLength; |
|
1179 } |
|
1180 /* span extDict & currentPrefixSegment */ |
|
1181 { size_t const length1 = dictEnd - match; |
|
1182 memmove(oLitEnd, match, length1); |
|
1183 op = oLitEnd + length1; |
|
1184 sequence.matchLength -= length1; |
|
1185 match = base; |
|
1186 if (op > oend_w || sequence.matchLength < MINMATCH) { |
|
1187 U32 i; |
|
1188 for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i]; |
|
1189 return sequenceLength; |
|
1190 } |
|
1191 } } |
|
1192 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */ |
|
1193 #endif |
|
1194 |
|
1195 /* match within prefix */ |
|
1196 if (sequence.offset < 8) { |
|
1197 /* close range match, overlap */ |
|
1198 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ |
|
1199 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ |
|
1200 int const sub2 = dec64table[sequence.offset]; |
|
1201 op[0] = match[0]; |
|
1202 op[1] = match[1]; |
|
1203 op[2] = match[2]; |
|
1204 op[3] = match[3]; |
|
1205 match += dec32table[sequence.offset]; |
|
1206 ZSTD_copy4(op+4, match); |
|
1207 match -= sub2; |
|
1208 } else { |
|
1209 ZSTD_copy8(op, match); |
|
1210 } |
|
1211 op += 8; match += 8; |
|
1212 |
|
1213 if (oMatchEnd > oend-(16-MINMATCH)) { |
|
1214 if (op < oend_w) { |
|
1215 ZSTD_wildcopy(op, match, oend_w - op); |
|
1216 match += oend_w - op; |
|
1217 op = oend_w; |
|
1218 } |
|
1219 while (op < oMatchEnd) *op++ = *match++; |
|
1220 } else { |
|
1221 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ |
|
1222 } |
|
1223 return sequenceLength; |
|
1224 } |
|
1225 |
|
1226 static size_t ZSTD_decompressSequencesLong( |
|
1227 ZSTD_DCtx* dctx, |
|
1228 void* dst, size_t maxDstSize, |
|
1229 const void* seqStart, size_t seqSize) |
|
1230 { |
|
1231 const BYTE* ip = (const BYTE*)seqStart; |
|
1232 const BYTE* const iend = ip + seqSize; |
|
1233 BYTE* const ostart = (BYTE* const)dst; |
|
1234 BYTE* const oend = ostart + maxDstSize; |
|
1235 BYTE* op = ostart; |
|
1236 const BYTE* litPtr = dctx->litPtr; |
|
1237 const BYTE* const litEnd = litPtr + dctx->litSize; |
|
1238 const BYTE* const base = (const BYTE*) (dctx->base); |
|
1239 const BYTE* const vBase = (const BYTE*) (dctx->vBase); |
|
1240 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); |
|
1241 int nbSeq; |
|
1242 |
|
1243 /* Build Decoding Tables */ |
|
1244 { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize); |
|
1245 if (ZSTD_isError(seqHSize)) return seqHSize; |
|
1246 ip += seqHSize; |
|
1247 } |
|
1248 |
1504 |
1249 /* Regen sequences */ |
1505 /* Regen sequences */ |
1250 if (nbSeq) { |
1506 if (nbSeq) { |
1251 #define STORED_SEQS 4 |
1507 #define STORED_SEQS 4 |
1252 #define STOSEQ_MASK (STORED_SEQS-1) |
1508 #define STOSEQ_MASK (STORED_SEQS-1) |
1302 } |
1561 } |
1303 |
1562 |
1304 return op-ostart; |
1563 return op-ostart; |
1305 } |
1564 } |
1306 |
1565 |
|
1566 static size_t |
|
1567 ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx, |
|
1568 void* dst, size_t maxDstSize, |
|
1569 const void* seqStart, size_t seqSize, int nbSeq, |
|
1570 const ZSTD_longOffset_e isLongOffset) |
|
1571 { |
|
1572 return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1573 } |
|
1574 |
|
1575 |
|
1576 |
|
1577 #if DYNAMIC_BMI2 |
|
1578 |
|
1579 static TARGET_ATTRIBUTE("bmi2") size_t |
|
1580 ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx, |
|
1581 void* dst, size_t maxDstSize, |
|
1582 const void* seqStart, size_t seqSize, int nbSeq, |
|
1583 const ZSTD_longOffset_e isLongOffset) |
|
1584 { |
|
1585 return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1586 } |
|
1587 |
|
1588 static TARGET_ATTRIBUTE("bmi2") size_t |
|
1589 ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx, |
|
1590 void* dst, size_t maxDstSize, |
|
1591 const void* seqStart, size_t seqSize, int nbSeq, |
|
1592 const ZSTD_longOffset_e isLongOffset) |
|
1593 { |
|
1594 return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1595 } |
|
1596 |
|
1597 #endif |
|
1598 |
|
1599 typedef size_t (*ZSTD_decompressSequences_t)( |
|
1600 ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, |
|
1601 const void *seqStart, size_t seqSize, int nbSeq, |
|
1602 const ZSTD_longOffset_e isLongOffset); |
|
1603 |
|
1604 static size_t ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize, |
|
1605 const void* seqStart, size_t seqSize, int nbSeq, |
|
1606 const ZSTD_longOffset_e isLongOffset) |
|
1607 { |
|
1608 DEBUGLOG(5, "ZSTD_decompressSequences"); |
|
1609 #if DYNAMIC_BMI2 |
|
1610 if (dctx->bmi2) { |
|
1611 return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1612 } |
|
1613 #endif |
|
1614 return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1615 } |
|
1616 |
|
1617 static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx, |
|
1618 void* dst, size_t maxDstSize, |
|
1619 const void* seqStart, size_t seqSize, int nbSeq, |
|
1620 const ZSTD_longOffset_e isLongOffset) |
|
1621 { |
|
1622 DEBUGLOG(5, "ZSTD_decompressSequencesLong"); |
|
1623 #if DYNAMIC_BMI2 |
|
1624 if (dctx->bmi2) { |
|
1625 return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1626 } |
|
1627 #endif |
|
1628 return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset); |
|
1629 } |
|
1630 |
|
1631 /* ZSTD_getLongOffsetsShare() : |
|
1632 * condition : offTable must be valid |
|
1633 * @return : "share" of long offsets (arbitrarily defined as > (1<<23)) |
|
1634 * compared to maximum possible of (1<<OffFSELog) */ |
|
1635 static unsigned |
|
1636 ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable) |
|
1637 { |
|
1638 const void* ptr = offTable; |
|
1639 U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog; |
|
1640 const ZSTD_seqSymbol* table = offTable + 1; |
|
1641 U32 const max = 1 << tableLog; |
|
1642 U32 u, total = 0; |
|
1643 DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog); |
|
1644 |
|
1645 assert(max <= (1 << OffFSELog)); /* max not too large */ |
|
1646 for (u=0; u<max; u++) { |
|
1647 if (table[u].nbAdditionalBits > 22) total += 1; |
|
1648 } |
|
1649 |
|
1650 assert(tableLog <= OffFSELog); |
|
1651 total <<= (OffFSELog - tableLog); /* scale to OffFSELog */ |
|
1652 |
|
1653 return total; |
|
1654 } |
|
1655 |
1307 |
1656 |
1308 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, |
1657 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, |
1309 void* dst, size_t dstCapacity, |
1658 void* dst, size_t dstCapacity, |
1310 const void* src, size_t srcSize) |
1659 const void* src, size_t srcSize, const int frame) |
1311 { /* blockType == blockCompressed */ |
1660 { /* blockType == blockCompressed */ |
1312 const BYTE* ip = (const BYTE*)src; |
1661 const BYTE* ip = (const BYTE*)src; |
1313 |
1662 /* isLongOffset must be true if there are long offsets. |
1314 if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong); |
1663 * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN. |
1315 |
1664 * We don't expect that to be the case in 64-bit mode. |
1316 /* Decode literals sub-block */ |
1665 * In block mode, window size is not known, so we have to be conservative. (note: but it could be evaluated from current-lowLimit) |
|
1666 */ |
|
1667 ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))); |
|
1668 DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize); |
|
1669 |
|
1670 if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); |
|
1671 |
|
1672 /* Decode literals section */ |
1317 { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); |
1673 { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize); |
|
1674 DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize); |
1318 if (ZSTD_isError(litCSize)) return litCSize; |
1675 if (ZSTD_isError(litCSize)) return litCSize; |
1319 ip += litCSize; |
1676 ip += litCSize; |
1320 srcSize -= litCSize; |
1677 srcSize -= litCSize; |
1321 } |
1678 } |
1322 if (dctx->fParams.windowSize > (1<<23)) return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize); |
1679 |
1323 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); |
1680 /* Build Decoding Tables */ |
|
1681 { int nbSeq; |
|
1682 size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize); |
|
1683 if (ZSTD_isError(seqHSize)) return seqHSize; |
|
1684 ip += seqHSize; |
|
1685 srcSize -= seqHSize; |
|
1686 |
|
1687 if ( (!frame || dctx->fParams.windowSize > (1<<24)) |
|
1688 && (nbSeq>0) ) { /* could probably use a larger nbSeq limit */ |
|
1689 U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr); |
|
1690 U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */ |
|
1691 if (shareLongOffsets >= minShare) |
|
1692 return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); |
|
1693 } |
|
1694 |
|
1695 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset); |
|
1696 } |
1324 } |
1697 } |
1325 |
1698 |
1326 |
1699 |
1327 static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) |
1700 static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst) |
1328 { |
1701 { |
1631 dctx->base = dict; |
2163 dctx->base = dict; |
1632 dctx->previousDstEnd = (const char*)dict + dictSize; |
2164 dctx->previousDstEnd = (const char*)dict + dictSize; |
1633 return 0; |
2165 return 0; |
1634 } |
2166 } |
1635 |
2167 |
1636 static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* const dict, size_t const dictSize) |
2168 /* ZSTD_loadEntropy() : |
|
2169 * dict : must point at beginning of a valid zstd dictionary |
|
2170 * @return : size of entropy tables read */ |
|
2171 static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const dict, size_t const dictSize) |
1637 { |
2172 { |
1638 const BYTE* dictPtr = (const BYTE*)dict; |
2173 const BYTE* dictPtr = (const BYTE*)dict; |
1639 const BYTE* const dictEnd = dictPtr + dictSize; |
2174 const BYTE* const dictEnd = dictPtr + dictSize; |
1640 |
2175 |
1641 { size_t const hSize = HUF_readDTableX4(dctx->hufTable, dict, dictSize); |
2176 if (dictSize <= 8) return ERROR(dictionary_corrupted); |
|
2177 dictPtr += 8; /* skip header = magic + dictID */ |
|
2178 |
|
2179 |
|
2180 { size_t const hSize = HUF_readDTableX4_wksp( |
|
2181 entropy->hufTable, dictPtr, dictEnd - dictPtr, |
|
2182 entropy->workspace, sizeof(entropy->workspace)); |
1642 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); |
2183 if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); |
1643 dictPtr += hSize; |
2184 dictPtr += hSize; |
1644 } |
2185 } |
1645 |
2186 |
1646 { short offcodeNCount[MaxOff+1]; |
2187 { short offcodeNCount[MaxOff+1]; |
1647 U32 offcodeMaxValue=MaxOff, offcodeLog; |
2188 U32 offcodeMaxValue = MaxOff, offcodeLog; |
1648 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); |
2189 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr); |
1649 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); |
2190 if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); |
|
2191 if (offcodeMaxValue > MaxOff) return ERROR(dictionary_corrupted); |
1650 if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); |
2192 if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted); |
1651 CHECK_E(FSE_buildDTable(dctx->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted); |
2193 ZSTD_buildFSETable(entropy->OFTable, |
|
2194 offcodeNCount, offcodeMaxValue, |
|
2195 OF_base, OF_bits, |
|
2196 offcodeLog); |
1652 dictPtr += offcodeHeaderSize; |
2197 dictPtr += offcodeHeaderSize; |
1653 } |
2198 } |
1654 |
2199 |
1655 { short matchlengthNCount[MaxML+1]; |
2200 { short matchlengthNCount[MaxML+1]; |
1656 unsigned matchlengthMaxValue = MaxML, matchlengthLog; |
2201 unsigned matchlengthMaxValue = MaxML, matchlengthLog; |
1657 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); |
2202 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr); |
1658 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2203 if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); |
|
2204 if (matchlengthMaxValue > MaxML) return ERROR(dictionary_corrupted); |
1659 if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); |
2205 if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted); |
1660 CHECK_E(FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted); |
2206 ZSTD_buildFSETable(entropy->MLTable, |
|
2207 matchlengthNCount, matchlengthMaxValue, |
|
2208 ML_base, ML_bits, |
|
2209 matchlengthLog); |
1661 dictPtr += matchlengthHeaderSize; |
2210 dictPtr += matchlengthHeaderSize; |
1662 } |
2211 } |
1663 |
2212 |
1664 { short litlengthNCount[MaxLL+1]; |
2213 { short litlengthNCount[MaxLL+1]; |
1665 unsigned litlengthMaxValue = MaxLL, litlengthLog; |
2214 unsigned litlengthMaxValue = MaxLL, litlengthLog; |
1666 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); |
2215 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr); |
1667 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); |
2216 if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); |
|
2217 if (litlengthMaxValue > MaxLL) return ERROR(dictionary_corrupted); |
1668 if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); |
2218 if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted); |
1669 CHECK_E(FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted); |
2219 ZSTD_buildFSETable(entropy->LLTable, |
|
2220 litlengthNCount, litlengthMaxValue, |
|
2221 LL_base, LL_bits, |
|
2222 litlengthLog); |
1670 dictPtr += litlengthHeaderSize; |
2223 dictPtr += litlengthHeaderSize; |
1671 } |
2224 } |
1672 |
2225 |
1673 if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); |
2226 if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted); |
1674 dctx->rep[0] = MEM_readLE32(dictPtr+0); if (dctx->rep[0] == 0 || dctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted); |
2227 { int i; |
1675 dctx->rep[1] = MEM_readLE32(dictPtr+4); if (dctx->rep[1] == 0 || dctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted); |
2228 size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12)); |
1676 dctx->rep[2] = MEM_readLE32(dictPtr+8); if (dctx->rep[2] == 0 || dctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted); |
2229 for (i=0; i<3; i++) { |
1677 dictPtr += 12; |
2230 U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4; |
1678 |
2231 if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted); |
1679 dctx->litEntropy = dctx->fseEntropy = 1; |
2232 entropy->rep[i] = rep; |
|
2233 } } |
|
2234 |
1680 return dictPtr - (const BYTE*)dict; |
2235 return dictPtr - (const BYTE*)dict; |
1681 } |
2236 } |
1682 |
2237 |
1683 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
2238 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
1684 { |
2239 { |
1685 if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); |
2240 if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize); |
1686 { U32 const magic = MEM_readLE32(dict); |
2241 { U32 const magic = MEM_readLE32(dict); |
1687 if (magic != ZSTD_DICT_MAGIC) { |
2242 if (magic != ZSTD_MAGIC_DICTIONARY) { |
1688 return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ |
2243 return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */ |
1689 } } |
2244 } } |
1690 dctx->dictID = MEM_readLE32((const char*)dict + 4); |
2245 dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_frameIdSize); |
1691 |
2246 |
1692 /* load entropy tables */ |
2247 /* load entropy tables */ |
1693 dict = (const char*)dict + 8; |
2248 { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize); |
1694 dictSize -= 8; |
|
1695 { size_t const eSize = ZSTD_loadEntropy(dctx, dict, dictSize); |
|
1696 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted); |
2249 if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted); |
1697 dict = (const char*)dict + eSize; |
2250 dict = (const char*)dict + eSize; |
1698 dictSize -= eSize; |
2251 dictSize -= eSize; |
1699 } |
2252 } |
|
2253 dctx->litEntropy = dctx->fseEntropy = 1; |
1700 |
2254 |
1701 /* reference dictionary content */ |
2255 /* reference dictionary content */ |
1702 return ZSTD_refDictContent(dctx, dict, dictSize); |
2256 return ZSTD_refDictContent(dctx, dict, dictSize); |
1703 } |
2257 } |
1704 |
2258 |
|
2259 /* Note : this function cannot fail */ |
|
2260 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx) |
|
2261 { |
|
2262 assert(dctx != NULL); |
|
2263 dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */ |
|
2264 dctx->stage = ZSTDds_getFrameHeaderSize; |
|
2265 dctx->decodedSize = 0; |
|
2266 dctx->previousDstEnd = NULL; |
|
2267 dctx->base = NULL; |
|
2268 dctx->vBase = NULL; |
|
2269 dctx->dictEnd = NULL; |
|
2270 dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ |
|
2271 dctx->litEntropy = dctx->fseEntropy = 0; |
|
2272 dctx->dictID = 0; |
|
2273 ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue)); |
|
2274 memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */ |
|
2275 dctx->LLTptr = dctx->entropy.LLTable; |
|
2276 dctx->MLTptr = dctx->entropy.MLTable; |
|
2277 dctx->OFTptr = dctx->entropy.OFTable; |
|
2278 dctx->HUFptr = dctx->entropy.hufTable; |
|
2279 return 0; |
|
2280 } |
|
2281 |
1705 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
2282 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
1706 { |
2283 { |
1707 CHECK_F(ZSTD_decompressBegin(dctx)); |
2284 CHECK_F( ZSTD_decompressBegin(dctx) ); |
1708 if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted); |
2285 if (dict && dictSize) |
|
2286 CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted); |
1709 return 0; |
2287 return 0; |
1710 } |
2288 } |
1711 |
2289 |
1712 |
2290 |
1713 /* ====== ZSTD_DDict ====== */ |
2291 /* ====== ZSTD_DDict ====== */ |
1714 |
2292 |
1715 struct ZSTD_DDict_s { |
2293 struct ZSTD_DDict_s { |
1716 void* dictBuffer; |
2294 void* dictBuffer; |
1717 const void* dictContent; |
2295 const void* dictContent; |
1718 size_t dictSize; |
2296 size_t dictSize; |
1719 ZSTD_DCtx* refContext; |
2297 ZSTD_entropyDTables_t entropy; |
|
2298 U32 dictID; |
|
2299 U32 entropyPresent; |
|
2300 ZSTD_customMem cMem; |
1720 }; /* typedef'd to ZSTD_DDict within "zstd.h" */ |
2301 }; /* typedef'd to ZSTD_DDict within "zstd.h" */ |
1721 |
2302 |
1722 ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem) |
2303 static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict) |
1723 { |
2304 { |
1724 if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem; |
2305 return ddict->dictContent; |
1725 if (!customMem.customAlloc || !customMem.customFree) return NULL; |
2306 } |
|
2307 |
|
2308 static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict) |
|
2309 { |
|
2310 return ddict->dictSize; |
|
2311 } |
|
2312 |
|
2313 size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict) |
|
2314 { |
|
2315 CHECK_F( ZSTD_decompressBegin(dstDCtx) ); |
|
2316 if (ddict) { /* support begin on NULL */ |
|
2317 dstDCtx->dictID = ddict->dictID; |
|
2318 dstDCtx->base = ddict->dictContent; |
|
2319 dstDCtx->vBase = ddict->dictContent; |
|
2320 dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize; |
|
2321 dstDCtx->previousDstEnd = dstDCtx->dictEnd; |
|
2322 if (ddict->entropyPresent) { |
|
2323 dstDCtx->litEntropy = 1; |
|
2324 dstDCtx->fseEntropy = 1; |
|
2325 dstDCtx->LLTptr = ddict->entropy.LLTable; |
|
2326 dstDCtx->MLTptr = ddict->entropy.MLTable; |
|
2327 dstDCtx->OFTptr = ddict->entropy.OFTable; |
|
2328 dstDCtx->HUFptr = ddict->entropy.hufTable; |
|
2329 dstDCtx->entropy.rep[0] = ddict->entropy.rep[0]; |
|
2330 dstDCtx->entropy.rep[1] = ddict->entropy.rep[1]; |
|
2331 dstDCtx->entropy.rep[2] = ddict->entropy.rep[2]; |
|
2332 } else { |
|
2333 dstDCtx->litEntropy = 0; |
|
2334 dstDCtx->fseEntropy = 0; |
|
2335 } |
|
2336 } |
|
2337 return 0; |
|
2338 } |
|
2339 |
|
2340 static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict, ZSTD_dictContentType_e dictContentType) |
|
2341 { |
|
2342 ddict->dictID = 0; |
|
2343 ddict->entropyPresent = 0; |
|
2344 if (dictContentType == ZSTD_dct_rawContent) return 0; |
|
2345 |
|
2346 if (ddict->dictSize < 8) { |
|
2347 if (dictContentType == ZSTD_dct_fullDict) |
|
2348 return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ |
|
2349 return 0; /* pure content mode */ |
|
2350 } |
|
2351 { U32 const magic = MEM_readLE32(ddict->dictContent); |
|
2352 if (magic != ZSTD_MAGIC_DICTIONARY) { |
|
2353 if (dictContentType == ZSTD_dct_fullDict) |
|
2354 return ERROR(dictionary_corrupted); /* only accept specified dictionaries */ |
|
2355 return 0; /* pure content mode */ |
|
2356 } |
|
2357 } |
|
2358 ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_frameIdSize); |
|
2359 |
|
2360 /* load entropy tables */ |
|
2361 CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted ); |
|
2362 ddict->entropyPresent = 1; |
|
2363 return 0; |
|
2364 } |
|
2365 |
|
2366 |
|
2367 static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, |
|
2368 const void* dict, size_t dictSize, |
|
2369 ZSTD_dictLoadMethod_e dictLoadMethod, |
|
2370 ZSTD_dictContentType_e dictContentType) |
|
2371 { |
|
2372 if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) { |
|
2373 ddict->dictBuffer = NULL; |
|
2374 ddict->dictContent = dict; |
|
2375 } else { |
|
2376 void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem); |
|
2377 ddict->dictBuffer = internalBuffer; |
|
2378 ddict->dictContent = internalBuffer; |
|
2379 if (!internalBuffer) return ERROR(memory_allocation); |
|
2380 memcpy(internalBuffer, dict, dictSize); |
|
2381 } |
|
2382 ddict->dictSize = dictSize; |
|
2383 ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */ |
|
2384 |
|
2385 /* parse dictionary content */ |
|
2386 CHECK_F( ZSTD_loadEntropy_inDDict(ddict, dictContentType) ); |
|
2387 |
|
2388 return 0; |
|
2389 } |
|
2390 |
|
2391 ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, |
|
2392 ZSTD_dictLoadMethod_e dictLoadMethod, |
|
2393 ZSTD_dictContentType_e dictContentType, |
|
2394 ZSTD_customMem customMem) |
|
2395 { |
|
2396 if (!customMem.customAlloc ^ !customMem.customFree) return NULL; |
1726 |
2397 |
1727 { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem); |
2398 { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem); |
1728 ZSTD_DCtx* const dctx = ZSTD_createDCtx_advanced(customMem); |
2399 if (!ddict) return NULL; |
1729 |
2400 ddict->cMem = customMem; |
1730 if (!ddict || !dctx) { |
2401 |
1731 ZSTD_free(ddict, customMem); |
2402 if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, dictLoadMethod, dictContentType) )) { |
1732 ZSTD_free(dctx, customMem); |
2403 ZSTD_freeDDict(ddict); |
1733 return NULL; |
2404 return NULL; |
1734 } |
2405 } |
1735 |
2406 |
1736 if ((byReference) || (!dict) || (!dictSize)) { |
|
1737 ddict->dictBuffer = NULL; |
|
1738 ddict->dictContent = dict; |
|
1739 } else { |
|
1740 void* const internalBuffer = ZSTD_malloc(dictSize, customMem); |
|
1741 if (!internalBuffer) { ZSTD_free(dctx, customMem); ZSTD_free(ddict, customMem); return NULL; } |
|
1742 memcpy(internalBuffer, dict, dictSize); |
|
1743 ddict->dictBuffer = internalBuffer; |
|
1744 ddict->dictContent = internalBuffer; |
|
1745 } |
|
1746 { size_t const errorCode = ZSTD_decompressBegin_usingDict(dctx, ddict->dictContent, dictSize); |
|
1747 if (ZSTD_isError(errorCode)) { |
|
1748 ZSTD_free(ddict->dictBuffer, customMem); |
|
1749 ZSTD_free(ddict, customMem); |
|
1750 ZSTD_free(dctx, customMem); |
|
1751 return NULL; |
|
1752 } } |
|
1753 |
|
1754 ddict->dictSize = dictSize; |
|
1755 ddict->refContext = dctx; |
|
1756 return ddict; |
2407 return ddict; |
1757 } |
2408 } |
1758 } |
2409 } |
1759 |
2410 |
1760 /*! ZSTD_createDDict() : |
2411 /*! ZSTD_createDDict() : |
1761 * Create a digested dictionary, ready to start decompression without startup delay. |
2412 * Create a digested dictionary, to start decompression without startup delay. |
1762 * `dict` can be released after `ZSTD_DDict` creation */ |
2413 * `dict` content is copied inside DDict. |
|
2414 * Consequently, `dict` can be released after `ZSTD_DDict` creation */ |
1763 ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) |
2415 ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize) |
1764 { |
2416 { |
1765 ZSTD_customMem const allocator = { NULL, NULL, NULL }; |
2417 ZSTD_customMem const allocator = { NULL, NULL, NULL }; |
1766 return ZSTD_createDDict_advanced(dict, dictSize, 0, allocator); |
2418 return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator); |
1767 } |
2419 } |
1768 |
|
1769 |
2420 |
1770 /*! ZSTD_createDDict_byReference() : |
2421 /*! ZSTD_createDDict_byReference() : |
1771 * Create a digested dictionary, ready to start decompression operation without startup delay. |
2422 * Create a digested dictionary, to start decompression without startup delay. |
1772 * Dictionary content is simply referenced, and therefore stays in dictBuffer. |
2423 * Dictionary content is simply referenced, it will be accessed during decompression. |
1773 * It is important that dictBuffer outlives DDict, it must remain read accessible throughout the lifetime of DDict */ |
2424 * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */ |
1774 ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) |
2425 ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize) |
1775 { |
2426 { |
1776 ZSTD_customMem const allocator = { NULL, NULL, NULL }; |
2427 ZSTD_customMem const allocator = { NULL, NULL, NULL }; |
1777 return ZSTD_createDDict_advanced(dictBuffer, dictSize, 1, allocator); |
2428 return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator); |
|
2429 } |
|
2430 |
|
2431 |
|
2432 const ZSTD_DDict* ZSTD_initStaticDDict( |
|
2433 void* workspace, size_t workspaceSize, |
|
2434 const void* dict, size_t dictSize, |
|
2435 ZSTD_dictLoadMethod_e dictLoadMethod, |
|
2436 ZSTD_dictContentType_e dictContentType) |
|
2437 { |
|
2438 size_t const neededSpace = |
|
2439 sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); |
|
2440 ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace; |
|
2441 assert(workspace != NULL); |
|
2442 assert(dict != NULL); |
|
2443 if ((size_t)workspace & 7) return NULL; /* 8-aligned */ |
|
2444 if (workspaceSize < neededSpace) return NULL; |
|
2445 if (dictLoadMethod == ZSTD_dlm_byCopy) { |
|
2446 memcpy(ddict+1, dict, dictSize); /* local copy */ |
|
2447 dict = ddict+1; |
|
2448 } |
|
2449 if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, ZSTD_dlm_byRef, dictContentType) )) |
|
2450 return NULL; |
|
2451 return ddict; |
1778 } |
2452 } |
1779 |
2453 |
1780 |
2454 |
1781 size_t ZSTD_freeDDict(ZSTD_DDict* ddict) |
2455 size_t ZSTD_freeDDict(ZSTD_DDict* ddict) |
1782 { |
2456 { |
1783 if (ddict==NULL) return 0; /* support free on NULL */ |
2457 if (ddict==NULL) return 0; /* support free on NULL */ |
1784 { ZSTD_customMem const cMem = ddict->refContext->customMem; |
2458 { ZSTD_customMem const cMem = ddict->cMem; |
1785 ZSTD_freeDCtx(ddict->refContext); |
|
1786 ZSTD_free(ddict->dictBuffer, cMem); |
2459 ZSTD_free(ddict->dictBuffer, cMem); |
1787 ZSTD_free(ddict, cMem); |
2460 ZSTD_free(ddict, cMem); |
1788 return 0; |
2461 return 0; |
1789 } |
2462 } |
1790 } |
2463 } |
1791 |
2464 |
|
2465 /*! ZSTD_estimateDDictSize() : |
|
2466 * Estimate amount of memory that will be needed to create a dictionary for decompression. |
|
2467 * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */ |
|
2468 size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod) |
|
2469 { |
|
2470 return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize); |
|
2471 } |
|
2472 |
1792 size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) |
2473 size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict) |
1793 { |
2474 { |
1794 if (ddict==NULL) return 0; /* support sizeof on NULL */ |
2475 if (ddict==NULL) return 0; /* support sizeof on NULL */ |
1795 return sizeof(*ddict) + ZSTD_sizeof_DCtx(ddict->refContext) + (ddict->dictBuffer ? ddict->dictSize : 0) ; |
2476 return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ; |
1796 } |
2477 } |
1797 |
2478 |
1798 /*! ZSTD_getDictID_fromDict() : |
2479 /*! ZSTD_getDictID_fromDict() : |
1799 * Provides the dictID stored within dictionary. |
2480 * Provides the dictID stored within dictionary. |
1800 * if @return == 0, the dictionary is not conformant with Zstandard specification. |
2481 * if @return == 0, the dictionary is not conformant with Zstandard specification. |
1801 * It can still be loaded, but as a content-only dictionary. */ |
2482 * It can still be loaded, but as a content-only dictionary. */ |
1802 unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) |
2483 unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize) |
1803 { |
2484 { |
1804 if (dictSize < 8) return 0; |
2485 if (dictSize < 8) return 0; |
1805 if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0; |
2486 if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0; |
1806 return MEM_readLE32((const char*)dict + 4); |
2487 return MEM_readLE32((const char*)dict + ZSTD_frameIdSize); |
1807 } |
2488 } |
1808 |
2489 |
1809 /*! ZSTD_getDictID_fromDDict() : |
2490 /*! ZSTD_getDictID_fromDDict() : |
1810 * Provides the dictID of the dictionary loaded into `ddict`. |
2491 * Provides the dictID of the dictionary loaded into `ddict`. |
1811 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. |
2492 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty. |
1841 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, |
2525 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx, |
1842 void* dst, size_t dstCapacity, |
2526 void* dst, size_t dstCapacity, |
1843 const void* src, size_t srcSize, |
2527 const void* src, size_t srcSize, |
1844 const ZSTD_DDict* ddict) |
2528 const ZSTD_DDict* ddict) |
1845 { |
2529 { |
1846 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) |
2530 /* pass content and size in case legacy frames are encountered */ |
1847 if (ZSTD_isLegacy(src, srcSize)) return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, ddict->dictContent, ddict->dictSize); |
2531 return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, |
1848 #endif |
2532 NULL, 0, |
1849 ZSTD_refDCtx(dctx, ddict->refContext); |
2533 ddict); |
1850 ZSTD_checkContinuity(dctx, dst); |
|
1851 return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize); |
|
1852 } |
2534 } |
1853 |
2535 |
1854 |
2536 |
1855 /*===================================== |
2537 /*===================================== |
1856 * Streaming decompression |
2538 * Streaming decompression |
1857 *====================================*/ |
2539 *====================================*/ |
1858 |
2540 |
1859 typedef enum { zdss_init, zdss_loadHeader, |
|
1860 zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage; |
|
1861 |
|
1862 /* *** Resource management *** */ |
|
1863 struct ZSTD_DStream_s { |
|
1864 ZSTD_DCtx* dctx; |
|
1865 ZSTD_DDict* ddictLocal; |
|
1866 const ZSTD_DDict* ddict; |
|
1867 ZSTD_frameParams fParams; |
|
1868 ZSTD_dStreamStage stage; |
|
1869 char* inBuff; |
|
1870 size_t inBuffSize; |
|
1871 size_t inPos; |
|
1872 size_t maxWindowSize; |
|
1873 char* outBuff; |
|
1874 size_t outBuffSize; |
|
1875 size_t outStart; |
|
1876 size_t outEnd; |
|
1877 size_t blockSize; |
|
1878 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */ |
|
1879 size_t lhSize; |
|
1880 ZSTD_customMem customMem; |
|
1881 void* legacyContext; |
|
1882 U32 previousLegacyVersion; |
|
1883 U32 legacyVersion; |
|
1884 U32 hostageByte; |
|
1885 }; /* typedef'd to ZSTD_DStream within "zstd.h" */ |
|
1886 |
|
1887 |
|
1888 ZSTD_DStream* ZSTD_createDStream(void) |
2541 ZSTD_DStream* ZSTD_createDStream(void) |
1889 { |
2542 { |
1890 return ZSTD_createDStream_advanced(defaultCustomMem); |
2543 DEBUGLOG(3, "ZSTD_createDStream"); |
|
2544 return ZSTD_createDStream_advanced(ZSTD_defaultCMem); |
|
2545 } |
|
2546 |
|
2547 ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize) |
|
2548 { |
|
2549 return ZSTD_initStaticDCtx(workspace, workspaceSize); |
1891 } |
2550 } |
1892 |
2551 |
1893 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) |
2552 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem) |
1894 { |
2553 { |
1895 ZSTD_DStream* zds; |
2554 return ZSTD_createDCtx_advanced(customMem); |
1896 |
|
1897 if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem; |
|
1898 if (!customMem.customAlloc || !customMem.customFree) return NULL; |
|
1899 |
|
1900 zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem); |
|
1901 if (zds==NULL) return NULL; |
|
1902 memset(zds, 0, sizeof(ZSTD_DStream)); |
|
1903 memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem)); |
|
1904 zds->dctx = ZSTD_createDCtx_advanced(customMem); |
|
1905 if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; } |
|
1906 zds->stage = zdss_init; |
|
1907 zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; |
|
1908 return zds; |
|
1909 } |
2555 } |
1910 |
2556 |
1911 size_t ZSTD_freeDStream(ZSTD_DStream* zds) |
2557 size_t ZSTD_freeDStream(ZSTD_DStream* zds) |
1912 { |
2558 { |
1913 if (zds==NULL) return 0; /* support free on null */ |
2559 return ZSTD_freeDCtx(zds); |
1914 { ZSTD_customMem const cMem = zds->customMem; |
|
1915 ZSTD_freeDCtx(zds->dctx); |
|
1916 ZSTD_freeDDict(zds->ddictLocal); |
|
1917 ZSTD_free(zds->inBuff, cMem); |
|
1918 ZSTD_free(zds->outBuff, cMem); |
|
1919 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1) |
|
1920 if (zds->legacyContext) |
|
1921 ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion); |
|
1922 #endif |
|
1923 ZSTD_free(zds, cMem); |
|
1924 return 0; |
|
1925 } |
|
1926 } |
2560 } |
1927 |
2561 |
1928 |
2562 |
1929 /* *** Initialization *** */ |
2563 /* *** Initialization *** */ |
1930 |
2564 |
1931 size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; } |
2565 size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; } |
1932 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; } |
2566 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; } |
1933 |
2567 |
|
2568 size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType) |
|
2569 { |
|
2570 if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); |
|
2571 ZSTD_freeDDict(dctx->ddictLocal); |
|
2572 if (dict && dictSize >= 8) { |
|
2573 dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem); |
|
2574 if (dctx->ddictLocal == NULL) return ERROR(memory_allocation); |
|
2575 } else { |
|
2576 dctx->ddictLocal = NULL; |
|
2577 } |
|
2578 dctx->ddict = dctx->ddictLocal; |
|
2579 return 0; |
|
2580 } |
|
2581 |
|
2582 size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
|
2583 { |
|
2584 return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto); |
|
2585 } |
|
2586 |
|
2587 size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) |
|
2588 { |
|
2589 return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto); |
|
2590 } |
|
2591 |
|
2592 size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType) |
|
2593 { |
|
2594 return ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType); |
|
2595 } |
|
2596 |
|
2597 size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize) |
|
2598 { |
|
2599 return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent); |
|
2600 } |
|
2601 |
|
2602 |
|
2603 /* ZSTD_initDStream_usingDict() : |
|
2604 * return : expected size, aka ZSTD_frameHeaderSize_prefix. |
|
2605 * this function cannot fail */ |
1934 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize) |
2606 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize) |
1935 { |
2607 { |
1936 zds->stage = zdss_loadHeader; |
2608 DEBUGLOG(4, "ZSTD_initDStream_usingDict"); |
1937 zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; |
2609 zds->streamStage = zdss_init; |
1938 ZSTD_freeDDict(zds->ddictLocal); |
2610 CHECK_F( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) ); |
1939 if (dict && dictSize >= 8) { |
|
1940 zds->ddictLocal = ZSTD_createDDict(dict, dictSize); |
|
1941 if (zds->ddictLocal == NULL) return ERROR(memory_allocation); |
|
1942 } else zds->ddictLocal = NULL; |
|
1943 zds->ddict = zds->ddictLocal; |
|
1944 zds->legacyVersion = 0; |
|
1945 zds->hostageByte = 0; |
|
1946 return ZSTD_frameHeaderSize_prefix; |
2611 return ZSTD_frameHeaderSize_prefix; |
1947 } |
2612 } |
1948 |
2613 |
|
2614 /* note : this variant can't fail */ |
1949 size_t ZSTD_initDStream(ZSTD_DStream* zds) |
2615 size_t ZSTD_initDStream(ZSTD_DStream* zds) |
1950 { |
2616 { |
|
2617 DEBUGLOG(4, "ZSTD_initDStream"); |
1951 return ZSTD_initDStream_usingDict(zds, NULL, 0); |
2618 return ZSTD_initDStream_usingDict(zds, NULL, 0); |
1952 } |
2619 } |
1953 |
2620 |
1954 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict) /**< note : ddict will just be referenced, and must outlive decompression session */ |
2621 size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict) |
1955 { |
2622 { |
1956 size_t const initResult = ZSTD_initDStream(zds); |
2623 if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); |
1957 zds->ddict = ddict; |
2624 dctx->ddict = ddict; |
|
2625 return 0; |
|
2626 } |
|
2627 |
|
2628 /* ZSTD_initDStream_usingDDict() : |
|
2629 * ddict will just be referenced, and must outlive decompression session |
|
2630 * this function cannot fail */ |
|
2631 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict) |
|
2632 { |
|
2633 size_t const initResult = ZSTD_initDStream(dctx); |
|
2634 dctx->ddict = ddict; |
1958 return initResult; |
2635 return initResult; |
1959 } |
2636 } |
1960 |
2637 |
1961 size_t ZSTD_resetDStream(ZSTD_DStream* zds) |
2638 /* ZSTD_resetDStream() : |
1962 { |
2639 * return : expected size, aka ZSTD_frameHeaderSize_prefix. |
1963 zds->stage = zdss_loadHeader; |
2640 * this function cannot fail */ |
1964 zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0; |
2641 size_t ZSTD_resetDStream(ZSTD_DStream* dctx) |
1965 zds->legacyVersion = 0; |
2642 { |
1966 zds->hostageByte = 0; |
2643 DEBUGLOG(4, "ZSTD_resetDStream"); |
|
2644 dctx->streamStage = zdss_loadHeader; |
|
2645 dctx->lhSize = dctx->inPos = dctx->outStart = dctx->outEnd = 0; |
|
2646 dctx->legacyVersion = 0; |
|
2647 dctx->hostageByte = 0; |
1967 return ZSTD_frameHeaderSize_prefix; |
2648 return ZSTD_frameHeaderSize_prefix; |
1968 } |
2649 } |
1969 |
2650 |
1970 size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, |
2651 size_t ZSTD_setDStreamParameter(ZSTD_DStream* dctx, |
1971 ZSTD_DStreamParameter_e paramType, unsigned paramValue) |
2652 ZSTD_DStreamParameter_e paramType, unsigned paramValue) |
1972 { |
2653 { |
|
2654 if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); |
1973 switch(paramType) |
2655 switch(paramType) |
1974 { |
2656 { |
1975 default : return ERROR(parameter_unknown); |
2657 default : return ERROR(parameter_unsupported); |
1976 case DStream_p_maxWindowSize : zds->maxWindowSize = paramValue ? paramValue : (U32)(-1); break; |
2658 case DStream_p_maxWindowSize : |
|
2659 DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10); |
|
2660 dctx->maxWindowSize = paramValue ? paramValue : (U32)(-1); |
|
2661 break; |
1977 } |
2662 } |
1978 return 0; |
2663 return 0; |
1979 } |
2664 } |
1980 |
2665 |
1981 |
2666 size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize) |
1982 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds) |
2667 { |
1983 { |
2668 if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); |
1984 if (zds==NULL) return 0; /* support sizeof on NULL */ |
2669 dctx->maxWindowSize = maxWindowSize; |
1985 return sizeof(*zds) + ZSTD_sizeof_DCtx(zds->dctx) + ZSTD_sizeof_DDict(zds->ddictLocal) + zds->inBuffSize + zds->outBuffSize; |
2670 return 0; |
|
2671 } |
|
2672 |
|
2673 size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format) |
|
2674 { |
|
2675 DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format); |
|
2676 if (dctx->streamStage != zdss_init) return ERROR(stage_wrong); |
|
2677 dctx->format = format; |
|
2678 return 0; |
|
2679 } |
|
2680 |
|
2681 |
|
2682 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx) |
|
2683 { |
|
2684 return ZSTD_sizeof_DCtx(dctx); |
|
2685 } |
|
2686 |
|
2687 size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize) |
|
2688 { |
|
2689 size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX); |
|
2690 unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2); |
|
2691 unsigned long long const neededSize = MIN(frameContentSize, neededRBSize); |
|
2692 size_t const minRBSize = (size_t) neededSize; |
|
2693 if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge); |
|
2694 return minRBSize; |
|
2695 } |
|
2696 |
|
2697 size_t ZSTD_estimateDStreamSize(size_t windowSize) |
|
2698 { |
|
2699 size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX); |
|
2700 size_t const inBuffSize = blockSize; /* no block can be larger */ |
|
2701 size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN); |
|
2702 return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize; |
|
2703 } |
|
2704 |
|
2705 size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize) |
|
2706 { |
|
2707 U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */ |
|
2708 ZSTD_frameHeader zfh; |
|
2709 size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize); |
|
2710 if (ZSTD_isError(err)) return err; |
|
2711 if (err>0) return ERROR(srcSize_wrong); |
|
2712 if (zfh.windowSize > windowSizeMax) |
|
2713 return ERROR(frameParameter_windowTooLarge); |
|
2714 return ZSTD_estimateDStreamSize((size_t)zfh.windowSize); |
1986 } |
2715 } |
1987 |
2716 |
1988 |
2717 |
1989 /* ***** Decompression ***** */ |
2718 /* ***** Decompression ***** */ |
1990 |
2719 |
2004 char* const ostart = (char*)(output->dst) + output->pos; |
2733 char* const ostart = (char*)(output->dst) + output->pos; |
2005 char* const oend = (char*)(output->dst) + output->size; |
2734 char* const oend = (char*)(output->dst) + output->size; |
2006 char* op = ostart; |
2735 char* op = ostart; |
2007 U32 someMoreWork = 1; |
2736 U32 someMoreWork = 1; |
2008 |
2737 |
2009 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |
2738 DEBUGLOG(5, "ZSTD_decompressStream"); |
2010 if (zds->legacyVersion) |
2739 if (input->pos > input->size) { /* forbidden */ |
2011 return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); |
2740 DEBUGLOG(5, "in: pos: %u vs size: %u", |
2012 #endif |
2741 (U32)input->pos, (U32)input->size); |
|
2742 return ERROR(srcSize_wrong); |
|
2743 } |
|
2744 if (output->pos > output->size) { /* forbidden */ |
|
2745 DEBUGLOG(5, "out: pos: %u vs size: %u", |
|
2746 (U32)output->pos, (U32)output->size); |
|
2747 return ERROR(dstSize_tooSmall); |
|
2748 } |
|
2749 DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos)); |
2013 |
2750 |
2014 while (someMoreWork) { |
2751 while (someMoreWork) { |
2015 switch(zds->stage) |
2752 switch(zds->streamStage) |
2016 { |
2753 { |
2017 case zdss_init : |
2754 case zdss_init : |
|
2755 DEBUGLOG(5, "stage zdss_init => transparent reset "); |
2018 ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ |
2756 ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ |
2019 /* fall-through */ |
2757 /* fall-through */ |
2020 |
2758 |
2021 case zdss_loadHeader : |
2759 case zdss_loadHeader : |
2022 { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); |
2760 DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip)); |
2023 if (ZSTD_isError(hSize)) |
|
2024 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |
2761 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |
2025 { U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart); |
2762 if (zds->legacyVersion) { |
|
2763 /* legacy support is incompatible with static dctx */ |
|
2764 if (zds->staticSize) return ERROR(memory_allocation); |
|
2765 { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); |
|
2766 if (hint==0) zds->streamStage = zdss_init; |
|
2767 return hint; |
|
2768 } } |
|
2769 #endif |
|
2770 { size_t const hSize = ZSTD_getFrameHeader_internal(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format); |
|
2771 DEBUGLOG(5, "header size : %u", (U32)hSize); |
|
2772 if (ZSTD_isError(hSize)) { |
|
2773 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) |
|
2774 U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart); |
2026 if (legacyVersion) { |
2775 if (legacyVersion) { |
2027 const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL; |
2776 const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL; |
2028 size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0; |
2777 size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0; |
2029 CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion, |
2778 DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion); |
2030 dict, dictSize)); |
2779 /* legacy support is incompatible with static dctx */ |
|
2780 if (zds->staticSize) return ERROR(memory_allocation); |
|
2781 CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, |
|
2782 zds->previousLegacyVersion, legacyVersion, |
|
2783 dict, dictSize)); |
2031 zds->legacyVersion = zds->previousLegacyVersion = legacyVersion; |
2784 zds->legacyVersion = zds->previousLegacyVersion = legacyVersion; |
2032 return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input); |
2785 { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input); |
2033 } else { |
2786 if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */ |
2034 return hSize; /* error */ |
2787 return hint; |
2035 } } |
2788 } } |
2036 #else |
|
2037 return hSize; |
|
2038 #endif |
2789 #endif |
|
2790 return hSize; /* error */ |
|
2791 } |
2039 if (hSize != 0) { /* need more input */ |
2792 if (hSize != 0) { /* need more input */ |
2040 size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ |
2793 size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */ |
2041 if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */ |
2794 size_t const remainingInput = (size_t)(iend-ip); |
2042 memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip); |
2795 assert(iend >= ip); |
2043 zds->lhSize += iend-ip; |
2796 if (toLoad > remainingInput) { /* not enough input to load full header */ |
|
2797 if (remainingInput > 0) { |
|
2798 memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput); |
|
2799 zds->lhSize += remainingInput; |
|
2800 } |
2044 input->pos = input->size; |
2801 input->pos = input->size; |
2045 return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ |
2802 return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */ |
2046 } |
2803 } |
|
2804 assert(ip != NULL); |
2047 memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; |
2805 memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad; |
2048 break; |
2806 break; |
2049 } } |
2807 } } |
2050 |
2808 |
2051 /* Consume header */ |
2809 /* check for single-pass mode opportunity */ |
2052 { const ZSTD_DCtx* refContext = zds->ddict ? zds->ddict->refContext : NULL; |
2810 if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */ |
2053 ZSTD_refDCtx(zds->dctx, refContext); |
2811 && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) { |
|
2812 size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart); |
|
2813 if (cSize <= (size_t)(iend-istart)) { |
|
2814 /* shortcut : using single-pass mode */ |
|
2815 size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds->ddict); |
|
2816 if (ZSTD_isError(decompressedSize)) return decompressedSize; |
|
2817 DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()") |
|
2818 ip = istart + cSize; |
|
2819 op += decompressedSize; |
|
2820 zds->expected = 0; |
|
2821 zds->streamStage = zdss_init; |
|
2822 someMoreWork = 0; |
|
2823 break; |
|
2824 } } |
|
2825 |
|
2826 /* Consume header (see ZSTDds_decodeFrameHeader) */ |
|
2827 DEBUGLOG(4, "Consume header"); |
|
2828 CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict)); |
|
2829 |
|
2830 if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */ |
|
2831 zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_frameIdSize); |
|
2832 zds->stage = ZSTDds_skipFrame; |
|
2833 } else { |
|
2834 CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize)); |
|
2835 zds->expected = ZSTD_blockHeaderSize; |
|
2836 zds->stage = ZSTDds_decodeBlockHeader; |
2054 } |
2837 } |
2055 { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */ |
2838 |
2056 CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size)); |
2839 /* control buffer memory usage */ |
2057 { size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); |
2840 DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)", |
2058 CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size)); |
2841 (U32)(zds->fParams.windowSize >>10), |
2059 } } |
2842 (U32)(zds->maxWindowSize >> 10) ); |
2060 |
|
2061 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); |
2843 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN); |
2062 if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); |
2844 if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge); |
2063 |
2845 |
2064 /* Adapt buffer sizes to frame header instructions */ |
2846 /* Adapt buffer sizes to frame header instructions */ |
2065 { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX); |
2847 { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */); |
2066 size_t const neededOutSize = zds->fParams.windowSize + blockSize; |
2848 size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize); |
2067 zds->blockSize = blockSize; |
2849 if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) { |
2068 if (zds->inBuffSize < blockSize) { |
2850 size_t const bufferSize = neededInBuffSize + neededOutBuffSize; |
2069 ZSTD_free(zds->inBuff, zds->customMem); |
2851 DEBUGLOG(4, "inBuff : from %u to %u", |
2070 zds->inBuffSize = blockSize; |
2852 (U32)zds->inBuffSize, (U32)neededInBuffSize); |
2071 zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem); |
2853 DEBUGLOG(4, "outBuff : from %u to %u", |
2072 if (zds->inBuff == NULL) return ERROR(memory_allocation); |
2854 (U32)zds->outBuffSize, (U32)neededOutBuffSize); |
2073 } |
2855 if (zds->staticSize) { /* static DCtx */ |
2074 if (zds->outBuffSize < neededOutSize) { |
2856 DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize); |
2075 ZSTD_free(zds->outBuff, zds->customMem); |
2857 assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */ |
2076 zds->outBuffSize = neededOutSize; |
2858 if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx)) |
2077 zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem); |
2859 return ERROR(memory_allocation); |
2078 if (zds->outBuff == NULL) return ERROR(memory_allocation); |
2860 } else { |
|
2861 ZSTD_free(zds->inBuff, zds->customMem); |
|
2862 zds->inBuffSize = 0; |
|
2863 zds->outBuffSize = 0; |
|
2864 zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem); |
|
2865 if (zds->inBuff == NULL) return ERROR(memory_allocation); |
|
2866 } |
|
2867 zds->inBuffSize = neededInBuffSize; |
|
2868 zds->outBuff = zds->inBuff + zds->inBuffSize; |
|
2869 zds->outBuffSize = neededOutBuffSize; |
2079 } } |
2870 } } |
2080 zds->stage = zdss_read; |
2871 zds->streamStage = zdss_read; |
2081 /* pass-through */ |
2872 /* fall-through */ |
2082 |
2873 |
2083 case zdss_read: |
2874 case zdss_read: |
2084 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); |
2875 DEBUGLOG(5, "stage zdss_read"); |
|
2876 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); |
|
2877 DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize); |
2085 if (neededInSize==0) { /* end of frame */ |
2878 if (neededInSize==0) { /* end of frame */ |
2086 zds->stage = zdss_init; |
2879 zds->streamStage = zdss_init; |
2087 someMoreWork = 0; |
2880 someMoreWork = 0; |
2088 break; |
2881 break; |
2089 } |
2882 } |
2090 if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ |
2883 if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */ |
2091 const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx); |
2884 int const isSkipFrame = ZSTD_isSkipFrame(zds); |
2092 size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, |
2885 size_t const decodedSize = ZSTD_decompressContinue(zds, |
2093 zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), |
2886 zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), |
2094 ip, neededInSize); |
2887 ip, neededInSize); |
2095 if (ZSTD_isError(decodedSize)) return decodedSize; |
2888 if (ZSTD_isError(decodedSize)) return decodedSize; |
2096 ip += neededInSize; |
2889 ip += neededInSize; |
2097 if (!decodedSize && !isSkipFrame) break; /* this was just a header */ |
2890 if (!decodedSize && !isSkipFrame) break; /* this was just a header */ |
2098 zds->outEnd = zds->outStart + decodedSize; |
2891 zds->outEnd = zds->outStart + decodedSize; |
2099 zds->stage = zdss_flush; |
2892 zds->streamStage = zdss_flush; |
2100 break; |
2893 break; |
|
2894 } } |
|
2895 if (ip==iend) { someMoreWork = 0; break; } /* no more input */ |
|
2896 zds->streamStage = zdss_load; |
|
2897 /* fall-through */ |
|
2898 |
|
2899 case zdss_load: |
|
2900 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds); |
|
2901 size_t const toLoad = neededInSize - zds->inPos; |
|
2902 int const isSkipFrame = ZSTD_isSkipFrame(zds); |
|
2903 size_t loadedSize; |
|
2904 if (isSkipFrame) { |
|
2905 loadedSize = MIN(toLoad, (size_t)(iend-ip)); |
|
2906 } else { |
|
2907 if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */ |
|
2908 loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip); |
2101 } |
2909 } |
2102 if (ip==iend) { someMoreWork = 0; break; } /* no more input */ |
|
2103 zds->stage = zdss_load; |
|
2104 /* pass-through */ |
|
2105 } |
|
2106 |
|
2107 case zdss_load: |
|
2108 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx); |
|
2109 size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */ |
|
2110 size_t loadedSize; |
|
2111 if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */ |
|
2112 loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip); |
|
2113 ip += loadedSize; |
2910 ip += loadedSize; |
2114 zds->inPos += loadedSize; |
2911 zds->inPos += loadedSize; |
2115 if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ |
2912 if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */ |
2116 |
2913 |
2117 /* decode loaded input */ |
2914 /* decode loaded input */ |
2118 { const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx); |
2915 { size_t const decodedSize = ZSTD_decompressContinue(zds, |
2119 size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, |
|
2120 zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart, |
2916 zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart, |
2121 zds->inBuff, neededInSize); |
2917 zds->inBuff, neededInSize); |
2122 if (ZSTD_isError(decodedSize)) return decodedSize; |
2918 if (ZSTD_isError(decodedSize)) return decodedSize; |
2123 zds->inPos = 0; /* input is consumed */ |
2919 zds->inPos = 0; /* input is consumed */ |
2124 if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; } /* this was just a header */ |
2920 if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; } /* this was just a header */ |
2125 zds->outEnd = zds->outStart + decodedSize; |
2921 zds->outEnd = zds->outStart + decodedSize; |
2126 zds->stage = zdss_flush; |
|
2127 /* pass-through */ |
|
2128 } } |
2922 } } |
|
2923 zds->streamStage = zdss_flush; |
|
2924 /* fall-through */ |
2129 |
2925 |
2130 case zdss_flush: |
2926 case zdss_flush: |
2131 { size_t const toFlushSize = zds->outEnd - zds->outStart; |
2927 { size_t const toFlushSize = zds->outEnd - zds->outStart; |
2132 size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize); |
2928 size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize); |
2133 op += flushedSize; |
2929 op += flushedSize; |
2134 zds->outStart += flushedSize; |
2930 zds->outStart += flushedSize; |
2135 if (flushedSize == toFlushSize) { /* flush completed */ |
2931 if (flushedSize == toFlushSize) { /* flush completed */ |
2136 zds->stage = zdss_read; |
2932 zds->streamStage = zdss_read; |
2137 if (zds->outStart + zds->blockSize > zds->outBuffSize) |
2933 if ( (zds->outBuffSize < zds->fParams.frameContentSize) |
|
2934 && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) { |
|
2935 DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)", |
|
2936 (int)(zds->outBuffSize - zds->outStart), |
|
2937 (U32)zds->fParams.blockSizeMax); |
2138 zds->outStart = zds->outEnd = 0; |
2938 zds->outStart = zds->outEnd = 0; |
|
2939 } |
2139 break; |
2940 break; |
2140 } |
2941 } } |
2141 /* cannot complete flush */ |
2942 /* cannot complete flush */ |
2142 someMoreWork = 0; |
2943 someMoreWork = 0; |
2143 break; |
2944 break; |
2144 } |
2945 |
2145 default: return ERROR(GENERIC); /* impossible */ |
2946 default: return ERROR(GENERIC); /* impossible */ |
2146 } } |
2947 } } |
2147 |
2948 |
2148 /* result */ |
2949 /* result */ |
2149 input->pos += (size_t)(ip-istart); |
2950 input->pos += (size_t)(ip-istart); |
2150 output->pos += (size_t)(op-ostart); |
2951 output->pos += (size_t)(op-ostart); |
2151 { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx); |
2952 { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds); |
2152 if (!nextSrcSizeHint) { /* frame fully decoded */ |
2953 if (!nextSrcSizeHint) { /* frame fully decoded */ |
2153 if (zds->outEnd == zds->outStart) { /* output fully flushed */ |
2954 if (zds->outEnd == zds->outStart) { /* output fully flushed */ |
2154 if (zds->hostageByte) { |
2955 if (zds->hostageByte) { |
2155 if (input->pos >= input->size) { zds->stage = zdss_read; return 1; } /* can't release hostage (not present) */ |
2956 if (input->pos >= input->size) { |
|
2957 /* can't release hostage (not present) */ |
|
2958 zds->streamStage = zdss_read; |
|
2959 return 1; |
|
2960 } |
2156 input->pos++; /* release hostage */ |
2961 input->pos++; /* release hostage */ |
2157 } |
2962 } /* zds->hostageByte */ |
2158 return 0; |
2963 return 0; |
2159 } |
2964 } /* zds->outEnd == zds->outStart */ |
2160 if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ |
2965 if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */ |
2161 input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ |
2966 input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */ |
2162 zds->hostageByte=1; |
2967 zds->hostageByte=1; |
2163 } |
2968 } |
2164 return 1; |
2969 return 1; |
2165 } |
2970 } /* nextSrcSizeHint==0 */ |
2166 nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */ |
2971 nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */ |
2167 if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */ |
2972 assert(zds->inPos <= nextSrcSizeHint); |
2168 nextSrcSizeHint -= zds->inPos; /* already loaded*/ |
2973 nextSrcSizeHint -= zds->inPos; /* part already loaded*/ |
2169 return nextSrcSizeHint; |
2974 return nextSrcSizeHint; |
2170 } |
2975 } |
2171 } |
2976 } |
|
2977 |
|
2978 |
|
2979 size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input) |
|
2980 { |
|
2981 return ZSTD_decompressStream(dctx, output, input); |
|
2982 } |
|
2983 |
|
2984 size_t ZSTD_decompress_generic_simpleArgs ( |
|
2985 ZSTD_DCtx* dctx, |
|
2986 void* dst, size_t dstCapacity, size_t* dstPos, |
|
2987 const void* src, size_t srcSize, size_t* srcPos) |
|
2988 { |
|
2989 ZSTD_outBuffer output = { dst, dstCapacity, *dstPos }; |
|
2990 ZSTD_inBuffer input = { src, srcSize, *srcPos }; |
|
2991 /* ZSTD_compress_generic() will check validity of dstPos and srcPos */ |
|
2992 size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input); |
|
2993 *dstPos = output.pos; |
|
2994 *srcPos = input.pos; |
|
2995 return cErr; |
|
2996 } |
|
2997 |
|
2998 void ZSTD_DCtx_reset(ZSTD_DCtx* dctx) |
|
2999 { |
|
3000 (void)ZSTD_initDStream(dctx); |
|
3001 dctx->format = ZSTD_f_zstd1; |
|
3002 dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT; |
|
3003 } |