Compare commits

..
14 Commits
15 changed files with 277 additions and 277 deletions
+4 -2
View File
@@ -1,6 +1,6 @@
language: c language: c
compiler: gcc compiler: gcc
script: make test-travis script: make $ZSTD_TRAVIS_CI_ENV
before_install: before_install:
- sudo apt-get update -qq - sudo apt-get update -qq
- sudo apt-get install -qq gcc-arm-linux-gnueabi - sudo apt-get install -qq gcc-arm-linux-gnueabi
@@ -11,11 +11,13 @@ before_install:
env: env:
- ZSTD_TRAVIS_CI_ENV=travis-install - ZSTD_TRAVIS_CI_ENV=travis-install
- ZSTD_TRAVIS_CI_ENV=test-all
- ZSTD_TRAVIS_CI_ENV=clangtest - ZSTD_TRAVIS_CI_ENV=clangtest
- ZSTD_TRAVIS_CI_ENV=gpptest - ZSTD_TRAVIS_CI_ENV=gpptest
- ZSTD_TRAVIS_CI_ENV=armtest - ZSTD_TRAVIS_CI_ENV=armtest
- ZSTD_TRAVIS_CI_ENV=test
- ZSTD_TRAVIS_CI_ENV="-C programs test32"
- ZSTD_TRAVIS_CI_ENV=sanitize - ZSTD_TRAVIS_CI_ENV=sanitize
- ZSTD_TRAVIS_CI_ENV="-C programs memtest"
matrix: matrix:
fast_finish: true fast_finish: true
+15 -35
View File
@@ -32,40 +32,25 @@
# ################################################################ # ################################################################
# Version number # Version number
export VERSION=0.1.0 export VERSION := 0.1.2
export RELEASE=r$(VERSION)
DESTDIR?=
PREFIX ?= /usr
LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR=$(PREFIX)/include
PRGDIR = programs PRGDIR = programs
ZSTDDIR = lib ZSTDDIR = lib
# Select test target for Travis CI's Build Matrix
ifneq (,$(filter test-%,$(ZSTD_TRAVIS_CI_ENV)))
TRAVIS_TARGET=prg-travis
else
TRAVIS_TARGET=$(ZSTD_TRAVIS_CI_ENV)
endif
.PHONY: clean .PHONY: clean
default: zstdprograms default: zstdprogram
all: all:
@cd $(ZSTDDIR); $(MAKE) -e all $(MAKE) -C $(ZSTDDIR) $@
@cd $(PRGDIR); $(MAKE) -e all $(MAKE) -C $(PRGDIR) $@
zstdprograms: zstdprogram:
@cd $(PRGDIR); $(MAKE) -e $(MAKE) -C $(PRGDIR)
clean: clean:
@cd $(PRGDIR); $(MAKE) clean $(MAKE) -C $(ZSTDDIR) $@
@cd $(ZSTDDIR); $(MAKE) clean $(MAKE) -C $(PRGDIR) $@
# @cd examples; $(MAKE) clean
@echo Cleaning completed @echo Cleaning completed
@@ -74,23 +59,18 @@ clean:
ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU)) ifneq (,$(filter $(shell uname),Linux Darwin GNU/kFreeBSD GNU))
install: install:
@cd $(ZSTDDIR); $(MAKE) -e install $(MAKE) -C $(ZSTDDIR) $@
@cd $(PRGDIR); $(MAKE) -e install $(MAKE) -C $(PRGDIR) $@
uninstall: uninstall:
@cd $(ZSTDDIR); $(MAKE) uninstall $(MAKE) -C $(ZSTDDIR) $@
@cd $(PRGDIR); $(MAKE) uninstall $(MAKE) -C $(PRGDIR) $@
travis-install: travis-install:
sudo $(MAKE) install sudo $(MAKE) install
test: test:
@cd $(PRGDIR); $(MAKE) -e test $(MAKE) -C $(PRGDIR) $@
test-travis: $(TRAVIS_TARGET)
prg-travis:
@cd $(PRGDIR); $(MAKE) -e $(ZSTD_TRAVIS_CI_ENV)
clangtest: clean clangtest: clean
clang -v clang -v
@@ -100,8 +80,8 @@ gpptest: clean
$(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror" $(MAKE) all CC=g++ CFLAGS="-O3 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Werror"
armtest: clean armtest: clean
cd $(ZSTDDIR); $(MAKE) -e all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror" $(MAKE) -C $(ZSTDDIR) -e all CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
cd $(PRGDIR); $(MAKE) -e CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror" $(MAKE) -C $(PRGDIR) -e CC=arm-linux-gnueabi-gcc MOREFLAGS="-Werror"
sanitize: clean sanitize: clean
$(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined" $(MAKE) test CC=clang MOREFLAGS="-g -fsanitize=undefined"
+8 -2
View File
@@ -1,3 +1,9 @@
r0 v0.1.2
initial release
v0.1.1
fix compression bug
detects write-flush errors
v0.1.0
first release
+3 -4
View File
@@ -32,17 +32,16 @@
# ################################################################ # ################################################################
# Version numbers # Version numbers
VERSION?= 0 VERSION?= 0.1.2
LIBVER_MAJOR=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h` LIBVER_MAJOR=`sed -n '/define ZSTD_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h`
LIBVER_MINOR=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h` LIBVER_MINOR=`sed -n '/define ZSTD_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h`
LIBVER_PATCH=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h` LIBVER_PATCH=`sed -n '/define ZSTD_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < zstd.h`
LIBVER = $(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH) LIBVER = $(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH)
DESTDIR?= DESTDIR?=
PREFIX ?= /usr PREFIX ?= /usr/local
CFLAGS ?= -O3 CFLAGS ?= -O3
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wstrict-prototypes CFLAGS += -I. -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wstrict-prototypes
LDFLAGS = -I.
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS) FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
LIBDIR ?= $(PREFIX)/lib LIBDIR ?= $(PREFIX)/lib
+45 -36
View File
@@ -135,7 +135,7 @@ typedef signed long long S64;
* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
* This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
* Method 2 : direct access. This method is portable but violate C standard. * Method 2 : direct access. This method is portable but violate C standard.
* It can generate buggy code on targets which generate assembly depending on alignment. * It can generate buggy code on targets generating assembly depending on alignment.
* But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
* See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
* Prefer these methods in priority order (0 > 1 > 2) * Prefer these methods in priority order (0 > 1 > 2)
@@ -914,8 +914,8 @@ size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* t
else else
{ {
bitCount -= (int)(8 * (iend - 4 - ip)); bitCount -= (int)(8 * (iend - 4 - ip));
ip = iend - 4; ip = iend - 4;
} }
bitStream = FSE_readLE32(ip) >> (bitCount & 31); bitStream = FSE_readLE32(ip) >> (bitCount & 31);
} }
} }
@@ -967,20 +967,20 @@ void FSE_freeCTable (FSE_CTable* ct)
/* provides the minimum logSize to safely represent a distribution */ /* provides the minimum logSize to safely represent a distribution */
static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue) static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
{ {
U32 minBitsSrc = FSE_highbit32((U32)(srcSize - 1)) + 1; U32 minBitsSrc = FSE_highbit32((U32)(srcSize - 1)) + 1;
U32 minBitsSymbols = FSE_highbit32(maxSymbolValue) + 2; U32 minBitsSymbols = FSE_highbit32(maxSymbolValue) + 2;
U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols; U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
return minBits; return minBits;
} }
unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue) unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
{ {
U32 maxBitsSrc = FSE_highbit32((U32)(srcSize - 1)) - 2; U32 maxBitsSrc = FSE_highbit32((U32)(srcSize - 1)) - 2;
U32 tableLog = maxTableLog; U32 tableLog = maxTableLog;
U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue); U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG; if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */ if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */ if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG; if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG; if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
return tableLog; return tableLog;
@@ -1398,6 +1398,7 @@ size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize
errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize); errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
if (FSE_isError(errorCode)) return errorCode; if (FSE_isError(errorCode)) return errorCode;
if (errorCode == srcSize) return 1; if (errorCode == srcSize) return 1;
if (errorCode == 1) return 0; /* each symbol only present once */
if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */ if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue); tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
@@ -1529,12 +1530,14 @@ size_t FSE_initDStream(FSE_DStream_t* bitD, const void* srcBuffer, size_t srcSiz
*/ */
static size_t FSE_lookBits(FSE_DStream_t* bitD, U32 nbBits) static size_t FSE_lookBits(FSE_DStream_t* bitD, U32 nbBits)
{ {
return ((bitD->bitContainer << (bitD->bitsConsumed & ((sizeof(bitD->bitContainer)*8)-1))) >> 1) >> (((sizeof(bitD->bitContainer)*8)-1)-nbBits); const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;
return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);
} }
static size_t FSE_lookBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */ static size_t FSE_lookBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >= 1 !! */
{ {
return (bitD->bitContainer << bitD->bitsConsumed) >> ((sizeof(bitD->bitContainer)*8)-nbBits); const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1;
return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask);
} }
static void FSE_skipBits(FSE_DStream_t* bitD, U32 nbBits) static void FSE_skipBits(FSE_DStream_t* bitD, U32 nbBits)
@@ -1566,8 +1569,8 @@ size_t FSE_readBitsFast(FSE_DStream_t* bitD, U32 nbBits) /* only if nbBits >=
unsigned FSE_reloadDStream(FSE_DStream_t* bitD) unsigned FSE_reloadDStream(FSE_DStream_t* bitD)
{ {
if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
return FSE_DStream_tooFar; return FSE_DStream_tooFar;
if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer))
{ {
@@ -1831,7 +1834,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* tree, U32
if (maxSymbolValue > (241-128)) return (size_t)-FSE_ERROR_GENERIC; /* not implemented (not possible with current format) */ if (maxSymbolValue > (241-128)) return (size_t)-FSE_ERROR_GENERIC; /* not implemented (not possible with current format) */
if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* not enough space within dst buffer */ if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return (size_t)-FSE_ERROR_dstSize_tooSmall; /* not enough space within dst buffer */
op[0] = (BYTE)(128 /*special case*/ + 0 /* Not Compressible */ + (maxSymbolValue-1)); op[0] = (BYTE)(128 /*special case*/ + 0 /* Not Compressible */ + (maxSymbolValue-1));
huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */ huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause issue in final combination */
for (n=0; n<maxSymbolValue; n+=2) for (n=0; n<maxSymbolValue; n+=2)
op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]); op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
return ((maxSymbolValue+1)/2) + 1; return ((maxSymbolValue+1)/2) + 1;
@@ -1875,7 +1878,7 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
U32 rankLast[HUF_MAX_TABLELOG]; U32 rankLast[HUF_MAX_TABLELOG];
U32 currentNbBits = maxNbBits; U32 currentNbBits = maxNbBits;
int pos; int pos;
memset(rankLast, 0xF0, sizeof(rankLast)); memset(rankLast, 0xF0, sizeof(rankLast));
for (pos=n ; pos >= 0; pos--) for (pos=n ; pos >= 0; pos--)
{ {
if (huffNode[pos].nbBits >= currentNbBits) continue; if (huffNode[pos].nbBits >= currentNbBits) continue;
@@ -1904,24 +1907,30 @@ static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
if (rankLast[nBitsToDecrease-1] == noOne) if (rankLast[nBitsToDecrease-1] == noOne)
rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; // now there is one elt rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; // now there is one elt
huffNode[rankLast[nBitsToDecrease]].nbBits ++; huffNode[rankLast[nBitsToDecrease]].nbBits ++;
rankLast[nBitsToDecrease]--; if (rankLast[nBitsToDecrease] == 0)
if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease) rankLast[nBitsToDecrease] = noOne;
rankLast[nBitsToDecrease] = noOne; // rank list emptied else
{
rankLast[nBitsToDecrease]--;
if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
rankLast[nBitsToDecrease] = noOne; // rank list emptied
}
}
while (totalCost < 0) /* Sometimes, cost correction overshoot */
{
if (rankLast[1] == noOne) /* special case, no weight 1, let's find it back at n */
{
while (huffNode[n].nbBits == maxNbBits) n--;
huffNode[n+1].nbBits--;
rankLast[1] = n+1;
totalCost++;
continue;
}
huffNode[ rankLast[1] + 1 ].nbBits--;
rankLast[1]++;
totalCost ++;
} }
while (totalCost < 0) // Sometimes, cost correction overshoot
{
if (rankLast[1] == noOne) /* special case, no weight 1, let's find it back at n */
{
while (huffNode[n].nbBits == maxNbBits) n--;
huffNode[n+1].nbBits--;
rankLast[1] = n+1;
totalCost++;
continue;
}
huffNode[ rankLast[1] + 1 ].nbBits--;
rankLast[1]++;
totalCost ++;
}
} }
} }
@@ -1972,7 +1981,7 @@ size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U3
/* safety checks */ /* safety checks */
if (maxNbBits == 0) maxNbBits = HUF_DEFAULT_TABLELOG; if (maxNbBits == 0) maxNbBits = HUF_DEFAULT_TABLELOG;
if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_GENERIC; if (maxSymbolValue > HUF_MAX_SYMBOL_VALUE) return (size_t)-FSE_ERROR_GENERIC;
memset(huffNode0, 0, sizeof(huffNode0)); memset(huffNode0, 0, sizeof(huffNode0));
// sort, decreasing order // sort, decreasing order
HUF_sort(huffNode, count, maxSymbolValue); HUF_sort(huffNode, count, maxSymbolValue);
@@ -2057,7 +2066,7 @@ size_t HUF_compress_usingCTable(void* dst, size_t dstSize, const void* src, size
FSE_CStream_t bitC; FSE_CStream_t bitC;
/* init */ /* init */
if (dstSize < 8) return 0; if (dstSize < 8) return 0;
op += 6; /* jump Table -- could be optimized by delta / deviation */ op += 6; /* jump Table -- could be optimized by delta / deviation */
errorCode = FSE_initCStream(&bitC, op, oend-op); errorCode = FSE_initCStream(&bitC, op, oend-op);
if (FSE_isError(errorCode)) return 0; if (FSE_isError(errorCode)) return 0;
+55 -50
View File
@@ -542,11 +542,11 @@ static size_t ZSTD_compressLiterals (void* dst, size_t dstSize,
const size_t minGain = ZSTD_minGain(srcSize); const size_t minGain = ZSTD_minGain(srcSize);
BYTE* const ostart = (BYTE*)dst; BYTE* const ostart = (BYTE*)dst;
size_t hsize; size_t hsize;
static const size_t LHSIZE = 5; static const size_t LHSIZE = 5;
if (dstSize < LHSIZE+1) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* not enough space for compression */ if (dstSize < LHSIZE+1) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* not enough space for compression */
hsize = HUF_compress(ostart+LHSIZE, dstSize-LHSIZE, src, srcSize); hsize = HUF_compress(ostart+LHSIZE, dstSize-LHSIZE, src, srcSize);
if (hsize<2) return hsize; /* special cases */ if (hsize<2) return hsize; /* special cases */
if (hsize >= srcSize - minGain) return 0; if (hsize >= srcSize - minGain) return 0;
@@ -619,8 +619,8 @@ static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
} }
/* Sequences Header */ /* Sequences Header */
if ((oend-op) < 2+3+6) /* nbSeq + dumpsLength + 3*rleCTable*/ if ((oend-op) < 2+3+6) /* nbSeq + dumpsLength + 3*rleCTable*/
return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
ZSTD_writeLE16(op, (U16)nbSeq); op+=2; ZSTD_writeLE16(op, (U16)nbSeq); op+=2;
seqHead = op; seqHead = op;
@@ -640,7 +640,7 @@ static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
op[2] = (BYTE)(dumpsLength); op[2] = (BYTE)(dumpsLength);
op += 3; op += 3;
} }
if ((size_t)(oend-op) < dumpsLength+6) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; if ((size_t)(oend-op) < dumpsLength+6) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
memcpy(op, seqStorePtr->dumpsStart, dumpsLength); memcpy(op, seqStorePtr->dumpsStart, dumpsLength);
op += dumpsLength; op += dumpsLength;
} }
@@ -661,11 +661,11 @@ static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
} }
else else
{ {
size_t NCountSize; size_t NCountSize;
tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max); tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
FSE_normalizeCount(norm, tableLog, count, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
op += NCountSize; op += NCountSize;
FSE_buildCTable(CTable_LitLength, norm, max, tableLog); FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
LLtype = bt_compressed; LLtype = bt_compressed;
@@ -696,11 +696,11 @@ static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
} }
else else
{ {
size_t NCountSize; size_t NCountSize;
tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max); tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
FSE_normalizeCount(norm, tableLog, count, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
op += NCountSize; op += NCountSize;
FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog); FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
Offtype = bt_compressed; Offtype = bt_compressed;
@@ -722,11 +722,11 @@ static size_t ZSTD_compressSequences(BYTE* dst, size_t maxDstSize,
} }
else else
{ {
size_t NCountSize; size_t NCountSize;
tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max); tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
FSE_normalizeCount(norm, tableLog, count, nbSeq, max); FSE_normalizeCount(norm, tableLog, count, nbSeq, max);
NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */ NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(NCountSize)) return (size_t)-ZSTD_ERROR_GENERIC;
op += NCountSize; op += NCountSize;
FSE_buildCTable(CTable_MatchLength, norm, max, tableLog); FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
MLtype = bt_compressed; MLtype = bt_compressed;
@@ -1028,7 +1028,7 @@ size_t ZSTD_compressContinue(ZSTD_Cctx* cctx, void* dst, size_t maxDstSize, con
size_t blockSize = BLOCKSIZE; size_t blockSize = BLOCKSIZE;
if (blockSize > srcSize) blockSize = srcSize; if (blockSize > srcSize) blockSize = srcSize;
if (maxDstSize < 2*ZSTD_blockHeaderSize+1) /* one RLE block + endMark */ if (maxDstSize < 2*ZSTD_blockHeaderSize+1) /* one RLE block + endMark */
return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
/* update hash table */ /* update hash table */
@@ -1250,8 +1250,8 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
U32 LLlog, Offlog, MLlog; U32 LLlog, Offlog, MLlog;
size_t dumpsLength; size_t dumpsLength;
/* check */ /* check */
if (srcSize < 5) return (size_t)-ZSTD_ERROR_SrcSize; if (srcSize < 5) return (size_t)-ZSTD_ERROR_SrcSize;
/* SeqHead */ /* SeqHead */
*nbSeq = ZSTD_readLE16(ip); ip+=2; *nbSeq = ZSTD_readLE16(ip); ip+=2;
@@ -1273,8 +1273,8 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
*dumpsPtr = ip; *dumpsPtr = ip;
ip += dumpsLength; ip += dumpsLength;
/* check */ /* check */
if (ip > iend-3) return (size_t)-ZSTD_ERROR_SrcSize; /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */ if (ip > iend-3) return (size_t)-ZSTD_ERROR_SrcSize; /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
/* sequences */ /* sequences */
{ {
@@ -1295,7 +1295,7 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
max = MaxLL; max = MaxLL;
headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip); headerSize = FSE_readNCount(norm, &max, &LLlog, ip, iend-ip);
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
if (LLlog > LLFSELog) return (size_t)-ZSTD_ERROR_corruption; if (LLlog > LLFSELog) return (size_t)-ZSTD_ERROR_corruption;
ip += headerSize; ip += headerSize;
FSE_buildDTable(DTableLL, norm, max, LLlog); FSE_buildDTable(DTableLL, norm, max, LLlog);
} }
@@ -1314,7 +1314,7 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
max = MaxOff; max = MaxOff;
headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip); headerSize = FSE_readNCount(norm, &max, &Offlog, ip, iend-ip);
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
if (Offlog > OffFSELog) return (size_t)-ZSTD_ERROR_corruption; if (Offlog > OffFSELog) return (size_t)-ZSTD_ERROR_corruption;
ip += headerSize; ip += headerSize;
FSE_buildDTable(DTableOffb, norm, max, Offlog); FSE_buildDTable(DTableOffb, norm, max, Offlog);
} }
@@ -1333,7 +1333,7 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
max = MaxML; max = MaxML;
headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip); headerSize = FSE_readNCount(norm, &max, &MLlog, ip, iend-ip);
if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC; if (FSE_isError(headerSize)) return (size_t)-ZSTD_ERROR_GENERIC;
if (MLlog > MLFSELog) return (size_t)-ZSTD_ERROR_corruption; if (MLlog > MLFSELog) return (size_t)-ZSTD_ERROR_corruption;
ip += headerSize; ip += headerSize;
FSE_buildDTable(DTableML, norm, max, MLlog); FSE_buildDTable(DTableML, norm, max, MLlog);
} }
@@ -1389,7 +1389,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream)); if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream));
nbBits = offsetCode - 1; nbBits = offsetCode - 1;
if (offsetCode==0) nbBits = 0; /* cmove */ if (offsetCode==0) nbBits = 0; /* cmove */
offset = ((size_t)1 << nbBits) + FSE_readBits(&(seqState->DStream), nbBits); offset = ((size_t)1 << (nbBits & ((sizeof(offset)*8)-1))) + FSE_readBits(&(seqState->DStream), nbBits);
if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream)); if (ZSTD_32bits()) FSE_reloadDStream(&(seqState->DStream));
if (offsetCode==0) offset = prevOffset; if (offsetCode==0) offset = prevOffset;
} }
@@ -1417,9 +1417,9 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
static size_t ZSTD_execSequence(BYTE* op, static size_t ZSTD_execSequence(BYTE* op,
seq_t sequence, seq_t sequence,
const BYTE** litPtr, const BYTE* const litLimit, const BYTE** litPtr, const BYTE* const litLimit,
BYTE* const base, BYTE* const oend) BYTE* const base, BYTE* const oend)
{ {
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* substracted */ static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* substracted */
@@ -1430,7 +1430,7 @@ static size_t ZSTD_execSequence(BYTE* op,
/* check */ /* check */
if (endMatch > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite beyond dst buffer */ if (endMatch > oend) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite beyond dst buffer */
if (litEnd > litLimit) return (size_t)-ZSTD_ERROR_corruption; if (litEnd > litLimit) return (size_t)-ZSTD_ERROR_corruption;
if (sequence.matchLength > (size_t)(*litPtr-op)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite literal segment */ if (sequence.matchLength > (size_t)(*litPtr-op)) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; /* overwrite literal segment */
/* copy Literals */ /* copy Literals */
@@ -1442,18 +1442,18 @@ static size_t ZSTD_execSequence(BYTE* op,
*litPtr = litEnd; /* update for next sequence */ *litPtr = litEnd; /* update for next sequence */
/* check : last match must be at a minimum distance of 8 from end of dest buffer */ /* check : last match must be at a minimum distance of 8 from end of dest buffer */
if (oend-op < 8) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall; if (oend-op < 8) return (size_t)-ZSTD_ERROR_maxDstSize_tooSmall;
/* copy Match */ /* copy Match */
{ {
const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12); const U32 overlapRisk = (((size_t)(litEnd - endMatch)) < 12);
const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */ const BYTE* match = op - sequence.offset; /* possible underflow at op - offset ? */
size_t qutt = 12; size_t qutt = 12;
U64 saved[2]; U64 saved[2];
/* check */ /* check */
if (match < base) return (size_t)-ZSTD_ERROR_corruption; if (match < base) return (size_t)-ZSTD_ERROR_corruption;
if (sequence.offset > (size_t)base) return (size_t)-ZSTD_ERROR_corruption; if (sequence.offset > (size_t)base) return (size_t)-ZSTD_ERROR_corruption;
/* save beginning of literal sequence, in case of write overlap */ /* save beginning of literal sequence, in case of write overlap */
if (overlapRisk) if (overlapRisk)
@@ -1473,7 +1473,7 @@ static size_t ZSTD_execSequence(BYTE* op,
ZSTD_copy4(op+4, match); ZSTD_copy4(op+4, match);
match -= dec64; match -= dec64;
} else { ZSTD_copy8(op, match); } } else { ZSTD_copy8(op, match); }
op += 8; match += 8; op += 8; match += 8;
if (endMatch > oend-12) if (endMatch > oend-12)
{ {
@@ -1498,11 +1498,11 @@ static size_t ZSTD_execSequence(BYTE* op,
typedef struct ZSTD_Dctx_s typedef struct ZSTD_Dctx_s
{ {
U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)]; U32 LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)]; U32 OffTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)]; U32 MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
void* previousDstEnd; void* previousDstEnd;
void* base; void* base;
size_t expected; size_t expected;
blockType_t bType; blockType_t bType;
U32 phase; U32 phase;
} dctx_t; } dctx_t;
@@ -1514,7 +1514,7 @@ static size_t ZSTD_decompressSequences(
const void* seqStart, size_t seqSize, const void* seqStart, size_t seqSize,
const BYTE* litStart, size_t litSize) const BYTE* litStart, size_t litSize)
{ {
dctx_t* dctx = (dctx_t*)ctx; dctx_t* dctx = (dctx_t*)ctx;
const BYTE* ip = (const BYTE*)seqStart; const BYTE* ip = (const BYTE*)seqStart;
const BYTE* const iend = ip + seqSize; const BYTE* const iend = ip + seqSize;
BYTE* const ostart = (BYTE* const)dst; BYTE* const ostart = (BYTE* const)dst;
@@ -1526,9 +1526,9 @@ static size_t ZSTD_decompressSequences(
int nbSeq; int nbSeq;
const BYTE* dumps; const BYTE* dumps;
U32* DTableLL = dctx->LLTable; U32* DTableLL = dctx->LLTable;
U32* DTableML = dctx->MLTable; U32* DTableML = dctx->MLTable;
U32* DTableOffb = dctx->OffTable; U32* DTableOffb = dctx->OffTable;
BYTE* const base = (BYTE*) (dctx->base); BYTE* const base = (BYTE*) (dctx->base);
/* Build Decoding Tables */ /* Build Decoding Tables */
errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps, errorCode = ZSTD_decodeSeqHeaders(&nbSeq, &dumps,
@@ -1658,8 +1658,8 @@ static size_t ZSTD_decompressDCtx(void* ctx, void* dst, size_t maxDstSize, const
size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize) size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
{ {
dctx_t ctx; dctx_t ctx;
ctx.base = dst; ctx.base = dst;
return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize); return ZSTD_decompressDCtx(&ctx, dst, maxDstSize, src, srcSize);
} }
@@ -1668,14 +1668,20 @@ size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t src
* Streaming Decompression API * Streaming Decompression API
*******************************/ *******************************/
size_t ZSTD_resetDCtx(ZSTD_Dctx* dctx)
{
dctx->expected = ZSTD_frameHeaderSize;
dctx->phase = 0;
dctx->previousDstEnd = NULL;
dctx->base = NULL;
return 0;
}
ZSTD_Dctx* ZSTD_createDCtx(void) ZSTD_Dctx* ZSTD_createDCtx(void)
{ {
ZSTD_Dctx* dctx = (ZSTD_Dctx*)malloc(sizeof(ZSTD_Dctx)); ZSTD_Dctx* dctx = (ZSTD_Dctx*)malloc(sizeof(ZSTD_Dctx));
if (dctx==NULL) return NULL; if (dctx==NULL) return NULL;
dctx->expected = ZSTD_frameHeaderSize; ZSTD_resetDCtx(dctx);
dctx->phase = 0;
dctx->previousDstEnd = NULL;
dctx->base = NULL;
return dctx; return dctx;
} }
@@ -1685,7 +1691,6 @@ size_t ZSTD_freeDCtx(ZSTD_Dctx* dctx)
return 0; return 0;
} }
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_Dctx* dctx) size_t ZSTD_nextSrcSizeToDecompress(ZSTD_Dctx* dctx)
{ {
return ((dctx_t*)dctx)->expected; return ((dctx_t*)dctx)->expected;
@@ -1697,8 +1702,8 @@ size_t ZSTD_decompressContinue(ZSTD_Dctx* dctx, void* dst, size_t maxDstSize, co
/* Sanity check */ /* Sanity check */
if (srcSize != ctx->expected) return (size_t)-ZSTD_ERROR_SrcSize; if (srcSize != ctx->expected) return (size_t)-ZSTD_ERROR_SrcSize;
if (dst != ctx->previousDstEnd) /* not contiguous */ if (dst != ctx->previousDstEnd) /* not contiguous */
ctx->base = dst; ctx->base = dst;
/* Decompress : frame header */ /* Decompress : frame header */
if (ctx->phase == 0) if (ctx->phase == 0)
@@ -1754,7 +1759,7 @@ size_t ZSTD_decompressContinue(ZSTD_Dctx* dctx, void* dst, size_t maxDstSize, co
} }
ctx->phase = 1; ctx->phase = 1;
ctx->expected = ZSTD_blockHeaderSize; ctx->expected = ZSTD_blockHeaderSize;
ctx->previousDstEnd = (void*)( ((char*)dst) + rSize); ctx->previousDstEnd = (void*)( ((char*)dst) + rSize);
return rSize; return rSize;
} }
+1 -1
View File
@@ -47,7 +47,7 @@ extern "C" {
**************************************/ **************************************/
#define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */ #define ZSTD_VERSION_MAJOR 0 /* for breaking interface changes */
#define ZSTD_VERSION_MINOR 1 /* for new (non-breaking) interface capabilities */ #define ZSTD_VERSION_MINOR 1 /* for new (non-breaking) interface capabilities */
#define ZSTD_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ #define ZSTD_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */
#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE) #define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
unsigned ZSTD_versionNumber (void); unsigned ZSTD_versionNumber (void);
+1
View File
@@ -56,6 +56,7 @@ size_t ZSTD_compressEnd(ZSTD_Cctx* cctx, void* dst, size_t maxDstSize);
typedef struct ZSTD_Dctx_s ZSTD_Dctx; typedef struct ZSTD_Dctx_s ZSTD_Dctx;
ZSTD_Dctx* ZSTD_createDCtx(void); ZSTD_Dctx* ZSTD_createDCtx(void);
size_t ZSTD_resetDCtx(ZSTD_Dctx* dctx);
size_t ZSTD_freeDCtx(ZSTD_Dctx* dctx); size_t ZSTD_freeDCtx(ZSTD_Dctx* dctx);
size_t ZSTD_nextSrcSizeToDecompress(ZSTD_Dctx* dctx); size_t ZSTD_nextSrcSizeToDecompress(ZSTD_Dctx* dctx);
+32 -19
View File
@@ -30,21 +30,18 @@
# fullbench32: Same as fullbench, but forced to compile in 32-bits mode # fullbench32: Same as fullbench, but forced to compile in 32-bits mode
# ########################################################################## # ##########################################################################
RELEASE?= v0.1.0 VERSION?= v0.1.2
DESTDIR?= DESTDIR?=
PREFIX ?= /usr PREFIX ?= /usr/local
CFLAGS ?= -O3 CFLAGS ?= -O3
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -DZSTD_VERSION=\"$(RELEASE)\" CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -DZSTD_VERSION=\"$(VERSION)\"
LDFLAGS = -I../lib LDFLAGS = -I../lib
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS) FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
BINDIR=$(PREFIX)/bin BINDIR = $(PREFIX)/bin
MANDIR=$(PREFIX)/share/man/man1 MANDIR = $(PREFIX)/share/man/man1
ZSTDDIR=../lib ZSTDDIR = ../lib
TEST_FILES = COPYING
TEST_TARGETS=test-native
# Define *.exe as extension for Windows systems # Define *.exe as extension for Windows systems
@@ -103,26 +100,42 @@ install: zstd
@ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd @ln -sf zstd$(EXT) $(DESTDIR)$(BINDIR)/unzstd
@echo Installing man pages @echo Installing man pages
@install -m 644 zstd.1 $(DESTDIR)$(MANDIR)/zstd.1 @install -m 644 zstd.1 $(DESTDIR)$(MANDIR)/zstd.1
@install -m 644 zstdcat.1 $(DESTDIR)$(MANDIR)/zstdcat.1 @ln -sf zstd.1 $(DESTDIR)$(MANDIR)/zstdcat.1
@install -m 644 unzstd.1 $(DESTDIR)$(MANDIR)/unzstd.1 @ln -sf zstd.1 $(DESTDIR)$(MANDIR)/unzstd.1
@echo zstd installation completed @echo zstd installation completed
uninstall: uninstall:
rm -f $(DESTDIR)$(BINDIR)/zstdcat rm -f $(DESTDIR)$(BINDIR)/zstdcat
rm -f $(DESTDIR)$(BINDIR)/unzstd rm -f $(DESTDIR)$(BINDIR)/unzstd
[ -x $(DESTDIR)$(BINDIR)/zstd$(EXT) ] && rm -f $(DESTDIR)$(BINDIR)/zstd$(EXT) [ -x $(DESTDIR)$(BINDIR)/zstd$(EXT) ] && rm -f $(DESTDIR)$(BINDIR)/zstd$(EXT)
rm -f $(DESTDIR)$(MANDIR)/zstdcat.1
rm -f $(DESTDIR)$(MANDIR)/unzstd.1
[ -f $(DESTDIR)$(MANDIR)/zstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstd.1 [ -f $(DESTDIR)$(MANDIR)/zstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstd.1
[ -f $(DESTDIR)$(MANDIR)/zstdcat.1 ] && rm -f $(DESTDIR)$(MANDIR)/zstdcat.1
[ -f $(DESTDIR)$(MANDIR)/unzstd.1 ] && rm -f $(DESTDIR)$(MANDIR)/unzstd.1
@echo zstd programs successfully uninstalled @echo zstd programs successfully uninstalled
test: test-zstd test-fullbench test-fuzzer test: test-zstd test-fullbench test-fuzzer
test32: test-zstd32 test-fullbench32 test-fuzzer32 test32: test-zstd32 test-fullbench32 test-fuzzer32
test-all: test test32 test-mem test-all: test test32 memtest
test-zstd: zstd datagen test-zstd: zstd datagen
@echo "\n**** frame concatenation **** "
@echo "hello " > hello.tmp
@echo "world!" > world.tmp
@cat hello.tmp world.tmp > helloworld.tmp
./zstd hello.tmp > hello.zstd
./zstd world.tmp > world.zstd
@cat hello.zstd world.zstd > helloworld.zstd
./zstd -d helloworld.zstd > result.tmp
cat result.tmp
sdiff helloworld.tmp result.tmp
@rm *.tmp *.zstd
@echo frame concatenation test completed
@echo "**** flush write error test **** "
echo foo | ./zstd > /dev/full; if [ $$? -eq 0 ] ; then echo "write error not detected!"; false; fi
echo foo | ./zstd | ./zstd -d > /dev/full; if [ $$? -eq 0 ] ; then echo "write error not detected!"; false; fi
@echo "**** zstd round-trip tests **** "
./datagen | ./zstd -v | ./zstd -d > $(VOID) ./datagen | ./zstd -v | ./zstd -d > $(VOID)
./datagen -g256MB | ./zstd -v | ./zstd -d > $(VOID) ./datagen -g256MB | ./zstd -v | ./zstd -d > $(VOID)
./datagen -g6GB -P99 | ./zstd -vq | ./zstd -d > $(VOID) ./datagen -g6GB -P99 | ./zstd -vq | ./zstd -d > $(VOID)
@@ -146,15 +159,15 @@ test-fuzzer: fuzzer
test-fuzzer32: fuzzer32 test-fuzzer32: fuzzer32
./fuzzer32 ./fuzzer32
test-mem: zstd datagen fuzzer fullbench memtest: zstd datagen fuzzer fullbench
@echo "\n ---- valgrind tests : memory analyzer ----" @echo "\n ---- valgrind tests : memory analyzer ----"
valgrind --leak-check=yes --error-exitcode=1 ./datagen -g50M > /dev/null valgrind --leak-check=yes --error-exitcode=1 ./datagen -g50M > $(VOID)
./datagen -g16KB > tmp ./datagen -g16KB > tmp
valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp /dev/null valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp $(VOID)
./datagen -g64MB > tmp ./datagen -g64MB > tmp
valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp /dev/null valgrind --leak-check=yes --error-exitcode=1 ./zstd -vf tmp $(VOID)
@rm tmp @rm tmp
valgrind --leak-check=yes --error-exitcode=1 ./fuzzer -i128 -t1 valgrind --leak-check=yes --error-exitcode=1 ./fuzzer -i1000 -t1
valgrind --leak-check=yes --error-exitcode=1 ./fullbench -i1 valgrind --leak-check=yes --error-exitcode=1 ./fullbench -i1
endif endif
+75 -40
View File
@@ -52,6 +52,7 @@
#include <stdlib.h> /* malloc, free */ #include <stdlib.h> /* malloc, free */
#include <string.h> /* strcmp, strlen */ #include <string.h> /* strcmp, strlen */
#include <time.h> /* clock */ #include <time.h> /* clock */
#include <errno.h> /* errno */
#include "fileio.h" #include "fileio.h"
#include "zstd_static.h" #include "zstd_static.h"
@@ -254,7 +255,7 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
if (ZSTD_isError(cSize)) EXM_THROW(22, "Compression error : cannot create frame header"); if (ZSTD_isError(cSize)) EXM_THROW(22, "Compression error : cannot create frame header");
sizeCheck = fwrite(outBuff, 1, cSize, foutput); sizeCheck = fwrite(outBuff, 1, cSize, foutput);
if (sizeCheck!=cSize) EXM_THROW(23, "Write error : cannot write header"); if (sizeCheck!=cSize) EXM_THROW(23, "Write error : cannot write header into %s", output_filename);
compressedfilesize += cSize; compressedfilesize += cSize;
/* Main compression loop */ /* Main compression loop */
@@ -276,7 +277,7 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
/* Write cBlock */ /* Write cBlock */
sizeCheck = fwrite(outBuff, 1, cSize, foutput); sizeCheck = fwrite(outBuff, 1, cSize, foutput);
if (sizeCheck!=cSize) EXM_THROW(25, "Write error : cannot write compressed block"); if (sizeCheck!=cSize) EXM_THROW(25, "Write error : cannot write compressed block into %s", output_filename);
compressedfilesize += cSize; compressedfilesize += cSize;
inSlot += inSize; inSlot += inSize;
@@ -288,7 +289,7 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
if (ZSTD_isError(cSize)) EXM_THROW(26, "Compression error : cannot create frame end"); if (ZSTD_isError(cSize)) EXM_THROW(26, "Compression error : cannot create frame end");
sizeCheck = fwrite(outBuff, 1, cSize, foutput); sizeCheck = fwrite(outBuff, 1, cSize, foutput);
if (sizeCheck!=cSize) EXM_THROW(27, "Write error : cannot write frame end"); if (sizeCheck!=cSize) EXM_THROW(27, "Write error : cannot write frame end into %s", output_filename);
compressedfilesize += cSize; compressedfilesize += cSize;
/* Status */ /* Status */
@@ -299,54 +300,27 @@ unsigned long long FIO_compressFilename(const char* output_filename, const char*
/* clean */ /* clean */
free(inBuff); free(inBuff);
free(outBuff); free(outBuff);
fclose(finput);
fclose(foutput);
ZSTD_freeCCtx(ctx); ZSTD_freeCCtx(ctx);
fclose(finput);
if (fclose(foutput)) EXM_THROW(28, "Write error : cannot properly close %s", output_filename);
return compressedfilesize; return compressedfilesize;
} }
#define MAXHEADERSIZE FIO_FRAMEHEADERSIZE+3 #define MAXHEADERSIZE FIO_FRAMEHEADERSIZE+3
unsigned long long FIO_decompressFilename(const char* output_filename, const char* input_filename) unsigned long long FIO_decompressFrame(FILE* foutput, FILE* finput,
BYTE* inBuff, size_t inBuffSize,
BYTE* outBuff, size_t outBuffSize,
ZSTD_Dctx* dctx)
{ {
FILE* finput, *foutput; BYTE* op = outBuff;
BYTE* inBuff; BYTE* const oend = outBuff + outBuffSize;
size_t inBuffSize;
BYTE* outBuff, *op, *oend;
size_t outBuffSize;
U32 blockSize = 128 KB;
U32 wNbBlocks = 4;
U64 filesize = 0; U64 filesize = 0;
BYTE* header[MAXHEADERSIZE];
ZSTD_Dctx* dctx;
size_t toRead; size_t toRead;
size_t sizeCheck; size_t sizeCheck;
/* Init */
FIO_getFileHandles(&finput, &foutput, input_filename, output_filename);
dctx = ZSTD_createDCtx();
/* check header */
toRead = ZSTD_nextSrcSizeToDecompress(dctx);
if (toRead > MAXHEADERSIZE) EXM_THROW(30, "Not enough memory to read header");
sizeCheck = fread(header, (size_t)1, toRead, finput);
if (sizeCheck != toRead) EXM_THROW(31, "Read error : cannot read header");
sizeCheck = ZSTD_decompressContinue(dctx, NULL, 0, header, toRead); // Decode frame header
if (ZSTD_isError(sizeCheck)) EXM_THROW(32, "Error decoding header");
/* Here later : blockSize determination */
/* Allocate Memory */
inBuffSize = blockSize + FIO_blockHeaderSize;
inBuff = (BYTE*)malloc(inBuffSize);
outBuffSize = wNbBlocks * blockSize;
outBuff = (BYTE*)malloc(outBuffSize);
op = outBuff;
oend = outBuff + outBuffSize;
if (!inBuff || !outBuff) EXM_THROW(33, "Allocation error : not enough memory");
/* Main decompression Loop */ /* Main decompression Loop */
toRead = ZSTD_nextSrcSizeToDecompress(dctx); toRead = ZSTD_nextSrcSizeToDecompress(dctx);
while (toRead) while (toRead)
@@ -379,15 +353,76 @@ unsigned long long FIO_decompressFilename(const char* output_filename, const cha
toRead = ZSTD_nextSrcSizeToDecompress(dctx); toRead = ZSTD_nextSrcSizeToDecompress(dctx);
} }
return filesize;
}
unsigned long long FIO_decompressFilename(const char* output_filename, const char* input_filename)
{
FILE* finput, *foutput;
BYTE* inBuff=NULL;
size_t inBuffSize = 0;
BYTE* outBuff=NULL;
size_t outBuffSize = 0;
U32 blockSize = 128 KB;
U32 wNbBlocks = 4;
U64 filesize = 0;
BYTE* header[MAXHEADERSIZE];
ZSTD_Dctx* dctx;
size_t toRead;
size_t sizeCheck;
/* Init */
FIO_getFileHandles(&finput, &foutput, input_filename, output_filename);
dctx = ZSTD_createDCtx();
/* for each frame */
for ( ; ; )
{
/* check header */
ZSTD_resetDCtx(dctx);
toRead = ZSTD_nextSrcSizeToDecompress(dctx);
if (toRead > MAXHEADERSIZE) EXM_THROW(30, "Not enough memory to read header");
sizeCheck = fread(header, (size_t)1, toRead, finput);
if (sizeCheck==0) break; /* no more input */
if (sizeCheck != toRead) EXM_THROW(31, "Read error : cannot read header");
sizeCheck = ZSTD_decompressContinue(dctx, NULL, 0, header, toRead); // Decode frame header
if (ZSTD_isError(sizeCheck)) EXM_THROW(32, "Error decoding header");
/* Here later : blockSize determination */
/* Allocate Memory (if needed) */
{
size_t newInBuffSize = blockSize + FIO_blockHeaderSize;
size_t newOutBuffSize = wNbBlocks * blockSize;
if (newInBuffSize > inBuffSize)
{
free(inBuff);
inBuffSize = newInBuffSize;
inBuff = (BYTE*)malloc(inBuffSize);
}
if (newOutBuffSize > outBuffSize)
{
free(outBuff);
outBuffSize = newOutBuffSize;
outBuff = (BYTE*)malloc(outBuffSize);
}
}
if (!inBuff || !outBuff) EXM_THROW(33, "Allocation error : not enough memory");
filesize += FIO_decompressFrame(foutput, finput, inBuff, inBuffSize, outBuff, outBuffSize, dctx);
}
DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "\r%79s\r", "");
DISPLAYLEVEL(2,"Decoded %llu bytes \n", (long long unsigned)filesize); DISPLAYLEVEL(2,"Decoded %llu bytes \n", (long long unsigned)filesize);
/* clean */ /* clean */
free(inBuff); free(inBuff);
free(outBuff); free(outBuff);
fclose(finput);
fclose(foutput);
ZSTD_freeDCtx(dctx); ZSTD_freeDCtx(dctx);
fclose(finput);
if (fclose(foutput)) EXM_THROW(38, "Write error : cannot properly close %s", output_filename);
return filesize; return filesize;
} }
+1 -1
View File
@@ -616,7 +616,7 @@ int main(int argc, char** argv)
/* Modify Nb Iterations */ /* Modify Nb Iterations */
case 'i': case 'i':
if ((argument[1] >='1') && (argument[1] <='9')) if ((argument[1] >='0') && (argument[1] <='9'))
{ {
int iters = argument[1] - '0'; int iters = argument[1] - '0';
BMK_SetNbIterations(iters); BMK_SetNbIterations(iters);
-31
View File
@@ -1,31 +0,0 @@
\"
\" unzstd.1: This is a manual page for 'unzstd' program. This file is part of
\" the zstd <https://github.com/Cyan4973/zstd/> project.
\"
\" No hyphenation
.hy 0
.nr HY 0
.TH unzstd "1" "2014-06-20" "unzstd" "User Commands"
.SH NAME
\fBunzstd\fR - Utility based on zstd
.SH SYNOPSIS
.TP 5
\fBunzstd\fR [\fBOPTIONS\fR] [-|INPUT-FILE]
.SH DESCRIPTION
.PP
\fBunzstd\fR is an utility based on \fBzstd\fR, a fast lossless compression algorithm.
\fBunzstd\fR decompress input file, it is equivalent to \fBzstd -d\fR,
Available options are the same as \fBzstd\fR ones (man zstd).
.SH BUGS
Report bugs at:- https://github.com/Cyan4973/zstd/
.SH AUTHOR
Yann Collet
+20 -11
View File
@@ -1,26 +1,35 @@
\" \"
\" zstd.1: This is a manual page for 'zstd' program. This file is part of the \" zstd.1: This is a manual page for 'zstd' program. This file is part of the
\" zstd <https://github.com/Cyan4973/zstd> project. \" zstd <http://www.zstd.net/> project.
\" Author: Yann Collet
\" \"
\" No hyphenation \" No hyphenation
.hy 0 .hy 0
.nr HY 0 .nr HY 0
.TH zstd "1" "2015-01-22" "zstd" "User Commands" .TH zstd "1" "2015-08-22" "zstd" "User Commands"
.SH NAME .SH NAME
\fBzstd\fR - standard compression algorithm \fBzstd, unzstd, zstdcat\fR - Compress or decompress .zst files
.SH SYNOPSIS .SH SYNOPSIS
.TP 5 .TP 5
\fBzstd\fR [\fBOPTIONS\fR] [-|INPUT-FILE] <OUTPUT-FILE> \fBzstd\fR [\fBOPTIONS\fR] [-|INPUT-FILE] <OUTPUT-FILE>
.PP
.B unzstd
is equivalent to
.BR "zstd \-d"
.br
.B zstdcat
is equivalent to
.BR "zstd \-dc"
.br
.SH DESCRIPTION .SH DESCRIPTION
.PP .PP
\fBzstd\fR is a fast lossless compression algorithm \fBzstd\fR is a fast lossless compression algorithm.
with highly parametrable compression strength and memory usage. It is based on the \fBLZ77\fR family, with FSE & huff0 entropy stage.
It is based on the \fBLZ77\fR family, coupled with FSE entropy stage. zstd offers compression speed > 200 MB/s per core.
zstd offers compression speed of 200 MB/s per core.
It also features a fast decoder, with speed > 500 MB/s per core. It also features a fast decoder, with speed > 500 MB/s per core.
\fBzstd\fR supports the following options : \fBzstd\fR supports the following options :
@@ -35,13 +44,13 @@ It also features a fast decoder, with speed > 500 MB/s per core.
.B \-f .B \-f
overwrite output without prompting overwrite output without prompting
.TP .TP
.B \-h/\-H .BR \-h/\-H ", " --help
display help/long help and exit display help/long help and exit
.TP .TP
.B \-V .BR \-V ", " --version
display Version number and exit display Version number and exit
.TP .TP
.B \-v .BR \-v ", " --verbose
verbose mode verbose mode
.TP .TP
.B \-q .B \-q
@@ -63,7 +72,7 @@ It also features a fast decoder, with speed > 500 MB/s per core.
iteration loops [1-9](default : 3), benchmark mode only iteration loops [1-9](default : 3), benchmark mode only
.SH BUGS .SH BUGS
Report bugs at:- https://github.com/Cyan4973/zstd Report bugs at:- https://github.com/Cyan4973/zstd/issues
.SH AUTHOR .SH AUTHOR
Yann Collet Yann Collet
-32
View File
@@ -1,32 +0,0 @@
\"
\" zstdcat.1: This is a manual page for 'zstdcat' program. This file is part of
\" the zstd <https://github.com/Cyan4973/zstd/> project.
\"
\" No hyphenation
.hy 0
.nr HY 0
.TH zstdcat "1" "2014-06-20" "zstdcat" "User Commands"
.SH NAME
\fBzstdcat\fR - Utility based on zstd
.SH SYNOPSIS
.TP 5
\fBzstdcat\fR [\fBOPTIONS\fR] [-|INPUT-FILE]
.SH DESCRIPTION
.PP
\fBzstdcat\fR is an utility based on \fBzstd\fR, a fast lossless compression algorithm.
\fBzstdcat\fR decompress input file or stream, redirecting its output to the console.
It is equivalent to \fBzstd -cd\fR,
Available options are the same as \fBzstd\fR ones (man zstd).
.SH BUGS
Report bugs at:- https://github.com/Cyan4973/zstd/
.SH AUTHOR
Yann Collet
+17 -13
View File
@@ -86,8 +86,9 @@
/************************************** /**************************************
* Display Macros * Display Macros
**************************************/ **************************************/
#define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAY(...) fprintf(displayOut, __VA_ARGS__)
#define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } #define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); }
static FILE* displayOut;
static unsigned displayLevel = 2; // 0 : no display // 1: errors // 2 : + result + interaction + warnings ; // 3 : + progression; // 4 : + information static unsigned displayLevel = 2; // 0 : no display // 1: errors // 2 : + result + interaction + warnings ; // 3 : + progression; // 4 : + information
@@ -137,7 +138,7 @@ static int usage_advanced(const char* programName)
//DISPLAY( " -t : test compressed file integrity\n"); //DISPLAY( " -t : test compressed file integrity\n");
DISPLAY( "Benchmark arguments :\n"); DISPLAY( "Benchmark arguments :\n");
DISPLAY( " -b : benchmark file(s)\n"); DISPLAY( " -b : benchmark file(s)\n");
DISPLAY( " -i# : iteration loops [1-9](default : 3), benchmark mode only\n"); DISPLAY( " -i# : iteration loops [1-9](default : 3)\n");
return 0; return 0;
} }
@@ -173,30 +174,32 @@ int main(int argc, char** argv)
char* dynNameSpace = NULL; char* dynNameSpace = NULL;
char extension[] = ZSTD_EXTENSION; char extension[] = ZSTD_EXTENSION;
displayOut = stderr;
/* Pick out basename component. Don't rely on stdlib because of conflicting behaviour. */ /* Pick out basename component. Don't rely on stdlib because of conflicting behaviour. */
for (i = (int)strlen(programName); i > 0; i--) for (i = (int)strlen(programName); i > 0; i--)
{ {
if (programName[i] == '/') if (programName[i] == '/') { i++; break; }
{
i++;
break;
}
} }
programName += i; programName += i;
/* zstdcat behavior */ /* zstdcat preset behavior */
if (!strcmp(programName, ZSTD_CAT)) { decode=1; forceStdout=1; displayLevel=1; outFileName=stdoutmark; } if (!strcmp(programName, ZSTD_CAT)) { decode=1; forceStdout=1; displayLevel=1; outFileName=stdoutmark; }
/* unzstd behavior */ /* unzstd preset behavior */
if (!strcmp(programName, ZSTD_UNZSTD)) if (!strcmp(programName, ZSTD_UNZSTD))
decode=1; decode=1;
// command switches /* command switches */
for(i=1; i<argc; i++) for(i=1; i<argc; i++)
{ {
char* argument = argv[i]; char* argument = argv[i];
if(!argument) continue; // Protection if argument empty if(!argument) continue; /* Protection if argument empty */
/* long commands (--long-word) */
if (!strcmp(argument, "--version")) { displayOut=stdout; DISPLAY(WELCOME_MESSAGE); return 0; }
if (!strcmp(argument, "--help")) { displayOut=stdout; return usage_advanced(programName); }
if (!strcmp(argument, "--verbose")) { displayLevel=4; continue; }
/* Decode commands (note : aggregated commands are allowed) */ /* Decode commands (note : aggregated commands are allowed) */
if (argument[0]=='-') if (argument[0]=='-')
@@ -206,6 +209,7 @@ int main(int argc, char** argv)
{ {
if (!inFileName) inFileName=stdinmark; if (!inFileName) inFileName=stdinmark;
else outFileName=stdoutmark; else outFileName=stdoutmark;
continue;
} }
argument++; argument++;
@@ -215,9 +219,9 @@ int main(int argc, char** argv)
switch(argument[0]) switch(argument[0])
{ {
/* Display help */ /* Display help */
case 'V': DISPLAY(WELCOME_MESSAGE); return 0; /* Version Only */ case 'V': displayOut=stdout; DISPLAY(WELCOME_MESSAGE); return 0; /* Version Only */
case 'H': case 'H':
case 'h': return usage_advanced(programName); case 'h': displayOut=stdout; return usage_advanced(programName);
// Compression (default) // Compression (default)
//case 'z': forceCompress = 1; break; //case 'z': forceCompress = 1; break;