From: Yann Collet Date: Sat, 3 Dec 2016 02:37:38 +0000 (-0800) Subject: API : changed : streaming decompression : implicit reset on starting new frames X-Git-Tag: v1.1.2~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ffbeea87507215a8c6846f179325ecb4662b5d6;p=thirdparty%2Fzstd.git API : changed : streaming decompression : implicit reset on starting new frames --- diff --git a/NEWS b/NEWS index 69b24e635..580889542 100644 --- a/NEWS +++ b/NEWS @@ -2,10 +2,11 @@ v1.1.2 Improved : faster decompression speed at ultra compression settings and in 32-bits mode cli : new : gzstd, experimental version able to decode .gz files, by Przemyslaw Skibinski cli : new : preserve file attributes -cli : new : added zstdless +cli : new : added zstdless and zstdgrep tools cli : fixed : status displays total amount decoded, even for file consisting of multiple frames (like pzstd) cli : fixed : zstdcat API : changed : zbuff prototypes now generate deprecation warnings +API : changed : streaming decompression implicit reset on starting new frame Changed : reduced stack memory use v1.1.1 diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index 3106fa014..7c4f54bd3 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -1959,7 +1959,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB switch(zds->stage) { case zdss_init : - return ERROR(init_missing); + ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */ + /* fall-through */ case zdss_loadHeader : { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize); diff --git a/lib/zstd.h b/lib/zstd.h index 607612026..b7a8bb989 100644 --- a/lib/zstd.h +++ b/lib/zstd.h @@ -299,8 +299,8 @@ ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output * If `output.pos < output.size`, decoder has flushed everything it could. * @return : 0 when a frame is completely decoded and fully flushed, * an error code, which can be tested using ZSTD_isError(), -* any other value > 0, which means there is still some work to do to complete the frame. -* The return value is a suggested next input size (just an hint, to help latency). +* any other value > 0, which means there is still some decoding to do to complete current frame. +* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame. * *******************************************************************************/ /*===== Streaming decompression functions =====*/ diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index aa119e636..c21b9de9b 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -130,7 +130,7 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo U32 testNb=0; ZSTD_CStream* zc = ZSTD_createCStream_advanced(customMem); ZSTD_DStream* zd = ZSTD_createDStream_advanced(customMem); - ZSTD_inBuffer inBuff; + ZSTD_inBuffer inBuff, inBuff2; ZSTD_outBuffer outBuff; /* Create compressible test buffer */ @@ -183,12 +183,22 @@ static int basicUnitTests(U32 seed, double compressibility, ZSTD_customMem custo DISPLAYLEVEL(4, "OK \n"); /* Basic decompression test */ + inBuff2 = inBuff; DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, COMPRESSIBLE_NOISE_LENGTH); ZSTD_initDStream_usingDict(zd, CNBuffer, 128 KB); { size_t const r = ZSTD_setDStreamParameter(zd, ZSTDdsp_maxWindowSize, 1000000000); /* large limit */ if (ZSTD_isError(r)) goto _output_error; } - { size_t const r = ZSTD_decompressStream(zd, &outBuff, &inBuff); - if (r != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ + { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff); + if (remaining != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ + if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */ + if (inBuff.pos != inBuff.size) goto _output_error; /* should have read the entire frame */ + DISPLAYLEVEL(4, "OK \n"); + + /* Re-use without init */ + DISPLAYLEVEL(4, "test%3i : decompress again without init (re-use previous settings): ", testNb++); + outBuff.pos = 0; + { size_t const remaining = ZSTD_decompressStream(zd, &outBuff, &inBuff2); + if (remaining != 0) goto _output_error; } /* should reach end of frame == 0; otherwise, some data left, or an error */ if (outBuff.pos != CNBufferSize) goto _output_error; /* should regenerate the same amount */ if (inBuff.pos != inBuff.size) goto _output_error; /* should have read the entire frame */ DISPLAYLEVEL(4, "OK \n"); @@ -553,8 +563,9 @@ static int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compres /* multi - fragments decompression test */ if (!dictSize /* don't reset if dictionary : could be different */ && (FUZ_rand(&lseed) & 1)) { CHECK (ZSTD_isError(ZSTD_resetDStream(zd)), "ZSTD_resetDStream failed"); - } else + } else { ZSTD_initDStream_usingDict(zd, dict, dictSize); + } { size_t decompressionResult = 1; ZSTD_inBuffer inBuff = { cBuffer, cSize, 0 }; ZSTD_outBuffer outBuff= { dstBuffer, dstBufferSize, 0 };