This commit is contained in:
Yann Collet
2015-10-23 19:25:06 +01:00
parent 563c6ba8cc
commit ed0a781246
3 changed files with 42 additions and 22 deletions
+10 -9
View File
@@ -904,22 +904,23 @@ static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,
/** ZSTD_decodeLiteralsBlock /** ZSTD_decodeLiteralsBlock
@return : nb of bytes read from src (< srcSize )*/ @return : nb of bytes read from src (< srcSize )*/
size_t ZSTD_decodeLiteralsBlock(void* ctx, size_t ZSTD_decodeLiteralsBlock(void* ctx,
const void* src, size_t srcSize) const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
{ {
ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx; ZSTD_DCtx* dctx = (ZSTD_DCtx*)ctx;
const BYTE* const istart = (const BYTE* const)src; const BYTE* const istart = (const BYTE*) src;
/* any compressed block with literals segment must be at least this size */ /* any compressed block with literals segment must be at least this size */
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected); if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
switch(*istart & 3) switch(*istart & 3)
{ {
/* compressed */
case 0: case 0:
{ {
size_t litSize = BLOCKSIZE; size_t litSize = BLOCKSIZE;
const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize); const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);
dctx->litPtr = dctx->litBuffer; dctx->litPtr = dctx->litBuffer;
dctx->litBufSize = BLOCKSIZE; dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize; dctx->litSize = litSize;
return readSize; /* works if it's an error too */ return readSize; /* works if it's an error too */
} }
@@ -930,7 +931,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
{ {
if (litSize > srcSize-3) return ERROR(corruption_detected); if (litSize > srcSize-3) return ERROR(corruption_detected);
memcpy(dctx->litBuffer, istart, litSize); memcpy(dctx->litBuffer, istart, litSize);
dctx->litBufSize = BLOCKSIZE; dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize; dctx->litSize = litSize;
return litSize+3; return litSize+3;
} }
@@ -945,7 +946,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
if (litSize > BLOCKSIZE) return ERROR(corruption_detected); if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
memset(dctx->litBuffer, istart[3], litSize); memset(dctx->litBuffer, istart[3], litSize);
dctx->litPtr = dctx->litBuffer; dctx->litPtr = dctx->litBuffer;
dctx->litBufSize = BLOCKSIZE; dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize; dctx->litSize = litSize;
return 4; return 4;
} }
@@ -1144,7 +1145,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
static size_t ZSTD_execSequence(BYTE* op, static size_t ZSTD_execSequence(BYTE* op,
seq_t sequence, seq_t sequence,
const BYTE** litPtr, const BYTE* const litLimit, const BYTE** litPtr, const BYTE* const litLimit_8,
BYTE* const base, BYTE* const oend) BYTE* const base, BYTE* const oend)
{ {
static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */ static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
@@ -1158,7 +1159,7 @@ static size_t ZSTD_execSequence(BYTE* op,
/* check */ /* check */
if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
if (litEnd > litLimit-8) return ERROR(corruption_detected); /* overRead beyond lit buffer */ if (litEnd > litLimit_8) return ERROR(corruption_detected); /* overRead beyond lit buffer */
/* copy Literals */ /* copy Literals */
ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ ZSTD_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
@@ -1224,7 +1225,7 @@ static size_t ZSTD_decompressSequences(
BYTE* const oend = ostart + maxDstSize; BYTE* const oend = ostart + maxDstSize;
size_t errorCode, dumpsLength; size_t errorCode, dumpsLength;
const BYTE* litPtr = dctx->litPtr; const BYTE* litPtr = dctx->litPtr;
const BYTE* const litMax = litPtr + dctx->litBufSize; const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
const BYTE* const litEnd = litPtr + dctx->litSize; const BYTE* const litEnd = litPtr + dctx->litSize;
int nbSeq; int nbSeq;
const BYTE* dumps; const BYTE* dumps;
@@ -1261,7 +1262,7 @@ static size_t ZSTD_decompressSequences(
size_t oneSeqSize; size_t oneSeqSize;
nbSeq--; nbSeq--;
ZSTD_decodeSequence(&sequence, &seqState); ZSTD_decodeSequence(&sequence, &seqState);
oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litMax, base, oend); oneSeqSize = ZSTD_execSequence(op, sequence, &litPtr, litLimit_8, base, oend);
if (ZSTD_isError(oneSeqSize)) return oneSeqSize; if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
op += oneSeqSize; op += oneSeqSize;
} }
+1
View File
@@ -219,6 +219,7 @@ typedef struct {
void ZSTD_resetSeqStore(seqStore_t* ssPtr); void ZSTD_resetSeqStore(seqStore_t* ssPtr);
#define REPCODE_STARTVALUE 4
#define MLbits 7 #define MLbits 7
#define LLbits 6 #define LLbits 6
#define Offbits 5 #define Offbits 5
+31 -13
View File
@@ -295,34 +295,52 @@ static size_t ZSTD_HC_compressBlock(ZSTD_HC_CCtx* ctx, void* dst, size_t maxDstS
{ {
seqStore_t* seqStorePtr = &(ctx->seqStore); seqStore_t* seqStorePtr = &(ctx->seqStore);
const BYTE* const istart = (const BYTE*)src; const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart + 1; const BYTE* ip = istart;
const BYTE* anchor = istart; const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize; const BYTE* const iend = istart + srcSize;
const BYTE* const ilimit = iend - 8; const BYTE* const ilimit = iend - 8;
size_t offset_2=4, offset_1=4; size_t offset_2=REPCODE_STARTVALUE, offset_1=REPCODE_STARTVALUE;
const U32 maxSearches = 1 << ctx->compressionLevel; const U32 maxSearches = 1 << ctx->compressionLevel;
/* init */ /* init */
ZSTD_resetSeqStore(seqStorePtr); ZSTD_resetSeqStore(seqStorePtr);
if (((ip-ctx->base) - ctx->dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
/* Main Search Loop */ /* Match Loop */
while (ip < ilimit) while (ip < ilimit)
{ {
const BYTE* match; /* repcode */
size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, ilimit, &match, maxSearches); if (MEM_read32(ip) == MEM_read32(ip - offset_2))
if (!matchLength) { ip++; continue; } /* store sequence */
/* save match */
{ {
size_t matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend);
size_t litLength = ip-anchor; size_t litLength = ip-anchor;
size_t offset = ip-match; size_t offset = offset_2;
if (litLength) offset_2 = offset_1;
if (offset == offset_2) offset = 0;
offset_2 = offset_1; offset_2 = offset_1;
offset_1 = ip-match; offset_1 = offset;
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH); ZSTD_storeSeq(seqStorePtr, litLength, anchor, 0, matchLength);
ip += matchLength; ip += matchLength+MINMATCH;
anchor = ip; anchor = ip;
continue;
}
/* search */
{
const BYTE* match;
size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, iend, &match, maxSearches);
if (!matchLength) { ip++; offset_2 = offset_1; continue; }
/* store sequence */
{
size_t litLength = ip-anchor;
size_t offset = ip-match;
if (offset == offset_2) offset = 0;
offset_2 = offset_1;
offset_1 = ip-match;
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH);
ip += matchLength;
anchor = ip;
}
} }
} }