v0.7.3
added : `--` separator, stating that all following arguments are file names. Suggested by Chip Turner.
+added : `ZSTD_getDecompressedSize()`
added : OpenBSD target, by Juan Francisco Cantero Hurtado
fixed : dictBuilder using HC levels, reported by Bartosz Taudul
fixed : legacy support from ZSTD_decompress_usingDDict(), reported by Felix Handte
/*--- Advanced Decompression functions ---*/
+/** ZSTD_getDecompressedSize() :
+* compatible with legacy mode
+* @return : decompressed size if known, 0 otherwise
+ note : 0 can mean any of the following :
+ - decompressed size is not provided within frame header
+ - frame header unknown / not supported
+ - frame header not completely provided (`srcSize` too small) */
+unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+
/*! ZSTD_createDCtx_advanced() :
* Create a ZSTD decompression context using external alloc and free functions */
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
}
+/** ZSTD_getDecompressedSize() :
+* compatible with legacy mode
+* @return : decompressed size if known, 0 otherwise
+ note : 0 can mean any of the following :
+ - decompressed size is not provided within frame header
+ - frame header unknown / not supported
+ - frame header not completely provided (`srcSize` too small) */
+unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize) {
+#if ZSTD_LEGACY_SUPPORT
+ if (srcSize < 4) return 0;
+ { U32 const magic = MEM_readLE32(src);
+ if (ZSTD_isLegacy(magic)) return ZSTD_getDecompressedSize_legacy(src, srcSize);
+ }
+#endif
+ { ZSTD_frameParams fparams;
+ size_t const frResult = ZSTD_getFrameParams(&fparams, src, srcSize);
+ if (frResult!=0) return 0;
+ return fparams.frameContentSize;
+ }
+}
+
+
/** ZSTD_decodeFrameHeader() :
* `srcSize` must be the size provided by ZSTD_frameHeaderSize().
* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
}
+MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
+{
+ if (srcSize < 4) return 0;
+
+ { U32 const magic = MEM_readLE32(src);
+ U32 const version = ZSTD_isLegacy(magic);
+ if (!version) return 0; /* not a supported legacy format */
+ if (version < 5) return 0; /* no decompressed size in frame header */
+ if (version==5) {
+ ZSTDv05_parameters fParams;
+ size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
+ if (frResult != 0) return 0;
+ return fParams.srcSize;
+ }
+ if (version==6) {
+ ZSTDv06_frameParams fParams;
+ size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
+ if (frResult != 0) return 0;
+ return fParams.frameContentSize;
+ }
+ return 0; /* should not be possible */
+ }
+}
+
MEM_STATIC size_t ZSTD_decompressLegacy(
void* dst, size_t dstCapacity,
const void* src, size_t compressedSize,
#include "zstd_v06.h"
#include <stddef.h> /* size_t, ptrdiff_t */
#include <string.h> /* memcpy */
-#include <stdlib.h> /* malloc, free, qsort */
+#include <stdlib.h> /* malloc, free, qsort */
-struct ZSTDv06_frameParams_s { U64 frameContentSize; U32 windowLog; };
-
#define ZSTDv06_FRAMEHEADERSIZE_MAX 13 /* for static allocation */
static const size_t ZSTDv06_frameHeaderSize_min = 5;
static const size_t ZSTDv06_frameHeaderSize_max = ZSTDv06_FRAMEHEADERSIZE_MAX;
/*-************************
* Advanced Streaming API
***************************/
-
+struct ZSTDv06_frameParams_s { unsigned long long frameContentSize; unsigned windowLog; };
typedef struct ZSTDv06_frameParams_s ZSTDv06_frameParams;
ZSTDLIB_API size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input */
cSize=r );
DISPLAYLEVEL(4, "OK (%u bytes : %.2f%%)\n", (U32)cSize, (double)cSize/CNBuffSize*100);
+ DISPLAYLEVEL(4, "test%3i : decompressed size test : ", testNb++);
+ { unsigned long long const rSize = ZSTD_getDecompressedSize(compressedBuffer, cSize);
+ if (rSize != CNBuffSize) goto _output_error;
+ }
+ DISPLAYLEVEL(4, "OK \n");
+
DISPLAYLEVEL(4, "test%3i : decompress %u bytes : ", testNb++, (U32)CNBuffSize);
CHECKPLUS( r , ZSTD_decompress(decodedBuffer, CNBuffSize, compressedBuffer, cSize),
if (r != CNBuffSize) goto _output_error);
U32 rSeed = 1;
/* create batch of 3-bytes sequences */
- { int i; for (i=0; i < NB3BYTESSEQ; i++) {
- _3BytesSeqs[i][0] = (BYTE)(FUZ_rand(&rSeed) & 255);
- _3BytesSeqs[i][1] = (BYTE)(FUZ_rand(&rSeed) & 255);
- _3BytesSeqs[i][2] = (BYTE)(FUZ_rand(&rSeed) & 255);
- }}
+ { int i;
+ for (i=0; i < NB3BYTESSEQ; i++) {
+ _3BytesSeqs[i][0] = (BYTE)(FUZ_rand(&rSeed) & 255);
+ _3BytesSeqs[i][1] = (BYTE)(FUZ_rand(&rSeed) & 255);
+ _3BytesSeqs[i][2] = (BYTE)(FUZ_rand(&rSeed) & 255);
+ } }
/* randomly fills CNBuffer with prepared 3-bytes sequences */
- { int i; for (i=0; i < _3BYTESTESTLENGTH; i += 3) { /* note : CNBuffer size > _3BYTESTESTLENGTH+3 */
- U32 const id = FUZ_rand(&rSeed) & NB3BYTESSEQMASK;
- ((BYTE*)CNBuffer)[i+0] = _3BytesSeqs[id][0];
- ((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
- ((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
- } }}
+ { int i;
+ for (i=0; i < _3BYTESTESTLENGTH; i += 3) { /* note : CNBuffer size > _3BYTESTESTLENGTH+3 */
+ U32 const id = FUZ_rand(&rSeed) & NB3BYTESSEQMASK;
+ ((BYTE*)CNBuffer)[i+0] = _3BytesSeqs[id][0];
+ ((BYTE*)CNBuffer)[i+1] = _3BytesSeqs[id][1];
+ ((BYTE*)CNBuffer)[i+2] = _3BytesSeqs[id][2];
+ } } }
DISPLAYLEVEL(4, "test%3i : compress lots 3-bytes sequences : ", testNb++);
{ CHECK_V(r, ZSTD_compress(compressedBuffer, ZSTD_compressBound(_3BYTESTESTLENGTH),
CNBuffer, _3BYTESTESTLENGTH, 19) );
CHECK(endCheck != endMark, "ZSTD_compressCCtx : dst buffer overflow"); }
} }
+ /* Decompressed size test */
+ { unsigned long long const rSize = ZSTD_getDecompressedSize(cBuffer, cSize);
+ CHECK(rSize != sampleSize, "decompressed size incorrect");
+ }
+
/* frame header decompression test */
{ ZSTD_frameParams dParams;
size_t const check = ZSTD_getFrameParams(&dParams, cBuffer, cSize);