1
0
mirror of https://github.com/facebook/zstd.git synced 2025-03-07 01:10:04 +02:00
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

View File

@ -904,22 +904,23 @@ static size_t ZSTD_decompressLiterals(void* dst, size_t* maxDstSizePtr,
/** ZSTD_decodeLiteralsBlock
@return : nb of bytes read from src (< srcSize )*/
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;
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 */
if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
switch(*istart & 3)
{
/* compressed */
case 0:
{
size_t litSize = BLOCKSIZE;
const size_t readSize = ZSTD_decompressLiterals(dctx->litBuffer, &litSize, src, srcSize);
dctx->litPtr = dctx->litBuffer;
dctx->litBufSize = BLOCKSIZE;
dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
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);
memcpy(dctx->litBuffer, istart, litSize);
dctx->litBufSize = BLOCKSIZE;
dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
return litSize+3;
}
@ -945,7 +946,7 @@ size_t ZSTD_decodeLiteralsBlock(void* ctx,
if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
memset(dctx->litBuffer, istart[3], litSize);
dctx->litPtr = dctx->litBuffer;
dctx->litBufSize = BLOCKSIZE;
dctx->litBufSize = BLOCKSIZE+8;
dctx->litSize = litSize;
return 4;
}
@ -1144,7 +1145,7 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
static size_t ZSTD_execSequence(BYTE* op,
seq_t sequence,
const BYTE** litPtr, const BYTE* const litLimit,
const BYTE** litPtr, const BYTE* const litLimit_8,
BYTE* const base, BYTE* const oend)
{
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 */
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 (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 */
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;
size_t errorCode, dumpsLength;
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;
int nbSeq;
const BYTE* dumps;
@ -1261,7 +1262,7 @@ static size_t ZSTD_decompressSequences(
size_t oneSeqSize;
nbSeq--;
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;
op += oneSeqSize;
}

View File

@ -219,6 +219,7 @@ typedef struct {
void ZSTD_resetSeqStore(seqStore_t* ssPtr);
#define REPCODE_STARTVALUE 4
#define MLbits 7
#define LLbits 6
#define Offbits 5

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);
const BYTE* const istart = (const BYTE*)src;
const BYTE* ip = istart + 1;
const BYTE* ip = istart;
const BYTE* anchor = istart;
const BYTE* const iend = istart + srcSize;
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;
/* init */
ZSTD_resetSeqStore(seqStorePtr);
if (((ip-ctx->base) - ctx->dictLimit) < REPCODE_STARTVALUE) ip += REPCODE_STARTVALUE;
/* Main Search Loop */
/* Match Loop */
while (ip < ilimit)
{
const BYTE* match;
size_t matchLength = ZSTD_HC_insertAndFindBestMatch(ctx, ip, ilimit, &match, maxSearches);
if (!matchLength) { ip++; continue; }
/* save match */
/* repcode */
if (MEM_read32(ip) == MEM_read32(ip - offset_2))
/* store sequence */
{
size_t matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend);
size_t litLength = ip-anchor;
size_t offset = ip-match;
if (litLength) offset_2 = offset_1;
if (offset == offset_2) offset = 0;
size_t offset = offset_2;
offset_2 = offset_1;
offset_1 = ip-match;
ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, matchLength-MINMATCH);
ip += matchLength;
offset_1 = offset;
ZSTD_storeSeq(seqStorePtr, litLength, anchor, 0, matchLength);
ip += matchLength+MINMATCH;
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;
}
}
}