Compare commits

...
20 Commits
Author SHA1 Message Date
Yann Collet b7d9065a9a Merge pull request #47 from Cyan4973/dev
Dev
2015-10-15 12:10:12 +02:00
Yann Collet 0fef5be1cc Fix fullbench 2015-10-14 18:07:24 +01:00
Yann Collet 8f86c700cd Fix uninitialized warnings reported by @nemequ 2015-10-14 17:53:44 +01:00
Yann Collet 59aac5f467 Clarified comments 2015-10-14 16:28:19 +01:00
Yann Collet 2282e26b14 Merge pull request #46 from xaphier/dev
Remove one malloc/free from compression
2015-10-14 15:23:01 +02:00
xaphier 77ee44c7b6 Remove one malloc/free from compression
By making the buffer part of the zstd context structure, one malloc/free
can be removed from the compression.
2015-10-10 12:14:51 +02:00
Yann Collet 9c57b424d6 Merge pull request #44 from Cyan4973/dev
Dev
2015-09-11 01:22:25 +02:00
Yann Collet be50aaa0ee Added : Frame concatenation ability 2015-09-10 23:26:09 +01:00
Yann Collet 5abd8203cb Fix : decompression i/o detects flush write errors 2015-08-27 03:16:04 +01:00
Yann Collet 77dce3eba1 Merge pull request #43 from Cyan4973/dev
Dev
2015-08-27 00:59:17 +02:00
Yann Collet 866a3c3158 Fixed minor visual warning 2015-08-26 23:10:09 +01:00
Yann Collet 352ab88aea fixed minor issue on decoding invalid data 2015-08-26 22:45:23 +01:00
Yann Collet 6b5198fe3a Updated FSE 2015-08-26 19:22:01 +01:00
Yann Collet ddf39e91c5 modified man page 2015-08-26 12:04:58 +02:00
Yann Collet 50b6f941e8 added : --verbose command 2015-08-26 10:32:17 +01:00
Yann Collet bf50409e05 Refactor Makefile and .travis tests 2015-08-26 00:19:06 +01:00
Yann Collet f44b2b02b4 Zstd cli : --version and --help write to stdout 2015-08-25 23:32:45 +01:00
Yann Collet c705567522 Fixed : compression error on some specific distribution 2015-08-25 22:56:42 +01:00
Yann Collet 61d08c52a5 More informative write error messages 2015-08-25 18:13:32 +01:00
Yann Collet 5b147600f9 Fixed #42 2015-08-25 17:41:46 +01:00
15 changed files with 311 additions and 301 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
+13 -4
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)
@@ -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)
@@ -1904,11 +1907,17 @@ 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 ++;
if (rankLast[nBitsToDecrease] == 0)
rankLast[nBitsToDecrease] = noOne;
else
{
rankLast[nBitsToDecrease]--; rankLast[nBitsToDecrease]--;
if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease) if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
rankLast[nBitsToDecrease] = noOne; // rank list emptied rankLast[nBitsToDecrease] = noOne; // rank list emptied
} }
while (totalCost < 0) // Sometimes, cost correction overshoot }
while (totalCost < 0) /* Sometimes, cost correction overshoot */
{ {
if (rankLast[1] == noOne) /* special case, no weight 1, let's find it back at n */ if (rankLast[1] == noOne) /* special case, no weight 1, let's find it back at n */
{ {
+30 -20
View File
@@ -314,6 +314,7 @@ typedef struct ZSTD_Cctx_s
#else #else
U32 hashTable[HASH_TABLESIZE]; U32 hashTable[HASH_TABLESIZE];
#endif #endif
BYTE buffer[WORKPLACESIZE];
} cctxi_t; } cctxi_t;
@@ -321,12 +322,7 @@ ZSTD_Cctx* ZSTD_createCCtx(void)
{ {
ZSTD_Cctx* ctx = (ZSTD_Cctx*) malloc( sizeof(ZSTD_Cctx) ); ZSTD_Cctx* ctx = (ZSTD_Cctx*) malloc( sizeof(ZSTD_Cctx) );
if (ctx==NULL) return NULL; if (ctx==NULL) return NULL;
ctx->seqStore.buffer = malloc(WORKPLACESIZE); ctx->seqStore.buffer = ctx->buffer;
if (ctx->seqStore.buffer==NULL)
{
free(ctx);
return NULL;
}
ctx->seqStore.offsetStart = (U32*) (ctx->seqStore.buffer); ctx->seqStore.offsetStart = (U32*) (ctx->seqStore.buffer);
ctx->seqStore.offCodeStart = (BYTE*) (ctx->seqStore.offsetStart + (BLOCKSIZE>>2)); ctx->seqStore.offCodeStart = (BYTE*) (ctx->seqStore.offsetStart + (BLOCKSIZE>>2));
ctx->seqStore.litStart = ctx->seqStore.offCodeStart + (BLOCKSIZE>>2); ctx->seqStore.litStart = ctx->seqStore.offCodeStart + (BLOCKSIZE>>2);
@@ -344,7 +340,6 @@ void ZSTD_resetCCtx(ZSTD_Cctx* ctx)
size_t ZSTD_freeCCtx(ZSTD_Cctx* ctx) size_t ZSTD_freeCCtx(ZSTD_Cctx* ctx)
{ {
free(ctx->seqStore.buffer);
free(ctx); free(ctx);
return 0; return 0;
} }
@@ -1239,7 +1234,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
} }
size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr,
FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb,
const void* src, size_t srcSize) const void* src, size_t srcSize)
{ {
@@ -1272,6 +1267,7 @@ size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr,
} }
*dumpsPtr = ip; *dumpsPtr = ip;
ip += dumpsLength; ip += dumpsLength;
*dumpsLengthPtr = 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 */
@@ -1356,6 +1352,7 @@ typedef struct {
FSE_DState_t stateML; FSE_DState_t stateML;
size_t prevOffset; size_t prevOffset;
const BYTE* dumps; const BYTE* dumps;
const BYTE* dumpsEnd;
} seqState_t; } seqState_t;
@@ -1366,6 +1363,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
size_t offset; size_t offset;
size_t matchLength; size_t matchLength;
const BYTE* dumps = seqState->dumps; const BYTE* dumps = seqState->dumps;
const BYTE* const de = seqState->dumpsEnd;
/* Literal length */ /* Literal length */
litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
@@ -1373,14 +1371,17 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
seqState->prevOffset = seq->offset; seqState->prevOffset = seq->offset;
if (litLength == MaxLL) if (litLength == MaxLL)
{ {
U32 add = *dumps++; U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) litLength += add; if (add < 255) litLength += add;
else else
{ {
litLength = ZSTD_readLE32(dumps) & 0xFFFFFF; if (dumps<=(de-3))
{
litLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
dumps += 3; dumps += 3;
} }
} }
}
/* Offset */ /* Offset */
{ {
@@ -1389,7 +1390,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;
} }
@@ -1398,14 +1399,17 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
if (matchLength == MaxML) if (matchLength == MaxML)
{ {
U32 add = *dumps++; U32 add = dumps<de ? *dumps++ : 0;
if (add < 255) matchLength += add; if (add < 255) matchLength += add;
else else
{
if (dumps<=(de-3))
{ {
matchLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */ matchLength = ZSTD_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
dumps += 3; dumps += 3;
} }
} }
}
matchLength += MINMATCH; matchLength += MINMATCH;
/* save result */ /* save result */
@@ -1520,7 +1524,7 @@ static size_t ZSTD_decompressSequences(
BYTE* const ostart = (BYTE* const)dst; BYTE* const ostart = (BYTE* const)dst;
BYTE* op = ostart; BYTE* op = ostart;
BYTE* const oend = ostart + maxDstSize; BYTE* const oend = ostart + maxDstSize;
size_t errorCode; size_t errorCode, dumpsLength;
const BYTE* litPtr = litStart; const BYTE* litPtr = litStart;
const BYTE* const litEnd = litStart + litSize; const BYTE* const litEnd = litStart + litSize;
int nbSeq; int nbSeq;
@@ -1531,7 +1535,7 @@ static size_t ZSTD_decompressSequences(
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, &dumpsLength,
DTableLL, DTableML, DTableOffb, DTableLL, DTableML, DTableOffb,
ip, iend-ip); ip, iend-ip);
if (ZSTD_isError(errorCode)) return errorCode; if (ZSTD_isError(errorCode)) return errorCode;
@@ -1544,6 +1548,7 @@ static size_t ZSTD_decompressSequences(
memset(&sequence, 0, sizeof(sequence)); memset(&sequence, 0, sizeof(sequence));
seqState.dumps = dumps; seqState.dumps = dumps;
seqState.dumpsEnd = dumps + dumpsLength;
seqState.prevOffset = 1; seqState.prevOffset = 1;
errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip); errorCode = FSE_initDStream(&(seqState.DStream), ip, iend-ip);
if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_corruption; if (FSE_isError(errorCode)) return (size_t)-ZSTD_ERROR_corruption;
@@ -1551,7 +1556,7 @@ static size_t ZSTD_decompressSequences(
FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb); FSE_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb);
FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML); FSE_initDState(&(seqState.stateML), &(seqState.DStream), DTableML);
for ( ; (FSE_reloadDStream(&(seqState.DStream)) < FSE_DStream_completed) || (nbSeq>0) ; ) for ( ; (FSE_reloadDStream(&(seqState.DStream)) <= FSE_DStream_completed) && (nbSeq>0) ; )
{ {
size_t oneSeqSize; size_t oneSeqSize;
nbSeq--; nbSeq--;
@@ -1562,7 +1567,7 @@ static size_t ZSTD_decompressSequences(
} }
/* check if reached exact end */ /* check if reached exact end */
if (FSE_reloadDStream(&(seqState.DStream)) > FSE_DStream_completed) return (size_t)-ZSTD_ERROR_corruption; /* requested too much : data is corrupted */ if ( !FSE_endOfDStream(&(seqState.DStream)) ) return (size_t)-ZSTD_ERROR_corruption; /* requested too much : data is corrupted */
if (nbSeq<0) return (size_t)-ZSTD_ERROR_corruption; /* requested too many sequences : data is corrupted */ if (nbSeq<0) return (size_t)-ZSTD_ERROR_corruption; /* requested too many sequences : data is corrupted */
/* last literal segment */ /* last literal segment */
@@ -1668,14 +1673,20 @@ size_t ZSTD_decompress(void* dst, size_t maxDstSize, const void* src, size_t src
* Streaming Decompression API * Streaming Decompression API
*******************************/ *******************************/
ZSTD_Dctx* ZSTD_createDCtx(void) size_t ZSTD_resetDCtx(ZSTD_Dctx* dctx)
{ {
ZSTD_Dctx* dctx = (ZSTD_Dctx*)malloc(sizeof(ZSTD_Dctx));
if (dctx==NULL) return NULL;
dctx->expected = ZSTD_frameHeaderSize; dctx->expected = ZSTD_frameHeaderSize;
dctx->phase = 0; dctx->phase = 0;
dctx->previousDstEnd = NULL; dctx->previousDstEnd = NULL;
dctx->base = NULL; dctx->base = NULL;
return 0;
}
ZSTD_Dctx* ZSTD_createDCtx(void)
{
ZSTD_Dctx* dctx = (ZSTD_Dctx*)malloc(sizeof(ZSTD_Dctx));
if (dctx==NULL) return NULL;
ZSTD_resetDCtx(dctx);
return dctx; return dctx;
} }
@@ -1685,7 +1696,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;
+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);
+9 -4
View File
@@ -32,6 +32,11 @@
*/ */
#pragma once #pragma once
/* The objects defined into this file should be considered experimental.
* They are not labelled stable, as their prototype may change in the future.
* You can use them for tests, provide feedback, or if you can endure risk of future changes.
*/
#if defined (__cplusplus) #if defined (__cplusplus)
extern "C" { extern "C" {
#endif #endif
@@ -56,16 +61,16 @@ 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);
size_t ZSTD_decompressContinue(ZSTD_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize); size_t ZSTD_decompressContinue(ZSTD_Dctx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
/* /*
Use above functions alternatively. Use above functions alternatively.
ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as input to ZSTD_decompressContinue(). ZSTD_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTD_decompressContinue().
This value is expected to be provided, precisely, as 'srcSize'. ZSTD_decompressContinue() will use previous data blocks to improve compresson if they are located prior to current block.
Otherwise, compression will fail (result is an error code, which can be tested using ZSTD_isError() ) Result is the number of bytes regenerated within 'dst'.
ZSTD_decompressContinue() result is the number of bytes regenerated within 'dst'.
It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header. It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some header.
*/ */
+29 -16
View File
@@ -30,12 +30,12 @@
# 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)
@@ -43,9 +43,6 @@ 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
ifneq (,$(filter Windows%,$(OS))) ifneq (,$(filter Windows%,$(OS)))
@@ -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;
} }
+4 -3
View File
@@ -229,7 +229,7 @@ typedef struct
static size_t g_cSize = 0; static size_t g_cSize = 0;
extern size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr); extern size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr);
extern size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, const void* src, size_t srcSize); extern size_t ZSTD_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr, FSE_DTable* DTableLL, FSE_DTable* DTableML, FSE_DTable* DTableOffb, const void* src, size_t srcSize);
size_t local_ZSTD_compress(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize) size_t local_ZSTD_compress(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
{ {
@@ -258,9 +258,10 @@ size_t local_ZSTD_decodeSeqHeaders(void* dst, size_t dstSize, void* buff2, const
{ {
U32 DTableML[1<<11], DTableLL[1<<10], DTableOffb[1<<9]; U32 DTableML[1<<11], DTableLL[1<<10], DTableOffb[1<<9];
const BYTE* dumps; const BYTE* dumps;
size_t length;
int nbSeq; int nbSeq;
(void)src; (void)srcSize; (void)dst; (void)dstSize; (void)src; (void)srcSize; (void)dst; (void)dstSize;
return ZSTD_decodeSeqHeaders(&nbSeq, &dumps, DTableLL, DTableML, DTableOffb, buff2, g_cSize); return ZSTD_decodeSeqHeaders(&nbSeq, &dumps, &length, DTableLL, DTableML, DTableOffb, buff2, g_cSize);
} }
size_t local_conditionalNull(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize) size_t local_conditionalNull(void* dst, size_t dstSize, void* buff2, const void* src, size_t srcSize)
@@ -616,7 +617,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;