multi_compress 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -3
- data/GET_STARTED.md +3 -3
- data/README.md +75 -66
- data/THIRD_PARTY_NOTICES.md +24 -0
- data/ext/multi_compress/brotli_dec_static_init.c +3 -0
- data/ext/multi_compress/brotli_enc_static_init.c +3 -0
- data/ext/multi_compress/extconf.rb +22 -1
- data/ext/multi_compress/vendor/.vendored +2 -2
- data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
- data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
- data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
- data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
- data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
- data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
- data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
- data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
- data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
- data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
- data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
- data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
- data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
- data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
- data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
- data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
- data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
- data/ext/multi_compress/vendor/zstd/COPYING +339 -0
- data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
- data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
- data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
- data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
- data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
- data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
- data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
- data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
- data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
- data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
- data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
- data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
- data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
- data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
- data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
- data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
- data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
- data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
- data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
- data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
- data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
- data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
- data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
- data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
- data/lib/multi_compress/version.rb +1 -1
- metadata +29 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -56,13 +56,15 @@
|
|
|
56
56
|
* Dependencies
|
|
57
57
|
*********************************************************/
|
|
58
58
|
#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
|
|
59
|
+
#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
|
|
60
|
+
#include "../common/error_private.h"
|
|
61
|
+
#include "../common/zstd_internal.h" /* blockProperties_t */
|
|
59
62
|
#include "../common/mem.h" /* low level memory routines */
|
|
63
|
+
#include "../common/bits.h" /* ZSTD_highbit32 */
|
|
60
64
|
#define FSE_STATIC_LINKING_ONLY
|
|
61
65
|
#include "../common/fse.h"
|
|
62
|
-
#define HUF_STATIC_LINKING_ONLY
|
|
63
66
|
#include "../common/huf.h"
|
|
64
67
|
#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
|
|
65
|
-
#include "../common/zstd_internal.h" /* blockProperties_t */
|
|
66
68
|
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
|
67
69
|
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
|
68
70
|
#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
|
|
@@ -78,11 +80,11 @@
|
|
|
78
80
|
*************************************/
|
|
79
81
|
|
|
80
82
|
#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
|
|
81
|
-
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
|
|
84
|
+
* Currently, that means a 0.75 load factor.
|
|
85
|
+
* So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
|
|
86
|
+
* the load factor of the ddict hash set.
|
|
87
|
+
*/
|
|
86
88
|
|
|
87
89
|
#define DDICT_HASHSET_TABLE_BASE_SIZE 64
|
|
88
90
|
#define DDICT_HASHSET_RESIZE_FACTOR 2
|
|
@@ -243,6 +245,8 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
|
|
|
243
245
|
dctx->outBufferMode = ZSTD_bm_buffered;
|
|
244
246
|
dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
|
|
245
247
|
dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
|
|
248
|
+
dctx->disableHufAsm = 0;
|
|
249
|
+
dctx->maxBlockSizeParam = 0;
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
|
@@ -263,6 +267,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
|
|
263
267
|
#endif
|
|
264
268
|
dctx->noForwardProgress = 0;
|
|
265
269
|
dctx->oversizedDuration = 0;
|
|
270
|
+
dctx->isFrameDecompression = 1;
|
|
266
271
|
#if DYNAMIC_BMI2
|
|
267
272
|
dctx->bmi2 = ZSTD_cpuSupportsBmi2();
|
|
268
273
|
#endif
|
|
@@ -438,16 +443,40 @@ size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
|
|
|
438
443
|
* note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
|
|
439
444
|
* @return : 0, `zfhPtr` is correctly filled,
|
|
440
445
|
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
|
|
441
|
-
|
|
442
|
-
size_t ZSTD_getFrameHeader_advanced(
|
|
446
|
+
** or an error code, which can be tested using ZSTD_isError() */
|
|
447
|
+
size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
|
|
443
448
|
{
|
|
444
449
|
const BYTE* ip = (const BYTE*)src;
|
|
445
450
|
size_t const minInputSize = ZSTD_startingInputLength(format);
|
|
446
451
|
|
|
447
|
-
|
|
448
|
-
if (srcSize < minInputSize) return minInputSize;
|
|
449
|
-
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
|
|
452
|
+
DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize);
|
|
450
453
|
|
|
454
|
+
if (srcSize > 0) {
|
|
455
|
+
/* note : technically could be considered an assert(), since it's an invalid entry */
|
|
456
|
+
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0");
|
|
457
|
+
}
|
|
458
|
+
if (srcSize < minInputSize) {
|
|
459
|
+
if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) {
|
|
460
|
+
/* when receiving less than @minInputSize bytes,
|
|
461
|
+
* control these bytes at least correspond to a supported magic number
|
|
462
|
+
* in order to error out early if they don't.
|
|
463
|
+
**/
|
|
464
|
+
size_t const toCopy = MIN(4, srcSize);
|
|
465
|
+
unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER);
|
|
466
|
+
assert(src != NULL);
|
|
467
|
+
ZSTD_memcpy(hbuf, src, toCopy);
|
|
468
|
+
if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) {
|
|
469
|
+
/* not a zstd frame : let's check if it's a skippable frame */
|
|
470
|
+
MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START);
|
|
471
|
+
ZSTD_memcpy(hbuf, src, toCopy);
|
|
472
|
+
if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) {
|
|
473
|
+
RETURN_ERROR(prefix_unknown,
|
|
474
|
+
"first bytes don't correspond to any supported magic number");
|
|
475
|
+
} } }
|
|
476
|
+
return minInputSize;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */
|
|
451
480
|
if ( (format != ZSTD_f_zstd1_magicless)
|
|
452
481
|
&& (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
|
|
453
482
|
if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
|
@@ -455,8 +484,10 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
|
|
455
484
|
if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
|
|
456
485
|
return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
|
|
457
486
|
ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
|
|
458
|
-
zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
|
|
459
487
|
zfhPtr->frameType = ZSTD_skippableFrame;
|
|
488
|
+
zfhPtr->dictID = MEM_readLE32(src) - ZSTD_MAGIC_SKIPPABLE_START;
|
|
489
|
+
zfhPtr->headerSize = ZSTD_SKIPPABLEHEADERSIZE;
|
|
490
|
+
zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
|
|
460
491
|
return 0;
|
|
461
492
|
}
|
|
462
493
|
RETURN_ERROR(prefix_unknown, "");
|
|
@@ -525,7 +556,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
|
|
525
556
|
* @return : 0, `zfhPtr` is correctly filled,
|
|
526
557
|
* >0, `srcSize` is too small, value is wanted `srcSize` amount,
|
|
527
558
|
* or an error code, which can be tested using ZSTD_isError() */
|
|
528
|
-
size_t ZSTD_getFrameHeader(
|
|
559
|
+
size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize)
|
|
529
560
|
{
|
|
530
561
|
return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
|
|
531
562
|
}
|
|
@@ -543,7 +574,7 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
|
|
|
543
574
|
return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
|
|
544
575
|
}
|
|
545
576
|
#endif
|
|
546
|
-
{
|
|
577
|
+
{ ZSTD_FrameHeader zfh;
|
|
547
578
|
if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)
|
|
548
579
|
return ZSTD_CONTENTSIZE_ERROR;
|
|
549
580
|
if (zfh.frameType == ZSTD_skippableFrame) {
|
|
@@ -563,49 +594,52 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
|
|
|
563
594
|
sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
|
|
564
595
|
RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
|
|
565
596
|
frameParameter_unsupported, "");
|
|
566
|
-
{
|
|
567
|
-
size_t const skippableSize = skippableHeaderSize + sizeU32;
|
|
597
|
+
{ size_t const skippableSize = skippableHeaderSize + sizeU32;
|
|
568
598
|
RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
|
|
569
599
|
return skippableSize;
|
|
570
600
|
}
|
|
571
601
|
}
|
|
572
602
|
|
|
573
603
|
/*! ZSTD_readSkippableFrame() :
|
|
574
|
-
* Retrieves a
|
|
604
|
+
* Retrieves content of a skippable frame, and writes it to dst buffer.
|
|
575
605
|
*
|
|
576
606
|
* The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
|
|
577
607
|
* i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
|
|
578
608
|
* in the magicVariant.
|
|
579
609
|
*
|
|
580
|
-
* Returns an error if destination buffer is not large enough, or if
|
|
610
|
+
* Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame.
|
|
581
611
|
*
|
|
582
612
|
* @return : number of bytes written or a ZSTD error.
|
|
583
613
|
*/
|
|
584
|
-
|
|
585
|
-
|
|
614
|
+
size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
|
|
615
|
+
unsigned* magicVariant, /* optional, can be NULL */
|
|
616
|
+
const void* src, size_t srcSize)
|
|
586
617
|
{
|
|
587
|
-
|
|
588
|
-
size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
|
|
589
|
-
size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
|
|
590
|
-
|
|
591
|
-
/* check input validity */
|
|
592
|
-
RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
|
|
593
|
-
RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
|
|
594
|
-
RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
|
|
618
|
+
RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
|
|
595
619
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
620
|
+
{ U32 const magicNumber = MEM_readLE32(src);
|
|
621
|
+
size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
|
|
622
|
+
size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
|
|
623
|
+
|
|
624
|
+
/* check input validity */
|
|
625
|
+
RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
|
|
626
|
+
RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
|
|
627
|
+
RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
|
|
628
|
+
|
|
629
|
+
/* deliver payload */
|
|
630
|
+
if (skippableContentSize > 0 && dst != NULL)
|
|
631
|
+
ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
|
|
632
|
+
if (magicVariant != NULL)
|
|
633
|
+
*magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
|
|
634
|
+
return skippableContentSize;
|
|
635
|
+
}
|
|
602
636
|
}
|
|
603
637
|
|
|
604
638
|
/** ZSTD_findDecompressedSize() :
|
|
605
|
-
* compatible with legacy mode
|
|
606
639
|
* `srcSize` must be the exact length of some number of ZSTD compressed and/or
|
|
607
640
|
* skippable frames
|
|
608
|
-
*
|
|
641
|
+
* note: compatible with legacy mode
|
|
642
|
+
* @return : decompressed size of the frames contained */
|
|
609
643
|
unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
610
644
|
{
|
|
611
645
|
unsigned long long totalDstSize = 0;
|
|
@@ -615,9 +649,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
|
615
649
|
|
|
616
650
|
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
|
617
651
|
size_t const skippableSize = readSkippableFrameSize(src, srcSize);
|
|
618
|
-
if (ZSTD_isError(skippableSize))
|
|
619
|
-
return ZSTD_CONTENTSIZE_ERROR;
|
|
620
|
-
}
|
|
652
|
+
if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR;
|
|
621
653
|
assert(skippableSize <= srcSize);
|
|
622
654
|
|
|
623
655
|
src = (const BYTE *)src + skippableSize;
|
|
@@ -625,17 +657,17 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
|
|
|
625
657
|
continue;
|
|
626
658
|
}
|
|
627
659
|
|
|
628
|
-
{ unsigned long long const
|
|
629
|
-
if (
|
|
660
|
+
{ unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize);
|
|
661
|
+
if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs;
|
|
630
662
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
totalDstSize +=
|
|
663
|
+
if (totalDstSize + fcs < totalDstSize)
|
|
664
|
+
return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */
|
|
665
|
+
totalDstSize += fcs;
|
|
634
666
|
}
|
|
667
|
+
/* skip to next frame */
|
|
635
668
|
{ size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
|
|
636
|
-
if (ZSTD_isError(frameSrcSize))
|
|
637
|
-
|
|
638
|
-
}
|
|
669
|
+
if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR;
|
|
670
|
+
assert(frameSrcSize <= srcSize);
|
|
639
671
|
|
|
640
672
|
src = (const BYTE *)src + frameSrcSize;
|
|
641
673
|
srcSize -= frameSrcSize;
|
|
@@ -699,17 +731,17 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
|
|
|
699
731
|
return frameSizeInfo;
|
|
700
732
|
}
|
|
701
733
|
|
|
702
|
-
static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
|
|
734
|
+
static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format)
|
|
703
735
|
{
|
|
704
736
|
ZSTD_frameSizeInfo frameSizeInfo;
|
|
705
737
|
ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
|
|
706
738
|
|
|
707
739
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
|
708
|
-
if (ZSTD_isLegacy(src, srcSize))
|
|
740
|
+
if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize))
|
|
709
741
|
return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
|
|
710
742
|
#endif
|
|
711
743
|
|
|
712
|
-
if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
|
|
744
|
+
if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
|
|
713
745
|
&& (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
|
714
746
|
frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
|
|
715
747
|
assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
|
|
@@ -720,10 +752,10 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
|
|
|
720
752
|
const BYTE* const ipstart = ip;
|
|
721
753
|
size_t remainingSize = srcSize;
|
|
722
754
|
size_t nbBlocks = 0;
|
|
723
|
-
|
|
755
|
+
ZSTD_FrameHeader zfh;
|
|
724
756
|
|
|
725
757
|
/* Extract Frame Header */
|
|
726
|
-
{ size_t const ret =
|
|
758
|
+
{ size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format);
|
|
727
759
|
if (ZSTD_isError(ret))
|
|
728
760
|
return ZSTD_errorFrameSizeInfo(ret);
|
|
729
761
|
if (ret > 0)
|
|
@@ -757,28 +789,31 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
|
|
|
757
789
|
ip += 4;
|
|
758
790
|
}
|
|
759
791
|
|
|
792
|
+
frameSizeInfo.nbBlocks = nbBlocks;
|
|
760
793
|
frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
|
|
761
794
|
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
|
|
762
795
|
? zfh.frameContentSize
|
|
763
|
-
: nbBlocks * zfh.blockSizeMax;
|
|
796
|
+
: (unsigned long long)nbBlocks * zfh.blockSizeMax;
|
|
764
797
|
return frameSizeInfo;
|
|
765
798
|
}
|
|
766
799
|
}
|
|
767
800
|
|
|
801
|
+
static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) {
|
|
802
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format);
|
|
803
|
+
return frameSizeInfo.compressedSize;
|
|
804
|
+
}
|
|
805
|
+
|
|
768
806
|
/** ZSTD_findFrameCompressedSize() :
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
* `srcSize` must be at least as large as the frame contained
|
|
772
|
-
* @return : the compressed size of the frame starting at `src` */
|
|
807
|
+
* See docs in zstd.h
|
|
808
|
+
* Note: compatible with legacy mode */
|
|
773
809
|
size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
|
|
774
810
|
{
|
|
775
|
-
|
|
776
|
-
return frameSizeInfo.compressedSize;
|
|
811
|
+
return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1);
|
|
777
812
|
}
|
|
778
813
|
|
|
779
814
|
/** ZSTD_decompressBound() :
|
|
780
815
|
* compatible with legacy mode
|
|
781
|
-
* `src` must point to the start of a ZSTD frame or a
|
|
816
|
+
* `src` must point to the start of a ZSTD frame or a skippable frame
|
|
782
817
|
* `srcSize` must be at least as large as the frame contained
|
|
783
818
|
* @return : the maximum decompressed size of the compressed source
|
|
784
819
|
*/
|
|
@@ -787,7 +822,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
|
|
|
787
822
|
unsigned long long bound = 0;
|
|
788
823
|
/* Iterate over each frame */
|
|
789
824
|
while (srcSize > 0) {
|
|
790
|
-
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
|
|
825
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
|
|
791
826
|
size_t const compressedSize = frameSizeInfo.compressedSize;
|
|
792
827
|
unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
|
|
793
828
|
if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
|
|
@@ -800,6 +835,48 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
|
|
|
800
835
|
return bound;
|
|
801
836
|
}
|
|
802
837
|
|
|
838
|
+
size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
|
|
839
|
+
{
|
|
840
|
+
size_t margin = 0;
|
|
841
|
+
unsigned maxBlockSize = 0;
|
|
842
|
+
|
|
843
|
+
/* Iterate over each frame */
|
|
844
|
+
while (srcSize > 0) {
|
|
845
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
|
|
846
|
+
size_t const compressedSize = frameSizeInfo.compressedSize;
|
|
847
|
+
unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
|
|
848
|
+
ZSTD_FrameHeader zfh;
|
|
849
|
+
|
|
850
|
+
FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), "");
|
|
851
|
+
if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
|
|
852
|
+
return ERROR(corruption_detected);
|
|
853
|
+
|
|
854
|
+
if (zfh.frameType == ZSTD_frame) {
|
|
855
|
+
/* Add the frame header to our margin */
|
|
856
|
+
margin += zfh.headerSize;
|
|
857
|
+
/* Add the checksum to our margin */
|
|
858
|
+
margin += zfh.checksumFlag ? 4 : 0;
|
|
859
|
+
/* Add 3 bytes per block */
|
|
860
|
+
margin += 3 * frameSizeInfo.nbBlocks;
|
|
861
|
+
|
|
862
|
+
/* Compute the max block size */
|
|
863
|
+
maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax);
|
|
864
|
+
} else {
|
|
865
|
+
assert(zfh.frameType == ZSTD_skippableFrame);
|
|
866
|
+
/* Add the entire skippable frame size to our margin. */
|
|
867
|
+
margin += compressedSize;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
assert(srcSize >= compressedSize);
|
|
871
|
+
src = (const BYTE*)src + compressedSize;
|
|
872
|
+
srcSize -= compressedSize;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/* Add the max block size back to the margin. */
|
|
876
|
+
margin += maxBlockSize;
|
|
877
|
+
|
|
878
|
+
return margin;
|
|
879
|
+
}
|
|
803
880
|
|
|
804
881
|
/*-*************************************************************
|
|
805
882
|
* Frame decoding
|
|
@@ -825,7 +902,7 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
|
|
|
825
902
|
if (srcSize == 0) return 0;
|
|
826
903
|
RETURN_ERROR(dstBuffer_null, "");
|
|
827
904
|
}
|
|
828
|
-
|
|
905
|
+
ZSTD_memmove(dst, src, srcSize);
|
|
829
906
|
return srcSize;
|
|
830
907
|
}
|
|
831
908
|
|
|
@@ -842,7 +919,7 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
|
|
|
842
919
|
return regenSize;
|
|
843
920
|
}
|
|
844
921
|
|
|
845
|
-
static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize,
|
|
922
|
+
static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, int streaming)
|
|
846
923
|
{
|
|
847
924
|
#if ZSTD_TRACE
|
|
848
925
|
if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) {
|
|
@@ -901,8 +978,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
901
978
|
ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
|
|
902
979
|
}
|
|
903
980
|
|
|
981
|
+
/* Shrink the blockSizeMax if enabled */
|
|
982
|
+
if (dctx->maxBlockSizeParam != 0)
|
|
983
|
+
dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam);
|
|
984
|
+
|
|
904
985
|
/* Loop on each block */
|
|
905
986
|
while (1) {
|
|
987
|
+
BYTE* oBlockEnd = oend;
|
|
906
988
|
size_t decodedSize;
|
|
907
989
|
blockProperties_t blockProperties;
|
|
908
990
|
size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
|
|
@@ -912,27 +994,48 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
912
994
|
remainingSrcSize -= ZSTD_blockHeaderSize;
|
|
913
995
|
RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
|
|
914
996
|
|
|
997
|
+
if (ip >= op && ip < oBlockEnd) {
|
|
998
|
+
/* We are decompressing in-place. Limit the output pointer so that we
|
|
999
|
+
* don't overwrite the block that we are currently reading. This will
|
|
1000
|
+
* fail decompression if the input & output pointers aren't spaced
|
|
1001
|
+
* far enough apart.
|
|
1002
|
+
*
|
|
1003
|
+
* This is important to set, even when the pointers are far enough
|
|
1004
|
+
* apart, because ZSTD_decompressBlock_internal() can decide to store
|
|
1005
|
+
* literals in the output buffer, after the block it is decompressing.
|
|
1006
|
+
* Since we don't want anything to overwrite our input, we have to tell
|
|
1007
|
+
* ZSTD_decompressBlock_internal to never write past ip.
|
|
1008
|
+
*
|
|
1009
|
+
* See ZSTD_allocateLiteralsBuffer() for reference.
|
|
1010
|
+
*/
|
|
1011
|
+
oBlockEnd = op + (ip - op);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
915
1014
|
switch(blockProperties.blockType)
|
|
916
1015
|
{
|
|
917
1016
|
case bt_compressed:
|
|
918
|
-
|
|
1017
|
+
assert(dctx->isFrameDecompression == 1);
|
|
1018
|
+
decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming);
|
|
919
1019
|
break;
|
|
920
1020
|
case bt_raw :
|
|
1021
|
+
/* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
|
|
921
1022
|
decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
|
|
922
1023
|
break;
|
|
923
1024
|
case bt_rle :
|
|
924
|
-
decodedSize = ZSTD_setRleBlock(op, (size_t)(
|
|
1025
|
+
decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
|
|
925
1026
|
break;
|
|
926
1027
|
case bt_reserved :
|
|
927
1028
|
default:
|
|
928
1029
|
RETURN_ERROR(corruption_detected, "invalid block type");
|
|
929
1030
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
if (dctx->validateChecksum)
|
|
1031
|
+
FORWARD_IF_ERROR(decodedSize, "Block decompression failure");
|
|
1032
|
+
DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize);
|
|
1033
|
+
if (dctx->validateChecksum) {
|
|
933
1034
|
XXH64_update(&dctx->xxhState, op, decodedSize);
|
|
934
|
-
|
|
1035
|
+
}
|
|
1036
|
+
if (decodedSize) /* support dst = NULL,0 */ {
|
|
935
1037
|
op += decodedSize;
|
|
1038
|
+
}
|
|
936
1039
|
assert(ip != NULL);
|
|
937
1040
|
ip += cBlockSize;
|
|
938
1041
|
remainingSrcSize -= cBlockSize;
|
|
@@ -956,12 +1059,15 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
|
956
1059
|
}
|
|
957
1060
|
ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
|
|
958
1061
|
/* Allow caller to get size read */
|
|
1062
|
+
DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %i, consuming %i bytes of input", (int)(op-ostart), (int)(ip - (const BYTE*)*srcPtr));
|
|
959
1063
|
*srcPtr = ip;
|
|
960
1064
|
*srcSizePtr = remainingSrcSize;
|
|
961
1065
|
return (size_t)(op-ostart);
|
|
962
1066
|
}
|
|
963
1067
|
|
|
964
|
-
static
|
|
1068
|
+
static
|
|
1069
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
1070
|
+
size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
965
1071
|
void* dst, size_t dstCapacity,
|
|
966
1072
|
const void* src, size_t srcSize,
|
|
967
1073
|
const void* dict, size_t dictSize,
|
|
@@ -981,7 +1087,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
|
981
1087
|
while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
|
|
982
1088
|
|
|
983
1089
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
|
984
|
-
if (ZSTD_isLegacy(src, srcSize)) {
|
|
1090
|
+
if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) {
|
|
985
1091
|
size_t decodedSize;
|
|
986
1092
|
size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
|
|
987
1093
|
if (ZSTD_isError(frameSize)) return frameSize;
|
|
@@ -991,6 +1097,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
|
991
1097
|
decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
|
|
992
1098
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
|
993
1099
|
|
|
1100
|
+
{
|
|
1101
|
+
unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize);
|
|
1102
|
+
RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!");
|
|
1103
|
+
if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
|
1104
|
+
RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected,
|
|
1105
|
+
"Frame header size does not match decoded size!");
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
|
|
994
1109
|
assert(decodedSize <= dstCapacity);
|
|
995
1110
|
dst = (BYTE*)dst + decodedSize;
|
|
996
1111
|
dstCapacity -= decodedSize;
|
|
@@ -1002,17 +1117,18 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
|
1002
1117
|
}
|
|
1003
1118
|
#endif
|
|
1004
1119
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1120
|
+
if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) {
|
|
1121
|
+
U32 const magicNumber = MEM_readLE32(src);
|
|
1122
|
+
DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
|
|
1008
1123
|
if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
|
1124
|
+
/* skippable frame detected : skip it */
|
|
1009
1125
|
size_t const skippableSize = readSkippableFrameSize(src, srcSize);
|
|
1010
|
-
FORWARD_IF_ERROR(skippableSize, "
|
|
1126
|
+
FORWARD_IF_ERROR(skippableSize, "invalid skippable frame");
|
|
1011
1127
|
assert(skippableSize <= srcSize);
|
|
1012
1128
|
|
|
1013
1129
|
src = (const BYTE *)src + skippableSize;
|
|
1014
1130
|
srcSize -= skippableSize;
|
|
1015
|
-
continue;
|
|
1131
|
+
continue; /* check next frame */
|
|
1016
1132
|
} }
|
|
1017
1133
|
|
|
1018
1134
|
if (ddict) {
|
|
@@ -1108,8 +1224,8 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|
|
1108
1224
|
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
|
|
1109
1225
|
|
|
1110
1226
|
/**
|
|
1111
|
-
* Similar to ZSTD_nextSrcSizeToDecompress(), but when
|
|
1112
|
-
*
|
|
1227
|
+
* Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we
|
|
1228
|
+
* allow taking a partial block as the input. Currently only raw uncompressed blocks can
|
|
1113
1229
|
* be streamed.
|
|
1114
1230
|
*
|
|
1115
1231
|
* For blocks that can be streamed, this allows us to reduce the latency until we produce
|
|
@@ -1228,7 +1344,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
|
1228
1344
|
{
|
|
1229
1345
|
case bt_compressed:
|
|
1230
1346
|
DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
|
|
1231
|
-
|
|
1347
|
+
assert(dctx->isFrameDecompression == 1);
|
|
1348
|
+
rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming);
|
|
1232
1349
|
dctx->expected = 0; /* Streaming not supported */
|
|
1233
1350
|
break;
|
|
1234
1351
|
case bt_raw :
|
|
@@ -1297,6 +1414,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
|
1297
1414
|
case ZSTDds_decodeSkippableHeader:
|
|
1298
1415
|
assert(src != NULL);
|
|
1299
1416
|
assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
|
|
1417
|
+
assert(dctx->format != ZSTD_f_zstd1_magicless);
|
|
1300
1418
|
ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
|
|
1301
1419
|
dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
|
|
1302
1420
|
dctx->stage = ZSTDds_skipFrame;
|
|
@@ -1309,7 +1427,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
|
1309
1427
|
|
|
1310
1428
|
default:
|
|
1311
1429
|
assert(0); /* impossible */
|
|
1312
|
-
RETURN_ERROR(GENERIC, "impossible to reach"); /* some
|
|
1430
|
+
RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
|
|
1313
1431
|
}
|
|
1314
1432
|
}
|
|
1315
1433
|
|
|
@@ -1350,11 +1468,11 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
|
1350
1468
|
/* in minimal huffman, we always use X1 variants */
|
|
1351
1469
|
size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
|
|
1352
1470
|
dictPtr, dictEnd - dictPtr,
|
|
1353
|
-
workspace, workspaceSize);
|
|
1471
|
+
workspace, workspaceSize, /* flags */ 0);
|
|
1354
1472
|
#else
|
|
1355
1473
|
size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
|
|
1356
1474
|
dictPtr, (size_t)(dictEnd - dictPtr),
|
|
1357
|
-
workspace, workspaceSize);
|
|
1475
|
+
workspace, workspaceSize, /* flags */ 0);
|
|
1358
1476
|
#endif
|
|
1359
1477
|
RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
|
|
1360
1478
|
dictPtr += hSize;
|
|
@@ -1453,10 +1571,11 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|
|
1453
1571
|
dctx->prefixStart = NULL;
|
|
1454
1572
|
dctx->virtualStart = NULL;
|
|
1455
1573
|
dctx->dictEnd = NULL;
|
|
1456
|
-
dctx->entropy.hufTable[0] = (HUF_DTable)((
|
|
1574
|
+
dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
|
|
1457
1575
|
dctx->litEntropy = dctx->fseEntropy = 0;
|
|
1458
1576
|
dctx->dictID = 0;
|
|
1459
1577
|
dctx->bType = bt_reserved;
|
|
1578
|
+
dctx->isFrameDecompression = 1;
|
|
1460
1579
|
ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
|
|
1461
1580
|
ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
|
|
1462
1581
|
dctx->LLTptr = dctx->entropy.LLTable;
|
|
@@ -1515,7 +1634,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
|
1515
1634
|
* This could for one of the following reasons :
|
|
1516
1635
|
* - The frame does not require a dictionary (most common case).
|
|
1517
1636
|
* - The frame was built with dictID intentionally removed.
|
|
1518
|
-
* Needed dictionary is a hidden information.
|
|
1637
|
+
* Needed dictionary is a hidden piece of information.
|
|
1519
1638
|
* Note : this use case also happens when using a non-conformant dictionary.
|
|
1520
1639
|
* - `srcSize` is too small, and as a result, frame header could not be decoded.
|
|
1521
1640
|
* Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
|
|
@@ -1524,7 +1643,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
|
1524
1643
|
* ZSTD_getFrameHeader(), which will provide a more precise error code. */
|
|
1525
1644
|
unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
|
|
1526
1645
|
{
|
|
1527
|
-
|
|
1646
|
+
ZSTD_FrameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
|
|
1528
1647
|
size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
|
|
1529
1648
|
if (ZSTD_isError(hError)) return 0;
|
|
1530
1649
|
return zfp.dictID;
|
|
@@ -1631,7 +1750,9 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|
|
1631
1750
|
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|
1632
1751
|
{
|
|
1633
1752
|
DEBUGLOG(4, "ZSTD_initDStream");
|
|
1634
|
-
|
|
1753
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_reset(zds, ZSTD_reset_session_only), "");
|
|
1754
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), "");
|
|
1755
|
+
return ZSTD_startingInputLength(zds->format);
|
|
1635
1756
|
}
|
|
1636
1757
|
|
|
1637
1758
|
/* ZSTD_initDStream_usingDDict() :
|
|
@@ -1639,6 +1760,7 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|
|
1639
1760
|
* this function cannot fail */
|
|
1640
1761
|
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
|
1641
1762
|
{
|
|
1763
|
+
DEBUGLOG(4, "ZSTD_initDStream_usingDDict");
|
|
1642
1764
|
FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
|
|
1643
1765
|
FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
|
|
1644
1766
|
return ZSTD_startingInputLength(dctx->format);
|
|
@@ -1649,6 +1771,7 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
|
|
1649
1771
|
* this function cannot fail */
|
|
1650
1772
|
size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
|
|
1651
1773
|
{
|
|
1774
|
+
DEBUGLOG(4, "ZSTD_resetDStream");
|
|
1652
1775
|
FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
|
|
1653
1776
|
return ZSTD_startingInputLength(dctx->format);
|
|
1654
1777
|
}
|
|
@@ -1720,6 +1843,15 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
|
|
|
1720
1843
|
bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
|
|
1721
1844
|
bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
|
|
1722
1845
|
return bounds;
|
|
1846
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1847
|
+
bounds.lowerBound = 0;
|
|
1848
|
+
bounds.upperBound = 1;
|
|
1849
|
+
return bounds;
|
|
1850
|
+
case ZSTD_d_maxBlockSize:
|
|
1851
|
+
bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
|
|
1852
|
+
bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
|
|
1853
|
+
return bounds;
|
|
1854
|
+
|
|
1723
1855
|
default:;
|
|
1724
1856
|
}
|
|
1725
1857
|
bounds.error = ERROR(parameter_unsupported);
|
|
@@ -1760,6 +1892,12 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value
|
|
|
1760
1892
|
case ZSTD_d_refMultipleDDicts:
|
|
1761
1893
|
*value = (int)dctx->refMultipleDDicts;
|
|
1762
1894
|
return 0;
|
|
1895
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1896
|
+
*value = (int)dctx->disableHufAsm;
|
|
1897
|
+
return 0;
|
|
1898
|
+
case ZSTD_d_maxBlockSize:
|
|
1899
|
+
*value = dctx->maxBlockSizeParam;
|
|
1900
|
+
return 0;
|
|
1763
1901
|
default:;
|
|
1764
1902
|
}
|
|
1765
1903
|
RETURN_ERROR(parameter_unsupported, "");
|
|
@@ -1793,6 +1931,14 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
|
|
|
1793
1931
|
}
|
|
1794
1932
|
dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
|
|
1795
1933
|
return 0;
|
|
1934
|
+
case ZSTD_d_disableHuffmanAssembly:
|
|
1935
|
+
CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
|
|
1936
|
+
dctx->disableHufAsm = value != 0;
|
|
1937
|
+
return 0;
|
|
1938
|
+
case ZSTD_d_maxBlockSize:
|
|
1939
|
+
if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value);
|
|
1940
|
+
dctx->maxBlockSizeParam = value;
|
|
1941
|
+
return 0;
|
|
1796
1942
|
default:;
|
|
1797
1943
|
}
|
|
1798
1944
|
RETURN_ERROR(parameter_unsupported, "");
|
|
@@ -1804,6 +1950,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
|
|
|
1804
1950
|
|| (reset == ZSTD_reset_session_and_parameters) ) {
|
|
1805
1951
|
dctx->streamStage = zdss_init;
|
|
1806
1952
|
dctx->noForwardProgress = 0;
|
|
1953
|
+
dctx->isFrameDecompression = 1;
|
|
1807
1954
|
}
|
|
1808
1955
|
if ( (reset == ZSTD_reset_parameters)
|
|
1809
1956
|
|| (reset == ZSTD_reset_session_and_parameters) ) {
|
|
@@ -1820,11 +1967,17 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
|
|
|
1820
1967
|
return ZSTD_sizeof_DCtx(dctx);
|
|
1821
1968
|
}
|
|
1822
1969
|
|
|
1823
|
-
size_t
|
|
1970
|
+
static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax)
|
|
1824
1971
|
{
|
|
1825
|
-
size_t const blockSize = (size_t)
|
|
1826
|
-
/*
|
|
1827
|
-
|
|
1972
|
+
size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax);
|
|
1973
|
+
/* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block
|
|
1974
|
+
* ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing
|
|
1975
|
+
* the block at the beginning of the output buffer, and maintain a full window.
|
|
1976
|
+
*
|
|
1977
|
+
* We need another blockSize worth of buffer so that we can store split
|
|
1978
|
+
* literals at the end of the block without overwriting the extDict window.
|
|
1979
|
+
*/
|
|
1980
|
+
unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2);
|
|
1828
1981
|
unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
|
|
1829
1982
|
size_t const minRBSize = (size_t) neededSize;
|
|
1830
1983
|
RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
|
|
@@ -1832,6 +1985,11 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
|
|
|
1832
1985
|
return minRBSize;
|
|
1833
1986
|
}
|
|
1834
1987
|
|
|
1988
|
+
size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
|
|
1989
|
+
{
|
|
1990
|
+
return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX);
|
|
1991
|
+
}
|
|
1992
|
+
|
|
1835
1993
|
size_t ZSTD_estimateDStreamSize(size_t windowSize)
|
|
1836
1994
|
{
|
|
1837
1995
|
size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
|
|
@@ -1843,7 +2001,7 @@ size_t ZSTD_estimateDStreamSize(size_t windowSize)
|
|
|
1843
2001
|
size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
|
|
1844
2002
|
{
|
|
1845
2003
|
U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
|
|
1846
|
-
|
|
2004
|
+
ZSTD_FrameHeader zfh;
|
|
1847
2005
|
size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
|
|
1848
2006
|
if (ZSTD_isError(err)) return err;
|
|
1849
2007
|
RETURN_ERROR_IF(err>0, srcSize_wrong, "");
|
|
@@ -1938,6 +2096,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
1938
2096
|
U32 someMoreWork = 1;
|
|
1939
2097
|
|
|
1940
2098
|
DEBUGLOG(5, "ZSTD_decompressStream");
|
|
2099
|
+
assert(zds != NULL);
|
|
1941
2100
|
RETURN_ERROR_IF(
|
|
1942
2101
|
input->pos > input->size,
|
|
1943
2102
|
srcSize_wrong,
|
|
@@ -1980,7 +2139,6 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
1980
2139
|
if (zds->refMultipleDDicts && zds->ddictSet) {
|
|
1981
2140
|
ZSTD_DCtx_selectFrameDDict(zds);
|
|
1982
2141
|
}
|
|
1983
|
-
DEBUGLOG(5, "header size : %u", (U32)hSize);
|
|
1984
2142
|
if (ZSTD_isError(hSize)) {
|
|
1985
2143
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
|
1986
2144
|
U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
|
|
@@ -2012,6 +2170,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2012
2170
|
zds->lhSize += remainingInput;
|
|
2013
2171
|
}
|
|
2014
2172
|
input->pos = input->size;
|
|
2173
|
+
/* check first few bytes */
|
|
2174
|
+
FORWARD_IF_ERROR(
|
|
2175
|
+
ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format),
|
|
2176
|
+
"First few bytes detected incorrect" );
|
|
2177
|
+
/* return hint input size */
|
|
2015
2178
|
return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
|
|
2016
2179
|
}
|
|
2017
2180
|
assert(ip != NULL);
|
|
@@ -2023,14 +2186,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2023
2186
|
if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
|
|
2024
2187
|
&& zds->fParams.frameType != ZSTD_skippableFrame
|
|
2025
2188
|
&& (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
|
|
2026
|
-
size_t const cSize =
|
|
2189
|
+
size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format);
|
|
2027
2190
|
if (cSize <= (size_t)(iend-istart)) {
|
|
2028
2191
|
/* shortcut : using single-pass mode */
|
|
2029
2192
|
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
|
|
2030
2193
|
if (ZSTD_isError(decompressedSize)) return decompressedSize;
|
|
2031
|
-
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
|
|
2194
|
+
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()");
|
|
2195
|
+
assert(istart != NULL);
|
|
2032
2196
|
ip = istart + cSize;
|
|
2033
|
-
op
|
|
2197
|
+
op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
|
|
2034
2198
|
zds->expected = 0;
|
|
2035
2199
|
zds->streamStage = zdss_init;
|
|
2036
2200
|
someMoreWork = 0;
|
|
@@ -2049,7 +2213,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2049
2213
|
DEBUGLOG(4, "Consume header");
|
|
2050
2214
|
FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
|
|
2051
2215
|
|
|
2052
|
-
if (
|
|
2216
|
+
if (zds->format == ZSTD_f_zstd1
|
|
2217
|
+
&& (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
|
|
2053
2218
|
zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
|
|
2054
2219
|
zds->stage = ZSTDds_skipFrame;
|
|
2055
2220
|
} else {
|
|
@@ -2065,11 +2230,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2065
2230
|
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
|
2066
2231
|
RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
|
|
2067
2232
|
frameParameter_windowTooLarge, "");
|
|
2233
|
+
if (zds->maxBlockSizeParam != 0)
|
|
2234
|
+
zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam);
|
|
2068
2235
|
|
|
2069
2236
|
/* Adapt buffer sizes to frame header instructions */
|
|
2070
2237
|
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
|
|
2071
2238
|
size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
|
|
2072
|
-
?
|
|
2239
|
+
? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax)
|
|
2073
2240
|
: 0;
|
|
2074
2241
|
|
|
2075
2242
|
ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
|
|
@@ -2114,6 +2281,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2114
2281
|
}
|
|
2115
2282
|
if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
|
|
2116
2283
|
FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
|
|
2284
|
+
assert(ip != NULL);
|
|
2117
2285
|
ip += neededInSize;
|
|
2118
2286
|
/* Function modifies the stage so we must break */
|
|
2119
2287
|
break;
|
|
@@ -2128,7 +2296,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2128
2296
|
int const isSkipFrame = ZSTD_isSkipFrame(zds);
|
|
2129
2297
|
size_t loadedSize;
|
|
2130
2298
|
/* At this point we shouldn't be decompressing a block that we can stream. */
|
|
2131
|
-
assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip));
|
|
2299
|
+
assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)));
|
|
2132
2300
|
if (isSkipFrame) {
|
|
2133
2301
|
loadedSize = MIN(toLoad, (size_t)(iend-ip));
|
|
2134
2302
|
} else {
|
|
@@ -2137,8 +2305,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2137
2305
|
"should never happen");
|
|
2138
2306
|
loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
|
|
2139
2307
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2308
|
+
if (loadedSize != 0) {
|
|
2309
|
+
/* ip may be NULL */
|
|
2310
|
+
ip += loadedSize;
|
|
2311
|
+
zds->inPos += loadedSize;
|
|
2312
|
+
}
|
|
2142
2313
|
if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
|
|
2143
2314
|
|
|
2144
2315
|
/* decode loaded input */
|
|
@@ -2148,14 +2319,17 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2148
2319
|
break;
|
|
2149
2320
|
}
|
|
2150
2321
|
case zdss_flush:
|
|
2151
|
-
{
|
|
2322
|
+
{
|
|
2323
|
+
size_t const toFlushSize = zds->outEnd - zds->outStart;
|
|
2152
2324
|
size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
|
|
2153
|
-
|
|
2325
|
+
|
|
2326
|
+
op = op ? op + flushedSize : op;
|
|
2327
|
+
|
|
2154
2328
|
zds->outStart += flushedSize;
|
|
2155
2329
|
if (flushedSize == toFlushSize) { /* flush completed */
|
|
2156
2330
|
zds->streamStage = zdss_read;
|
|
2157
2331
|
if ( (zds->outBuffSize < zds->fParams.frameContentSize)
|
|
2158
|
-
|
|
2332
|
+
&& (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
|
|
2159
2333
|
DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
|
|
2160
2334
|
(int)(zds->outBuffSize - zds->outStart),
|
|
2161
2335
|
(U32)zds->fParams.blockSizeMax);
|
|
@@ -2169,7 +2343,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2169
2343
|
|
|
2170
2344
|
default:
|
|
2171
2345
|
assert(0); /* impossible */
|
|
2172
|
-
RETURN_ERROR(GENERIC, "impossible to reach"); /* some
|
|
2346
|
+
RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
|
|
2173
2347
|
} }
|
|
2174
2348
|
|
|
2175
2349
|
/* result */
|
|
@@ -2182,8 +2356,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
|
2182
2356
|
if ((ip==istart) && (op==ostart)) { /* no forward progress */
|
|
2183
2357
|
zds->noForwardProgress ++;
|
|
2184
2358
|
if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
|
|
2185
|
-
RETURN_ERROR_IF(op==oend,
|
|
2186
|
-
RETURN_ERROR_IF(ip==iend,
|
|
2359
|
+
RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, "");
|
|
2360
|
+
RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, "");
|
|
2187
2361
|
assert(0);
|
|
2188
2362
|
}
|
|
2189
2363
|
} else {
|
|
@@ -2220,11 +2394,17 @@ size_t ZSTD_decompressStream_simpleArgs (
|
|
|
2220
2394
|
void* dst, size_t dstCapacity, size_t* dstPos,
|
|
2221
2395
|
const void* src, size_t srcSize, size_t* srcPos)
|
|
2222
2396
|
{
|
|
2223
|
-
ZSTD_outBuffer output
|
|
2224
|
-
ZSTD_inBuffer input
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2397
|
+
ZSTD_outBuffer output;
|
|
2398
|
+
ZSTD_inBuffer input;
|
|
2399
|
+
output.dst = dst;
|
|
2400
|
+
output.size = dstCapacity;
|
|
2401
|
+
output.pos = *dstPos;
|
|
2402
|
+
input.src = src;
|
|
2403
|
+
input.size = srcSize;
|
|
2404
|
+
input.pos = *srcPos;
|
|
2405
|
+
{ size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
|
|
2406
|
+
*dstPos = output.pos;
|
|
2407
|
+
*srcPos = input.pos;
|
|
2408
|
+
return cErr;
|
|
2409
|
+
}
|
|
2230
2410
|
}
|