in lz4.cpp [1707:1783]
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* const streamPtr = &LZ4_stream->internal_donotuse;
const char* dictEnd = streamPtr->dictSize ? (const char*)streamPtr->dictionary + streamPtr->dictSize : NULL;
DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i, dictSize=%u)", inputSize, streamPtr->dictSize);
LZ4_renormDictT(streamPtr, inputSize); /* fix index overflow */
if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT;
if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX;
/* invalidate tiny dictionaries */
if ( (streamPtr->dictSize < 4) /* tiny dictionary : not enough for a hash */
&& (dictEnd != source) /* prefix mode */
&& (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */
&& (streamPtr->dictCtx == NULL) /* usingDictCtx */
) {
DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary);
/* remove dictionary existence from history, to employ faster prefix mode */
streamPtr->dictSize = 0;
streamPtr->dictionary = (const BYTE*)source;
dictEnd = source;
}
/* Check overlapping input/dictionary space */
{ const char* const sourceEnd = source + inputSize;
if ((sourceEnd > (const char*)streamPtr->dictionary) && (sourceEnd < dictEnd)) {
streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
streamPtr->dictionary = (const BYTE*)dictEnd - streamPtr->dictSize;
}
}
/* prefix mode : source data follows dictionary */
if (dictEnd == source) {
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration);
else
return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration);
}
/* external dictionary mode */
{ int result;
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 into one table.
*/
LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(*streamPtr));
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
} else {
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration);
}
} else { /* small data <= 4 KB */
if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) {
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration);
} else {
result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
}
}
streamPtr->dictionary = (const BYTE*)source;
streamPtr->dictSize = (U32)inputSize;
return result;
}
}