2 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of https://github.com/facebook/zstd.
7 * An additional grant of patent rights can be found in the PATENTS file in the
10 * This program is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU General Public License version 2 as published by the
12 * Free Software Foundation. This program is dual-licensed; you may select
13 * either version 2 of the GNU General Public License ("GPL") or BSD license
17 /* ***************************************************************
19 *****************************************************************/
21 * MAXWINDOWSIZE_DEFAULT :
22 * maximum window size accepted by DStream, by default.
23 * Frames requiring more memory will be rejected.
25 #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
26 #define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
29 /*-*******************************************************
31 *********************************************************/
34 #include "mem.h" /* low level memory routines */
35 #include "zstd_internal.h"
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/string.h> /* memcpy, memmove, memset */
40 #define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
42 /*-*************************************
44 ***************************************/
45 #define ZSTD_isError ERR_isError /* for inlining */
46 #define FSE_isError ERR_isError
47 #define HUF_isError ERR_isError
49 /*_*******************************************************
51 **********************************************************/
52 static void ZSTD_copy4(void *dst
, const void *src
) { memcpy(dst
, src
, 4); }
54 /*-*************************************************************
56 ***************************************************************/
58 ZSTDds_getFrameHeaderSize
,
59 ZSTDds_decodeFrameHeader
,
60 ZSTDds_decodeBlockHeader
,
61 ZSTDds_decompressBlock
,
62 ZSTDds_decompressLastBlock
,
64 ZSTDds_decodeSkippableHeader
,
69 FSE_DTable LLTable
[FSE_DTABLE_SIZE_U32(LLFSELog
)];
70 FSE_DTable OFTable
[FSE_DTABLE_SIZE_U32(OffFSELog
)];
71 FSE_DTable MLTable
[FSE_DTABLE_SIZE_U32(MLFSELog
)];
72 HUF_DTable hufTable
[HUF_DTABLE_SIZE(HufLog
)]; /* can accommodate HUF_decompress4X */
73 U64 workspace
[HUF_DECOMPRESS_WORKSPACE_SIZE_U32
/ 2];
74 U32 rep
[ZSTD_REP_NUM
];
75 } ZSTD_entropyTables_t
;
78 const FSE_DTable
*LLTptr
;
79 const FSE_DTable
*MLTptr
;
80 const FSE_DTable
*OFTptr
;
81 const HUF_DTable
*HUFptr
;
82 ZSTD_entropyTables_t entropy
;
83 const void *previousDstEnd
; /* detect continuity */
84 const void *base
; /* start of curr segment */
85 const void *vBase
; /* virtual start of previous segment if it was just before curr one */
86 const void *dictEnd
; /* end of previous segment */
88 ZSTD_frameParams fParams
;
89 blockType_e bType
; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
93 struct xxh64_state xxhState
;
97 ZSTD_customMem customMem
;
100 BYTE litBuffer
[ZSTD_BLOCKSIZE_ABSOLUTEMAX
+ WILDCOPY_OVERLENGTH
];
101 BYTE headerBuffer
[ZSTD_FRAMEHEADERSIZE_MAX
];
102 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
104 size_t ZSTD_DCtxWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack
)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx
)); }
106 size_t ZSTD_decompressBegin(ZSTD_DCtx
*dctx
)
108 dctx
->expected
= ZSTD_frameHeaderSize_prefix
;
109 dctx
->stage
= ZSTDds_getFrameHeaderSize
;
110 dctx
->previousDstEnd
= NULL
;
113 dctx
->dictEnd
= NULL
;
114 dctx
->entropy
.hufTable
[0] = (HUF_DTable
)((HufLog
)*0x1000001); /* cover both little and big endian */
115 dctx
->litEntropy
= dctx
->fseEntropy
= 0;
117 ZSTD_STATIC_ASSERT(sizeof(dctx
->entropy
.rep
) == sizeof(repStartValue
));
118 memcpy(dctx
->entropy
.rep
, repStartValue
, sizeof(repStartValue
)); /* initial repcodes */
119 dctx
->LLTptr
= dctx
->entropy
.LLTable
;
120 dctx
->MLTptr
= dctx
->entropy
.MLTable
;
121 dctx
->OFTptr
= dctx
->entropy
.OFTable
;
122 dctx
->HUFptr
= dctx
->entropy
.hufTable
;
126 ZSTD_DCtx
*ZSTD_createDCtx_advanced(ZSTD_customMem customMem
)
130 if (!customMem
.customAlloc
|| !customMem
.customFree
)
133 dctx
= (ZSTD_DCtx
*)ZSTD_malloc(sizeof(ZSTD_DCtx
), customMem
);
136 memcpy(&dctx
->customMem
, &customMem
, sizeof(customMem
));
137 ZSTD_decompressBegin(dctx
);
141 ZSTD_DCtx
*ZSTD_initDCtx(void *workspace
, size_t workspaceSize
)
143 ZSTD_customMem
const stackMem
= ZSTD_initStack(workspace
, workspaceSize
);
144 return ZSTD_createDCtx_advanced(stackMem
);
147 size_t ZSTD_freeDCtx(ZSTD_DCtx
*dctx
)
150 return 0; /* support free on NULL */
151 ZSTD_free(dctx
, dctx
->customMem
);
152 return 0; /* reserved as a potential error code in the future */
155 void ZSTD_copyDCtx(ZSTD_DCtx
*dstDCtx
, const ZSTD_DCtx
*srcDCtx
)
157 size_t const workSpaceSize
= (ZSTD_BLOCKSIZE_ABSOLUTEMAX
+ WILDCOPY_OVERLENGTH
) + ZSTD_frameHeaderSize_max
;
158 memcpy(dstDCtx
, srcDCtx
, sizeof(ZSTD_DCtx
) - workSpaceSize
); /* no need to copy workspace */
161 static void ZSTD_refDDict(ZSTD_DCtx
*dstDCtx
, const ZSTD_DDict
*ddict
);
163 /*-*************************************************************
164 * Decompression section
165 ***************************************************************/
168 * Tells if the content of `buffer` starts with a valid Frame Identifier.
169 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
170 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
171 * Note 3 : Skippable Frame Identifiers are considered valid. */
172 unsigned ZSTD_isFrame(const void *buffer
, size_t size
)
177 U32
const magic
= ZSTD_readLE32(buffer
);
178 if (magic
== ZSTD_MAGICNUMBER
)
180 if ((magic
& 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
)
186 /** ZSTD_frameHeaderSize() :
187 * srcSize must be >= ZSTD_frameHeaderSize_prefix.
188 * @return : size of the Frame Header */
189 static size_t ZSTD_frameHeaderSize(const void *src
, size_t srcSize
)
191 if (srcSize
< ZSTD_frameHeaderSize_prefix
)
192 return ERROR(srcSize_wrong
);
194 BYTE
const fhd
= ((const BYTE
*)src
)[4];
195 U32
const dictID
= fhd
& 3;
196 U32
const singleSegment
= (fhd
>> 5) & 1;
197 U32
const fcsId
= fhd
>> 6;
198 return ZSTD_frameHeaderSize_prefix
+ !singleSegment
+ ZSTD_did_fieldSize
[dictID
] + ZSTD_fcs_fieldSize
[fcsId
] + (singleSegment
&& !fcsId
);
202 /** ZSTD_getFrameParams() :
203 * decode Frame Header, or require larger `srcSize`.
204 * @return : 0, `fparamsPtr` is correctly filled,
205 * >0, `srcSize` is too small, result is expected `srcSize`,
206 * or an error code, which can be tested using ZSTD_isError() */
207 size_t ZSTD_getFrameParams(ZSTD_frameParams
*fparamsPtr
, const void *src
, size_t srcSize
)
209 const BYTE
*ip
= (const BYTE
*)src
;
211 if (srcSize
< ZSTD_frameHeaderSize_prefix
)
212 return ZSTD_frameHeaderSize_prefix
;
213 if (ZSTD_readLE32(src
) != ZSTD_MAGICNUMBER
) {
214 if ((ZSTD_readLE32(src
) & 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
) {
215 if (srcSize
< ZSTD_skippableHeaderSize
)
216 return ZSTD_skippableHeaderSize
; /* magic number + skippable frame length */
217 memset(fparamsPtr
, 0, sizeof(*fparamsPtr
));
218 fparamsPtr
->frameContentSize
= ZSTD_readLE32((const char *)src
+ 4);
219 fparamsPtr
->windowSize
= 0; /* windowSize==0 means a frame is skippable */
222 return ERROR(prefix_unknown
);
225 /* ensure there is enough `srcSize` to fully read/decode frame header */
227 size_t const fhsize
= ZSTD_frameHeaderSize(src
, srcSize
);
228 if (srcSize
< fhsize
)
233 BYTE
const fhdByte
= ip
[4];
235 U32
const dictIDSizeCode
= fhdByte
& 3;
236 U32
const checksumFlag
= (fhdByte
>> 2) & 1;
237 U32
const singleSegment
= (fhdByte
>> 5) & 1;
238 U32
const fcsID
= fhdByte
>> 6;
239 U32
const windowSizeMax
= 1U << ZSTD_WINDOWLOG_MAX
;
242 U64 frameContentSize
= 0;
243 if ((fhdByte
& 0x08) != 0)
244 return ERROR(frameParameter_unsupported
); /* reserved bits, which must be zero */
245 if (!singleSegment
) {
246 BYTE
const wlByte
= ip
[pos
++];
247 U32
const windowLog
= (wlByte
>> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN
;
248 if (windowLog
> ZSTD_WINDOWLOG_MAX
)
249 return ERROR(frameParameter_windowTooLarge
); /* avoids issue with 1 << windowLog */
250 windowSize
= (1U << windowLog
);
251 windowSize
+= (windowSize
>> 3) * (wlByte
& 7);
254 switch (dictIDSizeCode
) {
255 default: /* impossible */
262 dictID
= ZSTD_readLE16(ip
+ pos
);
266 dictID
= ZSTD_readLE32(ip
+ pos
);
271 default: /* impossible */
274 frameContentSize
= ip
[pos
];
276 case 1: frameContentSize
= ZSTD_readLE16(ip
+ pos
) + 256; break;
277 case 2: frameContentSize
= ZSTD_readLE32(ip
+ pos
); break;
278 case 3: frameContentSize
= ZSTD_readLE64(ip
+ pos
); break;
281 windowSize
= (U32
)frameContentSize
;
282 if (windowSize
> windowSizeMax
)
283 return ERROR(frameParameter_windowTooLarge
);
284 fparamsPtr
->frameContentSize
= frameContentSize
;
285 fparamsPtr
->windowSize
= windowSize
;
286 fparamsPtr
->dictID
= dictID
;
287 fparamsPtr
->checksumFlag
= checksumFlag
;
292 /** ZSTD_getFrameContentSize() :
293 * compatible with legacy mode
294 * @return : decompressed size of the single frame pointed to be `src` if known, otherwise
295 * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
296 * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
297 unsigned long long ZSTD_getFrameContentSize(const void *src
, size_t srcSize
)
300 ZSTD_frameParams fParams
;
301 if (ZSTD_getFrameParams(&fParams
, src
, srcSize
) != 0)
302 return ZSTD_CONTENTSIZE_ERROR
;
303 if (fParams
.windowSize
== 0) {
304 /* Either skippable or empty frame, size == 0 either way */
306 } else if (fParams
.frameContentSize
!= 0) {
307 return fParams
.frameContentSize
;
309 return ZSTD_CONTENTSIZE_UNKNOWN
;
314 /** ZSTD_findDecompressedSize() :
315 * compatible with legacy mode
316 * `srcSize` must be the exact length of some number of ZSTD compressed and/or
318 * @return : decompressed size of the frames contained */
319 unsigned long long ZSTD_findDecompressedSize(const void *src
, size_t srcSize
)
322 unsigned long long totalDstSize
= 0;
323 while (srcSize
>= ZSTD_frameHeaderSize_prefix
) {
324 const U32 magicNumber
= ZSTD_readLE32(src
);
326 if ((magicNumber
& 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
) {
327 size_t skippableSize
;
328 if (srcSize
< ZSTD_skippableHeaderSize
)
329 return ERROR(srcSize_wrong
);
330 skippableSize
= ZSTD_readLE32((const BYTE
*)src
+ 4) + ZSTD_skippableHeaderSize
;
331 if (srcSize
< skippableSize
) {
332 return ZSTD_CONTENTSIZE_ERROR
;
335 src
= (const BYTE
*)src
+ skippableSize
;
336 srcSize
-= skippableSize
;
341 unsigned long long const ret
= ZSTD_getFrameContentSize(src
, srcSize
);
342 if (ret
>= ZSTD_CONTENTSIZE_ERROR
)
345 /* check for overflow */
346 if (totalDstSize
+ ret
< totalDstSize
)
347 return ZSTD_CONTENTSIZE_ERROR
;
351 size_t const frameSrcSize
= ZSTD_findFrameCompressedSize(src
, srcSize
);
352 if (ZSTD_isError(frameSrcSize
)) {
353 return ZSTD_CONTENTSIZE_ERROR
;
356 src
= (const BYTE
*)src
+ frameSrcSize
;
357 srcSize
-= frameSrcSize
;
362 return ZSTD_CONTENTSIZE_ERROR
;
369 /** ZSTD_decodeFrameHeader() :
370 * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
371 * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
372 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx
*dctx
, const void *src
, size_t headerSize
)
374 size_t const result
= ZSTD_getFrameParams(&(dctx
->fParams
), src
, headerSize
);
375 if (ZSTD_isError(result
))
376 return result
; /* invalid header */
378 return ERROR(srcSize_wrong
); /* headerSize too small */
379 if (dctx
->fParams
.dictID
&& (dctx
->dictID
!= dctx
->fParams
.dictID
))
380 return ERROR(dictionary_wrong
);
381 if (dctx
->fParams
.checksumFlag
)
382 xxh64_reset(&dctx
->xxhState
, 0);
387 blockType_e blockType
;
392 /*! ZSTD_getcBlockSize() :
393 * Provides the size of compressed block from block header `src` */
394 size_t ZSTD_getcBlockSize(const void *src
, size_t srcSize
, blockProperties_t
*bpPtr
)
396 if (srcSize
< ZSTD_blockHeaderSize
)
397 return ERROR(srcSize_wrong
);
399 U32
const cBlockHeader
= ZSTD_readLE24(src
);
400 U32
const cSize
= cBlockHeader
>> 3;
401 bpPtr
->lastBlock
= cBlockHeader
& 1;
402 bpPtr
->blockType
= (blockType_e
)((cBlockHeader
>> 1) & 3);
403 bpPtr
->origSize
= cSize
; /* only useful for RLE */
404 if (bpPtr
->blockType
== bt_rle
)
406 if (bpPtr
->blockType
== bt_reserved
)
407 return ERROR(corruption_detected
);
412 static size_t ZSTD_copyRawBlock(void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
414 if (srcSize
> dstCapacity
)
415 return ERROR(dstSize_tooSmall
);
416 memcpy(dst
, src
, srcSize
);
420 static size_t ZSTD_setRleBlock(void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
, size_t regenSize
)
423 return ERROR(srcSize_wrong
);
424 if (regenSize
> dstCapacity
)
425 return ERROR(dstSize_tooSmall
);
426 memset(dst
, *(const BYTE
*)src
, regenSize
);
430 /*! ZSTD_decodeLiteralsBlock() :
431 @return : nb of bytes read from src (< srcSize ) */
432 size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx
*dctx
, const void *src
, size_t srcSize
) /* note : srcSize < BLOCKSIZE */
434 if (srcSize
< MIN_CBLOCK_SIZE
)
435 return ERROR(corruption_detected
);
438 const BYTE
*const istart
= (const BYTE
*)src
;
439 symbolEncodingType_e
const litEncType
= (symbolEncodingType_e
)(istart
[0] & 3);
441 switch (litEncType
) {
443 if (dctx
->litEntropy
== 0)
444 return ERROR(dictionary_corrupted
);
448 return ERROR(corruption_detected
); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
450 size_t lhSize
, litSize
, litCSize
;
451 U32 singleStream
= 0;
452 U32
const lhlCode
= (istart
[0] >> 2) & 3;
453 U32
const lhc
= ZSTD_readLE32(istart
);
457 default: /* note : default is impossible, since lhlCode into [0..3] */
458 /* 2 - 2 - 10 - 10 */
459 singleStream
= !lhlCode
;
461 litSize
= (lhc
>> 4) & 0x3FF;
462 litCSize
= (lhc
>> 14) & 0x3FF;
465 /* 2 - 2 - 14 - 14 */
467 litSize
= (lhc
>> 4) & 0x3FFF;
468 litCSize
= lhc
>> 18;
471 /* 2 - 2 - 18 - 18 */
473 litSize
= (lhc
>> 4) & 0x3FFFF;
474 litCSize
= (lhc
>> 22) + (istart
[4] << 10);
477 if (litSize
> ZSTD_BLOCKSIZE_ABSOLUTEMAX
)
478 return ERROR(corruption_detected
);
479 if (litCSize
+ lhSize
> srcSize
)
480 return ERROR(corruption_detected
);
483 (litEncType
== set_repeat
)
484 ? (singleStream
? HUF_decompress1X_usingDTable(dctx
->litBuffer
, litSize
, istart
+ lhSize
, litCSize
, dctx
->HUFptr
)
485 : HUF_decompress4X_usingDTable(dctx
->litBuffer
, litSize
, istart
+ lhSize
, litCSize
, dctx
->HUFptr
))
487 ? HUF_decompress1X2_DCtx_wksp(dctx
->entropy
.hufTable
, dctx
->litBuffer
, litSize
, istart
+ lhSize
, litCSize
,
488 dctx
->entropy
.workspace
, sizeof(dctx
->entropy
.workspace
))
489 : HUF_decompress4X_hufOnly_wksp(dctx
->entropy
.hufTable
, dctx
->litBuffer
, litSize
, istart
+ lhSize
, litCSize
,
490 dctx
->entropy
.workspace
, sizeof(dctx
->entropy
.workspace
)))))
491 return ERROR(corruption_detected
);
493 dctx
->litPtr
= dctx
->litBuffer
;
494 dctx
->litSize
= litSize
;
495 dctx
->litEntropy
= 1;
496 if (litEncType
== set_compressed
)
497 dctx
->HUFptr
= dctx
->entropy
.hufTable
;
498 memset(dctx
->litBuffer
+ dctx
->litSize
, 0, WILDCOPY_OVERLENGTH
);
499 return litCSize
+ lhSize
;
503 size_t litSize
, lhSize
;
504 U32
const lhlCode
= ((istart
[0]) >> 2) & 3;
508 default: /* note : default is impossible, since lhlCode into [0..3] */
510 litSize
= istart
[0] >> 3;
514 litSize
= ZSTD_readLE16(istart
) >> 4;
518 litSize
= ZSTD_readLE24(istart
) >> 4;
522 if (lhSize
+ litSize
+ WILDCOPY_OVERLENGTH
> srcSize
) { /* risk reading beyond src buffer with wildcopy */
523 if (litSize
+ lhSize
> srcSize
)
524 return ERROR(corruption_detected
);
525 memcpy(dctx
->litBuffer
, istart
+ lhSize
, litSize
);
526 dctx
->litPtr
= dctx
->litBuffer
;
527 dctx
->litSize
= litSize
;
528 memset(dctx
->litBuffer
+ dctx
->litSize
, 0, WILDCOPY_OVERLENGTH
);
529 return lhSize
+ litSize
;
531 /* direct reference into compressed stream */
532 dctx
->litPtr
= istart
+ lhSize
;
533 dctx
->litSize
= litSize
;
534 return lhSize
+ litSize
;
538 U32
const lhlCode
= ((istart
[0]) >> 2) & 3;
539 size_t litSize
, lhSize
;
543 default: /* note : default is impossible, since lhlCode into [0..3] */
545 litSize
= istart
[0] >> 3;
549 litSize
= ZSTD_readLE16(istart
) >> 4;
553 litSize
= ZSTD_readLE24(istart
) >> 4;
555 return ERROR(corruption_detected
); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
558 if (litSize
> ZSTD_BLOCKSIZE_ABSOLUTEMAX
)
559 return ERROR(corruption_detected
);
560 memset(dctx
->litBuffer
, istart
[lhSize
], litSize
+ WILDCOPY_OVERLENGTH
);
561 dctx
->litPtr
= dctx
->litBuffer
;
562 dctx
->litSize
= litSize
;
566 return ERROR(corruption_detected
); /* impossible */
572 FSE_decode_t realData
;
576 static const FSE_decode_t4 LL_defaultDTable
[(1 << LL_DEFAULTNORMLOG
) + 1] = {
577 {{LL_DEFAULTNORMLOG
, 1, 1}}, /* header : tableLog, fastMode, fastMode */
578 {{0, 0, 4}}, /* 0 : base, symbol, bits */
642 }; /* LL_defaultDTable */
644 static const FSE_decode_t4 ML_defaultDTable
[(1 << ML_DEFAULTNORMLOG
) + 1] = {
645 {{ML_DEFAULTNORMLOG
, 1, 1}}, /* header : tableLog, fastMode, fastMode */
646 {{0, 0, 6}}, /* 0 : base, symbol, bits */
710 }; /* ML_defaultDTable */
712 static const FSE_decode_t4 OF_defaultDTable
[(1 << OF_DEFAULTNORMLOG
) + 1] = {
713 {{OF_DEFAULTNORMLOG
, 1, 1}}, /* header : tableLog, fastMode, fastMode */
714 {{0, 0, 5}}, /* 0 : base, symbol, bits */
746 }; /* OF_defaultDTable */
748 /*! ZSTD_buildSeqTable() :
749 @return : nb bytes read from src,
750 or an error code if it fails, testable with ZSTD_isError()
752 static size_t ZSTD_buildSeqTable(FSE_DTable
*DTableSpace
, const FSE_DTable
**DTablePtr
, symbolEncodingType_e type
, U32 max
, U32 maxLog
, const void *src
,
753 size_t srcSize
, const FSE_decode_t4
*defaultTable
, U32 flagRepeatTable
, void *workspace
, size_t workspaceSize
)
755 const void *const tmpPtr
= defaultTable
; /* bypass strict aliasing */
759 return ERROR(srcSize_wrong
);
760 if ((*(const BYTE
*)src
) > max
)
761 return ERROR(corruption_detected
);
762 FSE_buildDTable_rle(DTableSpace
, *(const BYTE
*)src
);
763 *DTablePtr
= DTableSpace
;
765 case set_basic
: *DTablePtr
= (const FSE_DTable
*)tmpPtr
; return 0;
767 if (!flagRepeatTable
)
768 return ERROR(corruption_detected
);
770 default: /* impossible */
771 case set_compressed
: {
773 S16
*norm
= (S16
*)workspace
;
774 size_t const spaceUsed32
= ALIGN(sizeof(S16
) * (MaxSeq
+ 1), sizeof(U32
)) >> 2;
776 if ((spaceUsed32
<< 2) > workspaceSize
)
777 return ERROR(GENERIC
);
778 workspace
= (U32
*)workspace
+ spaceUsed32
;
779 workspaceSize
-= (spaceUsed32
<< 2);
781 size_t const headerSize
= FSE_readNCount(norm
, &max
, &tableLog
, src
, srcSize
);
782 if (FSE_isError(headerSize
))
783 return ERROR(corruption_detected
);
784 if (tableLog
> maxLog
)
785 return ERROR(corruption_detected
);
786 FSE_buildDTable_wksp(DTableSpace
, norm
, max
, tableLog
, workspace
, workspaceSize
);
787 *DTablePtr
= DTableSpace
;
794 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx
*dctx
, int *nbSeqPtr
, const void *src
, size_t srcSize
)
796 const BYTE
*const istart
= (const BYTE
*const)src
;
797 const BYTE
*const iend
= istart
+ srcSize
;
798 const BYTE
*ip
= istart
;
801 if (srcSize
< MIN_SEQUENCES_SIZE
)
802 return ERROR(srcSize_wrong
);
814 return ERROR(srcSize_wrong
);
815 nbSeq
= ZSTD_readLE16(ip
) + LONGNBSEQ
, ip
+= 2;
818 return ERROR(srcSize_wrong
);
819 nbSeq
= ((nbSeq
- 0x80) << 8) + *ip
++;
825 /* FSE table descriptors */
827 return ERROR(srcSize_wrong
); /* minimum possible size */
829 symbolEncodingType_e
const LLtype
= (symbolEncodingType_e
)(*ip
>> 6);
830 symbolEncodingType_e
const OFtype
= (symbolEncodingType_e
)((*ip
>> 4) & 3);
831 symbolEncodingType_e
const MLtype
= (symbolEncodingType_e
)((*ip
>> 2) & 3);
836 size_t const llhSize
= ZSTD_buildSeqTable(dctx
->entropy
.LLTable
, &dctx
->LLTptr
, LLtype
, MaxLL
, LLFSELog
, ip
, iend
- ip
,
837 LL_defaultDTable
, dctx
->fseEntropy
, dctx
->entropy
.workspace
, sizeof(dctx
->entropy
.workspace
));
838 if (ZSTD_isError(llhSize
))
839 return ERROR(corruption_detected
);
843 size_t const ofhSize
= ZSTD_buildSeqTable(dctx
->entropy
.OFTable
, &dctx
->OFTptr
, OFtype
, MaxOff
, OffFSELog
, ip
, iend
- ip
,
844 OF_defaultDTable
, dctx
->fseEntropy
, dctx
->entropy
.workspace
, sizeof(dctx
->entropy
.workspace
));
845 if (ZSTD_isError(ofhSize
))
846 return ERROR(corruption_detected
);
850 size_t const mlhSize
= ZSTD_buildSeqTable(dctx
->entropy
.MLTable
, &dctx
->MLTptr
, MLtype
, MaxML
, MLFSELog
, ip
, iend
- ip
,
851 ML_defaultDTable
, dctx
->fseEntropy
, dctx
->entropy
.workspace
, sizeof(dctx
->entropy
.workspace
));
852 if (ZSTD_isError(mlhSize
))
853 return ERROR(corruption_detected
);
869 BIT_DStream_t DStream
;
870 FSE_DState_t stateLL
;
871 FSE_DState_t stateOffb
;
872 FSE_DState_t stateML
;
873 size_t prevOffset
[ZSTD_REP_NUM
];
880 size_t ZSTD_execSequenceLast7(BYTE
*op
, BYTE
*const oend
, seq_t sequence
, const BYTE
**litPtr
, const BYTE
*const litLimit
, const BYTE
*const base
,
881 const BYTE
*const vBase
, const BYTE
*const dictEnd
)
883 BYTE
*const oLitEnd
= op
+ sequence
.litLength
;
884 size_t const sequenceLength
= sequence
.litLength
+ sequence
.matchLength
;
885 BYTE
*const oMatchEnd
= op
+ sequenceLength
; /* risk : address space overflow (32-bits) */
886 BYTE
*const oend_w
= oend
- WILDCOPY_OVERLENGTH
;
887 const BYTE
*const iLitEnd
= *litPtr
+ sequence
.litLength
;
888 const BYTE
*match
= oLitEnd
- sequence
.offset
;
891 if (oMatchEnd
> oend
)
892 return ERROR(dstSize_tooSmall
); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
893 if (iLitEnd
> litLimit
)
894 return ERROR(corruption_detected
); /* over-read beyond lit buffer */
895 if (oLitEnd
<= oend_w
)
896 return ERROR(GENERIC
); /* Precondition */
900 ZSTD_wildcopy(op
, *litPtr
, oend_w
- op
);
901 *litPtr
+= oend_w
- op
;
905 *op
++ = *(*litPtr
)++;
908 if (sequence
.offset
> (size_t)(oLitEnd
- base
)) {
909 /* offset beyond prefix */
910 if (sequence
.offset
> (size_t)(oLitEnd
- vBase
))
911 return ERROR(corruption_detected
);
912 match
= dictEnd
- (base
- match
);
913 if (match
+ sequence
.matchLength
<= dictEnd
) {
914 memmove(oLitEnd
, match
, sequence
.matchLength
);
915 return sequenceLength
;
917 /* span extDict & currPrefixSegment */
919 size_t const length1
= dictEnd
- match
;
920 memmove(oLitEnd
, match
, length1
);
921 op
= oLitEnd
+ length1
;
922 sequence
.matchLength
-= length1
;
926 while (op
< oMatchEnd
)
928 return sequenceLength
;
931 static seq_t
ZSTD_decodeSequence(seqState_t
*seqState
)
935 U32
const llCode
= FSE_peekSymbol(&seqState
->stateLL
);
936 U32
const mlCode
= FSE_peekSymbol(&seqState
->stateML
);
937 U32
const ofCode
= FSE_peekSymbol(&seqState
->stateOffb
); /* <= maxOff, by table construction */
939 U32
const llBits
= LL_bits
[llCode
];
940 U32
const mlBits
= ML_bits
[mlCode
];
941 U32
const ofBits
= ofCode
;
942 U32
const totalBits
= llBits
+ mlBits
+ ofBits
;
944 static const U32 LL_base
[MaxLL
+ 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18,
945 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
947 static const U32 ML_base
[MaxML
+ 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
948 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41,
949 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
951 static const U32 OF_base
[MaxOff
+ 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD,
952 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD,
953 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
961 offset
= OF_base
[ofCode
] + BIT_readBitsFast(&seqState
->DStream
, ofBits
); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
963 BIT_reloadDStream(&seqState
->DStream
);
967 offset
+= (llCode
== 0);
969 size_t temp
= (offset
== 3) ? seqState
->prevOffset
[0] - 1 : seqState
->prevOffset
[offset
];
970 temp
+= !temp
; /* 0 is not valid; input is corrupted; force offset to 1 */
972 seqState
->prevOffset
[2] = seqState
->prevOffset
[1];
973 seqState
->prevOffset
[1] = seqState
->prevOffset
[0];
974 seqState
->prevOffset
[0] = offset
= temp
;
976 offset
= seqState
->prevOffset
[0];
979 seqState
->prevOffset
[2] = seqState
->prevOffset
[1];
980 seqState
->prevOffset
[1] = seqState
->prevOffset
[0];
981 seqState
->prevOffset
[0] = offset
;
986 seq
.matchLength
= ML_base
[mlCode
] + ((mlCode
> 31) ? BIT_readBitsFast(&seqState
->DStream
, mlBits
) : 0); /* <= 16 bits */
987 if (ZSTD_32bits() && (mlBits
+ llBits
> 24))
988 BIT_reloadDStream(&seqState
->DStream
);
990 seq
.litLength
= LL_base
[llCode
] + ((llCode
> 15) ? BIT_readBitsFast(&seqState
->DStream
, llBits
) : 0); /* <= 16 bits */
991 if (ZSTD_32bits() || (totalBits
> 64 - 7 - (LLFSELog
+ MLFSELog
+ OffFSELog
)))
992 BIT_reloadDStream(&seqState
->DStream
);
994 /* ANS state update */
995 FSE_updateState(&seqState
->stateLL
, &seqState
->DStream
); /* <= 9 bits */
996 FSE_updateState(&seqState
->stateML
, &seqState
->DStream
); /* <= 9 bits */
998 BIT_reloadDStream(&seqState
->DStream
); /* <= 18 bits */
999 FSE_updateState(&seqState
->stateOffb
, &seqState
->DStream
); /* <= 8 bits */
1007 size_t ZSTD_execSequence(BYTE
*op
, BYTE
*const oend
, seq_t sequence
, const BYTE
**litPtr
, const BYTE
*const litLimit
, const BYTE
*const base
,
1008 const BYTE
*const vBase
, const BYTE
*const dictEnd
)
1010 BYTE
*const oLitEnd
= op
+ sequence
.litLength
;
1011 size_t const sequenceLength
= sequence
.litLength
+ sequence
.matchLength
;
1012 BYTE
*const oMatchEnd
= op
+ sequenceLength
; /* risk : address space overflow (32-bits) */
1013 BYTE
*const oend_w
= oend
- WILDCOPY_OVERLENGTH
;
1014 const BYTE
*const iLitEnd
= *litPtr
+ sequence
.litLength
;
1015 const BYTE
*match
= oLitEnd
- sequence
.offset
;
1018 if (oMatchEnd
> oend
)
1019 return ERROR(dstSize_tooSmall
); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1020 if (iLitEnd
> litLimit
)
1021 return ERROR(corruption_detected
); /* over-read beyond lit buffer */
1022 if (oLitEnd
> oend_w
)
1023 return ZSTD_execSequenceLast7(op
, oend
, sequence
, litPtr
, litLimit
, base
, vBase
, dictEnd
);
1026 ZSTD_copy8(op
, *litPtr
);
1027 if (sequence
.litLength
> 8)
1028 ZSTD_wildcopy(op
+ 8, (*litPtr
) + 8,
1029 sequence
.litLength
- 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1031 *litPtr
= iLitEnd
; /* update for next sequence */
1034 if (sequence
.offset
> (size_t)(oLitEnd
- base
)) {
1035 /* offset beyond prefix */
1036 if (sequence
.offset
> (size_t)(oLitEnd
- vBase
))
1037 return ERROR(corruption_detected
);
1038 match
= dictEnd
+ (match
- base
);
1039 if (match
+ sequence
.matchLength
<= dictEnd
) {
1040 memmove(oLitEnd
, match
, sequence
.matchLength
);
1041 return sequenceLength
;
1043 /* span extDict & currPrefixSegment */
1045 size_t const length1
= dictEnd
- match
;
1046 memmove(oLitEnd
, match
, length1
);
1047 op
= oLitEnd
+ length1
;
1048 sequence
.matchLength
-= length1
;
1050 if (op
> oend_w
|| sequence
.matchLength
< MINMATCH
) {
1052 for (i
= 0; i
< sequence
.matchLength
; ++i
)
1054 return sequenceLength
;
1058 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1060 /* match within prefix */
1061 if (sequence
.offset
< 8) {
1062 /* close range match, overlap */
1063 static const U32 dec32table
[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
1064 static const int dec64table
[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
1065 int const sub2
= dec64table
[sequence
.offset
];
1070 match
+= dec32table
[sequence
.offset
];
1071 ZSTD_copy4(op
+ 4, match
);
1074 ZSTD_copy8(op
, match
);
1079 if (oMatchEnd
> oend
- (16 - MINMATCH
)) {
1081 ZSTD_wildcopy(op
, match
, oend_w
- op
);
1082 match
+= oend_w
- op
;
1085 while (op
< oMatchEnd
)
1088 ZSTD_wildcopy(op
, match
, (ptrdiff_t)sequence
.matchLength
- 8); /* works even if matchLength < 8 */
1090 return sequenceLength
;
1093 static size_t ZSTD_decompressSequences(ZSTD_DCtx
*dctx
, void *dst
, size_t maxDstSize
, const void *seqStart
, size_t seqSize
)
1095 const BYTE
*ip
= (const BYTE
*)seqStart
;
1096 const BYTE
*const iend
= ip
+ seqSize
;
1097 BYTE
*const ostart
= (BYTE
* const)dst
;
1098 BYTE
*const oend
= ostart
+ maxDstSize
;
1100 const BYTE
*litPtr
= dctx
->litPtr
;
1101 const BYTE
*const litEnd
= litPtr
+ dctx
->litSize
;
1102 const BYTE
*const base
= (const BYTE
*)(dctx
->base
);
1103 const BYTE
*const vBase
= (const BYTE
*)(dctx
->vBase
);
1104 const BYTE
*const dictEnd
= (const BYTE
*)(dctx
->dictEnd
);
1107 /* Build Decoding Tables */
1109 size_t const seqHSize
= ZSTD_decodeSeqHeaders(dctx
, &nbSeq
, ip
, seqSize
);
1110 if (ZSTD_isError(seqHSize
))
1115 /* Regen sequences */
1117 seqState_t seqState
;
1118 dctx
->fseEntropy
= 1;
1121 for (i
= 0; i
< ZSTD_REP_NUM
; i
++)
1122 seqState
.prevOffset
[i
] = dctx
->entropy
.rep
[i
];
1124 CHECK_E(BIT_initDStream(&seqState
.DStream
, ip
, iend
- ip
), corruption_detected
);
1125 FSE_initDState(&seqState
.stateLL
, &seqState
.DStream
, dctx
->LLTptr
);
1126 FSE_initDState(&seqState
.stateOffb
, &seqState
.DStream
, dctx
->OFTptr
);
1127 FSE_initDState(&seqState
.stateML
, &seqState
.DStream
, dctx
->MLTptr
);
1129 for (; (BIT_reloadDStream(&(seqState
.DStream
)) <= BIT_DStream_completed
) && nbSeq
;) {
1132 seq_t
const sequence
= ZSTD_decodeSequence(&seqState
);
1133 size_t const oneSeqSize
= ZSTD_execSequence(op
, oend
, sequence
, &litPtr
, litEnd
, base
, vBase
, dictEnd
);
1134 if (ZSTD_isError(oneSeqSize
))
1140 /* check if reached exact end */
1142 return ERROR(corruption_detected
);
1143 /* save reps for next block */
1146 for (i
= 0; i
< ZSTD_REP_NUM
; i
++)
1147 dctx
->entropy
.rep
[i
] = (U32
)(seqState
.prevOffset
[i
]);
1151 /* last literal segment */
1153 size_t const lastLLSize
= litEnd
- litPtr
;
1154 if (lastLLSize
> (size_t)(oend
- op
))
1155 return ERROR(dstSize_tooSmall
);
1156 memcpy(op
, litPtr
, lastLLSize
);
1163 FORCE_INLINE seq_t
ZSTD_decodeSequenceLong_generic(seqState_t
*seqState
, int const longOffsets
)
1167 U32
const llCode
= FSE_peekSymbol(&seqState
->stateLL
);
1168 U32
const mlCode
= FSE_peekSymbol(&seqState
->stateML
);
1169 U32
const ofCode
= FSE_peekSymbol(&seqState
->stateOffb
); /* <= maxOff, by table construction */
1171 U32
const llBits
= LL_bits
[llCode
];
1172 U32
const mlBits
= ML_bits
[mlCode
];
1173 U32
const ofBits
= ofCode
;
1174 U32
const totalBits
= llBits
+ mlBits
+ ofBits
;
1176 static const U32 LL_base
[MaxLL
+ 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18,
1177 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
1179 static const U32 ML_base
[MaxML
+ 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1180 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41,
1181 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
1183 static const U32 OF_base
[MaxOff
+ 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD,
1184 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD,
1185 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
1194 int const extraBits
= ofBits
- MIN(ofBits
, STREAM_ACCUMULATOR_MIN
);
1195 offset
= OF_base
[ofCode
] + (BIT_readBitsFast(&seqState
->DStream
, ofBits
- extraBits
) << extraBits
);
1196 if (ZSTD_32bits() || extraBits
)
1197 BIT_reloadDStream(&seqState
->DStream
);
1199 offset
+= BIT_readBitsFast(&seqState
->DStream
, extraBits
);
1201 offset
= OF_base
[ofCode
] + BIT_readBitsFast(&seqState
->DStream
, ofBits
); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1203 BIT_reloadDStream(&seqState
->DStream
);
1208 offset
+= (llCode
== 0);
1210 size_t temp
= (offset
== 3) ? seqState
->prevOffset
[0] - 1 : seqState
->prevOffset
[offset
];
1211 temp
+= !temp
; /* 0 is not valid; input is corrupted; force offset to 1 */
1213 seqState
->prevOffset
[2] = seqState
->prevOffset
[1];
1214 seqState
->prevOffset
[1] = seqState
->prevOffset
[0];
1215 seqState
->prevOffset
[0] = offset
= temp
;
1217 offset
= seqState
->prevOffset
[0];
1220 seqState
->prevOffset
[2] = seqState
->prevOffset
[1];
1221 seqState
->prevOffset
[1] = seqState
->prevOffset
[0];
1222 seqState
->prevOffset
[0] = offset
;
1224 seq
.offset
= offset
;
1227 seq
.matchLength
= ML_base
[mlCode
] + ((mlCode
> 31) ? BIT_readBitsFast(&seqState
->DStream
, mlBits
) : 0); /* <= 16 bits */
1228 if (ZSTD_32bits() && (mlBits
+ llBits
> 24))
1229 BIT_reloadDStream(&seqState
->DStream
);
1231 seq
.litLength
= LL_base
[llCode
] + ((llCode
> 15) ? BIT_readBitsFast(&seqState
->DStream
, llBits
) : 0); /* <= 16 bits */
1232 if (ZSTD_32bits() || (totalBits
> 64 - 7 - (LLFSELog
+ MLFSELog
+ OffFSELog
)))
1233 BIT_reloadDStream(&seqState
->DStream
);
1236 size_t const pos
= seqState
->pos
+ seq
.litLength
;
1237 seq
.match
= seqState
->base
+ pos
- seq
.offset
; /* single memory segment */
1238 if (seq
.offset
> pos
)
1239 seq
.match
+= seqState
->gotoDict
; /* separate memory segment */
1240 seqState
->pos
= pos
+ seq
.matchLength
;
1243 /* ANS state update */
1244 FSE_updateState(&seqState
->stateLL
, &seqState
->DStream
); /* <= 9 bits */
1245 FSE_updateState(&seqState
->stateML
, &seqState
->DStream
); /* <= 9 bits */
1247 BIT_reloadDStream(&seqState
->DStream
); /* <= 18 bits */
1248 FSE_updateState(&seqState
->stateOffb
, &seqState
->DStream
); /* <= 8 bits */
1253 static seq_t
ZSTD_decodeSequenceLong(seqState_t
*seqState
, unsigned const windowSize
)
1255 if (ZSTD_highbit32(windowSize
) > STREAM_ACCUMULATOR_MIN
) {
1256 return ZSTD_decodeSequenceLong_generic(seqState
, 1);
1258 return ZSTD_decodeSequenceLong_generic(seqState
, 0);
1263 size_t ZSTD_execSequenceLong(BYTE
*op
, BYTE
*const oend
, seq_t sequence
, const BYTE
**litPtr
, const BYTE
*const litLimit
, const BYTE
*const base
,
1264 const BYTE
*const vBase
, const BYTE
*const dictEnd
)
1266 BYTE
*const oLitEnd
= op
+ sequence
.litLength
;
1267 size_t const sequenceLength
= sequence
.litLength
+ sequence
.matchLength
;
1268 BYTE
*const oMatchEnd
= op
+ sequenceLength
; /* risk : address space overflow (32-bits) */
1269 BYTE
*const oend_w
= oend
- WILDCOPY_OVERLENGTH
;
1270 const BYTE
*const iLitEnd
= *litPtr
+ sequence
.litLength
;
1271 const BYTE
*match
= sequence
.match
;
1274 if (oMatchEnd
> oend
)
1275 return ERROR(dstSize_tooSmall
); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1276 if (iLitEnd
> litLimit
)
1277 return ERROR(corruption_detected
); /* over-read beyond lit buffer */
1278 if (oLitEnd
> oend_w
)
1279 return ZSTD_execSequenceLast7(op
, oend
, sequence
, litPtr
, litLimit
, base
, vBase
, dictEnd
);
1282 ZSTD_copy8(op
, *litPtr
);
1283 if (sequence
.litLength
> 8)
1284 ZSTD_wildcopy(op
+ 8, (*litPtr
) + 8,
1285 sequence
.litLength
- 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1287 *litPtr
= iLitEnd
; /* update for next sequence */
1290 if (sequence
.offset
> (size_t)(oLitEnd
- base
)) {
1291 /* offset beyond prefix */
1292 if (sequence
.offset
> (size_t)(oLitEnd
- vBase
))
1293 return ERROR(corruption_detected
);
1294 if (match
+ sequence
.matchLength
<= dictEnd
) {
1295 memmove(oLitEnd
, match
, sequence
.matchLength
);
1296 return sequenceLength
;
1298 /* span extDict & currPrefixSegment */
1300 size_t const length1
= dictEnd
- match
;
1301 memmove(oLitEnd
, match
, length1
);
1302 op
= oLitEnd
+ length1
;
1303 sequence
.matchLength
-= length1
;
1305 if (op
> oend_w
|| sequence
.matchLength
< MINMATCH
) {
1307 for (i
= 0; i
< sequence
.matchLength
; ++i
)
1309 return sequenceLength
;
1313 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1315 /* match within prefix */
1316 if (sequence
.offset
< 8) {
1317 /* close range match, overlap */
1318 static const U32 dec32table
[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
1319 static const int dec64table
[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
1320 int const sub2
= dec64table
[sequence
.offset
];
1325 match
+= dec32table
[sequence
.offset
];
1326 ZSTD_copy4(op
+ 4, match
);
1329 ZSTD_copy8(op
, match
);
1334 if (oMatchEnd
> oend
- (16 - MINMATCH
)) {
1336 ZSTD_wildcopy(op
, match
, oend_w
- op
);
1337 match
+= oend_w
- op
;
1340 while (op
< oMatchEnd
)
1343 ZSTD_wildcopy(op
, match
, (ptrdiff_t)sequence
.matchLength
- 8); /* works even if matchLength < 8 */
1345 return sequenceLength
;
1348 static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx
*dctx
, void *dst
, size_t maxDstSize
, const void *seqStart
, size_t seqSize
)
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
;
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 unsigned const windowSize
= dctx
->fParams
.windowSize
;
1363 /* Build Decoding Tables */
1365 size_t const seqHSize
= ZSTD_decodeSeqHeaders(dctx
, &nbSeq
, ip
, seqSize
);
1366 if (ZSTD_isError(seqHSize
))
1371 /* Regen sequences */
1373 #define STORED_SEQS 4
1374 #define STOSEQ_MASK (STORED_SEQS - 1)
1375 #define ADVANCED_SEQS 4
1376 seq_t
*sequences
= (seq_t
*)dctx
->entropy
.workspace
;
1377 int const seqAdvance
= MIN(nbSeq
, ADVANCED_SEQS
);
1378 seqState_t seqState
;
1380 ZSTD_STATIC_ASSERT(sizeof(dctx
->entropy
.workspace
) >= sizeof(seq_t
) * STORED_SEQS
);
1381 dctx
->fseEntropy
= 1;
1384 for (i
= 0; i
< ZSTD_REP_NUM
; i
++)
1385 seqState
.prevOffset
[i
] = dctx
->entropy
.rep
[i
];
1387 seqState
.base
= base
;
1388 seqState
.pos
= (size_t)(op
- base
);
1389 seqState
.gotoDict
= (uPtrDiff
)dictEnd
- (uPtrDiff
)base
; /* cast to avoid undefined behaviour */
1390 CHECK_E(BIT_initDStream(&seqState
.DStream
, ip
, iend
- ip
), corruption_detected
);
1391 FSE_initDState(&seqState
.stateLL
, &seqState
.DStream
, dctx
->LLTptr
);
1392 FSE_initDState(&seqState
.stateOffb
, &seqState
.DStream
, dctx
->OFTptr
);
1393 FSE_initDState(&seqState
.stateML
, &seqState
.DStream
, dctx
->MLTptr
);
1395 /* prepare in advance */
1396 for (seqNb
= 0; (BIT_reloadDStream(&seqState
.DStream
) <= BIT_DStream_completed
) && seqNb
< seqAdvance
; seqNb
++) {
1397 sequences
[seqNb
] = ZSTD_decodeSequenceLong(&seqState
, windowSize
);
1399 if (seqNb
< seqAdvance
)
1400 return ERROR(corruption_detected
);
1402 /* decode and decompress */
1403 for (; (BIT_reloadDStream(&(seqState
.DStream
)) <= BIT_DStream_completed
) && seqNb
< nbSeq
; seqNb
++) {
1404 seq_t
const sequence
= ZSTD_decodeSequenceLong(&seqState
, windowSize
);
1405 size_t const oneSeqSize
=
1406 ZSTD_execSequenceLong(op
, oend
, sequences
[(seqNb
- ADVANCED_SEQS
) & STOSEQ_MASK
], &litPtr
, litEnd
, base
, vBase
, dictEnd
);
1407 if (ZSTD_isError(oneSeqSize
))
1409 ZSTD_PREFETCH(sequence
.match
);
1410 sequences
[seqNb
& STOSEQ_MASK
] = sequence
;
1414 return ERROR(corruption_detected
);
1417 seqNb
-= seqAdvance
;
1418 for (; seqNb
< nbSeq
; seqNb
++) {
1419 size_t const oneSeqSize
= ZSTD_execSequenceLong(op
, oend
, sequences
[seqNb
& STOSEQ_MASK
], &litPtr
, litEnd
, base
, vBase
, dictEnd
);
1420 if (ZSTD_isError(oneSeqSize
))
1425 /* save reps for next block */
1428 for (i
= 0; i
< ZSTD_REP_NUM
; i
++)
1429 dctx
->entropy
.rep
[i
] = (U32
)(seqState
.prevOffset
[i
]);
1433 /* last literal segment */
1435 size_t const lastLLSize
= litEnd
- litPtr
;
1436 if (lastLLSize
> (size_t)(oend
- op
))
1437 return ERROR(dstSize_tooSmall
);
1438 memcpy(op
, litPtr
, lastLLSize
);
1445 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
1446 { /* blockType == blockCompressed */
1447 const BYTE
*ip
= (const BYTE
*)src
;
1449 if (srcSize
>= ZSTD_BLOCKSIZE_ABSOLUTEMAX
)
1450 return ERROR(srcSize_wrong
);
1452 /* Decode literals section */
1454 size_t const litCSize
= ZSTD_decodeLiteralsBlock(dctx
, src
, srcSize
);
1455 if (ZSTD_isError(litCSize
))
1458 srcSize
-= litCSize
;
1460 if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
1461 /* likely because of register pressure */
1462 /* if that's the correct cause, then 32-bits ARM should be affected differently */
1463 /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
1464 if (dctx
->fParams
.windowSize
> (1 << 23))
1465 return ZSTD_decompressSequencesLong(dctx
, dst
, dstCapacity
, ip
, srcSize
);
1466 return ZSTD_decompressSequences(dctx
, dst
, dstCapacity
, ip
, srcSize
);
1469 static void ZSTD_checkContinuity(ZSTD_DCtx
*dctx
, const void *dst
)
1471 if (dst
!= dctx
->previousDstEnd
) { /* not contiguous */
1472 dctx
->dictEnd
= dctx
->previousDstEnd
;
1473 dctx
->vBase
= (const char *)dst
- ((const char *)(dctx
->previousDstEnd
) - (const char *)(dctx
->base
));
1475 dctx
->previousDstEnd
= dst
;
1479 size_t ZSTD_decompressBlock(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
1482 ZSTD_checkContinuity(dctx
, dst
);
1483 dSize
= ZSTD_decompressBlock_internal(dctx
, dst
, dstCapacity
, src
, srcSize
);
1484 dctx
->previousDstEnd
= (char *)dst
+ dSize
;
1488 /** ZSTD_insertBlock() :
1489 insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
1490 size_t ZSTD_insertBlock(ZSTD_DCtx
*dctx
, const void *blockStart
, size_t blockSize
)
1492 ZSTD_checkContinuity(dctx
, blockStart
);
1493 dctx
->previousDstEnd
= (const char *)blockStart
+ blockSize
;
1497 size_t ZSTD_generateNxBytes(void *dst
, size_t dstCapacity
, BYTE byte
, size_t length
)
1499 if (length
> dstCapacity
)
1500 return ERROR(dstSize_tooSmall
);
1501 memset(dst
, byte
, length
);
1505 /** ZSTD_findFrameCompressedSize() :
1506 * compatible with legacy mode
1507 * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
1508 * `srcSize` must be at least as large as the frame contained
1509 * @return : the compressed size of the frame starting at `src` */
1510 size_t ZSTD_findFrameCompressedSize(const void *src
, size_t srcSize
)
1512 if (srcSize
>= ZSTD_skippableHeaderSize
&& (ZSTD_readLE32(src
) & 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
) {
1513 return ZSTD_skippableHeaderSize
+ ZSTD_readLE32((const BYTE
*)src
+ 4);
1515 const BYTE
*ip
= (const BYTE
*)src
;
1516 const BYTE
*const ipstart
= ip
;
1517 size_t remainingSize
= srcSize
;
1518 ZSTD_frameParams fParams
;
1520 size_t const headerSize
= ZSTD_frameHeaderSize(ip
, remainingSize
);
1521 if (ZSTD_isError(headerSize
))
1526 size_t const ret
= ZSTD_getFrameParams(&fParams
, ip
, remainingSize
);
1527 if (ZSTD_isError(ret
))
1530 return ERROR(srcSize_wrong
);
1534 remainingSize
-= headerSize
;
1536 /* Loop on each block */
1538 blockProperties_t blockProperties
;
1539 size_t const cBlockSize
= ZSTD_getcBlockSize(ip
, remainingSize
, &blockProperties
);
1540 if (ZSTD_isError(cBlockSize
))
1543 if (ZSTD_blockHeaderSize
+ cBlockSize
> remainingSize
)
1544 return ERROR(srcSize_wrong
);
1546 ip
+= ZSTD_blockHeaderSize
+ cBlockSize
;
1547 remainingSize
-= ZSTD_blockHeaderSize
+ cBlockSize
;
1549 if (blockProperties
.lastBlock
)
1553 if (fParams
.checksumFlag
) { /* Frame content checksum */
1554 if (remainingSize
< 4)
1555 return ERROR(srcSize_wrong
);
1560 return ip
- ipstart
;
1564 /*! ZSTD_decompressFrame() :
1565 * @dctx must be properly initialized */
1566 static size_t ZSTD_decompressFrame(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void **srcPtr
, size_t *srcSizePtr
)
1568 const BYTE
*ip
= (const BYTE
*)(*srcPtr
);
1569 BYTE
*const ostart
= (BYTE
* const)dst
;
1570 BYTE
*const oend
= ostart
+ dstCapacity
;
1572 size_t remainingSize
= *srcSizePtr
;
1575 if (remainingSize
< ZSTD_frameHeaderSize_min
+ ZSTD_blockHeaderSize
)
1576 return ERROR(srcSize_wrong
);
1580 size_t const frameHeaderSize
= ZSTD_frameHeaderSize(ip
, ZSTD_frameHeaderSize_prefix
);
1581 if (ZSTD_isError(frameHeaderSize
))
1582 return frameHeaderSize
;
1583 if (remainingSize
< frameHeaderSize
+ ZSTD_blockHeaderSize
)
1584 return ERROR(srcSize_wrong
);
1585 CHECK_F(ZSTD_decodeFrameHeader(dctx
, ip
, frameHeaderSize
));
1586 ip
+= frameHeaderSize
;
1587 remainingSize
-= frameHeaderSize
;
1590 /* Loop on each block */
1593 blockProperties_t blockProperties
;
1594 size_t const cBlockSize
= ZSTD_getcBlockSize(ip
, remainingSize
, &blockProperties
);
1595 if (ZSTD_isError(cBlockSize
))
1598 ip
+= ZSTD_blockHeaderSize
;
1599 remainingSize
-= ZSTD_blockHeaderSize
;
1600 if (cBlockSize
> remainingSize
)
1601 return ERROR(srcSize_wrong
);
1603 switch (blockProperties
.blockType
) {
1604 case bt_compressed
: decodedSize
= ZSTD_decompressBlock_internal(dctx
, op
, oend
- op
, ip
, cBlockSize
); break;
1605 case bt_raw
: decodedSize
= ZSTD_copyRawBlock(op
, oend
- op
, ip
, cBlockSize
); break;
1606 case bt_rle
: decodedSize
= ZSTD_generateNxBytes(op
, oend
- op
, *ip
, blockProperties
.origSize
); break;
1608 default: return ERROR(corruption_detected
);
1611 if (ZSTD_isError(decodedSize
))
1613 if (dctx
->fParams
.checksumFlag
)
1614 xxh64_update(&dctx
->xxhState
, op
, decodedSize
);
1617 remainingSize
-= cBlockSize
;
1618 if (blockProperties
.lastBlock
)
1622 if (dctx
->fParams
.checksumFlag
) { /* Frame content checksum verification */
1623 U32
const checkCalc
= (U32
)xxh64_digest(&dctx
->xxhState
);
1625 if (remainingSize
< 4)
1626 return ERROR(checksum_wrong
);
1627 checkRead
= ZSTD_readLE32(ip
);
1628 if (checkRead
!= checkCalc
)
1629 return ERROR(checksum_wrong
);
1634 /* Allow caller to get size read */
1636 *srcSizePtr
= remainingSize
;
1640 static const void *ZSTD_DDictDictContent(const ZSTD_DDict
*ddict
);
1641 static size_t ZSTD_DDictDictSize(const ZSTD_DDict
*ddict
);
1643 static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
, const void *dict
, size_t dictSize
,
1644 const ZSTD_DDict
*ddict
)
1646 void *const dststart
= dst
;
1650 /* programmer error, these two cases should be mutually exclusive */
1651 return ERROR(GENERIC
);
1654 dict
= ZSTD_DDictDictContent(ddict
);
1655 dictSize
= ZSTD_DDictDictSize(ddict
);
1658 while (srcSize
>= ZSTD_frameHeaderSize_prefix
) {
1661 magicNumber
= ZSTD_readLE32(src
);
1662 if (magicNumber
!= ZSTD_MAGICNUMBER
) {
1663 if ((magicNumber
& 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
) {
1664 size_t skippableSize
;
1665 if (srcSize
< ZSTD_skippableHeaderSize
)
1666 return ERROR(srcSize_wrong
);
1667 skippableSize
= ZSTD_readLE32((const BYTE
*)src
+ 4) + ZSTD_skippableHeaderSize
;
1668 if (srcSize
< skippableSize
) {
1669 return ERROR(srcSize_wrong
);
1672 src
= (const BYTE
*)src
+ skippableSize
;
1673 srcSize
-= skippableSize
;
1676 return ERROR(prefix_unknown
);
1681 /* we were called from ZSTD_decompress_usingDDict */
1682 ZSTD_refDDict(dctx
, ddict
);
1684 /* this will initialize correctly with no dict if dict == NULL, so
1685 * use this in all cases but ddict */
1686 CHECK_F(ZSTD_decompressBegin_usingDict(dctx
, dict
, dictSize
));
1688 ZSTD_checkContinuity(dctx
, dst
);
1691 const size_t res
= ZSTD_decompressFrame(dctx
, dst
, dstCapacity
, &src
, &srcSize
);
1692 if (ZSTD_isError(res
))
1694 /* don't need to bounds check this, ZSTD_decompressFrame will have
1696 dst
= (BYTE
*)dst
+ res
;
1702 return ERROR(srcSize_wrong
); /* input not entirely consumed */
1704 return (BYTE
*)dst
- (BYTE
*)dststart
;
1707 size_t ZSTD_decompress_usingDict(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
, const void *dict
, size_t dictSize
)
1709 return ZSTD_decompressMultiFrame(dctx
, dst
, dstCapacity
, src
, srcSize
, dict
, dictSize
, NULL
);
1712 size_t ZSTD_decompressDCtx(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
1714 return ZSTD_decompress_usingDict(dctx
, dst
, dstCapacity
, src
, srcSize
, NULL
, 0);
1717 /*-**************************************
1718 * Advanced Streaming Decompression API
1719 * Bufferless and synchronous
1720 ****************************************/
1721 size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx
*dctx
) { return dctx
->expected
; }
1723 ZSTD_nextInputType_e
ZSTD_nextInputType(ZSTD_DCtx
*dctx
)
1725 switch (dctx
->stage
) {
1726 default: /* should not happen */
1727 case ZSTDds_getFrameHeaderSize
:
1728 case ZSTDds_decodeFrameHeader
: return ZSTDnit_frameHeader
;
1729 case ZSTDds_decodeBlockHeader
: return ZSTDnit_blockHeader
;
1730 case ZSTDds_decompressBlock
: return ZSTDnit_block
;
1731 case ZSTDds_decompressLastBlock
: return ZSTDnit_lastBlock
;
1732 case ZSTDds_checkChecksum
: return ZSTDnit_checksum
;
1733 case ZSTDds_decodeSkippableHeader
:
1734 case ZSTDds_skipFrame
: return ZSTDnit_skippableFrame
;
1738 int ZSTD_isSkipFrame(ZSTD_DCtx
*dctx
) { return dctx
->stage
== ZSTDds_skipFrame
; } /* for zbuff */
1740 /** ZSTD_decompressContinue() :
1741 * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1742 * or an error code, which can be tested using ZSTD_isError() */
1743 size_t ZSTD_decompressContinue(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
1746 if (srcSize
!= dctx
->expected
)
1747 return ERROR(srcSize_wrong
);
1749 ZSTD_checkContinuity(dctx
, dst
);
1751 switch (dctx
->stage
) {
1752 case ZSTDds_getFrameHeaderSize
:
1753 if (srcSize
!= ZSTD_frameHeaderSize_prefix
)
1754 return ERROR(srcSize_wrong
); /* impossible */
1755 if ((ZSTD_readLE32(src
) & 0xFFFFFFF0U
) == ZSTD_MAGIC_SKIPPABLE_START
) { /* skippable frame */
1756 memcpy(dctx
->headerBuffer
, src
, ZSTD_frameHeaderSize_prefix
);
1757 dctx
->expected
= ZSTD_skippableHeaderSize
- ZSTD_frameHeaderSize_prefix
; /* magic number + skippable frame length */
1758 dctx
->stage
= ZSTDds_decodeSkippableHeader
;
1761 dctx
->headerSize
= ZSTD_frameHeaderSize(src
, ZSTD_frameHeaderSize_prefix
);
1762 if (ZSTD_isError(dctx
->headerSize
))
1763 return dctx
->headerSize
;
1764 memcpy(dctx
->headerBuffer
, src
, ZSTD_frameHeaderSize_prefix
);
1765 if (dctx
->headerSize
> ZSTD_frameHeaderSize_prefix
) {
1766 dctx
->expected
= dctx
->headerSize
- ZSTD_frameHeaderSize_prefix
;
1767 dctx
->stage
= ZSTDds_decodeFrameHeader
;
1770 dctx
->expected
= 0; /* not necessary to copy more */
1772 case ZSTDds_decodeFrameHeader
:
1773 memcpy(dctx
->headerBuffer
+ ZSTD_frameHeaderSize_prefix
, src
, dctx
->expected
);
1774 CHECK_F(ZSTD_decodeFrameHeader(dctx
, dctx
->headerBuffer
, dctx
->headerSize
));
1775 dctx
->expected
= ZSTD_blockHeaderSize
;
1776 dctx
->stage
= ZSTDds_decodeBlockHeader
;
1779 case ZSTDds_decodeBlockHeader
: {
1780 blockProperties_t bp
;
1781 size_t const cBlockSize
= ZSTD_getcBlockSize(src
, ZSTD_blockHeaderSize
, &bp
);
1782 if (ZSTD_isError(cBlockSize
))
1784 dctx
->expected
= cBlockSize
;
1785 dctx
->bType
= bp
.blockType
;
1786 dctx
->rleSize
= bp
.origSize
;
1788 dctx
->stage
= bp
.lastBlock
? ZSTDds_decompressLastBlock
: ZSTDds_decompressBlock
;
1793 if (dctx
->fParams
.checksumFlag
) {
1795 dctx
->stage
= ZSTDds_checkChecksum
;
1797 dctx
->expected
= 0; /* end of frame */
1798 dctx
->stage
= ZSTDds_getFrameHeaderSize
;
1801 dctx
->expected
= 3; /* go directly to next header */
1802 dctx
->stage
= ZSTDds_decodeBlockHeader
;
1806 case ZSTDds_decompressLastBlock
:
1807 case ZSTDds_decompressBlock
: {
1809 switch (dctx
->bType
) {
1810 case bt_compressed
: rSize
= ZSTD_decompressBlock_internal(dctx
, dst
, dstCapacity
, src
, srcSize
); break;
1811 case bt_raw
: rSize
= ZSTD_copyRawBlock(dst
, dstCapacity
, src
, srcSize
); break;
1812 case bt_rle
: rSize
= ZSTD_setRleBlock(dst
, dstCapacity
, src
, srcSize
, dctx
->rleSize
); break;
1813 case bt_reserved
: /* should never happen */
1814 default: return ERROR(corruption_detected
);
1816 if (ZSTD_isError(rSize
))
1818 if (dctx
->fParams
.checksumFlag
)
1819 xxh64_update(&dctx
->xxhState
, dst
, rSize
);
1821 if (dctx
->stage
== ZSTDds_decompressLastBlock
) { /* end of frame */
1822 if (dctx
->fParams
.checksumFlag
) { /* another round for frame checksum */
1824 dctx
->stage
= ZSTDds_checkChecksum
;
1826 dctx
->expected
= 0; /* ends here */
1827 dctx
->stage
= ZSTDds_getFrameHeaderSize
;
1830 dctx
->stage
= ZSTDds_decodeBlockHeader
;
1831 dctx
->expected
= ZSTD_blockHeaderSize
;
1832 dctx
->previousDstEnd
= (char *)dst
+ rSize
;
1836 case ZSTDds_checkChecksum
: {
1837 U32
const h32
= (U32
)xxh64_digest(&dctx
->xxhState
);
1838 U32
const check32
= ZSTD_readLE32(src
); /* srcSize == 4, guaranteed by dctx->expected */
1840 return ERROR(checksum_wrong
);
1842 dctx
->stage
= ZSTDds_getFrameHeaderSize
;
1845 case ZSTDds_decodeSkippableHeader
: {
1846 memcpy(dctx
->headerBuffer
+ ZSTD_frameHeaderSize_prefix
, src
, dctx
->expected
);
1847 dctx
->expected
= ZSTD_readLE32(dctx
->headerBuffer
+ 4);
1848 dctx
->stage
= ZSTDds_skipFrame
;
1851 case ZSTDds_skipFrame
: {
1853 dctx
->stage
= ZSTDds_getFrameHeaderSize
;
1857 return ERROR(GENERIC
); /* impossible */
1861 static size_t ZSTD_refDictContent(ZSTD_DCtx
*dctx
, const void *dict
, size_t dictSize
)
1863 dctx
->dictEnd
= dctx
->previousDstEnd
;
1864 dctx
->vBase
= (const char *)dict
- ((const char *)(dctx
->previousDstEnd
) - (const char *)(dctx
->base
));
1866 dctx
->previousDstEnd
= (const char *)dict
+ dictSize
;
1870 /* ZSTD_loadEntropy() :
1871 * dict : must point at beginning of a valid zstd dictionary
1872 * @return : size of entropy tables read */
1873 static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t
*entropy
, const void *const dict
, size_t const dictSize
)
1875 const BYTE
*dictPtr
= (const BYTE
*)dict
;
1876 const BYTE
*const dictEnd
= dictPtr
+ dictSize
;
1879 return ERROR(dictionary_corrupted
);
1880 dictPtr
+= 8; /* skip header = magic + dictID */
1883 size_t const hSize
= HUF_readDTableX4_wksp(entropy
->hufTable
, dictPtr
, dictEnd
- dictPtr
, entropy
->workspace
, sizeof(entropy
->workspace
));
1884 if (HUF_isError(hSize
))
1885 return ERROR(dictionary_corrupted
);
1890 short offcodeNCount
[MaxOff
+ 1];
1891 U32 offcodeMaxValue
= MaxOff
, offcodeLog
;
1892 size_t const offcodeHeaderSize
= FSE_readNCount(offcodeNCount
, &offcodeMaxValue
, &offcodeLog
, dictPtr
, dictEnd
- dictPtr
);
1893 if (FSE_isError(offcodeHeaderSize
))
1894 return ERROR(dictionary_corrupted
);
1895 if (offcodeLog
> OffFSELog
)
1896 return ERROR(dictionary_corrupted
);
1897 CHECK_E(FSE_buildDTable_wksp(entropy
->OFTable
, offcodeNCount
, offcodeMaxValue
, offcodeLog
, entropy
->workspace
, sizeof(entropy
->workspace
)), dictionary_corrupted
);
1898 dictPtr
+= offcodeHeaderSize
;
1902 short matchlengthNCount
[MaxML
+ 1];
1903 unsigned matchlengthMaxValue
= MaxML
, matchlengthLog
;
1904 size_t const matchlengthHeaderSize
= FSE_readNCount(matchlengthNCount
, &matchlengthMaxValue
, &matchlengthLog
, dictPtr
, dictEnd
- dictPtr
);
1905 if (FSE_isError(matchlengthHeaderSize
))
1906 return ERROR(dictionary_corrupted
);
1907 if (matchlengthLog
> MLFSELog
)
1908 return ERROR(dictionary_corrupted
);
1909 CHECK_E(FSE_buildDTable_wksp(entropy
->MLTable
, matchlengthNCount
, matchlengthMaxValue
, matchlengthLog
, entropy
->workspace
, sizeof(entropy
->workspace
)), dictionary_corrupted
);
1910 dictPtr
+= matchlengthHeaderSize
;
1914 short litlengthNCount
[MaxLL
+ 1];
1915 unsigned litlengthMaxValue
= MaxLL
, litlengthLog
;
1916 size_t const litlengthHeaderSize
= FSE_readNCount(litlengthNCount
, &litlengthMaxValue
, &litlengthLog
, dictPtr
, dictEnd
- dictPtr
);
1917 if (FSE_isError(litlengthHeaderSize
))
1918 return ERROR(dictionary_corrupted
);
1919 if (litlengthLog
> LLFSELog
)
1920 return ERROR(dictionary_corrupted
);
1921 CHECK_E(FSE_buildDTable_wksp(entropy
->LLTable
, litlengthNCount
, litlengthMaxValue
, litlengthLog
, entropy
->workspace
, sizeof(entropy
->workspace
)), dictionary_corrupted
);
1922 dictPtr
+= litlengthHeaderSize
;
1925 if (dictPtr
+ 12 > dictEnd
)
1926 return ERROR(dictionary_corrupted
);
1929 size_t const dictContentSize
= (size_t)(dictEnd
- (dictPtr
+ 12));
1930 for (i
= 0; i
< 3; i
++) {
1931 U32
const rep
= ZSTD_readLE32(dictPtr
);
1933 if (rep
== 0 || rep
>= dictContentSize
)
1934 return ERROR(dictionary_corrupted
);
1935 entropy
->rep
[i
] = rep
;
1939 return dictPtr
- (const BYTE
*)dict
;
1942 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx
*dctx
, const void *dict
, size_t dictSize
)
1945 return ZSTD_refDictContent(dctx
, dict
, dictSize
);
1947 U32
const magic
= ZSTD_readLE32(dict
);
1948 if (magic
!= ZSTD_DICT_MAGIC
) {
1949 return ZSTD_refDictContent(dctx
, dict
, dictSize
); /* pure content mode */
1952 dctx
->dictID
= ZSTD_readLE32((const char *)dict
+ 4);
1954 /* load entropy tables */
1956 size_t const eSize
= ZSTD_loadEntropy(&dctx
->entropy
, dict
, dictSize
);
1957 if (ZSTD_isError(eSize
))
1958 return ERROR(dictionary_corrupted
);
1959 dict
= (const char *)dict
+ eSize
;
1962 dctx
->litEntropy
= dctx
->fseEntropy
= 1;
1964 /* reference dictionary content */
1965 return ZSTD_refDictContent(dctx
, dict
, dictSize
);
1968 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx
*dctx
, const void *dict
, size_t dictSize
)
1970 CHECK_F(ZSTD_decompressBegin(dctx
));
1971 if (dict
&& dictSize
)
1972 CHECK_E(ZSTD_decompress_insertDictionary(dctx
, dict
, dictSize
), dictionary_corrupted
);
1976 /* ====== ZSTD_DDict ====== */
1978 struct ZSTD_DDict_s
{
1980 const void *dictContent
;
1982 ZSTD_entropyTables_t entropy
;
1985 ZSTD_customMem cMem
;
1986 }; /* typedef'd to ZSTD_DDict within "zstd.h" */
1988 size_t ZSTD_DDictWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack
)) + ZSTD_ALIGN(sizeof(ZSTD_DDict
)); }
1990 static const void *ZSTD_DDictDictContent(const ZSTD_DDict
*ddict
) { return ddict
->dictContent
; }
1992 static size_t ZSTD_DDictDictSize(const ZSTD_DDict
*ddict
) { return ddict
->dictSize
; }
1994 static void ZSTD_refDDict(ZSTD_DCtx
*dstDCtx
, const ZSTD_DDict
*ddict
)
1996 ZSTD_decompressBegin(dstDCtx
); /* init */
1997 if (ddict
) { /* support refDDict on NULL */
1998 dstDCtx
->dictID
= ddict
->dictID
;
1999 dstDCtx
->base
= ddict
->dictContent
;
2000 dstDCtx
->vBase
= ddict
->dictContent
;
2001 dstDCtx
->dictEnd
= (const BYTE
*)ddict
->dictContent
+ ddict
->dictSize
;
2002 dstDCtx
->previousDstEnd
= dstDCtx
->dictEnd
;
2003 if (ddict
->entropyPresent
) {
2004 dstDCtx
->litEntropy
= 1;
2005 dstDCtx
->fseEntropy
= 1;
2006 dstDCtx
->LLTptr
= ddict
->entropy
.LLTable
;
2007 dstDCtx
->MLTptr
= ddict
->entropy
.MLTable
;
2008 dstDCtx
->OFTptr
= ddict
->entropy
.OFTable
;
2009 dstDCtx
->HUFptr
= ddict
->entropy
.hufTable
;
2010 dstDCtx
->entropy
.rep
[0] = ddict
->entropy
.rep
[0];
2011 dstDCtx
->entropy
.rep
[1] = ddict
->entropy
.rep
[1];
2012 dstDCtx
->entropy
.rep
[2] = ddict
->entropy
.rep
[2];
2014 dstDCtx
->litEntropy
= 0;
2015 dstDCtx
->fseEntropy
= 0;
2020 static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict
*ddict
)
2023 ddict
->entropyPresent
= 0;
2024 if (ddict
->dictSize
< 8)
2027 U32
const magic
= ZSTD_readLE32(ddict
->dictContent
);
2028 if (magic
!= ZSTD_DICT_MAGIC
)
2029 return 0; /* pure content mode */
2031 ddict
->dictID
= ZSTD_readLE32((const char *)ddict
->dictContent
+ 4);
2033 /* load entropy tables */
2034 CHECK_E(ZSTD_loadEntropy(&ddict
->entropy
, ddict
->dictContent
, ddict
->dictSize
), dictionary_corrupted
);
2035 ddict
->entropyPresent
= 1;
2039 static ZSTD_DDict
*ZSTD_createDDict_advanced(const void *dict
, size_t dictSize
, unsigned byReference
, ZSTD_customMem customMem
)
2041 if (!customMem
.customAlloc
|| !customMem
.customFree
)
2045 ZSTD_DDict
*const ddict
= (ZSTD_DDict
*)ZSTD_malloc(sizeof(ZSTD_DDict
), customMem
);
2048 ddict
->cMem
= customMem
;
2050 if ((byReference
) || (!dict
) || (!dictSize
)) {
2051 ddict
->dictBuffer
= NULL
;
2052 ddict
->dictContent
= dict
;
2054 void *const internalBuffer
= ZSTD_malloc(dictSize
, customMem
);
2055 if (!internalBuffer
) {
2056 ZSTD_freeDDict(ddict
);
2059 memcpy(internalBuffer
, dict
, dictSize
);
2060 ddict
->dictBuffer
= internalBuffer
;
2061 ddict
->dictContent
= internalBuffer
;
2063 ddict
->dictSize
= dictSize
;
2064 ddict
->entropy
.hufTable
[0] = (HUF_DTable
)((HufLog
)*0x1000001); /* cover both little and big endian */
2065 /* parse dictionary content */
2067 size_t const errorCode
= ZSTD_loadEntropy_inDDict(ddict
);
2068 if (ZSTD_isError(errorCode
)) {
2069 ZSTD_freeDDict(ddict
);
2078 /*! ZSTD_initDDict() :
2079 * Create a digested dictionary, to start decompression without startup delay.
2080 * `dict` content is copied inside DDict.
2081 * Consequently, `dict` can be released after `ZSTD_DDict` creation */
2082 ZSTD_DDict
*ZSTD_initDDict(const void *dict
, size_t dictSize
, void *workspace
, size_t workspaceSize
)
2084 ZSTD_customMem
const stackMem
= ZSTD_initStack(workspace
, workspaceSize
);
2085 return ZSTD_createDDict_advanced(dict
, dictSize
, 1, stackMem
);
2088 size_t ZSTD_freeDDict(ZSTD_DDict
*ddict
)
2091 return 0; /* support free on NULL */
2093 ZSTD_customMem
const cMem
= ddict
->cMem
;
2094 ZSTD_free(ddict
->dictBuffer
, cMem
);
2095 ZSTD_free(ddict
, cMem
);
2100 /*! ZSTD_getDictID_fromDict() :
2101 * Provides the dictID stored within dictionary.
2102 * if @return == 0, the dictionary is not conformant with Zstandard specification.
2103 * It can still be loaded, but as a content-only dictionary. */
2104 unsigned ZSTD_getDictID_fromDict(const void *dict
, size_t dictSize
)
2108 if (ZSTD_readLE32(dict
) != ZSTD_DICT_MAGIC
)
2110 return ZSTD_readLE32((const char *)dict
+ 4);
2113 /*! ZSTD_getDictID_fromDDict() :
2114 * Provides the dictID of the dictionary loaded into `ddict`.
2115 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
2116 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
2117 unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict
*ddict
)
2121 return ZSTD_getDictID_fromDict(ddict
->dictContent
, ddict
->dictSize
);
2124 /*! ZSTD_getDictID_fromFrame() :
2125 * Provides the dictID required to decompressed the frame stored within `src`.
2126 * If @return == 0, the dictID could not be decoded.
2127 * This could for one of the following reasons :
2128 * - The frame does not require a dictionary to be decoded (most common case).
2129 * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
2130 * Note : this use case also happens when using a non-conformant dictionary.
2131 * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
2132 * - This is not a Zstandard frame.
2133 * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
2134 unsigned ZSTD_getDictID_fromFrame(const void *src
, size_t srcSize
)
2136 ZSTD_frameParams zfp
= {0, 0, 0, 0};
2137 size_t const hError
= ZSTD_getFrameParams(&zfp
, src
, srcSize
);
2138 if (ZSTD_isError(hError
))
2143 /*! ZSTD_decompress_usingDDict() :
2144 * Decompression using a pre-digested Dictionary
2145 * Use dictionary without significant overhead. */
2146 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx
*dctx
, void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
, const ZSTD_DDict
*ddict
)
2148 /* pass content and size in case legacy frames are encountered */
2149 return ZSTD_decompressMultiFrame(dctx
, dst
, dstCapacity
, src
, srcSize
, NULL
, 0, ddict
);
2152 /*=====================================
2153 * Streaming decompression
2154 *====================================*/
2156 typedef enum { zdss_init
, zdss_loadHeader
, zdss_read
, zdss_load
, zdss_flush
} ZSTD_dStreamStage
;
2158 /* *** Resource management *** */
2159 struct ZSTD_DStream_s
{
2161 ZSTD_DDict
*ddictLocal
;
2162 const ZSTD_DDict
*ddict
;
2163 ZSTD_frameParams fParams
;
2164 ZSTD_dStreamStage stage
;
2168 size_t maxWindowSize
;
2174 BYTE headerBuffer
[ZSTD_FRAMEHEADERSIZE_MAX
]; /* tmp buffer to store frame header */
2176 ZSTD_customMem customMem
;
2177 void *legacyContext
;
2178 U32 previousLegacyVersion
;
2181 }; /* typedef'd to ZSTD_DStream within "zstd.h" */
2183 size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize
)
2185 size_t const blockSize
= MIN(maxWindowSize
, ZSTD_BLOCKSIZE_ABSOLUTEMAX
);
2186 size_t const inBuffSize
= blockSize
;
2187 size_t const outBuffSize
= maxWindowSize
+ blockSize
+ WILDCOPY_OVERLENGTH
* 2;
2188 return ZSTD_DCtxWorkspaceBound() + ZSTD_ALIGN(sizeof(ZSTD_DStream
)) + ZSTD_ALIGN(inBuffSize
) + ZSTD_ALIGN(outBuffSize
);
2191 static ZSTD_DStream
*ZSTD_createDStream_advanced(ZSTD_customMem customMem
)
2195 if (!customMem
.customAlloc
|| !customMem
.customFree
)
2198 zds
= (ZSTD_DStream
*)ZSTD_malloc(sizeof(ZSTD_DStream
), customMem
);
2201 memset(zds
, 0, sizeof(ZSTD_DStream
));
2202 memcpy(&zds
->customMem
, &customMem
, sizeof(ZSTD_customMem
));
2203 zds
->dctx
= ZSTD_createDCtx_advanced(customMem
);
2204 if (zds
->dctx
== NULL
) {
2205 ZSTD_freeDStream(zds
);
2208 zds
->stage
= zdss_init
;
2209 zds
->maxWindowSize
= ZSTD_MAXWINDOWSIZE_DEFAULT
;
2213 ZSTD_DStream
*ZSTD_initDStream(size_t maxWindowSize
, void *workspace
, size_t workspaceSize
)
2215 ZSTD_customMem
const stackMem
= ZSTD_initStack(workspace
, workspaceSize
);
2216 ZSTD_DStream
*zds
= ZSTD_createDStream_advanced(stackMem
);
2221 zds
->maxWindowSize
= maxWindowSize
;
2222 zds
->stage
= zdss_loadHeader
;
2223 zds
->lhSize
= zds
->inPos
= zds
->outStart
= zds
->outEnd
= 0;
2224 ZSTD_freeDDict(zds
->ddictLocal
);
2225 zds
->ddictLocal
= NULL
;
2226 zds
->ddict
= zds
->ddictLocal
;
2227 zds
->legacyVersion
= 0;
2228 zds
->hostageByte
= 0;
2231 size_t const blockSize
= MIN(zds
->maxWindowSize
, ZSTD_BLOCKSIZE_ABSOLUTEMAX
);
2232 size_t const neededOutSize
= zds
->maxWindowSize
+ blockSize
+ WILDCOPY_OVERLENGTH
* 2;
2234 zds
->inBuff
= (char *)ZSTD_malloc(blockSize
, zds
->customMem
);
2235 zds
->inBuffSize
= blockSize
;
2236 zds
->outBuff
= (char *)ZSTD_malloc(neededOutSize
, zds
->customMem
);
2237 zds
->outBuffSize
= neededOutSize
;
2238 if (zds
->inBuff
== NULL
|| zds
->outBuff
== NULL
) {
2239 ZSTD_freeDStream(zds
);
2246 ZSTD_DStream
*ZSTD_initDStream_usingDDict(size_t maxWindowSize
, const ZSTD_DDict
*ddict
, void *workspace
, size_t workspaceSize
)
2248 ZSTD_DStream
*zds
= ZSTD_initDStream(maxWindowSize
, workspace
, workspaceSize
);
2255 size_t ZSTD_freeDStream(ZSTD_DStream
*zds
)
2258 return 0; /* support free on null */
2260 ZSTD_customMem
const cMem
= zds
->customMem
;
2261 ZSTD_freeDCtx(zds
->dctx
);
2263 ZSTD_freeDDict(zds
->ddictLocal
);
2264 zds
->ddictLocal
= NULL
;
2265 ZSTD_free(zds
->inBuff
, cMem
);
2267 ZSTD_free(zds
->outBuff
, cMem
);
2268 zds
->outBuff
= NULL
;
2269 ZSTD_free(zds
, cMem
);
2274 /* *** Initialization *** */
2276 size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX
+ ZSTD_blockHeaderSize
; }
2277 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX
; }
2279 size_t ZSTD_resetDStream(ZSTD_DStream
*zds
)
2281 zds
->stage
= zdss_loadHeader
;
2282 zds
->lhSize
= zds
->inPos
= zds
->outStart
= zds
->outEnd
= 0;
2283 zds
->legacyVersion
= 0;
2284 zds
->hostageByte
= 0;
2285 return ZSTD_frameHeaderSize_prefix
;
2288 /* ***** Decompression ***** */
2290 ZSTD_STATIC
size_t ZSTD_limitCopy(void *dst
, size_t dstCapacity
, const void *src
, size_t srcSize
)
2292 size_t const length
= MIN(dstCapacity
, srcSize
);
2293 memcpy(dst
, src
, length
);
2297 size_t ZSTD_decompressStream(ZSTD_DStream
*zds
, ZSTD_outBuffer
*output
, ZSTD_inBuffer
*input
)
2299 const char *const istart
= (const char *)(input
->src
) + input
->pos
;
2300 const char *const iend
= (const char *)(input
->src
) + input
->size
;
2301 const char *ip
= istart
;
2302 char *const ostart
= (char *)(output
->dst
) + output
->pos
;
2303 char *const oend
= (char *)(output
->dst
) + output
->size
;
2305 U32 someMoreWork
= 1;
2307 while (someMoreWork
) {
2308 switch (zds
->stage
) {
2310 ZSTD_resetDStream(zds
); /* transparent reset on starting decoding a new frame */
2313 case zdss_loadHeader
: {
2314 size_t const hSize
= ZSTD_getFrameParams(&zds
->fParams
, zds
->headerBuffer
, zds
->lhSize
);
2315 if (ZSTD_isError(hSize
))
2317 if (hSize
!= 0) { /* need more input */
2318 size_t const toLoad
= hSize
- zds
->lhSize
; /* if hSize!=0, hSize > zds->lhSize */
2319 if (toLoad
> (size_t)(iend
- ip
)) { /* not enough input to load full header */
2320 memcpy(zds
->headerBuffer
+ zds
->lhSize
, ip
, iend
- ip
);
2321 zds
->lhSize
+= iend
- ip
;
2322 input
->pos
= input
->size
;
2323 return (MAX(ZSTD_frameHeaderSize_min
, hSize
) - zds
->lhSize
) +
2324 ZSTD_blockHeaderSize
; /* remaining header bytes + next block header */
2326 memcpy(zds
->headerBuffer
+ zds
->lhSize
, ip
, toLoad
);
2327 zds
->lhSize
= hSize
;
2332 /* check for single-pass mode opportunity */
2333 if (zds
->fParams
.frameContentSize
&& zds
->fParams
.windowSize
/* skippable frame if == 0 */
2334 && (U64
)(size_t)(oend
- op
) >= zds
->fParams
.frameContentSize
) {
2335 size_t const cSize
= ZSTD_findFrameCompressedSize(istart
, iend
- istart
);
2336 if (cSize
<= (size_t)(iend
- istart
)) {
2337 size_t const decompressedSize
= ZSTD_decompress_usingDDict(zds
->dctx
, op
, oend
- op
, istart
, cSize
, zds
->ddict
);
2338 if (ZSTD_isError(decompressedSize
))
2339 return decompressedSize
;
2340 ip
= istart
+ cSize
;
2341 op
+= decompressedSize
;
2342 zds
->dctx
->expected
= 0;
2343 zds
->stage
= zdss_init
;
2349 /* Consume header */
2350 ZSTD_refDDict(zds
->dctx
, zds
->ddict
);
2352 size_t const h1Size
= ZSTD_nextSrcSizeToDecompress(zds
->dctx
); /* == ZSTD_frameHeaderSize_prefix */
2353 CHECK_F(ZSTD_decompressContinue(zds
->dctx
, NULL
, 0, zds
->headerBuffer
, h1Size
));
2355 size_t const h2Size
= ZSTD_nextSrcSizeToDecompress(zds
->dctx
);
2356 CHECK_F(ZSTD_decompressContinue(zds
->dctx
, NULL
, 0, zds
->headerBuffer
+ h1Size
, h2Size
));
2360 zds
->fParams
.windowSize
= MAX(zds
->fParams
.windowSize
, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN
);
2361 if (zds
->fParams
.windowSize
> zds
->maxWindowSize
)
2362 return ERROR(frameParameter_windowTooLarge
);
2364 /* Buffers are preallocated, but double check */
2366 size_t const blockSize
= MIN(zds
->maxWindowSize
, ZSTD_BLOCKSIZE_ABSOLUTEMAX
);
2367 size_t const neededOutSize
= zds
->maxWindowSize
+ blockSize
+ WILDCOPY_OVERLENGTH
* 2;
2368 if (zds
->inBuffSize
< blockSize
) {
2369 return ERROR(GENERIC
);
2371 if (zds
->outBuffSize
< neededOutSize
) {
2372 return ERROR(GENERIC
);
2374 zds
->blockSize
= blockSize
;
2376 zds
->stage
= zdss_read
;
2381 size_t const neededInSize
= ZSTD_nextSrcSizeToDecompress(zds
->dctx
);
2382 if (neededInSize
== 0) { /* end of frame */
2383 zds
->stage
= zdss_init
;
2387 if ((size_t)(iend
- ip
) >= neededInSize
) { /* decode directly from src */
2388 const int isSkipFrame
= ZSTD_isSkipFrame(zds
->dctx
);
2389 size_t const decodedSize
= ZSTD_decompressContinue(zds
->dctx
, zds
->outBuff
+ zds
->outStart
,
2390 (isSkipFrame
? 0 : zds
->outBuffSize
- zds
->outStart
), ip
, neededInSize
);
2391 if (ZSTD_isError(decodedSize
))
2394 if (!decodedSize
&& !isSkipFrame
)
2395 break; /* this was just a header */
2396 zds
->outEnd
= zds
->outStart
+ decodedSize
;
2397 zds
->stage
= zdss_flush
;
2403 } /* no more input */
2404 zds
->stage
= zdss_load
;
2409 size_t const neededInSize
= ZSTD_nextSrcSizeToDecompress(zds
->dctx
);
2410 size_t const toLoad
= neededInSize
- zds
->inPos
; /* should always be <= remaining space within inBuff */
2412 if (toLoad
> zds
->inBuffSize
- zds
->inPos
)
2413 return ERROR(corruption_detected
); /* should never happen */
2414 loadedSize
= ZSTD_limitCopy(zds
->inBuff
+ zds
->inPos
, toLoad
, ip
, iend
- ip
);
2416 zds
->inPos
+= loadedSize
;
2417 if (loadedSize
< toLoad
) {
2420 } /* not enough input, wait for more */
2422 /* decode loaded input */
2424 const int isSkipFrame
= ZSTD_isSkipFrame(zds
->dctx
);
2425 size_t const decodedSize
= ZSTD_decompressContinue(zds
->dctx
, zds
->outBuff
+ zds
->outStart
, zds
->outBuffSize
- zds
->outStart
,
2426 zds
->inBuff
, neededInSize
);
2427 if (ZSTD_isError(decodedSize
))
2429 zds
->inPos
= 0; /* input is consumed */
2430 if (!decodedSize
&& !isSkipFrame
) {
2431 zds
->stage
= zdss_read
;
2433 } /* this was just a header */
2434 zds
->outEnd
= zds
->outStart
+ decodedSize
;
2435 zds
->stage
= zdss_flush
;
2441 size_t const toFlushSize
= zds
->outEnd
- zds
->outStart
;
2442 size_t const flushedSize
= ZSTD_limitCopy(op
, oend
- op
, zds
->outBuff
+ zds
->outStart
, toFlushSize
);
2444 zds
->outStart
+= flushedSize
;
2445 if (flushedSize
== toFlushSize
) { /* flush completed */
2446 zds
->stage
= zdss_read
;
2447 if (zds
->outStart
+ zds
->blockSize
> zds
->outBuffSize
)
2448 zds
->outStart
= zds
->outEnd
= 0;
2451 /* cannot complete flush */
2456 return ERROR(GENERIC
); /* impossible */
2461 input
->pos
+= (size_t)(ip
- istart
);
2462 output
->pos
+= (size_t)(op
- ostart
);
2464 size_t nextSrcSizeHint
= ZSTD_nextSrcSizeToDecompress(zds
->dctx
);
2465 if (!nextSrcSizeHint
) { /* frame fully decoded */
2466 if (zds
->outEnd
== zds
->outStart
) { /* output fully flushed */
2467 if (zds
->hostageByte
) {
2468 if (input
->pos
>= input
->size
) {
2469 zds
->stage
= zdss_read
;
2471 } /* can't release hostage (not present) */
2472 input
->pos
++; /* release hostage */
2476 if (!zds
->hostageByte
) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
2477 input
->pos
--; /* note : pos > 0, otherwise, impossible to finish reading last block */
2478 zds
->hostageByte
= 1;
2482 nextSrcSizeHint
+= ZSTD_blockHeaderSize
* (ZSTD_nextInputType(zds
->dctx
) == ZSTDnit_block
); /* preload header of next block */
2483 if (zds
->inPos
> nextSrcSizeHint
)
2484 return ERROR(GENERIC
); /* should never happen */
2485 nextSrcSizeHint
-= zds
->inPos
; /* already loaded*/
2486 return nextSrcSizeHint
;
2490 EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound
);
2491 EXPORT_SYMBOL(ZSTD_initDCtx
);
2492 EXPORT_SYMBOL(ZSTD_decompressDCtx
);
2493 EXPORT_SYMBOL(ZSTD_decompress_usingDict
);
2495 EXPORT_SYMBOL(ZSTD_DDictWorkspaceBound
);
2496 EXPORT_SYMBOL(ZSTD_initDDict
);
2497 EXPORT_SYMBOL(ZSTD_decompress_usingDDict
);
2499 EXPORT_SYMBOL(ZSTD_DStreamWorkspaceBound
);
2500 EXPORT_SYMBOL(ZSTD_initDStream
);
2501 EXPORT_SYMBOL(ZSTD_initDStream_usingDDict
);
2502 EXPORT_SYMBOL(ZSTD_resetDStream
);
2503 EXPORT_SYMBOL(ZSTD_decompressStream
);
2504 EXPORT_SYMBOL(ZSTD_DStreamInSize
);
2505 EXPORT_SYMBOL(ZSTD_DStreamOutSize
);
2507 EXPORT_SYMBOL(ZSTD_findFrameCompressedSize
);
2508 EXPORT_SYMBOL(ZSTD_getFrameContentSize
);
2509 EXPORT_SYMBOL(ZSTD_findDecompressedSize
);
2511 EXPORT_SYMBOL(ZSTD_isFrame
);
2512 EXPORT_SYMBOL(ZSTD_getDictID_fromDict
);
2513 EXPORT_SYMBOL(ZSTD_getDictID_fromDDict
);
2514 EXPORT_SYMBOL(ZSTD_getDictID_fromFrame
);
2516 EXPORT_SYMBOL(ZSTD_getFrameParams
);
2517 EXPORT_SYMBOL(ZSTD_decompressBegin
);
2518 EXPORT_SYMBOL(ZSTD_decompressBegin_usingDict
);
2519 EXPORT_SYMBOL(ZSTD_copyDCtx
);
2520 EXPORT_SYMBOL(ZSTD_nextSrcSizeToDecompress
);
2521 EXPORT_SYMBOL(ZSTD_decompressContinue
);
2522 EXPORT_SYMBOL(ZSTD_nextInputType
);
2524 EXPORT_SYMBOL(ZSTD_decompressBlock
);
2525 EXPORT_SYMBOL(ZSTD_insertBlock
);
2527 MODULE_LICENSE("Dual BSD/GPL");
2528 MODULE_DESCRIPTION("Zstd Decompressor");