Merge branch 'dev' of github.com:Cyan4973/lz4 into dev
This commit is contained in:
commit
5b67c7d185
362
lib/lz4.c
362
lib/lz4.c
@ -154,7 +154,8 @@
|
||||
* Memory routines
|
||||
**************************************/
|
||||
#include <stdlib.h> /* malloc, calloc, free */
|
||||
#define ALLOCATOR(n,s) calloc(n,s)
|
||||
#define ALLOC(s) malloc(s)
|
||||
#define ALLOC_AND_ZERO(s) calloc(1,s)
|
||||
#define FREEMEM free
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#define MEM_INIT memset
|
||||
@ -446,9 +447,32 @@ static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression ru
|
||||
* Local Structures and types
|
||||
**************************************/
|
||||
typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
|
||||
typedef enum { byPtr, byU32, byU16 } tableType_t;
|
||||
typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t;
|
||||
|
||||
typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
|
||||
/**
|
||||
* This enum distinguishes several different modes of accessing previous
|
||||
* content in the stream.
|
||||
*
|
||||
* - noDict : There is no preceding content.
|
||||
* - withPrefix64k : Table entries up to ctx->dictSize before the current blob
|
||||
* blob being compressed are valid and refer to the preceding
|
||||
* content (of length ctx->dictSize), which is available
|
||||
* contiguously preceding in memory the content currently
|
||||
* being compressed.
|
||||
* - usingExtDict : Like withPrefix64k, but the preceding content is somewhere
|
||||
* else in memory, starting at ctx->dictionary with length
|
||||
* ctx->dictSize.
|
||||
* - usingDictCtx : Like usingExtDict, but everything concerning the preceding
|
||||
* content is in a separate context, pointed to by
|
||||
* ctx->dictCtx. ctx->dictionary, ctx->dictSize, and table
|
||||
* entries in the current context that refer to positions
|
||||
* preceding the beginning of the current compression are
|
||||
* ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx
|
||||
* ->dictSize describe the location and size of the preceding
|
||||
* content, and matches are found by looking in the ctx
|
||||
* ->dictCtx->hashTable.
|
||||
*/
|
||||
typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive;
|
||||
typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
|
||||
|
||||
typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
|
||||
@ -496,6 +520,7 @@ static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableTy
|
||||
{
|
||||
switch (tableType)
|
||||
{
|
||||
case clearedTable: { /* illegal! */ assert(0); return; }
|
||||
case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
|
||||
case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
|
||||
case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
|
||||
@ -508,20 +533,55 @@ LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_
|
||||
LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
|
||||
}
|
||||
|
||||
static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
|
||||
static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType, const BYTE* srcBase)
|
||||
{
|
||||
if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
|
||||
if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
|
||||
{ const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
|
||||
if (tableType == byPtr) { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; }
|
||||
if (tableType == byU32) { const U32* const hashTable = (const U32*) tableBase; return hashTable[h] + srcBase; }
|
||||
{ const U16* const hashTable = (const U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
|
||||
}
|
||||
|
||||
LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
|
||||
LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, const void* tableBase, tableType_t tableType, const BYTE* srcBase)
|
||||
{
|
||||
U32 const h = LZ4_hashPosition(p, tableType);
|
||||
return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
|
||||
}
|
||||
|
||||
|
||||
LZ4_FORCE_INLINE void LZ4_prepareTable(
|
||||
LZ4_stream_t_internal* const cctx,
|
||||
const int inputSize,
|
||||
const tableType_t tableType,
|
||||
const dict_directive dictDirective) {
|
||||
/* If the table hasn't been used, it's guaranteed to be zeroed out, and is
|
||||
* therefore safe to use no matter what mode we're in. Otherwise, we figure
|
||||
* out if it's safe to leave as is or whether it needs to be reset.
|
||||
*/
|
||||
if (cctx->tableType != clearedTable) {
|
||||
if (cctx->tableType != tableType
|
||||
|| (tableType == byU16 && cctx->currentOffset + inputSize >= 0xFFFFU)
|
||||
|| (tableType == byU32 && cctx->currentOffset > 1 GB)
|
||||
|| tableType == byPtr
|
||||
|| inputSize >= 4 KB)
|
||||
{
|
||||
DEBUGLOG(4, "Resetting table in %p", cctx);
|
||||
MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE);
|
||||
cctx->currentOffset = 0;
|
||||
cctx->tableType = clearedTable;
|
||||
}
|
||||
}
|
||||
/* If the current offset is zero, we will never look in the external
|
||||
* dictionary context, since there is no value a table entry can take that
|
||||
* indicates a miss. In that case, we need to bump the offset to something
|
||||
* non-zero.
|
||||
*/
|
||||
if (dictDirective == usingDictCtx &&
|
||||
tableType != byPtr &&
|
||||
cctx->currentOffset == 0)
|
||||
{
|
||||
cctx->currentOffset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** LZ4_compress_generic() :
|
||||
inlined, to ensure branches are decided at compilation time */
|
||||
LZ4_FORCE_INLINE int LZ4_compress_generic(
|
||||
@ -532,45 +592,50 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
||||
const int maxOutputSize,
|
||||
const limitedOutput_directive outputLimited,
|
||||
const tableType_t tableType,
|
||||
const dict_directive dict,
|
||||
const dict_directive dictDirective,
|
||||
const dictIssue_directive dictIssue,
|
||||
const U32 acceleration)
|
||||
{
|
||||
const BYTE* ip = (const BYTE*) source;
|
||||
const BYTE* base;
|
||||
|
||||
size_t currentOffset = cctx->currentOffset;
|
||||
const BYTE* base = (const BYTE*) source - currentOffset;
|
||||
const BYTE* lowLimit;
|
||||
const BYTE* const lowRefLimit = ip - cctx->dictSize;
|
||||
const BYTE* const dictionary = cctx->dictionary;
|
||||
const BYTE* const dictEnd = dictionary + cctx->dictSize;
|
||||
const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source;
|
||||
|
||||
const LZ4_stream_t_internal* dictCtx = (const LZ4_stream_t_internal*) cctx->dictCtx;
|
||||
const BYTE* const dictionary =
|
||||
dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary;
|
||||
const U32 dictSize =
|
||||
dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize;
|
||||
|
||||
const BYTE* const lowRefLimit = (const BYTE*) source - dictSize;
|
||||
const BYTE* const dictEnd = dictionary + dictSize;
|
||||
const BYTE* anchor = (const BYTE*) source;
|
||||
const BYTE* const iend = ip + inputSize;
|
||||
const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1;
|
||||
const BYTE* const matchlimit = iend - LASTLITERALS;
|
||||
|
||||
/* the dictCtx currentOffset is indexed on the start of the dictionary,
|
||||
* while a dictionary in the current context precedes the currentOffset */
|
||||
const BYTE* dictBase = dictDirective == usingDictCtx ?
|
||||
(const BYTE*) source - dictCtx->currentOffset :
|
||||
(const BYTE*) source - dictSize - currentOffset;
|
||||
const ptrdiff_t dictDelta = dictionary ? dictEnd - (const BYTE*) source : 0;
|
||||
const BYTE* dictLowLimit;
|
||||
|
||||
BYTE* op = (BYTE*) dest;
|
||||
BYTE* const olimit = op + maxOutputSize;
|
||||
|
||||
ptrdiff_t retval = 0;
|
||||
|
||||
U32 forwardH;
|
||||
|
||||
/* Init conditions */
|
||||
if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */
|
||||
switch(dict)
|
||||
{
|
||||
case noDict:
|
||||
default:
|
||||
base = (const BYTE*)source;
|
||||
lowLimit = (const BYTE*)source;
|
||||
break;
|
||||
case withPrefix64k:
|
||||
base = (const BYTE*)source - cctx->currentOffset;
|
||||
lowLimit = (const BYTE*)source - cctx->dictSize;
|
||||
break;
|
||||
case usingExtDict:
|
||||
base = (const BYTE*)source - cctx->currentOffset;
|
||||
lowLimit = (const BYTE*)source;
|
||||
break;
|
||||
}
|
||||
|
||||
lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0);
|
||||
dictLowLimit = dictionary ? dictionary : lowLimit;
|
||||
|
||||
if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
|
||||
if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
|
||||
|
||||
@ -598,10 +663,20 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
||||
assert(ip < mflimitPlusOne);
|
||||
|
||||
match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base);
|
||||
if (dict==usingExtDict) {
|
||||
if (dictDirective == usingDictCtx) {
|
||||
if (match < (const BYTE*)source) {
|
||||
/* there was no match, try the dictionary */
|
||||
match = LZ4_getPosition(ip, dictCtx->hashTable, byU32, dictBase);
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictLowLimit;
|
||||
} else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
}
|
||||
} else if (dictDirective==usingExtDict) {
|
||||
if (match < (const BYTE*)source) {
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictionary;
|
||||
lowLimit = dictLowLimit;
|
||||
} else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
@ -622,7 +697,7 @@ LZ4_FORCE_INLINE int LZ4_compress_generic(
|
||||
token = op++;
|
||||
if ((outputLimited) && /* Check output buffer overflow */
|
||||
(unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
|
||||
return 0;
|
||||
goto _clean_up;
|
||||
if (litLength >= RUN_MASK) {
|
||||
int len = (int)litLength-RUN_MASK;
|
||||
*token = (RUN_MASK<<ML_BITS);
|
||||
@ -643,7 +718,7 @@ _next_match:
|
||||
/* Encode MatchLength */
|
||||
{ unsigned matchCode;
|
||||
|
||||
if ((dict==usingExtDict) && (lowLimit==dictionary)) {
|
||||
if ((dictDirective==usingExtDict || dictDirective==usingDictCtx) && lowLimit==dictionary) {
|
||||
const BYTE* limit;
|
||||
match += refDelta;
|
||||
limit = ip + (dictEnd-match);
|
||||
@ -662,7 +737,7 @@ _next_match:
|
||||
|
||||
if ( outputLimited && /* Check output buffer overflow */
|
||||
(unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) )
|
||||
return 0;
|
||||
goto _clean_up;
|
||||
if (matchCode >= ML_MASK) {
|
||||
*token += ML_MASK;
|
||||
matchCode -= ML_MASK;
|
||||
@ -688,10 +763,20 @@ _next_match:
|
||||
|
||||
/* Test next position */
|
||||
match = LZ4_getPosition(ip, cctx->hashTable, tableType, base);
|
||||
if (dict==usingExtDict) {
|
||||
if (dictDirective == usingDictCtx) {
|
||||
if (match < (const BYTE*)source) {
|
||||
/* there was no match, try the dictionary */
|
||||
match = LZ4_getPosition(ip, dictCtx->hashTable, byU32, dictBase);
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictLowLimit;
|
||||
} else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
}
|
||||
} else if (dictDirective==usingExtDict) {
|
||||
if (match < (const BYTE*)source) {
|
||||
refDelta = dictDelta;
|
||||
lowLimit = dictionary;
|
||||
lowLimit = dictLowLimit;
|
||||
} else {
|
||||
refDelta = 0;
|
||||
lowLimit = (const BYTE*)source;
|
||||
@ -711,7 +796,7 @@ _last_literals:
|
||||
{ size_t const lastRun = (size_t)(iend - anchor);
|
||||
if ( (outputLimited) && /* Check output buffer overflow */
|
||||
((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) )
|
||||
return 0;
|
||||
goto _clean_up;
|
||||
if (lastRun >= RUN_MASK) {
|
||||
size_t accumulator = lastRun - RUN_MASK;
|
||||
*op++ = RUN_MASK << ML_BITS;
|
||||
@ -724,41 +809,112 @@ _last_literals:
|
||||
op += lastRun;
|
||||
}
|
||||
|
||||
retval = (((char*)op)-dest);
|
||||
|
||||
_clean_up:
|
||||
if (dictDirective == usingDictCtx) {
|
||||
/* Subsequent linked blocks can't use the dictionary. */
|
||||
/* Instead, they use the block we just compressed. */
|
||||
cctx->dictCtx = NULL;
|
||||
cctx->dictSize = (U32)inputSize;
|
||||
} else {
|
||||
cctx->dictSize += (U32)inputSize;
|
||||
}
|
||||
cctx->currentOffset += (U32)inputSize;
|
||||
cctx->tableType = tableType;
|
||||
|
||||
/* End */
|
||||
return (int) (((char*)op)-dest);
|
||||
return (int)retval;
|
||||
}
|
||||
|
||||
|
||||
int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
|
||||
LZ4_resetStream((LZ4_stream_t*)state);
|
||||
if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
|
||||
LZ4_resetStream((LZ4_stream_t*)state);
|
||||
if (maxOutputSize >= LZ4_compressBound(inputSize)) {
|
||||
if (inputSize < LZ4_64Klimit) {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
|
||||
} else {
|
||||
const tableType_t tableType = (sizeof(void*)==8) ? byU32 : byPtr;
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
if (inputSize < LZ4_64Klimit) {;
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
||||
} else {
|
||||
const tableType_t tableType = (sizeof(void*)==8) ? byU32 : byPtr;
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LZ4_compress_fast_extState_noReset is a variant of LZ4_compress_fast_extState
|
||||
* that can be used when the state is known to have already been initialized
|
||||
* (via LZ4_resetStream or an earlier call to LZ4_compress_fast_extState /
|
||||
* LZ4_compress_fast_extState_noReset). This can provide significantly better
|
||||
* performance when the context reset would otherwise be a significant part of
|
||||
* the cost of the compression, e.g., when the data to be compressed is small.
|
||||
*/
|
||||
int LZ4_compress_fast_extState_noReset(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
|
||||
if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
|
||||
ctx->dictionary = NULL;
|
||||
ctx->dictSize = 0;
|
||||
ctx->dictCtx = NULL;
|
||||
|
||||
if (maxOutputSize >= LZ4_compressBound(inputSize)) {
|
||||
if (inputSize < LZ4_64Klimit)
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
|
||||
else
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
if (inputSize < LZ4_64Klimit) {
|
||||
const tableType_t tableType = byU16;
|
||||
LZ4_prepareTable(ctx, inputSize, tableType, noDict);
|
||||
if (ctx->currentOffset) {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, tableType, noDict, dictSmall, acceleration);
|
||||
} else {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
const tableType_t tableType = (sizeof(void*)==8) ? byU32 : byPtr;
|
||||
LZ4_prepareTable(ctx, inputSize, tableType, noDict);
|
||||
if (ctx->currentOffset) {
|
||||
ctx->currentOffset += 64 KB;
|
||||
}
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
if (inputSize < LZ4_64Klimit)
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
|
||||
else
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
|
||||
if (inputSize < LZ4_64Klimit) {
|
||||
const tableType_t tableType = byU16;
|
||||
LZ4_prepareTable(ctx, inputSize, tableType, noDict);
|
||||
if (ctx->currentOffset) {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, noDict, dictSmall, acceleration);
|
||||
} else {
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
const tableType_t tableType = (sizeof(void*)==8) ? byU32 : byPtr;
|
||||
LZ4_prepareTable(ctx, inputSize, tableType, noDict);
|
||||
if (ctx->currentOffset) {
|
||||
ctx->currentOffset += 64 KB;
|
||||
}
|
||||
return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
int result;
|
||||
#if (LZ4_HEAPMODE)
|
||||
void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
LZ4_stream_t* ctxPtr = ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
if (ctxPtr == NULL) return 0;
|
||||
#else
|
||||
LZ4_stream_t ctx;
|
||||
void* const ctxPtr = &ctx;
|
||||
LZ4_stream_t* const ctxPtr = &ctx;
|
||||
#endif
|
||||
|
||||
int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
|
||||
result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
|
||||
|
||||
#if (LZ4_HEAPMODE)
|
||||
FREEMEM(ctxPtr);
|
||||
@ -965,7 +1121,8 @@ static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src,
|
||||
int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
|
||||
{
|
||||
#if (LZ4_HEAPMODE)
|
||||
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
|
||||
if (ctx == NULL) return 0;
|
||||
#else
|
||||
LZ4_stream_t ctxBody;
|
||||
LZ4_stream_t* ctx = &ctxBody;
|
||||
@ -987,21 +1144,25 @@ int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targe
|
||||
|
||||
LZ4_stream_t* LZ4_createStream(void)
|
||||
{
|
||||
LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
|
||||
LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
|
||||
LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */
|
||||
DEBUGLOG(4, "LZ4_createStream %p", lz4s);
|
||||
if (lz4s == NULL) return NULL;
|
||||
LZ4_resetStream(lz4s);
|
||||
return lz4s;
|
||||
}
|
||||
|
||||
void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
|
||||
{
|
||||
DEBUGLOG(4, "LZ4_resetStream");
|
||||
DEBUGLOG(5, "LZ4_resetStream %p", LZ4_stream);
|
||||
MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
|
||||
LZ4_stream->internal_donotuse.tableType = clearedTable;
|
||||
}
|
||||
|
||||
int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
|
||||
{
|
||||
if (!LZ4_stream) return 0; /* support free on NULL */
|
||||
DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream);
|
||||
FREEMEM(LZ4_stream);
|
||||
return (0);
|
||||
}
|
||||
@ -1015,14 +1176,12 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
|
||||
const BYTE* const dictEnd = p + dictSize;
|
||||
const BYTE* base;
|
||||
|
||||
if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */
|
||||
LZ4_resetStream(LZ4_dict);
|
||||
DEBUGLOG(4, "LZ4_loadDict %p", LZ4_dict);
|
||||
|
||||
if (dictSize < (int)HASH_UNIT) {
|
||||
dict->dictionary = NULL;
|
||||
dict->dictSize = 0;
|
||||
return 0;
|
||||
}
|
||||
if ((dict->initCheck)
|
||||
|| (dict->tableType != byU32 && dict->tableType != clearedTable)
|
||||
|| (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */
|
||||
LZ4_resetStream(LZ4_dict);
|
||||
|
||||
if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
|
||||
dict->currentOffset += 64 KB;
|
||||
@ -1030,6 +1189,11 @@ int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
|
||||
dict->dictionary = p;
|
||||
dict->dictSize = (U32)(dictEnd - p);
|
||||
dict->currentOffset += dict->dictSize;
|
||||
dict->tableType = byU32;
|
||||
|
||||
if (dictSize < (int)HASH_UNIT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (p <= dictEnd-HASH_UNIT) {
|
||||
LZ4_putPosition(p, dict->hashTable, byU32, base);
|
||||
@ -1048,6 +1212,7 @@ static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
|
||||
U32 const delta = LZ4_dict->currentOffset - 64 KB;
|
||||
const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
|
||||
int i;
|
||||
DEBUGLOG(4, "LZ4_renormDictT %p", LZ4_dict);
|
||||
for (i=0; i<LZ4_HASH_SIZE_U32; i++) {
|
||||
if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
|
||||
else LZ4_dict->hashTable[i] -= delta;
|
||||
@ -1061,6 +1226,7 @@ static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
|
||||
|
||||
int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
|
||||
{
|
||||
const tableType_t tableType = byU32;
|
||||
LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse;
|
||||
const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
|
||||
|
||||
@ -1082,25 +1248,43 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch
|
||||
|
||||
/* prefix mode : source data follows dictionary */
|
||||
if (dictEnd == (const BYTE*)source) {
|
||||
int result;
|
||||
LZ4_prepareTable(streamPtr, inputSize, tableType, withPrefix64k);
|
||||
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration);
|
||||
return LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration);
|
||||
else
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration);
|
||||
streamPtr->dictSize += (U32)inputSize;
|
||||
streamPtr->currentOffset += (U32)inputSize;
|
||||
return result;
|
||||
return LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration);
|
||||
}
|
||||
|
||||
/* external dictionary mode */
|
||||
{ int result;
|
||||
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration);
|
||||
else
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration);
|
||||
if (streamPtr->dictCtx) {
|
||||
/* We depend here on the fact that dictCtx'es (produced by
|
||||
* LZ4_loadDict) guarantee that their tables contain no references
|
||||
* to offsets between dictCtx->currentOffset - 64 KB and
|
||||
* dictCtx->currentOffset - dictCtx->dictSize. This makes it safe
|
||||
* to use noDictIssue even when the dict isn't a full 64 KB.
|
||||
*/
|
||||
if (inputSize > 4 KB) {
|
||||
/* For compressing large blobs, it is faster to pay the setup
|
||||
* cost to copy the dictionary's tables into the active context,
|
||||
* so that the compression loop is only looking in one table.
|
||||
*/
|
||||
memcpy(streamPtr, streamPtr->dictCtx, sizeof(LZ4_stream_t));
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
|
||||
} else {
|
||||
LZ4_prepareTable(streamPtr, inputSize, tableType, usingDictCtx);
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration);
|
||||
}
|
||||
} else {
|
||||
LZ4_prepareTable(streamPtr, inputSize, tableType, usingExtDict);
|
||||
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) {
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration);
|
||||
} else {
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
|
||||
}
|
||||
}
|
||||
streamPtr->dictionary = (const BYTE*)source;
|
||||
streamPtr->dictSize = (U32)inputSize;
|
||||
streamPtr->currentOffset += (U32)inputSize;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -1117,11 +1301,14 @@ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char*
|
||||
if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
|
||||
LZ4_renormDictT(streamPtr, smallest);
|
||||
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
|
||||
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) {
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, dictSmall, 1);
|
||||
} else {
|
||||
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
|
||||
}
|
||||
|
||||
streamPtr->dictionary = (const BYTE*)source;
|
||||
streamPtr->dictSize = (U32)inputSize;
|
||||
streamPtr->currentOffset += (U32)inputSize;
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -1366,7 +1553,7 @@ int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
|
||||
|
||||
LZ4_streamDecode_t* LZ4_createStreamDecode(void)
|
||||
{
|
||||
LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t));
|
||||
LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t));
|
||||
return lz4s;
|
||||
}
|
||||
|
||||
@ -1516,36 +1703,27 @@ They are only provided here for compatibility with older user programs.
|
||||
int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
|
||||
int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
|
||||
|
||||
|
||||
/* Obsolete Streaming functions */
|
||||
|
||||
int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
|
||||
|
||||
static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base)
|
||||
{
|
||||
MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t));
|
||||
lz4ds->internal_donotuse.bufferStart = base;
|
||||
}
|
||||
|
||||
int LZ4_resetStreamState(void* state, char* inputBuffer)
|
||||
{
|
||||
if ((((uptrval)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */
|
||||
LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer);
|
||||
(void)inputBuffer;
|
||||
LZ4_resetStream((LZ4_stream_t*)state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* LZ4_create (char* inputBuffer)
|
||||
{
|
||||
LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t));
|
||||
LZ4_init (lz4ds, (BYTE*)inputBuffer);
|
||||
return lz4ds;
|
||||
(void)inputBuffer;
|
||||
return LZ4_createStream();
|
||||
}
|
||||
|
||||
char* LZ4_slideInputBuffer (void* LZ4_Data)
|
||||
char* LZ4_slideInputBuffer (void* state)
|
||||
{
|
||||
LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse;
|
||||
int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB);
|
||||
return (char*)(ctx->bufferStart + dictSize);
|
||||
// avoid const char * -> char * conversion warning
|
||||
return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary;
|
||||
}
|
||||
|
||||
/* Obsolete streaming decompression functions */
|
||||
|
57
lib/lz4.h
57
lib/lz4.h
@ -343,6 +343,29 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
|
||||
/*^**********************************************
|
||||
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||
***********************************************/
|
||||
|
||||
/*-************************************
|
||||
* Unstable declarations
|
||||
**************************************
|
||||
* Declarations in this section should be considered unstable.
|
||||
* Use at your own peril, etc., etc.
|
||||
* They may be removed in the future.
|
||||
* Their signatures may change.
|
||||
**************************************/
|
||||
|
||||
/*!
|
||||
LZ4_compress_fast_extState_noReset() :
|
||||
A variant of LZ4_compress_fast_extState().
|
||||
|
||||
Use the _noReset variant if LZ4_resetStream() was called on the state
|
||||
buffer before being used for the first time (calls to both extState
|
||||
functions leave the state in a safe state, so zeroing is not required
|
||||
between calls). Otherwise, using the plain _extState requires LZ4 to
|
||||
reinitialize the state internally for every call.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_extState_noReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Private definitions
|
||||
**************************************
|
||||
@ -357,14 +380,16 @@ LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int or
|
||||
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
uint32_t hashTable[LZ4_HASH_SIZE_U32];
|
||||
uint32_t currentOffset;
|
||||
uint32_t initCheck;
|
||||
uint16_t initCheck;
|
||||
uint16_t tableType;
|
||||
const uint8_t* dictionary;
|
||||
uint8_t* bufferStart; /* obsolete, used for slideInputBuffer */
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
uint32_t dictSize;
|
||||
} LZ4_stream_t_internal;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* externalDict;
|
||||
@ -375,14 +400,16 @@ typedef struct {
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
unsigned int hashTable[LZ4_HASH_SIZE_U32];
|
||||
unsigned int currentOffset;
|
||||
unsigned int initCheck;
|
||||
unsigned short initCheck;
|
||||
unsigned short tableType;
|
||||
const unsigned char* dictionary;
|
||||
unsigned char* bufferStart; /* obsolete, used for slideInputBuffer */
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
unsigned int dictSize;
|
||||
} LZ4_stream_t_internal;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const unsigned char* externalDict;
|
||||
@ -465,11 +492,15 @@ LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_co
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||
|
||||
/* Obsolete streaming functions; use new streaming interface whenever possible */
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||
/* Broken, obsolete streaming functions; do not use!
|
||||
*
|
||||
* These functions depended on data that is no longer tracked in the state. They
|
||||
* are therefore broken--they don't retain any history across compressions.
|
||||
*/
|
||||
LZ4_DEPRECATED("Broken!!! Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("Broken!!! Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("Broken!!! Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
|
178
lib/lz4frame.c
178
lib/lz4frame.c
@ -46,11 +46,25 @@ You can contact the author at :
|
||||
#endif
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Tuning parameters
|
||||
**************************************/
|
||||
/*
|
||||
* LZ4F_HEAPMODE :
|
||||
* Select how default compression functions will allocate memory for their hash table,
|
||||
* in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
|
||||
*/
|
||||
#ifndef LZ4F_HEAPMODE
|
||||
# define LZ4F_HEAPMODE 0
|
||||
#endif
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Memory routines
|
||||
**************************************/
|
||||
#include <stdlib.h> /* malloc, calloc, free */
|
||||
#define ALLOCATOR(s) calloc(1,s)
|
||||
#define ALLOC(s) malloc(s)
|
||||
#define ALLOC_AND_ZERO(s) calloc(1,s)
|
||||
#define FREEMEM free
|
||||
#include <string.h> /* memset, memcpy, memmove */
|
||||
#define MEM_INIT memset
|
||||
@ -188,7 +202,8 @@ typedef struct LZ4F_cctx_s
|
||||
U64 totalInSize;
|
||||
XXH32_state_t xxh;
|
||||
void* lz4CtxPtr;
|
||||
U32 lz4CtxLevel; /* 0: unallocated; 1: LZ4_stream_t; 3: LZ4_streamHC_t */
|
||||
U16 lz4CtxAlloc; // sized for: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx
|
||||
U16 lz4CtxState; // in use as: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx
|
||||
} LZ4F_cctx_t;
|
||||
|
||||
|
||||
@ -279,7 +294,7 @@ static size_t LZ4F_compressBound_internal(size_t srcSize,
|
||||
size_t alreadyBuffered)
|
||||
{
|
||||
LZ4F_preferences_t prefsNull;
|
||||
memset(&prefsNull, 0, sizeof(prefsNull));
|
||||
MEM_INIT(&prefsNull, 0, sizeof(prefsNull));
|
||||
prefsNull.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; /* worst case */
|
||||
{ const LZ4F_preferences_t* const prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
|
||||
U32 const flush = prefsPtr->autoFlush | (srcSize==0);
|
||||
@ -308,7 +323,7 @@ size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* prefere
|
||||
size_t const headerSize = maxFHSize; /* max header size, including optional fields */
|
||||
|
||||
if (preferencesPtr!=NULL) prefs = *preferencesPtr;
|
||||
else memset(&prefs, 0, sizeof(prefs));
|
||||
else MEM_INIT(&prefs, 0, sizeof(prefs));
|
||||
prefs.autoFlush = 1;
|
||||
|
||||
return headerSize + LZ4F_compressBound_internal(srcSize, &prefs, 0);;
|
||||
@ -324,27 +339,22 @@ size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* prefere
|
||||
* @return : number of bytes written into dstBuffer,
|
||||
* or an error code if it fails (can be tested using LZ4F_isError())
|
||||
*/
|
||||
size_t LZ4F_compressFrame_usingCDict(void* dstBuffer, size_t dstCapacity,
|
||||
size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
|
||||
void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_CDict* cdict,
|
||||
const LZ4F_preferences_t* preferencesPtr)
|
||||
{
|
||||
LZ4F_cctx_t cctxI;
|
||||
LZ4_stream_t lz4ctx; /* pretty large on stack */
|
||||
LZ4F_preferences_t prefs;
|
||||
LZ4F_compressOptions_t options;
|
||||
BYTE* const dstStart = (BYTE*) dstBuffer;
|
||||
BYTE* dstPtr = dstStart;
|
||||
BYTE* const dstEnd = dstStart + dstCapacity;
|
||||
|
||||
memset(&cctxI, 0, sizeof(cctxI));
|
||||
cctxI.version = LZ4F_VERSION;
|
||||
cctxI.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
|
||||
|
||||
if (preferencesPtr!=NULL)
|
||||
prefs = *preferencesPtr;
|
||||
else
|
||||
memset(&prefs, 0, sizeof(prefs));
|
||||
MEM_INIT(&prefs, 0, sizeof(prefs));
|
||||
if (prefs.frameInfo.contentSize != 0)
|
||||
prefs.frameInfo.contentSize = (U64)srcSize; /* auto-correct content size if selected (!=0) */
|
||||
|
||||
@ -353,32 +363,24 @@ size_t LZ4F_compressFrame_usingCDict(void* dstBuffer, size_t dstCapacity,
|
||||
if (srcSize <= LZ4F_getBlockSize(prefs.frameInfo.blockSizeID))
|
||||
prefs.frameInfo.blockMode = LZ4F_blockIndependent; /* only one block => no need for inter-block link */
|
||||
|
||||
if (prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
|
||||
cctxI.lz4CtxPtr = &lz4ctx;
|
||||
cctxI.lz4CtxLevel = 1;
|
||||
} /* fast compression context pre-created on stack */
|
||||
|
||||
memset(&options, 0, sizeof(options));
|
||||
MEM_INIT(&options, 0, sizeof(options));
|
||||
options.stableSrc = 1;
|
||||
|
||||
if (dstCapacity < LZ4F_compressFrameBound(srcSize, &prefs)) /* condition to guarantee success */
|
||||
return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
|
||||
|
||||
{ size_t const headerSize = LZ4F_compressBegin_usingCDict(&cctxI, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
|
||||
{ size_t const headerSize = LZ4F_compressBegin_usingCDict(cctx, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
|
||||
if (LZ4F_isError(headerSize)) return headerSize;
|
||||
dstPtr += headerSize; /* header size */ }
|
||||
|
||||
{ size_t const cSize = LZ4F_compressUpdate(&cctxI, dstPtr, dstEnd-dstPtr, srcBuffer, srcSize, &options);
|
||||
{ size_t const cSize = LZ4F_compressUpdate(cctx, dstPtr, dstEnd-dstPtr, srcBuffer, srcSize, &options);
|
||||
if (LZ4F_isError(cSize)) return cSize;
|
||||
dstPtr += cSize; }
|
||||
|
||||
{ size_t const tailSize = LZ4F_compressEnd(&cctxI, dstPtr, dstEnd-dstPtr, &options); /* flush last block, and generate suffix */
|
||||
{ size_t const tailSize = LZ4F_compressEnd(cctx, dstPtr, dstEnd-dstPtr, &options); /* flush last block, and generate suffix */
|
||||
if (LZ4F_isError(tailSize)) return tailSize;
|
||||
dstPtr += tailSize; }
|
||||
|
||||
if (prefs.compressionLevel >= LZ4HC_CLEVEL_MIN) /* Ctx allocation only for lz4hc */
|
||||
FREEMEM(cctxI.lz4CtxPtr);
|
||||
|
||||
return (dstPtr - dstStart);
|
||||
}
|
||||
|
||||
@ -394,9 +396,43 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
|
||||
const void* srcBuffer, size_t srcSize,
|
||||
const LZ4F_preferences_t* preferencesPtr)
|
||||
{
|
||||
return LZ4F_compressFrame_usingCDict(dstBuffer, dstCapacity,
|
||||
srcBuffer, srcSize,
|
||||
NULL, preferencesPtr);
|
||||
size_t result;
|
||||
#if (LZ4F_HEAPMODE)
|
||||
LZ4F_cctx_t *cctxPtr;
|
||||
result = LZ4F_createCompressionContext(&cctxPtr, LZ4F_VERSION);
|
||||
if (LZ4F_isError(result)) return result;
|
||||
#else
|
||||
LZ4F_cctx_t cctx;
|
||||
LZ4_stream_t lz4ctx;
|
||||
LZ4F_cctx_t *cctxPtr = &cctx;
|
||||
|
||||
MEM_INIT(&cctx, 0, sizeof(cctx));
|
||||
cctx.version = LZ4F_VERSION;
|
||||
cctx.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
|
||||
if (preferencesPtr == NULL ||
|
||||
preferencesPtr->compressionLevel < LZ4HC_CLEVEL_MIN)
|
||||
{
|
||||
LZ4_resetStream(&lz4ctx);
|
||||
cctxPtr->lz4CtxPtr = &lz4ctx;
|
||||
cctxPtr->lz4CtxAlloc = 1;
|
||||
cctxPtr->lz4CtxState = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
result = LZ4F_compressFrame_usingCDict(cctxPtr, dstBuffer, dstCapacity,
|
||||
srcBuffer, srcSize,
|
||||
NULL, preferencesPtr);
|
||||
|
||||
#if (LZ4F_HEAPMODE)
|
||||
LZ4F_freeCompressionContext(cctxPtr);
|
||||
#else
|
||||
if (preferencesPtr != NULL &&
|
||||
preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN)
|
||||
{
|
||||
FREEMEM(cctxPtr->lz4CtxPtr);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -425,7 +461,7 @@ LZ4F_CDict* LZ4F_createCDict(const void* dictBuffer, size_t dictSize)
|
||||
dictStart += dictSize - 64 KB;
|
||||
dictSize = 64 KB;
|
||||
}
|
||||
cdict->dictContent = ALLOCATOR(dictSize);
|
||||
cdict->dictContent = ALLOC(dictSize);
|
||||
cdict->fastCtx = LZ4_createStream();
|
||||
cdict->HCCtx = LZ4_createStreamHC();
|
||||
if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
|
||||
@ -464,7 +500,7 @@ void LZ4F_freeCDict(LZ4F_CDict* cdict)
|
||||
*/
|
||||
LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version)
|
||||
{
|
||||
LZ4F_cctx_t* const cctxPtr = (LZ4F_cctx_t*)ALLOCATOR(sizeof(LZ4F_cctx_t));
|
||||
LZ4F_cctx_t* const cctxPtr = (LZ4F_cctx_t*)ALLOC_AND_ZERO(sizeof(LZ4F_cctx_t));
|
||||
if (cctxPtr==NULL) return err0r(LZ4F_ERROR_allocation_failed);
|
||||
|
||||
cctxPtr->version = version;
|
||||
@ -490,6 +526,28 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp
|
||||
}
|
||||
|
||||
|
||||
static void LZ4F_applyCDict(void* ctx,
|
||||
const LZ4F_CDict* cdict,
|
||||
int level) {
|
||||
if (level < LZ4HC_CLEVEL_MIN) {
|
||||
LZ4_stream_t_internal* internal_ctx = &((LZ4_stream_t *)ctx)->internal_donotuse;
|
||||
assert(!internal_ctx->initCheck);
|
||||
/* Clear any local dictionary */
|
||||
internal_ctx->dictionary = NULL;
|
||||
internal_ctx->dictSize = 0;
|
||||
/* Point to the dictionary context */
|
||||
internal_ctx->dictCtx = cdict ? &(cdict->fastCtx->internal_donotuse) : NULL;
|
||||
} else {
|
||||
if (cdict) {
|
||||
memcpy(ctx, cdict->HCCtx, sizeof(*cdict->HCCtx));
|
||||
LZ4_setCompressionLevel((LZ4_streamHC_t*)ctx, level);
|
||||
} else {
|
||||
LZ4_resetStreamHC((LZ4_streamHC_t*)(ctx), level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! LZ4F_compressBegin_usingCDict() :
|
||||
* init streaming compression and writes frame header into dstBuffer.
|
||||
* dstBuffer must be >= LZ4F_HEADER_SIZE_MAX bytes.
|
||||
@ -507,21 +565,33 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
|
||||
BYTE* headerStart;
|
||||
|
||||
if (dstCapacity < maxFHSize) return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
|
||||
memset(&prefNull, 0, sizeof(prefNull));
|
||||
MEM_INIT(&prefNull, 0, sizeof(prefNull));
|
||||
if (preferencesPtr == NULL) preferencesPtr = &prefNull;
|
||||
cctxPtr->prefs = *preferencesPtr;
|
||||
|
||||
/* Ctx Management */
|
||||
{ U32 const ctxTypeID = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2; /* 0:nothing ; 1:LZ4 table ; 2:HC tables */
|
||||
if (cctxPtr->lz4CtxLevel < ctxTypeID) {
|
||||
{ U16 const ctxTypeID = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2;
|
||||
if (cctxPtr->lz4CtxAlloc < ctxTypeID) {
|
||||
FREEMEM(cctxPtr->lz4CtxPtr);
|
||||
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN)
|
||||
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
|
||||
cctxPtr->lz4CtxPtr = (void*)LZ4_createStream();
|
||||
else
|
||||
} else {
|
||||
cctxPtr->lz4CtxPtr = (void*)LZ4_createStreamHC();
|
||||
}
|
||||
if (cctxPtr->lz4CtxPtr == NULL) return err0r(LZ4F_ERROR_allocation_failed);
|
||||
cctxPtr->lz4CtxLevel = ctxTypeID;
|
||||
} }
|
||||
cctxPtr->lz4CtxAlloc = ctxTypeID;
|
||||
cctxPtr->lz4CtxState = ctxTypeID;
|
||||
} else if (cctxPtr->lz4CtxState != ctxTypeID) {
|
||||
/* otherwise, a sufficient buffer is allocated, but we need to
|
||||
* reset it to the correct context type */
|
||||
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
|
||||
LZ4_resetStream((LZ4_stream_t *) cctxPtr->lz4CtxPtr);
|
||||
} else {
|
||||
LZ4_resetStreamHC((LZ4_streamHC_t *) cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel);
|
||||
}
|
||||
cctxPtr->lz4CtxState = ctxTypeID;
|
||||
}
|
||||
}
|
||||
|
||||
/* Buffer Management */
|
||||
if (cctxPtr->prefs.frameInfo.blockSizeID == 0)
|
||||
@ -535,7 +605,7 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
|
||||
if (cctxPtr->maxBufferSize < requiredBuffSize) {
|
||||
cctxPtr->maxBufferSize = 0;
|
||||
FREEMEM(cctxPtr->tmpBuff);
|
||||
cctxPtr->tmpBuff = (BYTE*)ALLOCATOR(requiredBuffSize);
|
||||
cctxPtr->tmpBuff = (BYTE*)ALLOC_AND_ZERO(requiredBuffSize);
|
||||
if (cctxPtr->tmpBuff == NULL) return err0r(LZ4F_ERROR_allocation_failed);
|
||||
cctxPtr->maxBufferSize = requiredBuffSize;
|
||||
} }
|
||||
@ -547,19 +617,7 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
|
||||
cctxPtr->cdict = cdict;
|
||||
if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
|
||||
/* frame init only for blockLinked : blockIndependent will be init at each block */
|
||||
if (cdict) {
|
||||
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
|
||||
memcpy(cctxPtr->lz4CtxPtr, cdict->fastCtx, sizeof(*cdict->fastCtx));
|
||||
} else {
|
||||
memcpy(cctxPtr->lz4CtxPtr, cdict->HCCtx, sizeof(*cdict->HCCtx));
|
||||
LZ4_setCompressionLevel((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel);
|
||||
}
|
||||
} else {
|
||||
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN)
|
||||
LZ4_resetStream((LZ4_stream_t*)(cctxPtr->lz4CtxPtr));
|
||||
else
|
||||
LZ4_resetStreamHC((LZ4_streamHC_t*)(cctxPtr->lz4CtxPtr), cctxPtr->prefs.compressionLevel);
|
||||
}
|
||||
LZ4F_applyCDict(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel);
|
||||
}
|
||||
|
||||
/* Magic Number */
|
||||
@ -654,11 +712,12 @@ static size_t LZ4F_makeBlock(void* dst, const void* src, size_t srcSize,
|
||||
static int LZ4F_compressBlock(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
|
||||
{
|
||||
int const acceleration = (level < -1) ? -level : 1;
|
||||
LZ4F_applyCDict(ctx, cdict, level);
|
||||
if (cdict) {
|
||||
memcpy(ctx, cdict->fastCtx, sizeof(*cdict->fastCtx));
|
||||
return LZ4_compress_fast_continue((LZ4_stream_t*)ctx, src, dst, srcSize, dstCapacity, acceleration);
|
||||
} else {
|
||||
return LZ4_compress_fast_extState_noReset(ctx, src, dst, srcSize, dstCapacity, acceleration);
|
||||
}
|
||||
return LZ4_compress_fast_extState(ctx, src, dst, srcSize, dstCapacity, acceleration);
|
||||
}
|
||||
|
||||
static int LZ4F_compressBlock_continue(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
|
||||
@ -671,8 +730,7 @@ static int LZ4F_compressBlock_continue(void* ctx, const char* src, char* dst, in
|
||||
static int LZ4F_compressBlockHC(void* ctx, const char* src, char* dst, int srcSize, int dstCapacity, int level, const LZ4F_CDict* cdict)
|
||||
{
|
||||
if (cdict) {
|
||||
memcpy(ctx, cdict->HCCtx, sizeof(*cdict->HCCtx));
|
||||
LZ4_setCompressionLevel((LZ4_streamHC_t*)ctx, level);
|
||||
LZ4F_applyCDict(ctx, cdict, level);
|
||||
return LZ4_compress_HC_continue((LZ4_streamHC_t*)ctx, src, dst, srcSize, dstCapacity);
|
||||
}
|
||||
return LZ4_compress_HC_extStateHC(ctx, src, dst, srcSize, dstCapacity, level);
|
||||
@ -728,7 +786,7 @@ size_t LZ4F_compressUpdate(LZ4F_cctx* cctxPtr,
|
||||
if (cctxPtr->cStage != 1) return err0r(LZ4F_ERROR_GENERIC);
|
||||
if (dstCapacity < LZ4F_compressBound_internal(srcSize, &(cctxPtr->prefs), cctxPtr->tmpInSize))
|
||||
return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
|
||||
memset(&cOptionsNull, 0, sizeof(cOptionsNull));
|
||||
MEM_INIT(&cOptionsNull, 0, sizeof(cOptionsNull));
|
||||
if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
|
||||
|
||||
/* complete tmp buffer */
|
||||
@ -932,7 +990,7 @@ struct LZ4F_dctx_s {
|
||||
*/
|
||||
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_dctx** LZ4F_decompressionContextPtr, unsigned versionNumber)
|
||||
{
|
||||
LZ4F_dctx* const dctx = (LZ4F_dctx*)ALLOCATOR(sizeof(LZ4F_dctx));
|
||||
LZ4F_dctx* const dctx = (LZ4F_dctx*)ALLOC_AND_ZERO(sizeof(LZ4F_dctx));
|
||||
if (dctx==NULL) return err0r(LZ4F_ERROR_GENERIC);
|
||||
|
||||
dctx->version = versionNumber;
|
||||
@ -1004,7 +1062,7 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize
|
||||
|
||||
/* need to decode header to get frameInfo */
|
||||
if (srcSize < minFHSize) return err0r(LZ4F_ERROR_frameHeader_incomplete); /* minimal frame header size */
|
||||
memset(&(dctx->frameInfo), 0, sizeof(dctx->frameInfo));
|
||||
MEM_INIT(&(dctx->frameInfo), 0, sizeof(dctx->frameInfo));
|
||||
|
||||
/* special case : skippable frames */
|
||||
if ((LZ4F_readLE32(srcPtr) & 0xFFFFFFF0U) == LZ4F_MAGIC_SKIPPABLE_START) {
|
||||
@ -1231,7 +1289,7 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx,
|
||||
size_t nextSrcSizeHint = 1;
|
||||
|
||||
|
||||
memset(&optionsNull, 0, sizeof(optionsNull));
|
||||
MEM_INIT(&optionsNull, 0, sizeof(optionsNull));
|
||||
if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
|
||||
*srcSizePtr = 0;
|
||||
*dstSizePtr = 0;
|
||||
@ -1280,11 +1338,11 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx,
|
||||
if (bufferNeeded > dctx->maxBufferSize) { /* tmp buffers too small */
|
||||
dctx->maxBufferSize = 0; /* ensure allocation will be re-attempted on next entry*/
|
||||
FREEMEM(dctx->tmpIn);
|
||||
dctx->tmpIn = (BYTE*)ALLOCATOR(dctx->maxBlockSize + 4 /* block checksum */);
|
||||
dctx->tmpIn = (BYTE*)ALLOC(dctx->maxBlockSize + 4 /* block checksum */);
|
||||
if (dctx->tmpIn == NULL)
|
||||
return err0r(LZ4F_ERROR_allocation_failed);
|
||||
FREEMEM(dctx->tmpOutBuffer);
|
||||
dctx->tmpOutBuffer= (BYTE*)ALLOCATOR(bufferNeeded);
|
||||
dctx->tmpOutBuffer= (BYTE*)ALLOC(bufferNeeded);
|
||||
if (dctx->tmpOutBuffer== NULL)
|
||||
return err0r(LZ4F_ERROR_allocation_failed);
|
||||
dctx->maxBufferSize = bufferNeeded;
|
||||
|
@ -107,6 +107,7 @@ LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
|
||||
|
||||
/*! LZ4_compressFrame_usingCDict() :
|
||||
* Compress an entire srcBuffer into a valid LZ4 frame using a digested Dictionary.
|
||||
* cctx must point to a context created by LZ4F_createCompressionContext().
|
||||
* If cdict==NULL, compress without a dictionary.
|
||||
* dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
|
||||
* If this condition is not respected, function will fail (@return an errorCode).
|
||||
@ -115,6 +116,7 @@ LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
|
||||
* @return : number of bytes written into dstBuffer.
|
||||
* or an error code if it fails (can be tested using LZ4F_isError()) */
|
||||
LZ4FLIB_STATIC_API size_t LZ4F_compressFrame_usingCDict(
|
||||
LZ4F_cctx* cctx,
|
||||
void* dst, size_t dstCapacity,
|
||||
const void* src, size_t srcSize,
|
||||
const LZ4F_CDict* cdict,
|
||||
|
@ -858,7 +858,7 @@ int LZ4_resetStreamStateHC(void* state, char* inputBuffer)
|
||||
|
||||
void* LZ4_createHC (char* inputBuffer)
|
||||
{
|
||||
LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOCATOR(1, sizeof(LZ4_streamHC_t));
|
||||
LZ4_streamHC_t* hc4 = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t));
|
||||
if (hc4 == NULL) return NULL; /* not enough memory */
|
||||
LZ4HC_init (&hc4->internal_donotuse, (const BYTE*)inputBuffer);
|
||||
hc4->internal_donotuse.inputBuffer = (BYTE*)inputBuffer;
|
||||
|
@ -560,7 +560,7 @@ static int LZ4IO_compressFilename_extRess(cRess_t ress, const char* srcFileName,
|
||||
/* single-block file */
|
||||
if (readSize < blockSize) {
|
||||
/* Compress in single pass */
|
||||
size_t cSize = LZ4F_compressFrame_usingCDict(dstBuffer, dstBufferSize, srcBuffer, readSize, ress.cdict, &prefs);
|
||||
size_t cSize = LZ4F_compressFrame_usingCDict(ctx, dstBuffer, dstBufferSize, srcBuffer, readSize, ress.cdict, &prefs);
|
||||
if (LZ4F_isError(cSize)) EXM_THROW(31, "Compression failed : %s", LZ4F_getErrorName(cSize));
|
||||
compressedfilesize = cSize;
|
||||
DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%% ",
|
||||
|
@ -164,7 +164,7 @@ static unsigned FUZ_highbit(U32 v32)
|
||||
/*-*******************************************************
|
||||
* Tests
|
||||
*********************************************************/
|
||||
#define CHECK_V(v,f) v = f; if (LZ4F_isError(v)) goto _output_error
|
||||
#define CHECK_V(v,f) v = f; if (LZ4F_isError(v)) { fprintf(stderr, "%s\n", LZ4F_getErrorName(v)); goto _output_error; }
|
||||
#define CHECK(f) { LZ4F_errorCode_t const CHECK_V(err_ , f); }
|
||||
|
||||
int basicTests(U32 seed, double compressibility)
|
||||
@ -509,23 +509,25 @@ int basicTests(U32 seed, double compressibility)
|
||||
CHECK( LZ4F_freeCompressionContext(cctx) ); cctx = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Dictionary compression test */
|
||||
{ size_t const dictSize = 63 KB;
|
||||
size_t const dstCapacity = LZ4F_compressFrameBound(dictSize, NULL);
|
||||
size_t cSizeNoDict, cSizeWithDict;
|
||||
LZ4F_CDict* const cdict = LZ4F_createCDict(CNBuffer, dictSize);
|
||||
if (cdict == NULL) goto _output_error;
|
||||
CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
|
||||
DISPLAYLEVEL(3, "LZ4F_compressFrame_usingCDict, with NULL dict : ");
|
||||
CHECK_V(cSizeNoDict,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
|
||||
CNBuffer, dictSize,
|
||||
NULL, NULL) );
|
||||
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeNoDict);
|
||||
|
||||
CHECK( LZ4F_freeCompressionContext(cctx) );
|
||||
CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
|
||||
DISPLAYLEVEL(3, "LZ4F_compressFrame_usingCDict, with dict : ");
|
||||
CHECK_V(cSizeWithDict,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
|
||||
CNBuffer, dictSize,
|
||||
cdict, NULL) );
|
||||
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
|
||||
@ -557,7 +559,7 @@ int basicTests(U32 seed, double compressibility)
|
||||
memset(&cParams, 0, sizeof(cParams));
|
||||
cParams.compressionLevel = -3;
|
||||
CHECK_V(cSizeLevelMax,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
|
||||
CNBuffer, dictSize,
|
||||
cdict, &cParams) );
|
||||
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeLevelMax);
|
||||
@ -569,7 +571,7 @@ int basicTests(U32 seed, double compressibility)
|
||||
memset(&cParams, 0, sizeof(cParams));
|
||||
cParams.compressionLevel = LZ4F_compressionLevel_max();
|
||||
CHECK_V(cSizeLevelMax,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
|
||||
CNBuffer, dictSize,
|
||||
cdict, &cParams) );
|
||||
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeLevelMax);
|
||||
@ -584,7 +586,7 @@ int basicTests(U32 seed, double compressibility)
|
||||
cParams.frameInfo.blockMode = LZ4F_blockLinked;
|
||||
cParams.frameInfo.blockSizeID = LZ4F_max64KB;
|
||||
CHECK_V(cSizeContiguous,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, outCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, outCapacity,
|
||||
CNBuffer, inSize,
|
||||
cdict, &cParams) );
|
||||
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
|
||||
@ -620,7 +622,7 @@ int basicTests(U32 seed, double compressibility)
|
||||
cParams.frameInfo.blockMode = LZ4F_blockIndependent;
|
||||
cParams.frameInfo.blockSizeID = LZ4F_max64KB;
|
||||
CHECK_V(cSizeIndep,
|
||||
LZ4F_compressFrame_usingCDict(compressedBuffer, outCapacity,
|
||||
LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, outCapacity,
|
||||
CNBuffer, inSize,
|
||||
cdict, &cParams) );
|
||||
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
|
||||
@ -647,6 +649,7 @@ int basicTests(U32 seed, double compressibility)
|
||||
}
|
||||
|
||||
LZ4F_freeCDict(cdict);
|
||||
CHECK( LZ4F_freeCompressionContext(cctx) ); cctx = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -730,15 +733,17 @@ _output_error:
|
||||
|
||||
static void locateBuffDiff(const void* buff1, const void* buff2, size_t size, unsigned nonContiguous)
|
||||
{
|
||||
int p=0;
|
||||
size_t p=0;
|
||||
const BYTE* b1=(const BYTE*)buff1;
|
||||
const BYTE* b2=(const BYTE*)buff2;
|
||||
if (nonContiguous) {
|
||||
DISPLAY("Non-contiguous output test (%i bytes)\n", (int)size);
|
||||
return;
|
||||
}
|
||||
while (b1[p]==b2[p]) p++;
|
||||
DISPLAY("Error at pos %i/%i : %02X != %02X \n", p, (int)size, b1[p], b2[p]);
|
||||
while (p < size && b1[p]==b2[p]) p++;
|
||||
if (p != size) {
|
||||
DISPLAY("Error at pos %i/%i : %02X != %02X \n", (int)p, (int)size, b1[p], b2[p]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user