From 7c3dea42cebf9a1c67136078988825a6ab22bee9 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Sun, 24 Sep 2017 15:57:29 -0700 Subject: [PATCH] added prototypes for advanced parameters for decompression API required to decode custom formats --- doc/zstd_manual.html | 150 +++++++++++++++++++++++++------- lib/common/zstd_internal.h | 1 + lib/compress/zstd_compress.c | 9 ++ lib/zstd.h | 160 ++++++++++++++++++++++++++--------- 4 files changed, 251 insertions(+), 69 deletions(-) diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index e7d86170..64870229 100644 --- a/doc/zstd_manual.html +++ b/doc/zstd_manual.html @@ -27,8 +27,8 @@
  • Buffer-less and synchronous inner streaming functions
  • Buffer-less streaming compression (synchronous mode)
  • Buffer-less streaming decompression (synchronous mode)
  • -
  • ZSTD_CCtx_params
  • -
  • Block functions
  • +
  • === New advanced API (experimental) ===
  • +
  • === Block level API ===

  • Introduction

    @@ -399,7 +399,7 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
     size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
     size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
     

    These functions give the current memory usage of selected object. - Object memory usage can evolve if it's re-used multiple times. + Object memory usage can evolve when re-used multiple times.


    size_t ZSTD_estimateCCtxSize(int compressionLevel);
    @@ -646,12 +646,12 @@ size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict*
       @return : 0, or an error code (which can be tested using ZSTD_isError()) 
     


    -

    Advanced Streaming decompression functions

    typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
    -ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
    +

    Advanced Streaming decompression functions

    ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
     ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */
    +typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
    -size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
    -size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
    +size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: no dictionary will be used if dict == NULL or dictSize < 8 */
    +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

    @@ -783,8 +783,29 @@ 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, and compression only)


    +

    === New advanced API (experimental) ===

    
    +
     
    typedef enum {
    +    ZSTD_f_zstd1 = 0,        /* Normal zstd frame format, specified in zstd_compression_format.md (default) */
    +    ZSTD_f_zstd1_magicless,  /* Variant of zstd frame format, without initial 4-bytes magic number.
    +                              * Useful to save 4 bytes per generated frame.
    +                              * Decoder will not be able to recognise this format, requiring instructions. */
    +    ZSTD_f_zstd1_headerless, /* Variant of zstd frame format, without any frame header;
    +                              * Other metadata, like block size or frame checksum, are still generated.
    +                              * Useful to save between 6 and ZSTD_frameHeaderSize_max bytes per generated frame.
    +                              * However, required decoding parameters will have to be saved or known by some mechanism.
    +                              * Decoder will not be able to recognise this format, requiring instructions and parameters. */
    +    ZSTD_f_zstd1_block       /* Generate a zstd compressed block, without any metadata.
    +                              * Note that size of block content must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB.
    +                              * See ZSTD_compressBlock() for more details.
    +                              * Resulting compressed block can be decoded with ZSTD_decompressBlock(). */
    +} ZSTD_format_e;
    +

    +
    typedef enum {
    +    /* compression format */
    +    ZSTD_p_format = 10,      /* See ZSTD_format_e enum definition.
    +                              * Cast selected format as unsigned for ZSTD_CCtx_setParameter() compatibility. */
    +
         /* compression parameters */
         ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
                                   * Default level is ZSTD_CLEVEL_DEFAULT==3.
    @@ -949,7 +970,7 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t
     
    typedef enum {
         ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
         ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    -    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +    ZSTD_e_end         /* flush any remaining data and close current frame. Any additional data starts a new frame. */
     } ZSTD_EndDirective;
     

    size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
    @@ -959,8 +980,8 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t
     

    Behave about the same as ZSTD_compressStream. To note : - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter() - Compression parameters cannot be changed once compression is started. - - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize - - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit. + - outpot->pos must be <= dstCapacity, input->pos must be <= srcSize + - outpot->pos and input->pos will be updated. They are guaranteed to remain below their respective limit. - @return provides the minimum amount of data still to flush from internal buffers or an error code, which can be tested using ZSTD_isError(). if @return != 0, flush is not fully completed, there is some data left within internal buffers. @@ -976,6 +997,7 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t Useful after an error, or to interrupt an ongoing compression job and start a new one. Any internal data not yet flushed is cancelled. Dictionary (if any) is dropped. + All parameters are back to default values. It's possible to modify compression parameters after a reset.


    @@ -987,26 +1009,30 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t ZSTD_EndDirective endOp);

    Same as ZSTD_compress_generic(), but using only integral types as arguments. - Argument list is larger and less expressive than ZSTD_{in,out}Buffer, + Argument list is larger than ZSTD_{in,out}Buffer, but can be helpful for binders from dynamic languages which have troubles handling structures containing memory pointers.


    -

    ZSTD_CCtx_params

    +
    ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
    +

    Quick howto : - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure - - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an - existing ZSTD_CCtx_params structure. This is similar to - ZSTD_CCtx_setParameter(). - - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to an existing CCtx. These - parameters will be applied to all subsequent compression jobs. + - ZSTD_CCtxParam_setParameter() : Push parameters one by one into + an existing ZSTD_CCtx_params structure. + This is similar to + ZSTD_CCtx_setParameter(). + - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to + an existing CCtx. + These parameters will be applied to + all subsequent compression jobs. - ZSTD_compress_generic() : Do compression using the CCtx. - ZSTD_freeCCtxParams() : Free the memory. - This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation - for single-threaded compression. + This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams() + for static allocation for single-threaded compression. -

    +


    size_t ZSTD_resetCCtxParams(ZSTD_CCtx_params* params);
     

    Reset params to default, with the default compression level. @@ -1030,22 +1056,84 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t Set one compression parameter, selected by enum ZSTD_cParameter. Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams(). Note : when `value` is an enum, cast it to unsigned for proper type checking. - @result : 0, or an error code (which can be tested with ZSTD_isError()). + @result : 0, or an error code (which can be tested with ZSTD_isError()).


    size_t ZSTD_CCtx_setParametersUsingCCtxParams(
             ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
    -

    Apply a set of ZSTD_CCtx_params to the compression context. - This must be done before the dictionary is loaded. - The pledgedSrcSize is treated as unknown. - Multithreading parameters are applied only if nbThreads > 1. +

    Apply a set of ZSTD_CCtx_params to the compression context. + This must be done before the dictionary is loaded. + The pledgedSrcSize is treated as unknown. + Multithreading parameters are applied only if nbThreads > 1.


    -

    Block functions

    -    Block functions produce and decode raw zstd blocks, without frame metadata.
    -    Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
    +

    Advanced parameters for decompression API


    +
    size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode);
    +

    Create an internal DDict from dict buffer, + to be used to decompress next frames. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary, + meaning "return to no-dictionary mode". + Note 1 : `dict` content will be copied internally. + Use ZSTD_DCtx_loadDictionary_byReference() + to reference dictionary content instead. + In which case, the dictionary buffer must outlive its users. + Note 2 : Loading a dictionary involves building tables, + which has a non-negligible impact on CPU usage and latency. + Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to select + how dictionary content will be interpreted and loaded. + +


    + +
    size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
    +

    Reference a prepared dictionary, to be used to decompress next frames. + The dictionary remains active for decompression of future frames using same DCtx. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : Currently, only one dictionary can be managed. + Referencing a new dictionary effectively "discards" any previous one. + Special : adding a NULL DDict means "return to no-dictionary mode". + Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx. + +


    + +
    size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize);
    +size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode);
    +

    Reference a prefix (single-usage dictionary) for next compression job. + Prefix is **only used once**. It must be explicitly referenced before each frame. + If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_DDict instead. + @result : 0, or an error code (which can be tested with ZSTD_isError()). + Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary + Note 2 : Prefix buffer is referenced. It must outlive compression job. + Note 3 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent). + Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode. + Note 4 : Referencing a raw content prefix costs almost nothing cpu and memory wise. + +


    + +
    size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
    +

    Refuses allocating internal buffers for frames requiring a window size larger than provided limit. + This is useful to prevent a decoder context from reserving too much memory for itself (potential attack scenario). + This parameter is only useful in streaming mode, since no internal buffer is allocated in direct mode. + By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_MAX) + @return : 0, or an error code (which can be tested using ZSTD_isError()). + +


    + +
    size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
    +

    Instruct the decoder context about what kind of data to decode next. + This instruction is mandatory to decode data without a fully-formed header, + such ZSTD_f_zstd1_magicless for example. + @return : 0, or an error code (which can be tested using ZSTD_isError()). + +


    + +

    === 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. A few rules to respect : @@ -1055,7 +1143,7 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t + compression : any ZSTD_compressBegin*() variant, including with dictionary + decompression : any ZSTD_decompressBegin*() variant, including with dictionary + copyCCtx() and copyDCtx() can be used too - - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX + - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB + If input is larger than a block size, it's necessary to split input data into multiple blocks + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead. Frame metadata is not that costly, and quickly becomes negligible as source size grows larger. @@ -1066,7 +1154,7 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t + In case of multiple successive blocks, should some of them be uncompressed, decoder must be informed of their existence in order to follow proper history. Use ZSTD_insertBlock() for such a case. -

    +


    Raw zstd block functions

    size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);
     size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
    diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h
    index cd0dbcc2..8a24d42f 100644
    --- a/lib/common/zstd_internal.h
    +++ b/lib/common/zstd_internal.h
    @@ -282,6 +282,7 @@ typedef struct {
     } ZSTD_entropyCTables_t;
     
     struct ZSTD_CCtx_params_s {
    +    ZSTD_format_e format;
         ZSTD_compressionParameters cParams;
         ZSTD_frameParameters fParams;
     
    diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c
    index c58d3044..88eb51dc 100644
    --- a/lib/compress/zstd_compress.c
    +++ b/lib/compress/zstd_compress.c
    @@ -256,6 +256,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
     
         switch(param)
         {
    +    case ZSTD_p_format :
    +        return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
    +
         case ZSTD_p_compressionLevel:
             if (value == 0) return 0;  /* special value : 0 means "don't change anything" */
             if (cctx->cdict) return ERROR(stage_wrong);
    @@ -326,6 +329,12 @@ size_t ZSTD_CCtxParam_setParameter(
     {
         switch(param)
         {
    +    case ZSTD_p_format :
    +        if (value > (unsigned)ZSTD_f_zstd1_block)
    +            return ERROR(parameter_unsupported);
    +        params->format = (ZSTD_format_e)value;
    +        return 0;
    +
         case ZSTD_p_compressionLevel :
             if ((int)value > ZSTD_maxCLevel()) value = ZSTD_maxCLevel();
             if (value == 0) return 0;
    diff --git a/lib/zstd.h b/lib/zstd.h
    index 81158a20..655fa29d 100644
    --- a/lib/zstd.h
    +++ b/lib/zstd.h
    @@ -486,7 +486,7 @@ ZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
     
     /*! ZSTD_sizeof_*() :
      *  These functions give the current memory usage of selected object.
    - *  Object memory usage can evolve if it's re-used multiple times. */
    + *  Object memory usage can evolve when re-used multiple times. */
     ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
     ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
     ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
    @@ -747,12 +747,12 @@ ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledg
     
     
     /*=====   Advanced Streaming decompression functions  =====*/
    -typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
     ZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */
    +typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
     ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
    -ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
    -ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict will just be referenced, and must outlive decompression session */
    +ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: no dictionary will be used if dict == NULL or dictSize < 8 */
    +ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);  /**< note : ddict is referenced, it must outlive decompression session */
     ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);  /**< re-use decompression parameters from previous init; saves dictionary loading */
     
     
    @@ -908,17 +908,17 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
     
     
     
    -/*===   New advanced API (experimental, and compression only)  ===*/
    +/** ===   New advanced API (experimental)  === **/
     
     /* notes on API design :
    - *   In this proposal, parameters are pushed one by one into an existing CCtx,
    + *   In this proposal, parameters are pushed one by one into an existing context,
      *   and then applied on all subsequent compression jobs.
      *   When no parameter is ever provided, CCtx is created with compression level ZSTD_CLEVEL_DEFAULT.
      *
      *   This API is intended to replace all others experimental API.
      *   It can basically do all other use cases, and even new ones.
    - *   It stands a good chance to become "stable",
    - *   after a reasonable testing period.
    + *   In constrast with _advanced() variants, it stands a reasonable chance to become "stable",
    + *   after a testing period.
      */
     
     /* note on naming convention :
    @@ -934,19 +934,25 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
      * All enum will be manually set to explicit values before reaching "stable API" status */
     
     typedef enum {
    -    ZSTD_f_zstd1,            /* Normal (default) zstd frame format, as specified in zstd_compression_format.md */
    -    ZSTD_f_zstd1_magicLess,  /* Almost zstd frame format, but without initial 4-bytes magic number */
    -    ZSTD_f_zstd1_headerless, /* Almost zstd frame format, but without any frame header;
    -                              * Other metadata, like block size or frame checksum, are still generated */
    -    ZSTD_f_zstd_block        /* Pure zstd compressed block, without any metadata.
    -                              * Note that size of uncompressed block must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB.
    -                              * See ZSTD_compressBlock() for more details. */
    -} ZSTD_format;
    +    ZSTD_f_zstd1 = 0,        /* Normal zstd frame format, specified in zstd_compression_format.md (default) */
    +    ZSTD_f_zstd1_magicless,  /* Variant of zstd frame format, without initial 4-bytes magic number.
    +                              * Useful to save 4 bytes per generated frame.
    +                              * Decoder will not be able to recognise this format, requiring instructions. */
    +    ZSTD_f_zstd1_headerless, /* Variant of zstd frame format, without any frame header;
    +                              * Other metadata, like block size or frame checksum, are still generated.
    +                              * Useful to save between 6 and ZSTD_frameHeaderSize_max bytes per generated frame.
    +                              * However, required decoding parameters will have to be saved or known by some mechanism.
    +                              * Decoder will not be able to recognise this format, requiring instructions and parameters. */
    +    ZSTD_f_zstd1_block       /* Generate a zstd compressed block, without any metadata.
    +                              * Note that size of block content must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB.
    +                              * See ZSTD_compressBlock() for more details.
    +                              * Resulting compressed block can be decoded with ZSTD_decompressBlock(). */
    +} ZSTD_format_e;
     
     typedef enum {
         /* compression format */
    -    ZSTD_p_format = 10,      /* See ZSTD_format enum definition.
    -                              * Cast selected strategy as unsigned for ZSTD_CCtx_setParameter() compatibility. */
    +    ZSTD_p_format = 10,      /* See ZSTD_format_e enum definition.
    +                              * Cast selected format as unsigned for ZSTD_CCtx_setParameter() compatibility. */
     
         /* compression parameters */
         ZSTD_p_compressionLevel=100, /* Update all compression parameters according to pre-defined cLevel table
    @@ -1116,15 +1122,15 @@ ZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* pre
     typedef enum {
         ZSTD_e_continue=0, /* collect more data, encoder transparently decides when to output result, for optimal conditions */
         ZSTD_e_flush,      /* flush any data provided so far - frame will continue, future data can still reference previous data for better compression */
    -    ZSTD_e_end         /* flush any remaining data and ends current frame. Any future compression starts a new frame. */
    +    ZSTD_e_end         /* flush any remaining data and close current frame. Any additional data starts a new frame. */
     } ZSTD_EndDirective;
     
     /*! ZSTD_compress_generic() :
      *  Behave about the same as ZSTD_compressStream. To note :
      *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_setParameter()
      *  - Compression parameters cannot be changed once compression is started.
    - *  - *dstPos must be <= dstCapacity, *srcPos must be <= srcSize
    - *  - *dspPos and *srcPos will be updated. They are guaranteed to remain below their respective limit.
    + *  - outpot->pos must be <= dstCapacity, input->pos must be <= srcSize
    + *  - outpot->pos and input->pos will be updated. They are guaranteed to remain below their respective limit.
      *  - @return provides the minimum amount of data still to flush from internal buffers
      *            or an error code, which can be tested using ZSTD_isError().
      *            if @return != 0, flush is not fully completed, there is some data left within internal buffers.
    @@ -1143,6 +1149,7 @@ ZSTDLIB_API size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
      *  Useful after an error, or to interrupt an ongoing compression job and start a new one.
      *  Any internal data not yet flushed is cancelled.
      *  Dictionary (if any) is dropped.
    + *  All parameters are back to default values.
      *  It's possible to modify compression parameters after a reset.
      */
     ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
    @@ -1151,7 +1158,7 @@ ZSTDLIB_API void ZSTD_CCtx_reset(ZSTD_CCtx* cctx);   /* Not ready yet ! */
     /*! ZSTD_compress_generic_simpleArgs() :
      *  Same as ZSTD_compress_generic(),
      *  but using only integral types as arguments.
    - *  Argument list is larger and less expressive than ZSTD_{in,out}Buffer,
    + *  Argument list is larger than ZSTD_{in,out}Buffer,
      *  but can be helpful for binders from dynamic languages
      *  which have troubles handling structures containing memory pointers.
      */
    @@ -1162,19 +1169,22 @@ size_t ZSTD_compress_generic_simpleArgs (
                                 ZSTD_EndDirective endOp);
     
     
    -/** ZSTD_CCtx_params
    - *
    +/*! ZSTD_CCtx_params :
    + *  Quick howto :
      *  - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
    - *  - ZSTD_CCtxParam_setParameter() : Push parameters one by one into an
    - *  existing ZSTD_CCtx_params structure. This is similar to
    - *  ZSTD_CCtx_setParameter().
    - *  - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to an existing CCtx. These
    - *  parameters will be applied to all subsequent compression jobs.
    + *  - ZSTD_CCtxParam_setParameter() : Push parameters one by one into
    + *                                    an existing ZSTD_CCtx_params structure.
    + *                                    This is similar to
    + *                                    ZSTD_CCtx_setParameter().
    + *  - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to
    + *                                    an existing CCtx.
    + *                                    These parameters will be applied to
    + *                                    all subsequent compression jobs.
      *  - ZSTD_compress_generic() : Do compression using the CCtx.
      *  - ZSTD_freeCCtxParams() : Free the memory.
      *
    - *  This can be used with ZSTD_estimateCCtxSize_opaque() for static allocation
    - *  for single-threaded compression.
    + *  This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()
    + *  for static allocation for single-threaded compression.
      */
     ZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
     
    @@ -1202,22 +1212,96 @@ ZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);
      *  Set one compression parameter, selected by enum ZSTD_cParameter.
      *  Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams().
      *  Note : when `value` is an enum, cast it to unsigned for proper type checking.
    - *  @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
      */
     ZSTDLIB_API size_t ZSTD_CCtxParam_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, unsigned value);
     
     /*! ZSTD_CCtx_setParametersUsingCCtxParams() :
    - * Apply a set of ZSTD_CCtx_params to the compression context.
    - * This must be done before the dictionary is loaded.
    - * The pledgedSrcSize is treated as unknown.
    - * Multithreading parameters are applied only if nbThreads > 1.
    + *  Apply a set of ZSTD_CCtx_params to the compression context.
    + *  This must be done before the dictionary is loaded.
    + *  The pledgedSrcSize is treated as unknown.
    + *  Multithreading parameters are applied only if nbThreads > 1.
      */
     ZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
             ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
     
    -/**
    -    Block functions
     
    +/*===   Advanced parameters for decompression API  ===*/
    +
    +/* The following parameters must be set after creating a ZSTD_DCtx* (or ZSTD_DStream*) object,
    + * but before starting decompression of a frame.
    + */
    +
    +/*! ZSTD_DCtx_loadDictionary() :
    + *  Create an internal DDict from dict buffer,
    + *  to be used to decompress next frames.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
    + *            meaning "return to no-dictionary mode".
    + *  Note 1 : `dict` content will be copied internally.
    + *            Use ZSTD_DCtx_loadDictionary_byReference()
    + *            to reference dictionary content instead.
    + *            In which case, the dictionary buffer must outlive its users.
    + *  Note 2 : Loading a dictionary involves building tables,
    + *           which has a non-negligible impact on CPU usage and latency.
    + *  Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to select
    + *           how dictionary content will be interpreted and loaded.
    + */
    +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
    +ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode);
    +
    +
    +/*! ZSTD_DCtx_refDDict() :
    + *  Reference a prepared dictionary, to be used to decompress next frames.
    + *  The dictionary remains active for decompression of future frames using same DCtx.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Note 1 : Currently, only one dictionary can be managed.
    + *           Referencing a new dictionary effectively "discards" any previous one.
    + *  Special : adding a NULL DDict means "return to no-dictionary mode".
    + *  Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx.
    + */
    +ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
    +
    +
    +/*! ZSTD_DCtx_refPrefix() :
    + *  Reference a prefix (single-usage dictionary) for next compression job.
    + *  Prefix is **only used once**. It must be explicitly referenced before each frame.
    + *  If there is a need to use same prefix multiple times, consider embedding it into a ZSTD_DDict instead.
    + * @result : 0, or an error code (which can be tested with ZSTD_isError()).
    + *  Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary
    + *  Note 2 : Prefix buffer is referenced. It must outlive compression job.
    + *  Note 3 : By default, the prefix is treated as raw content (ZSTD_dm_rawContent).
    + *           Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode.
    + *  Note 4 : Referencing a raw content prefix costs almost nothing cpu and memory wise.
    + */
    +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize);
    +ZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode);
    +
    +
    +/*! ZSTD_DCtx_setMaxWindowSize() :
    + *  Refuses allocating internal buffers for frames requiring a window size larger than provided limit.
    + *  This is useful to prevent a decoder context from reserving too much memory for itself (potential attack scenario).
    + *  This parameter is only useful in streaming mode, since no internal buffer is allocated in direct mode.
    + *  By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_MAX)
    + * @return : 0, or an error code (which can be tested using ZSTD_isError()).
    + */
    +ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
    +
    +
    +/*! ZSTD_DCtx_setFormat() :
    + *  Instruct the decoder context about what kind of data to decode next.
    + *  This instruction is mandatory to decode data without a fully-formed header,
    + *  such ZSTD_f_zstd1_magicless for example.
    + * @return : 0, or an error code (which can be tested using ZSTD_isError()).
    + */
    +ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
    +
    +
    +
    +/** ===   Block level API  === **/
    +
    +/*!
         Block functions produce and decode raw zstd blocks, without frame metadata.
         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.