diff --git a/doc/zstd_manual.html b/doc/zstd_manual.html index 1cb08328..eebc2efb 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)
  • -
  • === New advanced API (experimental) ===
  • -
  • === Block level API ===
  • +
  • New advanced API (experimental)
  • +
  • Block level API

  • Introduction

    @@ -783,7 +783,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 {
         ZSTD_f_zstd1 = 0,        /* Normal zstd frame format, specified in zstd_compression_format.md (default) */
    @@ -1070,9 +1070,9 @@ size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t
     


    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);
    +
    size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);   /* not implemented */
    +size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);   /* not implemented */
    +size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictMode_e dictMode);   /* not implemented */
     

    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()). @@ -1089,7 +1089,7 @@ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size


    -
    size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
    +
    size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);   /* not implemented */
     

    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()). @@ -1100,8 +1100,8 @@ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size


    -
    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);
    +
    size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize);   /* not implemented */
    +size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictMode_e dictMode);   /* not implemented */
     

    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. @@ -1110,7 +1110,7 @@ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t 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. + Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost.


    @@ -1131,7 +1131,18 @@ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t


    -

    === Block level API ===

    
    +
    size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx,
    +                               ZSTD_outBuffer* output,
    +                               ZSTD_inBuffer* input);
    +

    Behave the same as ZSTD_decompressStream. + Decompression parameters cannot be changed once decompression is started. + @return : an error code, which can be tested using ZSTD_isError() + if >0, a hint, nb of expected input bytes for next invocation. + `0` means : a frame has just been fully decoded and flushed. + +


    + +

    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 16137bb7..c9b8b3cb 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2574,6 +2574,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, /** ZSTD_compressStream_generic(): * internal function for all *compressStream*() variants and *compress_generic() + * non-static, because can be called from zstdmt.c * @return : hint size for next input */ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs, ZSTD_outBuffer* output, diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index d2b85a4a..634706a5 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -2379,7 +2379,10 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB U32 someMoreWork = 1; DEBUGLOG(5, "ZSTD_decompressStream"); + if (input->pos > input->size) return ERROR(GENERIC); /* forbidden */ + if (output->pos > output->size) return ERROR(GENERIC); /* forbidden */ DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos)); + #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1) if (zds->legacyVersion) { /* legacy support is incompatible with static dctx */ @@ -2590,3 +2593,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB return nextSrcSizeHint; } } + + +size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input) +{ + return ZSTD_decompressStream(dctx, output, input); +} diff --git a/lib/zstd.h b/lib/zstd.h index 5b654d73..cdba0028 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -908,7 +908,9 @@ ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx); -/** === New advanced API (experimental) === **/ +/* ============================================ */ +/** New advanced API (experimental) */ +/* ============================================ */ /* notes on API design : * In this proposal, parameters are pushed one by one into an existing context, @@ -1295,23 +1297,31 @@ ZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowS * 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); /* implemented, but not functional */ +ZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format); -/* How to decompress ? - * - * currently, use ZSTD_decompressStream(). - * We could also create a ZSTD_decompress_generic(), - * for an API experience similar to the compression one. - * It would effectively works exactly the same as ZSTD_decompressStream(). - * +/*! ZSTD_decompress_generic() : + * Behave the same as ZSTD_decompressStream. + * Decompression parameters cannot be changed once decompression is started. + * @return : an error code, which can be tested using ZSTD_isError() + * if >0, a hint, nb of expected input bytes for next invocation. + * `0` means : a frame has just been fully decoded and flushed. + */ +ZSTDLIB_API size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, + ZSTD_outBuffer* output, + ZSTD_inBuffer* input); + + +/* * Also : to re-init a decoding context, use ZSTD_initDStream(). - * Here also, for a similar API logic, we could create ZSTD_DCtx_reset(). + * Here for a similar API logic, we could create ZSTD_DCtx_reset(). * It would behave the same. */ -/** === Block level API === **/ +/* ============================ */ +/** Block level API */ +/* ============================ */ /*! Block functions produce and decode raw zstd blocks, without frame metadata.