mirror of
https://github.com/facebook/zstd.git
synced 2025-08-05 19:15:58 +03:00
added ZSTD_duplicateCCtx()
This commit is contained in:
1
NEWS
1
NEWS
@@ -1,6 +1,7 @@
|
|||||||
v0.4.6
|
v0.4.6
|
||||||
fix : fast compression mode on Windows
|
fix : fast compression mode on Windows
|
||||||
Improved : high compression mode on repetitive data
|
Improved : high compression mode on repetitive data
|
||||||
|
Added : ZSTD_duplicateCCtx()
|
||||||
|
|
||||||
v0.4.5
|
v0.4.5
|
||||||
new : -m/--multiple : compress/decompress multiple files
|
new : -m/--multiple : compress/decompress multiple files
|
||||||
|
@@ -46,7 +46,7 @@ DESTDIR?=
|
|||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
CPPFLAGS= -I.
|
CPPFLAGS= -I.
|
||||||
CFLAGS ?= -O3
|
CFLAGS ?= -O3
|
||||||
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes
|
CFLAGS += -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -Wstrict-aliasing=1
|
||||||
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
FLAGS = $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(MOREFLAGS)
|
||||||
|
|
||||||
LIBDIR ?= $(PREFIX)/lib
|
LIBDIR ?= $(PREFIX)/lib
|
||||||
|
16
lib/zstd.h
16
lib/zstd.h
@@ -107,16 +107,24 @@ ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /** provides error co
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Advanced functions
|
* Advanced functions
|
||||||
***************************************/
|
***************************************/
|
||||||
|
/** Compression context management */
|
||||||
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */
|
typedef struct ZSTD_CCtx_s ZSTD_CCtx; /* incomplete type */
|
||||||
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
|
||||||
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
|
||||||
|
|
||||||
/**
|
/** ZSTD_compressCCtx() :
|
||||||
ZSTD_compressCCtx() :
|
Same as ZSTD_compress(), but requires an already allocated ZSTD_CCtx (see ZSTD_createCCtx()) */
|
||||||
Same as ZSTD_compress(), but requires a ZSTD_CCtx working space already allocated
|
|
||||||
*/
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize, int compressionLevel);
|
||||||
|
|
||||||
|
/** Decompression context management */
|
||||||
|
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
||||||
|
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
||||||
|
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
||||||
|
|
||||||
|
/** ZSTD_decompressDCtx
|
||||||
|
* Same as ZSTD_decompress(), but requires an already allocated ZSTD_DCtx (see ZSTD_createDCtx()) */
|
||||||
|
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
||||||
|
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
}
|
}
|
||||||
|
@@ -143,7 +143,7 @@ size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, ZSTD_parameters params)
|
|||||||
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
if (zbc->outBuff == NULL) return ERROR(memory_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
zbc->outBuffContentSize = ZSTD_compressBegin_advanced(zbc->zc, zbc->outBuff, zbc->outBuffSize, params);
|
zbc->outBuffContentSize = ZSTD_compressBegin_advanced(zbc->zc, params);
|
||||||
if (ZSTD_isError(zbc->outBuffContentSize)) return zbc->outBuffContentSize;
|
if (ZSTD_isError(zbc->outBuffContentSize)) return zbc->outBuffContentSize;
|
||||||
|
|
||||||
zbc->inToCompress = 0;
|
zbc->inToCompress = 0;
|
||||||
|
@@ -65,8 +65,9 @@
|
|||||||
/* *************************************
|
/* *************************************
|
||||||
* Constants
|
* Constants
|
||||||
***************************************/
|
***************************************/
|
||||||
unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
ZSTDLIB_API unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
||||||
static const U32 g_searchStrength = 8;
|
static const U32 g_searchStrength = 8;
|
||||||
|
static const size_t g_hbSize = (((ZSTD_frameHeaderSize_max+15)/8)*8);
|
||||||
|
|
||||||
|
|
||||||
/* *************************************
|
/* *************************************
|
||||||
@@ -109,10 +110,14 @@ struct ZSTD_CCtx_s
|
|||||||
U32 dictLimit; /* below that point, need extDict */
|
U32 dictLimit; /* below that point, need extDict */
|
||||||
U32 lowLimit; /* below that point, no more data */
|
U32 lowLimit; /* below that point, no more data */
|
||||||
U32 nextToUpdate; /* index from which to continue dictionary update */
|
U32 nextToUpdate; /* index from which to continue dictionary update */
|
||||||
|
U32 stage;
|
||||||
ZSTD_parameters params;
|
ZSTD_parameters params;
|
||||||
void* workSpace;
|
void* workSpace;
|
||||||
size_t workSpaceSize;
|
size_t workSpaceSize;
|
||||||
size_t blockSize;
|
size_t blockSize;
|
||||||
|
void* headerBuffer;
|
||||||
|
size_t hbSize;
|
||||||
|
|
||||||
|
|
||||||
seqStore_t seqStore; /* sequences storage ptrs */
|
seqStore_t seqStore; /* sequences storage ptrs */
|
||||||
U32* hashTable;
|
U32* hashTable;
|
||||||
@@ -205,6 +210,8 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|||||||
zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize;
|
zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize;
|
||||||
zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2);
|
zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2);
|
||||||
zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2);
|
zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2);
|
||||||
|
zc->headerBuffer = (char*)zc->workSpace + zc->workSpaceSize - g_hbSize;
|
||||||
|
zc->hbSize = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -790,7 +797,7 @@ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
const U32 current = (U32)(ip-base);
|
const U32 current = (U32)(ip-base);
|
||||||
hashTable[h] = current; /* update hash table */
|
hashTable[h] = current; /* update hash table */
|
||||||
|
|
||||||
if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) /* note : by construction, offset_1 <= (ip-base) */
|
if (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)) /* note : by construction, offset_1 <= current */
|
||||||
{
|
{
|
||||||
mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend);
|
mlCode = ZSTD_count(ip+1+MINMATCH, ip+1+MINMATCH-offset_1, iend);
|
||||||
ip++;
|
ip++;
|
||||||
@@ -819,7 +826,7 @@ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* zc,
|
|||||||
if (ip <= ilimit)
|
if (ip <= ilimit)
|
||||||
{
|
{
|
||||||
/* Fill Table */
|
/* Fill Table */
|
||||||
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 without ip <= ilimit check*/
|
hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
|
||||||
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
|
||||||
/* check immediate repcode */
|
/* check immediate repcode */
|
||||||
while ( (ip <= ilimit)
|
while ( (ip <= ilimit)
|
||||||
@@ -1852,6 +1859,17 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
|
|||||||
const void* src, size_t srcSize)
|
const void* src, size_t srcSize)
|
||||||
{
|
{
|
||||||
const BYTE* const ip = (const BYTE*) src;
|
const BYTE* const ip = (const BYTE*) src;
|
||||||
|
size_t hbSize = 0;
|
||||||
|
|
||||||
|
if (zc->stage==0)
|
||||||
|
{
|
||||||
|
hbSize = zc->hbSize;
|
||||||
|
if (dstSize <= hbSize) return ERROR(dstSize_tooSmall);
|
||||||
|
zc->stage = 1;
|
||||||
|
memcpy(dst, zc->headerBuffer, hbSize);
|
||||||
|
dstSize -= hbSize;
|
||||||
|
dst = (char*)dst + hbSize;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if blocks follow each other */
|
/* Check if blocks follow each other */
|
||||||
if (src != zc->nextSrc)
|
if (src != zc->nextSrc)
|
||||||
@@ -1890,8 +1908,11 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
zc->nextSrc = ip + srcSize;
|
zc->nextSrc = ip + srcSize;
|
||||||
|
{
|
||||||
return ZSTD_compress_generic (zc, dst, dstSize, src, srcSize);
|
size_t cSize = ZSTD_compress_generic (zc, dst, dstSize, src, srcSize);
|
||||||
|
if (ZSTD_isError(cSize)) return cSize;
|
||||||
|
return cSize + hbSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
||||||
@@ -1934,24 +1955,49 @@ size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* src, size_t src
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! ZSTD_duplicateCCtx
|
||||||
|
* Duplicate an existing context @srcCCtx into another one @dstCCtx.
|
||||||
|
* Only works during stage 0 (i.e. before first call to ZSTD_compressContinue())
|
||||||
|
* @return : 0, or an error code */
|
||||||
|
size_t ZSTD_duplicateCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
|
||||||
|
{
|
||||||
|
void* dstWorkSpace = dstCCtx->workSpace;
|
||||||
|
size_t dstWorkSpaceSize = dstCCtx->workSpaceSize;
|
||||||
|
|
||||||
|
if (dstWorkSpaceSize < srcCCtx->workSpaceSize)
|
||||||
|
{
|
||||||
|
free(dstCCtx->workSpace);
|
||||||
|
dstWorkSpaceSize = srcCCtx->workSpaceSize;
|
||||||
|
dstWorkSpace = malloc(dstWorkSpaceSize);
|
||||||
|
if (dstWorkSpace==NULL) return ERROR(memory_allocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dstCCtx, srcCCtx, sizeof(*dstCCtx));
|
||||||
|
dstCCtx->workSpace = dstWorkSpace;
|
||||||
|
dstCCtx->workSpaceSize = dstWorkSpaceSize;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! ZSTD_compressBegin_advanced
|
/*! ZSTD_compressBegin_advanced
|
||||||
* Write frame header, according to params
|
* @return : 0, or an error code */
|
||||||
* @return : nb of bytes written */
|
|
||||||
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx,
|
size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx,
|
||||||
void* dst, size_t maxDstSize,
|
|
||||||
ZSTD_parameters params)
|
ZSTD_parameters params)
|
||||||
{
|
{
|
||||||
size_t errorCode;
|
size_t errorCode;
|
||||||
|
|
||||||
ZSTD_validateParams(¶ms);
|
ZSTD_validateParams(¶ms);
|
||||||
|
|
||||||
if (maxDstSize < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
|
|
||||||
errorCode = ZSTD_resetCCtx_advanced(ctx, params);
|
errorCode = ZSTD_resetCCtx_advanced(ctx, params);
|
||||||
if (ZSTD_isError(errorCode)) return errorCode;
|
if (ZSTD_isError(errorCode)) return errorCode;
|
||||||
|
|
||||||
MEM_writeLE32(dst, ZSTD_MAGICNUMBER); /* Write Header */
|
MEM_writeLE32(ctx->headerBuffer, ZSTD_MAGICNUMBER); /* Write Header */
|
||||||
((BYTE*)dst)[4] = (BYTE)(params.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
((BYTE*)ctx->headerBuffer)[4] = (BYTE)(params.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
||||||
return ZSTD_frameHeaderSize_min;
|
ctx->hbSize = ZSTD_frameHeaderSize_min;
|
||||||
|
ctx->stage = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1970,29 +2016,38 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, U64 srcSizeHint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t ZSTD_compressBegin(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, int compressionLevel)
|
size_t ZSTD_compressBegin(ZSTD_CCtx* ctx, int compressionLevel)
|
||||||
{
|
{
|
||||||
return ZSTD_compressBegin_advanced(ctx, dst, maxDstSize, ZSTD_getParams(compressionLevel, 0));
|
return ZSTD_compressBegin_advanced(ctx, ZSTD_getParams(compressionLevel, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! ZSTD_compressEnd
|
/*! ZSTD_compressEnd
|
||||||
* Write frame epilogue
|
* Write frame epilogue
|
||||||
* @return : nb of bytes written into dst (or an error code) */
|
* @return : nb of bytes written into dst (or an error code) */
|
||||||
size_t ZSTD_compressEnd(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize)
|
size_t ZSTD_compressEnd(ZSTD_CCtx* zc, void* dst, size_t maxDstSize)
|
||||||
{
|
{
|
||||||
BYTE* op = (BYTE*)dst;
|
BYTE* op = (BYTE*)dst;
|
||||||
|
size_t hbSize = 0;
|
||||||
|
|
||||||
/* Sanity check */
|
/* empty frame */
|
||||||
(void)ctx;
|
if (zc->stage==0)
|
||||||
|
{
|
||||||
|
hbSize = zc->hbSize;
|
||||||
|
if (maxDstSize <= hbSize) return ERROR(dstSize_tooSmall);
|
||||||
|
zc->stage = 1;
|
||||||
|
memcpy(dst, zc->headerBuffer, hbSize);
|
||||||
|
maxDstSize -= hbSize;
|
||||||
|
op += hbSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* frame epilogue */
|
||||||
if (maxDstSize < 3) return ERROR(dstSize_tooSmall);
|
if (maxDstSize < 3) return ERROR(dstSize_tooSmall);
|
||||||
|
|
||||||
/* End of frame */
|
|
||||||
op[0] = (BYTE)(bt_end << 6);
|
op[0] = (BYTE)(bt_end << 6);
|
||||||
op[1] = 0;
|
op[1] = 0;
|
||||||
op[2] = 0;
|
op[2] = 0;
|
||||||
|
|
||||||
return 3;
|
return 3+hbSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
||||||
@@ -2006,10 +2061,8 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
size_t oSize;
|
size_t oSize;
|
||||||
|
|
||||||
/* Header */
|
/* Header */
|
||||||
oSize = ZSTD_compressBegin_advanced(ctx, dst, maxDstSize, params);
|
oSize = ZSTD_compressBegin_advanced(ctx, params);
|
||||||
if(ZSTD_isError(oSize)) return oSize;
|
if(ZSTD_isError(oSize)) return oSize;
|
||||||
op += oSize;
|
|
||||||
maxDstSize -= oSize;
|
|
||||||
|
|
||||||
/* dictionary */
|
/* dictionary */
|
||||||
if (dict)
|
if (dict)
|
||||||
@@ -2048,7 +2101,7 @@ size_t ZSTD_compress(void* dst, size_t maxDstSize, const void* src, size_t srcSi
|
|||||||
ZSTD_CCtx ctxBody;
|
ZSTD_CCtx ctxBody;
|
||||||
memset(&ctxBody, 0, sizeof(ctxBody));
|
memset(&ctxBody, 0, sizeof(ctxBody));
|
||||||
result = ZSTD_compressCCtx(&ctxBody, dst, maxDstSize, src, srcSize, compressionLevel);
|
result = ZSTD_compressCCtx(&ctxBody, dst, maxDstSize, src, srcSize, compressionLevel);
|
||||||
free(ctxBody.workSpace); /* can't free ctxBody, since it's on stack; free heap content */
|
free(ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -33,9 +33,9 @@
|
|||||||
#ifndef ZSTD_STATIC_H
|
#ifndef ZSTD_STATIC_H
|
||||||
#define ZSTD_STATIC_H
|
#define ZSTD_STATIC_H
|
||||||
|
|
||||||
/* The objects defined into this file should be considered experimental.
|
/* The objects defined into this file shall be considered experimental.
|
||||||
* They are not labelled stable, as their prototype may change in the future.
|
* They are not considered 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.
|
* You can use them for tests, provide feedback, or if you can endure risks of future changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined (__cplusplus)
|
#if defined (__cplusplus)
|
||||||
@@ -108,40 +108,33 @@ ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|||||||
const void* dict,size_t dictSize,
|
const void* dict,size_t dictSize,
|
||||||
ZSTD_parameters params);
|
ZSTD_parameters params);
|
||||||
|
|
||||||
/** Decompression context management */
|
|
||||||
typedef struct ZSTD_DCtx_s ZSTD_DCtx;
|
|
||||||
ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
|
|
||||||
ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
|
|
||||||
|
|
||||||
/** ZSTD_decompressDCtx
|
|
||||||
* Same as ZSTD_decompress, with pre-allocated DCtx structure */
|
|
||||||
ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
|
||||||
|
|
||||||
/** ZSTD_decompress_usingDict
|
/** ZSTD_decompress_usingDict
|
||||||
* Same as ZSTD_decompressDCtx, using a Dictionary content as prefix
|
* Same as ZSTD_decompressDCtx, using a Dictionary content as prefix
|
||||||
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
* Note : dict can be NULL, in which case, it's equivalent to ZSTD_decompressDCtx() */
|
||||||
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
|
ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
|
||||||
void* dst, size_t maxDstSize,
|
void* dst, size_t maxDstSize,
|
||||||
const void* src, size_t srcSize,
|
const void* src, size_t srcSize,
|
||||||
const void* dict, size_t dictSize);
|
const void* dict,size_t dictSize);
|
||||||
|
|
||||||
|
|
||||||
/* **************************************
|
/* **************************************
|
||||||
* Streaming functions (direct mode)
|
* Streaming functions (direct mode)
|
||||||
****************************************/
|
****************************************/
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, int compressionLevel);
|
ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
|
||||||
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx, void* dst, size_t maxDstSize, ZSTD_parameters params);
|
ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* ctx, ZSTD_parameters params);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
||||||
|
ZSTDLIB_API size_t ZSTD_duplicateCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx);
|
||||||
|
|
||||||
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize);
|
||||||
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Streaming compression, direct mode (bufferless)
|
Streaming compression, synchronous mode (bufferless)
|
||||||
|
|
||||||
A ZSTD_CCtx object is required to track streaming operations.
|
A ZSTD_CCtx object is required to track streaming operations.
|
||||||
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage it.
|
Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage it.
|
||||||
A ZSTD_CCtx object can be re-used multiple times.
|
ZSTD_CCtx object can be re-used multiple times within successive compression operations.
|
||||||
|
|
||||||
First operation is to start a new frame.
|
First operation is to start a new frame.
|
||||||
Use ZSTD_compressBegin().
|
Use ZSTD_compressBegin().
|
||||||
@@ -151,8 +144,13 @@ ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t maxDstSiz
|
|||||||
Note that dictionary presence is a "hidden" information,
|
Note that dictionary presence is a "hidden" information,
|
||||||
the decoder needs to be aware that it is required for proper decoding, or decoding will fail.
|
the decoder needs to be aware that it is required for proper decoding, or decoding will fail.
|
||||||
|
|
||||||
|
If you want to compress multiple messages using same dictionary,
|
||||||
|
it can be beneficial to duplicate compression context rather than reloading dictionary each time.
|
||||||
|
In such case, use ZSTD_duplicateCCtx(), which will need an already created ZSTD_CCtx,
|
||||||
|
in order to duplicate compression context into it.
|
||||||
|
|
||||||
Then, consume your input using ZSTD_compressContinue().
|
Then, consume your input using ZSTD_compressContinue().
|
||||||
The interface is synchronous, so all input will be consumed.
|
The interface is synchronous, so all input will be consumed and produce a compressed output.
|
||||||
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
You must ensure there is enough space in destination buffer to store compressed data under worst case scenario.
|
||||||
Worst case evaluation is provided by ZSTD_compressBound().
|
Worst case evaluation is provided by ZSTD_compressBound().
|
||||||
|
|
||||||
|
@@ -268,11 +268,13 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
U32 result = 0;
|
U32 result = 0;
|
||||||
U32 testNb = 0;
|
U32 testNb = 0;
|
||||||
U32 coreSeed = seed, lseed = 0;
|
U32 coreSeed = seed, lseed = 0;
|
||||||
|
ZSTD_CCtx* refCtx;
|
||||||
ZSTD_CCtx* ctx;
|
ZSTD_CCtx* ctx;
|
||||||
ZSTD_DCtx* dctx;
|
ZSTD_DCtx* dctx;
|
||||||
U32 startTime = FUZ_GetMilliStart();
|
U32 startTime = FUZ_GetMilliStart();
|
||||||
|
|
||||||
/* allocation */
|
/* allocation */
|
||||||
|
refCtx = ZSTD_createCCtx();
|
||||||
ctx = ZSTD_createCCtx();
|
ctx = ZSTD_createCCtx();
|
||||||
dctx= ZSTD_createDCtx();
|
dctx= ZSTD_createDCtx();
|
||||||
cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
|
cNoiseBuffer[0] = (BYTE*)malloc (srcBufferSize);
|
||||||
@@ -284,7 +286,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
mirrorBuffer = (BYTE*)malloc (dstBufferSize);
|
mirrorBuffer = (BYTE*)malloc (dstBufferSize);
|
||||||
cBuffer = (BYTE*)malloc (cBufferSize);
|
cBuffer = (BYTE*)malloc (cBufferSize);
|
||||||
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
|
CHECK (!cNoiseBuffer[0] || !cNoiseBuffer[1] || !cNoiseBuffer[2] || !cNoiseBuffer[3] || !cNoiseBuffer[4]
|
||||||
|| !dstBuffer || !mirrorBuffer || !cBuffer || !ctx || !dctx,
|
|| !dstBuffer || !mirrorBuffer || !cBuffer || !refCtx || !ctx || !dctx,
|
||||||
"Not enough memory, fuzzer tests cancelled");
|
"Not enough memory, fuzzer tests cancelled");
|
||||||
|
|
||||||
/* Create initial samples */
|
/* Create initial samples */
|
||||||
@@ -461,10 +463,13 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
dict = srcBuffer + sampleStart;
|
dict = srcBuffer + sampleStart;
|
||||||
dictSize = sampleSize;
|
dictSize = sampleSize;
|
||||||
|
|
||||||
cSize = ZSTD_compressBegin(ctx, cBuffer, cBufferSize, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
|
errorCode = ZSTD_compressBegin(refCtx, (FUZ_rand(&lseed) % (20 - (sampleSizeLog/3))) + 1);
|
||||||
errorCode = ZSTD_compress_insertDictionary(ctx, dict, dictSize);
|
CHECK (ZSTD_isError(errorCode), "start streaming error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
errorCode = ZSTD_compress_insertDictionary(refCtx, dict, dictSize);
|
||||||
CHECK (ZSTD_isError(errorCode), "dictionary insertion error : %s", ZSTD_getErrorName(errorCode));
|
CHECK (ZSTD_isError(errorCode), "dictionary insertion error : %s", ZSTD_getErrorName(errorCode));
|
||||||
totalTestSize = 0;
|
errorCode = ZSTD_duplicateCCtx(ctx, refCtx);
|
||||||
|
CHECK (ZSTD_isError(errorCode), "context duplication error : %s", ZSTD_getErrorName(errorCode));
|
||||||
|
totalTestSize = 0; cSize = 0;
|
||||||
for (n=0; n<nbChunks; n++)
|
for (n=0; n<nbChunks; n++)
|
||||||
{
|
{
|
||||||
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
sampleSizeLog = FUZ_rand(&lseed) % maxSampleLog;
|
||||||
@@ -517,6 +522,7 @@ int fuzzerTests(U32 seed, U32 nbTests, unsigned startTest, double compressibilit
|
|||||||
DISPLAY("\r%u fuzzer tests completed \n", testNb-1);
|
DISPLAY("\r%u fuzzer tests completed \n", testNb-1);
|
||||||
|
|
||||||
_cleanup:
|
_cleanup:
|
||||||
|
ZSTD_freeCCtx(refCtx);
|
||||||
ZSTD_freeCCtx(ctx);
|
ZSTD_freeCCtx(ctx);
|
||||||
ZSTD_freeDCtx(dctx);
|
ZSTD_freeDCtx(dctx);
|
||||||
free(cNoiseBuffer[0]);
|
free(cNoiseBuffer[0]);
|
||||||
|
Reference in New Issue
Block a user