diff --git a/.travis.yml b/.travis.yml index fda0b05b5..b7faed3eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ env: - ZSTD_TRAVIS_CI_ENV=cmaketest - ZSTD_TRAVIS_CI_ENV=clangtest - ZSTD_TRAVIS_CI_ENV=gpptest + - ZSTD_TRAVIS_CI_ENV=gnu90test - ZSTD_TRAVIS_CI_ENV=armtest-w-install - ZSTD_TRAVIS_CI_ENV=test - ZSTD_TRAVIS_CI_ENV="-C programs test32" diff --git a/Makefile b/Makefile index 3f32deeb1..7d1ae713f 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,9 @@ all: zstdprogram: $(MAKE) -C $(PRGDIR) +test: + $(MAKE) -C $(PRGDIR) $@ + clean: @$(MAKE) -C $(ZSTDDIR) $@ > $(VOID) @$(MAKE) -C $(PRGDIR) $@ > $(VOID) @@ -75,9 +78,6 @@ uninstall: travis-install: $(MAKE) install PREFIX=~/install_test_dir -test: - $(MAKE) -C $(PRGDIR) $@ - cmaketest: cd contrib/cmake ; cmake . ; $(MAKE) @@ -88,6 +88,21 @@ clangtest: clean gpptest: clean $(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror" +gnu90test: clean + $(MAKE) all CFLAGS="-std=gnu90 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef -Wdeclaration-after-statement -Werror" + +c90test: clean + $(MAKE) all CFLAGS="-std=c90 -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow -Wstrict-aliasing=1 -Wswitch-enum -Wstrict-prototypes -Wundef -Werror" # will fail, due to // and long long + +bmix64test: clean + CFLAGS="-O3 -mbmi -Werror" $(MAKE) -C $(PRGDIR) test + +bmix32test: clean + CFLAGS="-O3 -mbmi -mx32 -Werror" $(MAKE) -C $(PRGDIR) test + +bmi32test: clean + CFLAGS="-O3 -mbmi -m32 -Werror" $(MAKE) -C $(PRGDIR) test + armtest: clean $(MAKE) -C $(PRGDIR) datagen # use native, faster $(MAKE) -C $(PRGDIR) test CC=arm-linux-gnueabi-gcc ZSTDRTTEST= MOREFLAGS="-Werror -static" diff --git a/NEWS b/NEWS index d4abd36f9..84dc723d9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +v0.6.1 +Fixed : Legacy codec v0.5 compatible with dictionary decompression +Fixed : Decoder corruption error (#173) +New : midipix support + v0.6.0 Stronger high compression modes, thanks to Przemyslaw Skibinski API : ZSTD_getFrameParams() provides size of decompressed content @@ -95,7 +100,7 @@ frame concatenation support v0.1.1 fix compression bug detects write-flush errors - +git@github.com:Cyan4973/zstd.git v0.1.0 first release diff --git a/lib/common/bitstream.h b/lib/common/bitstream.h index fd114e55a..6b3f13df0 100644 --- a/lib/common/bitstream.h +++ b/lib/common/bitstream.h @@ -301,7 +301,12 @@ MEM_STATIC size_t BIT_getUpperBits(size_t bitD, U32 const start) MEM_STATIC size_t BIT_getMiddleBits(size_t bitD, U32 const nbBits, U32 const start) { #if defined(__BMI__) && defined(__GNUC__) /* experimental */ - return __builtin_ia32_bextr_u64(bitD, (nbBits<<8) | start ); +# if defined(__x86_64__) + if (sizeof(bitD)==8) + return _bextr_u64(bitD, start, nbBits); + else +# endif + return _bextr_u32(bitD, start, nbBits); #else return (bitD >> start) & BIT_mask[nbBits]; #endif @@ -322,7 +327,12 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitD, U32 const nbBits) MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits) { #if defined(__BMI__) && defined(__GNUC__) /* experimental */ - return __builtin_ia32_bextr_u64(bitD->bitContainer, (nbBits<<8) | (64 - bitD->bitsConsumed - nbBits) ); +# if defined(__x86_64__) + if (sizeof(bitD->bitContainer)==8) + return _bextr_u64(bitD->bitContainer, 64 - bitD->bitsConsumed - nbBits, nbBits); + else +# endif + return _bextr_u32(bitD->bitContainer, 32 - bitD->bitsConsumed - nbBits, nbBits); #else U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1; return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask); diff --git a/lib/common/fse_decompress.c b/lib/common/fse_decompress.c index 698dbfc24..8091c8457 100644 --- a/lib/common/fse_decompress.c +++ b/lib/common/fse_decompress.c @@ -111,17 +111,13 @@ void FSE_freeDTable (FSE_DTable* dt) size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { FSE_DTableHeader DTableH; - void* const tdPtr = dt+1; /* because dt is unsigned, 32-bits aligned on 32-bits */ + void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */ FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr); - const U32 tableSize = 1 << tableLog; - const U32 tableMask = tableSize-1; - const U32 step = FSE_TABLESTEP(tableSize); U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1]; + U32 const maxSV1 = maxSymbolValue + 1; + U32 const tableSize = 1 << tableLog; U32 highThreshold = tableSize-1; - S16 const largeLimit= (S16)(1 << (tableLog-1)); - U32 noLarge = 1; - U32 s; /* Sanity Checks */ if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); @@ -129,18 +125,24 @@ size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned /* Init, lay down lowprob symbols */ DTableH.tableLog = (U16)tableLog; - for (s=0; s<=maxSymbolValue; s++) { - if (normalizedCounter[s]==-1) { - tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s; - symbolNext[s] = 1; - } else { - if (normalizedCounter[s] >= largeLimit) noLarge=0; - symbolNext[s] = normalizedCounter[s]; - } } + DTableH.fastMode = 1; + { S16 const largeLimit= (S16)(1 << (tableLog-1)); + U32 s; + for (s=0; s= largeLimit) DTableH.fastMode=0; + symbolNext[s] = normalizedCounter[s]; + } } } + memcpy(dt, &DTableH, sizeof(DTableH)); /* Spread symbols */ - { U32 position = 0; - for (s=0; s<=maxSymbolValue; s++) { + { U32 const tableMask = tableSize-1; + U32 const step = FSE_TABLESTEP(tableSize); + U32 s, position = 0; + for (s=0; stableLog = (U16)nbBits; DTableH->fastMode = 1; - for (s=0; s<=maxSymbolValue; s++) { + for (s=0; s= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */ - ip += errorCode; - cSrcSize -= errorCode; + { size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); + if (FSE_isError(NCountLength)) return NCountLength; + if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */ + ip += NCountLength; + cSrcSize -= NCountLength; + } - errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog); - if (FSE_isError(errorCode)) return errorCode; + { size_t const errorCode = FSE_buildDTable (dt, counting, maxSymbolValue, tableLog); + if (FSE_isError(errorCode)) return errorCode; } - /* always return, even if it is an error code */ - return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); + return FSE_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); /* always return, even if it is an error code */ } diff --git a/lib/common/huf_static.h b/lib/common/huf_static.h index d2d29a42b..e68ec33dd 100644 --- a/lib/common/huf_static.h +++ b/lib/common/huf_static.h @@ -76,7 +76,7 @@ extern "C" { ******************************************/ size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */ -size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder */ +size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder, only works for dstSize >= 64 */ /* **************************************** @@ -122,7 +122,7 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ -size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbol decoder */ +size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder, only works for dstSize >= 64 */ size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable); size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable); @@ -157,7 +157,6 @@ MEM_STATIC size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, const void* src, size_t srcSize) { U32 weightTotal; - U32 tableLog; const BYTE* ip = (const BYTE*) src; size_t iSize = ip[0]; size_t oSize; @@ -191,31 +190,31 @@ MEM_STATIC size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, /* collect weight stats */ memset(rankStats, 0, (HUF_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32)); weightTotal = 0; - { U32 n; for (n=0; n= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); - rankStats[huffWeight[n]]++; - weightTotal += (1 << huffWeight[n]) >> 1; - }} + { U32 n; for (n=0; n= HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); + rankStats[huffWeight[n]]++; + weightTotal += (1 << huffWeight[n]) >> 1; + } } /* get last non-null symbol weight (implied, total must be 2^n) */ - tableLog = BIT_highbit32(weightTotal) + 1; - if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); - /* determine last weight */ - { U32 const total = 1 << tableLog; - U32 const rest = total - weightTotal; - U32 const verif = 1 << BIT_highbit32(rest); - U32 const lastWeight = BIT_highbit32(rest) + 1; - if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ - huffWeight[oSize] = (BYTE)lastWeight; - rankStats[lastWeight]++; - } + { U32 const tableLog = BIT_highbit32(weightTotal) + 1; + if (tableLog > HUF_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); + *tableLogPtr = tableLog; + /* determine last weight */ + { U32 const total = 1 << tableLog; + U32 const rest = total - weightTotal; + U32 const verif = 1 << BIT_highbit32(rest); + U32 const lastWeight = BIT_highbit32(rest) + 1; + if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ + huffWeight[oSize] = (BYTE)lastWeight; + rankStats[lastWeight]++; + } } /* check tree construction validity */ if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ /* results */ *nbSymbolsPtr = (U32)(oSize+1); - *tableLogPtr = tableLog; return iSize+1; } diff --git a/lib/common/mem.h b/lib/common/mem.h index ceafd57b4..dbefcdb21 100644 --- a/lib/common/mem.h +++ b/lib/common/mem.h @@ -63,7 +63,7 @@ extern "C" { /*-************************************************************** * Basic Types *****************************************************************/ -#if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) +#if !defined (__VMS) && ( defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint8_t BYTE; typedef uint16_t U16; diff --git a/lib/common/zstd_internal.h b/lib/common/zstd_internal.h index d5cc255a9..4c9a7615a 100644 --- a/lib/common/zstd_internal.h +++ b/lib/common/zstd_internal.h @@ -203,10 +203,10 @@ typedef struct { #include ".debug/zstd_stats.h" #else typedef struct { U32 unused; } ZSTD_stats_t; - MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength) { (void)stats; (void)searchLength; }; - MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats) { (void)stats; }; - MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats) { (void)stats; }; - MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; }; + MEM_STATIC void ZSTD_statsPrint(ZSTD_stats_t* stats, U32 searchLength) { (void)stats; (void)searchLength; } + MEM_STATIC void ZSTD_statsInit(ZSTD_stats_t* stats) { (void)stats; } + MEM_STATIC void ZSTD_statsResetFreqs(ZSTD_stats_t* stats) { (void)stats; } + MEM_STATIC void ZSTD_statsUpdatePrices(ZSTD_stats_t* stats, size_t litLength, const BYTE* literals, size_t offset, size_t matchLength) { (void)stats; (void)litLength; (void)literals; (void)offset; (void)matchLength; } #endif typedef struct { diff --git a/lib/common/zstd_static.h b/lib/common/zstd_static.h index 960808bc5..0ec5b635c 100644 --- a/lib/common/zstd_static.h +++ b/lib/common/zstd_static.h @@ -103,7 +103,7 @@ ZSTDLIB_API unsigned ZSTD_maxCLevel (void); /*! ZSTD_getCParams() : * @return ZSTD_compressionParameters structure for a selected compression level and srcSize. * `srcSize` value is optional, select 0 if not known */ -ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize); +ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, U64 srcSize, size_t dictSize); /*! ZSTD_checkParams() : * Ensure param values remain within authorized range */ @@ -250,8 +250,8 @@ ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t ds */ #define ZSTD_BLOCKSIZE_MAX (128 * 1024) /* define, for static allocation */ -size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); -size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); +ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); /*-************************************* @@ -261,7 +261,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, cons /*! ZSTD_getErrorCode() : convert a `size_t` function result into a `ZSTD_ErrorCode` enum type, which can be used to compare directly with enum list published into "error_public.h" */ -ZSTD_ErrorCode ZSTD_getError(size_t code); +ZSTDLIB_API ZSTD_ErrorCode ZSTD_getError(size_t code); #if defined (__cplusplus) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 7b07eb454..1bb75c68c 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -852,7 +852,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const B static const BYTE* g_start = NULL; const U32 pos = (U32)(literals - g_start); if (g_start==NULL) g_start = literals; - if ((pos > 5810300) && (pos < 5810500)) + if ((pos > 2587900) && (pos < 2588050)) printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n", pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode); #endif diff --git a/lib/decompress/huf_decompress.c b/lib/decompress/huf_decompress.c index 79e6fbae3..55f417baa 100644 --- a/lib/decompress/huf_decompress.c +++ b/lib/decompress/huf_decompress.c @@ -114,7 +114,7 @@ size_t HUF_readDTableX2 (U16* DTable, const void* src, size_t srcSize) /* Prepare ranks */ nextRankStart = 0; - for (n=1; n<=tableLog; n++) { + for (n=1; n> consumed; - } } } + { U32* const rankVal0 = rankVal[0]; + { int const rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */ + U32 nextRankVal = 0; + U32 w; + for (w=1; w> consumed; + } } } } HUF_fillDTableX4(dt, memLog, sortedSymbol, sizeOfSort, @@ -788,7 +790,7 @@ size_t HUF_readDTableX6 (U32* DTable, const void* src, size_t srcSize) /* Get start index of each weight */ { U32 w, nextRankStart = 0; - for (w=1; w<=maxW; w++) { + for (w=1; w> consumed; } } } @@ -847,17 +849,17 @@ size_t HUF_readDTableX6 (U32* DTable, const void* src, size_t srcSize) static U32 HUF_decodeSymbolX6(void* op, BIT_DStream_t* DStream, const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog) { - const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ memcpy(op, ds+val, sizeof(HUF_DSeqX6)); BIT_skipBits(DStream, dd[val].nbBits); return dd[val].nbBytes; } -static U32 HUF_decodeLastSymbolsX6(void* op, const U32 maxL, BIT_DStream_t* DStream, +static U32 HUF_decodeLastSymbolsX6(void* op, U32 const maxL, BIT_DStream_t* DStream, const HUF_DDescX6* dd, const HUF_DSeqX6* ds, const U32 dtLog) { - const size_t val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ - U32 length = dd[val].nbBytes; + size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ + U32 const length = dd[val].nbBytes; if (length <= maxL) { memcpy(op, ds+val, length); BIT_skipBits(DStream, dd[val].nbBits); @@ -910,7 +912,6 @@ static inline size_t HUF_decodeStreamX6(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* c return p-pStart; } - size_t HUF_decompress1X6_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -919,17 +920,15 @@ size_t HUF_decompress1X6_usingDTable( const BYTE* const istart = (const BYTE*) cSrc; BYTE* const ostart = (BYTE*) dst; BYTE* const oend = ostart + dstSize; - - const U32 dtLog = DTable[0]; - size_t errorCode; + BIT_DStream_t bitD; /* Init */ - BIT_DStream_t bitD; - errorCode = BIT_initDStream(&bitD, istart, cSrcSize); - if (HUF_isError(errorCode)) return errorCode; + { size_t const errorCode = BIT_initDStream(&bitD, istart, cSrcSize); + if (HUF_isError(errorCode)) return errorCode; } /* finish bitStreams one by one */ - HUF_decodeStreamX6(ostart, &bitD, oend, DTable, dtLog); + { U32 const dtLog = DTable[0]; + HUF_decodeStreamX6(ostart, &bitD, oend, DTable, dtLog); } /* check */ if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected); @@ -943,7 +942,7 @@ size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cS HUF_CREATE_STATIC_DTABLEX6(DTable, HUF_MAX_TABLELOG); const BYTE* ip = (const BYTE*) cSrc; - size_t hSize = HUF_readDTableX6 (DTable, cSrc, cSrcSize); + size_t const hSize = HUF_readDTableX6 (DTable, cSrc, cSrcSize); if (HUF_isError(hSize)) return hSize; if (hSize >= cSrcSize) return ERROR(srcSize_wrong); ip += hSize; @@ -953,6 +952,24 @@ size_t HUF_decompress1X6 (void* dst, size_t dstSize, const void* cSrc, size_t cS } +#define HUF_DECODE_ROUNDX6 \ + HUF_DECODE_SYMBOLX6_2(op1, &bitD1); \ + HUF_DECODE_SYMBOLX6_2(op2, &bitD2); \ + HUF_DECODE_SYMBOLX6_2(op3, &bitD3); \ + HUF_DECODE_SYMBOLX6_2(op4, &bitD4); \ + HUF_DECODE_SYMBOLX6_1(op1, &bitD1); \ + HUF_DECODE_SYMBOLX6_1(op2, &bitD2); \ + HUF_DECODE_SYMBOLX6_1(op3, &bitD3); \ + HUF_DECODE_SYMBOLX6_1(op4, &bitD4); \ + HUF_DECODE_SYMBOLX6_2(op1, &bitD1); \ + HUF_DECODE_SYMBOLX6_2(op2, &bitD2); \ + HUF_DECODE_SYMBOLX6_2(op3, &bitD3); \ + HUF_DECODE_SYMBOLX6_2(op4, &bitD4); \ + HUF_DECODE_SYMBOLX6_0(op1, &bitD1); \ + HUF_DECODE_SYMBOLX6_0(op2, &bitD2); \ + HUF_DECODE_SYMBOLX6_0(op3, &bitD3); \ + HUF_DECODE_SYMBOLX6_0(op4, &bitD4); + size_t HUF_decompress4X6_usingDTable( void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, @@ -960,6 +977,7 @@ size_t HUF_decompress4X6_usingDTable( { /* Check */ if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ + if (dstSize < 64) return ERROR(dstSize_tooSmall); /* only work for dstSize >= 64 */ { const BYTE* const istart = (const BYTE*) cSrc; BYTE* const ostart = (BYTE*) dst; @@ -970,7 +988,6 @@ size_t HUF_decompress4X6_usingDTable( const HUF_DDescX6* dd = (const HUF_DDescX6*)ddPtr; const void* const dsPtr = DTable + 1 + ((size_t)1<<(dtLog-1)); const HUF_DSeqX6* ds = (const HUF_DSeqX6*)dsPtr; - size_t errorCode; /* Init */ BIT_DStream_t bitD1; @@ -997,43 +1014,41 @@ size_t HUF_decompress4X6_usingDTable( length4 = cSrcSize - (length1 + length2 + length3 + 6); if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ - errorCode = BIT_initDStream(&bitD1, istart1, length1); - if (HUF_isError(errorCode)) return errorCode; - errorCode = BIT_initDStream(&bitD2, istart2, length2); - if (HUF_isError(errorCode)) return errorCode; - errorCode = BIT_initDStream(&bitD3, istart3, length3); - if (HUF_isError(errorCode)) return errorCode; - errorCode = BIT_initDStream(&bitD4, istart4, length4); - if (HUF_isError(errorCode)) return errorCode; + { size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1); + if (HUF_isError(errorCode)) return errorCode; } + { size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2); + if (HUF_isError(errorCode)) return errorCode; } + { size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3); + if (HUF_isError(errorCode)) return errorCode; } + { size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4); + if (HUF_isError(errorCode)) return errorCode; } - /* 16-64 symbols per loop (4-16 symbols per stream) */ + /* 4-64 symbols per loop (1-16 symbols per stream) */ endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); - for ( ; (op3 <= opStart4) && (endSignal==BIT_DStream_unfinished) && (op4<=(oend-16)) ; ) { - HUF_DECODE_SYMBOLX6_2(op1, &bitD1); - HUF_DECODE_SYMBOLX6_2(op2, &bitD2); - HUF_DECODE_SYMBOLX6_2(op3, &bitD3); - HUF_DECODE_SYMBOLX6_2(op4, &bitD4); - HUF_DECODE_SYMBOLX6_1(op1, &bitD1); - HUF_DECODE_SYMBOLX6_1(op2, &bitD2); - HUF_DECODE_SYMBOLX6_1(op3, &bitD3); - HUF_DECODE_SYMBOLX6_1(op4, &bitD4); - HUF_DECODE_SYMBOLX6_2(op1, &bitD1); - HUF_DECODE_SYMBOLX6_2(op2, &bitD2); - HUF_DECODE_SYMBOLX6_2(op3, &bitD3); - HUF_DECODE_SYMBOLX6_2(op4, &bitD4); - HUF_DECODE_SYMBOLX6_0(op1, &bitD1); - HUF_DECODE_SYMBOLX6_0(op2, &bitD2); - HUF_DECODE_SYMBOLX6_0(op3, &bitD3); - HUF_DECODE_SYMBOLX6_0(op4, &bitD4); - - endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); - } + if (endSignal==BIT_DStream_unfinished) { + HUF_DECODE_ROUNDX6; + if (sizeof(bitD1.bitContainer)==4) { /* need to decode at least 4 bytes per stream */ + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + HUF_DECODE_ROUNDX6; + } + { U32 const saved2 = MEM_read32(opStart2); /* saved from overwrite */ + U32 const saved3 = MEM_read32(opStart3); + U32 const saved4 = MEM_read32(opStart4); + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + for ( ; (op3 <= opStart4) && (endSignal==BIT_DStream_unfinished) && (op4<=(oend-16)) ; ) { + HUF_DECODE_ROUNDX6; + endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4); + } + MEM_write32(opStart2, saved2); + MEM_write32(opStart3, saved3); + MEM_write32(opStart4, saved4); + } } /* check corruption */ if (op1 > opStart2) return ERROR(corruption_detected); if (op2 > opStart3) return ERROR(corruption_detected); if (op3 > opStart4) return ERROR(corruption_detected); - /* note : op4 supposed already verified within main loop */ + /* note : op4 already verified within main loop */ /* finish bitStreams one by one */ HUF_decodeStreamX6(op1, &bitD1, opStart2, DTable, dtLog); @@ -1097,12 +1112,7 @@ typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) { static const decompressionAlgo decompress[3] = { HUF_decompress4X2, HUF_decompress4X4, HUF_decompress4X6 }; - /* estimate decompression time */ - U32 Q; - const U32 D256 = (U32)(dstSize >> 8); - U32 Dtime[3]; - U32 algoNb = 0; - int n; + U32 Dtime[3]; /* decompression time estimation */ /* validation checks */ if (dstSize == 0) return ERROR(dstSize_tooSmall); @@ -1111,16 +1121,19 @@ size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcS if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ /* decoder timing evaluation */ - Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */ - for (n=0; n<3; n++) - Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256); + { U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */ + U32 const D256 = (U32)(dstSize >> 8); + U32 n; for (n=0; n<3; n++) + Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256); + } Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */ - if (Dtime[1] < Dtime[0]) algoNb = 1; - if (Dtime[2] < Dtime[algoNb]) algoNb = 2; - - return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); + { U32 algoNb = 0; + if (Dtime[1] < Dtime[0]) algoNb = 1; + if (Dtime[2] < Dtime[algoNb]) algoNb = 2; + return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); + } //return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */ //return HUF_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */ diff --git a/lib/decompress/zstd_decompress.c b/lib/decompress/zstd_decompress.c index c34a7eb22..72e52a450 100644 --- a/lib/decompress/zstd_decompress.c +++ b/lib/decompress/zstd_decompress.c @@ -266,10 +266,9 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx) * @return : size of the Frame Header */ static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize) { - U32 fcsId; if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong); - fcsId = (((const BYTE*)src)[4]) >> 6; - return ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId]; + { U32 const fcsId = (((const BYTE*)src)[4]) >> 6; + return ZSTD_frameHeaderSize_min + ZSTD_fcs_fieldSize[fcsId]; } } @@ -843,14 +842,14 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, } -/*! ZSTD_decompress_continueDCtx() : -* `dctx` must have been properly initialized */ +/*! ZSTD_decompressFrame() : +* `dctx` must be properly initialized */ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize) { const BYTE* ip = (const BYTE*)src; - const BYTE* iend = ip + srcSize; + const BYTE* const iend = ip + srcSize; BYTE* const ostart = (BYTE* const)dst; BYTE* op = ostart; BYTE* const oend = ostart + dstCapacity; @@ -859,12 +858,6 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx, /* check */ if (srcSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong); -#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) - { const U32 magicNumber = MEM_readLE32(src); - if (ZSTD_isLegacy(magicNumber)) - return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, magicNumber); - } -#endif /* Frame Header */ { size_t const frameHeaderSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_min); @@ -929,6 +922,12 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx, const void* src, size_t srcSize, const void* dict, size_t dictSize) { +#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT==1) + { const U32 magicNumber = MEM_readLE32(src); + if (ZSTD_isLegacy(magicNumber)) + return ZSTD_decompressLegacy(dst, dstCapacity, src, srcSize, dict, dictSize, magicNumber); + } +#endif ZSTD_decompressBegin_usingDict(dctx, dict, dictSize); ZSTD_checkContinuity(dctx, dst); return ZSTD_decompressFrame(dctx, dst, dstCapacity, src, srcSize); @@ -950,7 +949,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize); ZSTD_freeDCtx(dctx); return regenSize; -#else +#else /* stack mode */ ZSTD_DCtx dctx; return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize); #endif @@ -1054,37 +1053,40 @@ static void ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSi static size_t ZSTD_loadEntropy(ZSTD_DCtx* dctx, const void* dict, size_t dictSize) { - size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize; - short offcodeNCount[MaxOff+1]; - U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog; - short matchlengthNCount[MaxML+1]; - unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog; - short litlengthNCount[MaxLL+1]; - unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog; + size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, litlengthHeaderSize; hSize = HUF_readDTableX4(dctx->hufTableX4, dict, dictSize); if (HUF_isError(hSize)) return ERROR(dictionary_corrupted); dict = (const char*)dict + hSize; dictSize -= hSize; - offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize); - if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); - errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog); - if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); - dict = (const char*)dict + offcodeHeaderSize; - dictSize -= offcodeHeaderSize; + { short offcodeNCount[MaxOff+1]; + U32 offcodeMaxValue=MaxOff, offcodeLog=OffFSELog; + offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize); + if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); + { size_t const errorCode = FSE_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); } + dict = (const char*)dict + offcodeHeaderSize; + dictSize -= offcodeHeaderSize; + } - matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize); - if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); - errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog); - if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); - dict = (const char*)dict + matchlengthHeaderSize; - dictSize -= matchlengthHeaderSize; + { short matchlengthNCount[MaxML+1]; + unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog; + matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize); + if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); + { size_t const errorCode = FSE_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); } + dict = (const char*)dict + matchlengthHeaderSize; + dictSize -= matchlengthHeaderSize; + } - litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize); - if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); - errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog); - if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); + { short litlengthNCount[MaxLL+1]; + unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog; + litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize); + if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); + { size_t const errorCode = FSE_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog); + if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); } + } dctx->flagRepeatTable = 1; return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize; diff --git a/lib/legacy/zstd_legacy.h b/lib/legacy/zstd_legacy.h index 3285bbebf..8584d5b9b 100644 --- a/lib/legacy/zstd_legacy.h +++ b/lib/legacy/zstd_legacy.h @@ -1,7 +1,7 @@ /* zstd_legacy - decoder for legacy format Header File - Copyright (C) 2015, Yann Collet. + Copyright (C) 2015-2016, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) @@ -48,16 +48,20 @@ extern "C" { #include "zstd_v04.h" #include "zstd_v05.h" + +/** ZSTD_isLegacy() : + @return : > 0 if supported by legacy decoder. 0 otherwise. + return value is the version. +*/ MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE) { switch(magicNumberLE) { - case ZSTDv01_magicNumberLE : - case ZSTDv02_magicNumber : - case ZSTDv03_magicNumber : - case ZSTDv04_magicNumber : - case ZSTDv05_MAGICNUMBER : - return 1; + case ZSTDv01_magicNumberLE:return 1; + case ZSTDv02_magicNumber : return 2; + case ZSTDv03_magicNumber : return 3; + case ZSTDv04_magicNumber : return 4; + case ZSTDv05_MAGICNUMBER : return 5; default : return 0; } } @@ -66,6 +70,7 @@ MEM_STATIC unsigned ZSTD_isLegacy (U32 magicNumberLE) MEM_STATIC size_t ZSTD_decompressLegacy( void* dst, size_t dstCapacity, const void* src, size_t compressedSize, + const void* dict,size_t dictSize, U32 magicNumberLE) { switch(magicNumberLE) @@ -79,7 +84,14 @@ MEM_STATIC size_t ZSTD_decompressLegacy( case ZSTDv04_magicNumber : return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize); case ZSTDv05_MAGICNUMBER : - return ZSTDv05_decompress(dst, dstCapacity, src, compressedSize); + { + size_t result; + ZSTDv05_DCtx* zd = ZSTDv05_createDCtx(); + if (zd==NULL) return ERROR(memory_allocation); + result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize); + ZSTDv05_freeDCtx(zd); + return result; + } default : return ERROR(prefix_unknown); } diff --git a/lib/legacy/zstd_v01.c b/lib/legacy/zstd_v01.c index 2fcf18885..d62367df2 100644 --- a/lib/legacy/zstd_v01.c +++ b/lib/legacy/zstd_v01.c @@ -407,7 +407,7 @@ FORCE_INLINE unsigned FSE_highbit32 (register U32 val) static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } -#define FSE_DECODE_TYPE FSE_TYPE_NAME(FSE_decode_t, FSE_FUNCTION_EXTENSION) +#define FSE_DECODE_TYPE FSE_decode_t typedef struct { @@ -415,7 +415,7 @@ typedef struct { U16 fastMode; } FSE_DTableHeader; /* sizeof U32 */ -static size_t FSE_FUNCTION_NAME(FSE_buildDTable, FSE_FUNCTION_EXTENSION) +static size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { void* ptr = dt; diff --git a/lib/legacy/zstd_v02.c b/lib/legacy/zstd_v02.c index 860df94a6..89501111e 100644 --- a/lib/legacy/zstd_v02.c +++ b/lib/legacy/zstd_v02.c @@ -1266,11 +1266,11 @@ typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; /* Function templates */ -#define FSE_DECODE_TYPE FSE_TYPE_NAME(FSE_decode_t, FSE_FUNCTION_EXTENSION) +#define FSE_DECODE_TYPE FSE_decode_t static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } -static size_t FSE_FUNCTION_NAME(FSE_buildDTable, FSE_FUNCTION_EXTENSION) +static size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { void* ptr = dt+1; diff --git a/lib/legacy/zstd_v03.c b/lib/legacy/zstd_v03.c index 6a048fd27..f06b47fdc 100644 --- a/lib/legacy/zstd_v03.c +++ b/lib/legacy/zstd_v03.c @@ -991,7 +991,6 @@ extern "C" { ******************************************/ static size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */ -static size_t HUF_decompress4X6 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* quad-symbols decoder */ #if defined (__cplusplus) @@ -1266,11 +1265,11 @@ typedef U32 DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)]; /* Function templates */ -#define FSE_DECODE_TYPE FSE_TYPE_NAME(FSE_decode_t, FSE_FUNCTION_EXTENSION) +#define FSE_DECODE_TYPE FSE_decode_t static U32 FSE_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } -static size_t FSE_FUNCTION_NAME(FSE_buildDTable, FSE_FUNCTION_EXTENSION) +static size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) { void* ptr = dt+1; @@ -2371,362 +2370,6 @@ static size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, si } -/**********************************/ -/* quad-symbol decoding */ -/**********************************/ -typedef struct { BYTE nbBits; BYTE nbBytes; } HUF_DDescX6; -typedef union { BYTE byte[4]; U32 sequence; } HUF_DSeqX6; - -/* recursive, up to level 3; may benefit from