diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 5e01a19c3..6173712bf 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -1,10 +1,10 @@
-@@ -336,15 +333,16 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
The definitions in this section are considered experimental. +ADVANCED AND EXPERIMENTAL FUNCTIONS
+ The definitions in this section are considered experimental. They should never be used with a dynamic library, as prototypes may change in the future. They are provided for advanced scenarios. Use them only in association with static linking.-Advanced types
- +int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed */ +
typedef enum { ZSTD_fast=1, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btultra } ZSTD_strategy; /* from faster to stronger */
@@ -380,7 +378,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB ZSTD_dlm_byRef, /**< Reference dictionary content -- the dictionary buffer must outlive its users. */ } ZSTD_dictLoadMethod_e;
size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);`src` should point to the start of a ZSTD encoded frame or skippable frame @@ -413,12 +411,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB however it does mean that all frame data must be present and valid.
srcSize must be >= ZSTD_frameHeaderSize_prefix. +size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize); ++srcSize must be >= ZSTD_frameHeaderSize_prefix. @return : size of the Frame Header, or an error code (if srcSize is too small) -
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx); size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx); @@ -508,7 +507,7 @@ static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< t
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);Create a digested dictionary for compression @@ -550,7 +549,7 @@ static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< t
Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters
unsigned ZSTD_isFrame(const void* buffer, size_t size);Tells if the content of `buffer` starts with a valid Frame Identifier. @@ -590,7 +589,7 @@ static ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< t When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code.
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize);/**< pledgedSrcSize must be correct. If it is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs, "0" also disables frame content size field. It may be enabled in the future. */ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< creates of an internal CDict (incompatible with static CCtx), except if dict == NULL or dictSize < 8, in which case no dict is used. Note: dict is loaded with ZSTD_dm_auto (treated as a full zstd dictionary if it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.*/ @@ -622,14 +621,14 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /**< note : ddict is referenced, it must outlive decompression session */ size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */
+Buffer-less and synchronous inner streaming functions
This is an advanced API, giving full control over buffer management, for users which need direct control over memory. But it's also a complex one, with several restrictions, documented below. Prefer normal streaming API for an easier experience.-Buffer-less streaming compression (synchronous mode)
+Buffer-less streaming compression (synchronous mode)
A ZSTD_CCtx object is required to track streaming operations. Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource. ZSTD_CCtx object can be re-used multiple times within successive compression operations. @@ -665,7 +664,7 @@ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */ size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
-Buffer-less streaming decompression (synchronous mode)
+Buffer-less streaming decompression (synchronous mode)
A ZSTD_DCtx object is required to track streaming operations. Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it. A ZSTD_DCtx object can be re-used multiple times. @@ -756,7 +755,7 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
-New advanced API (experimental)
+New advanced API (experimental)
typedef enum { /* Opened question : should we have a format ZSTD_f_auto ? @@ -1193,9 +1192,11 @@ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx,
-ZSTD_getFrameHeader_advanced() :
same as ZSTD_getFrameHeader(), +size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, + const void* src, size_t srcSize, ZSTD_format_e format); ++same as ZSTD_getFrameHeader(), with added capability to select a format (like ZSTD_f_zstd1_magicless) -
size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, @@ -1229,7 +1230,7 @@ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx,
-Block level API
+Block level API
Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes). User will have to take in charge required information to regenerate data, such as compressed and content sizes. diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index f375ee2ce..98e9917ab 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -679,6 +679,9 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams) CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); + ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0); + if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX) + return ERROR(parameter_outOfBound); if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) return ERROR(parameter_unsupported); return 0; @@ -699,6 +702,9 @@ ZSTD_clampCParams(ZSTD_compressionParameters cParams) CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX); + ZSTD_STATIC_ASSERT(ZSTD_TARGETLENGTH_MIN == 0); + if (cParams.targetLength > ZSTD_TARGETLENGTH_MAX) + cParams.targetLength = ZSTD_TARGETLENGTH_MAX; CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra); return cParams; } @@ -3782,6 +3788,7 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output) #define ZSTD_MAX_CLEVEL 22 int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; } +int ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; } static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = { { /* "default" - guarantees a monotonically increasing memory budget */ diff --git a/lib/zstd.h b/lib/zstd.h index 277ab7ffb..8a39de59a 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -71,7 +71,7 @@ extern "C" { /*------ Version ------*/ #define ZSTD_VERSION_MAJOR 1 #define ZSTD_VERSION_MINOR 3 -#define ZSTD_VERSION_RELEASE 5 +#define ZSTD_VERSION_RELEASE 6 #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< useful to check dll version */ @@ -80,7 +80,7 @@ ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< useful to check dll versio #define ZSTD_QUOTE(str) #str #define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str) #define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION) -ZSTDLIB_API const char* ZSTD_versionString(void); /* added in v1.3.0 */ +ZSTDLIB_API const char* ZSTD_versionString(void); /* v1.3.0+ */ /*************************************** * Default constant @@ -330,7 +330,7 @@ typedef struct ZSTD_outBuffer_s { * *******************************************************************/ typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same object (>= v1.3.0) */ - /* Continue to distinguish them for compatibility with versions <= v1.2.0 */ + /* Continue to distinguish them for compatibility with older versions <= v1.2.0 */ /*===== ZSTD_CStream management functions =====*/ ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void); ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); @@ -385,21 +385,28 @@ ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output + +#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) +#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY + /**************************************************************************************** - * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS + * ADVANCED AND EXPERIMENTAL FUNCTIONS + **************************************************************************************** * The definitions in this section are considered experimental. * They should never be used with a dynamic library, as prototypes may change in the future. * They are provided for advanced scenarios. * Use them only in association with static linking. * ***************************************************************************************/ -#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY) -#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY +ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed */ -/* --- Constants ---*/ -#define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */ +/* --- Constants ---*/ +#define ZSTD_MAGICNUMBER 0xFD2FB528 /* v0.8+ */ +#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* v0.7+ */ #define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U -#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* >= v0.7.0 */ + +#define ZSTD_BLOCKSIZELOG_MAX 17 +#define ZSTD_BLOCKSIZE_MAX (1<
= ZSTD_frameHeaderSize_prefix. * @return : size of the Frame Header, * or an error code (if srcSize is too small) */ @@ -1401,7 +1411,7 @@ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowS ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); -/** ZSTD_getFrameHeader_advanced() : +/*! ZSTD_getFrameHeader_advanced() : * same as ZSTD_getFrameHeader(), * with added capability to select a format (like ZSTD_f_zstd1_magicless) */ ZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, @@ -1473,8 +1483,6 @@ ZSTDLIB_API void ZSTD_DCtx_reset(ZSTD_DCtx* dctx); Use ZSTD_insertBlock() for such a case. */ -#define ZSTD_BLOCKSIZELOG_MAX 17 -#define ZSTD_BLOCKSIZE_MAX (1< maxFast) fastLevel = maxFast; if (fastLevel) { dictCLevel = cLevel = -(int)fastLevel; } else { @@ -648,6 +651,7 @@ int main(int argCount, const char* argv[]) } continue; } +#endif /* fall-through, will trigger bad_usage() later on */ } diff --git a/tests/fuzzer.c b/tests/fuzzer.c index 641357e76..7191ffcbb 100644 --- a/tests/fuzzer.c +++ b/tests/fuzzer.c @@ -333,9 +333,13 @@ static int basicUnitTests(U32 seed, double compressibility) DISPLAYLEVEL(3, "OK : %s \n", errorString); } + DISPLAYLEVEL(3, "test%3i : min compression level : ", testNb++); + { int const mcl = ZSTD_minCLevel(); + DISPLAYLEVEL(3, "%i (OK) \n", mcl); + } DISPLAYLEVEL(3, "test%3i : compress %u bytes : ", testNb++, (U32)CNBuffSize); - { ZSTD_CCtx* cctx = ZSTD_createCCtx(); + { ZSTD_CCtx* const cctx = ZSTD_createCCtx(); if (cctx==NULL) goto _output_error; CHECKPLUS(r, ZSTD_compressCCtx(cctx, compressedBuffer, compressedBufferSize, diff --git a/tests/paramgrill.c b/tests/paramgrill.c index 5275f10a5..68e1fbc4d 100644 --- a/tests/paramgrill.c +++ b/tests/paramgrill.c @@ -70,9 +70,6 @@ static const int g_maxNbVariations = 64; #define FADT_MIN 0 #define FADT_MAX ((U32)-1) -#define ZSTD_TARGETLENGTH_MIN 0 -#define ZSTD_TARGETLENGTH_MAX 999 - #define WLOG_RANGE (ZSTD_WINDOWLOG_MAX - ZSTD_WINDOWLOG_MIN + 1) #define CLOG_RANGE (ZSTD_CHAINLOG_MAX - ZSTD_CHAINLOG_MIN + 1) #define HLOG_RANGE (ZSTD_HASHLOG_MAX - ZSTD_HASHLOG_MIN + 1) @@ -1186,37 +1183,42 @@ static int createContexts(contexts_t* ctx, const char* dictFileName) { size_t readSize; ctx->cctx = ZSTD_createCCtx(); ctx->dctx = ZSTD_createDCtx(); + assert(ctx->cctx != NULL); + assert(ctx->dctx != NULL); + if(dictFileName == NULL) { ctx->dictSize = 0; ctx->dictBuffer = NULL; return 0; } - ctx->dictSize = UTIL_getFileSize(dictFileName); + { U64 const dictFileSize = UTIL_getFileSize(dictFileName); + assert(dictFileSize != UTIL_FILESIZE_UNKNOWN); + ctx->dictSize = dictFileSize; + assert((U64)ctx->dictSize == dictFileSize); /* check overflow */ + } ctx->dictBuffer = malloc(ctx->dictSize); f = fopen(dictFileName, "rb"); - if(!f) { + if (f==NULL) { DISPLAY("unable to open file\n"); - fclose(f); freeContexts(*ctx); return 1; } - if(ctx->dictSize > 64 MB || !(ctx->dictBuffer)) { + if (ctx->dictSize > 64 MB || !(ctx->dictBuffer)) { DISPLAY("dictionary too large\n"); fclose(f); freeContexts(*ctx); return 1; } readSize = fread(ctx->dictBuffer, 1, ctx->dictSize, f); - if(readSize != ctx->dictSize) { + fclose(f); + if (readSize != ctx->dictSize) { DISPLAY("unable to read file\n"); - fclose(f); freeContexts(*ctx); return 1; } - fclose(f); return 0; }