API : changed : streaming decompression : implicit reset on starting new frames
diff --git a/NEWS b/NEWS
index 69b24e6..5808895 100644
--- a/NEWS
+++ b/NEWS
@@ -2,10 +2,11 @@
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 3106fa0..7c4f54b 100644
--- a/lib/decompress/zstd_decompress.c
+++ b/lib/decompress/zstd_decompress.c
@@ -1959,7 +1959,8 @@
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 6076120..b7a8bb9 100644
--- a/lib/zstd.h
+++ b/lib/zstd.h
@@ -299,8 +299,8 @@
* 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 aa119e6..c21b9de 100644
--- a/tests/zstreamtest.c
+++ b/tests/zstreamtest.c
@@ -130,7 +130,7 @@
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 @@
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 @@
/* 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 };