diff --git a/lib/zstd_compress.c b/lib/zstd_compress.c index 4858831e3..50979ce58 100644 --- a/lib/zstd_compress.c +++ b/lib/zstd_compress.c @@ -147,13 +147,14 @@ void ZSTD_validateParams(ZSTD_parameters* params) const U32 btPlus = (params->strategy == ZSTD_btlazy2) || (params->strategy == ZSTD_btopt); const U32 searchLengthMax = (params->strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1; const U32 searchLengthMin = (params->strategy == ZSTD_btopt) ? ZSTD_SEARCHLENGTH_MIN : ZSTD_SEARCHLENGTH_MIN+1; + const U32 hashLog3Min = (params->strategy == ZSTD_btopt) ? ZSTD_HASHLOG3_MIN : 0; /* validate params */ if (MEM_32bits()) if (params->windowLog > 25) params->windowLog = 25; /* 32 bits mode cannot flush > 24 bits */ CLAMP(params->windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX); CLAMP(params->contentLog, ZSTD_CONTENTLOG_MIN, ZSTD_CONTENTLOG_MAX); CLAMP(params->hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX); - CLAMP(params->hashLog3, ZSTD_HASHLOG3_MIN, ZSTD_HASHLOG3_MAX); + CLAMP(params->hashLog3, hashLog3Min, ZSTD_HASHLOG3_MAX); CLAMP(params->searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX); CLAMP(params->searchLength, searchLengthMin, searchLengthMax); CLAMP(params->targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX); @@ -164,8 +165,8 @@ void ZSTD_validateParams(ZSTD_parameters* params) U32 srcLog = ZSTD_highbit((U32)(params->srcSize)-1) + 1; if (params->windowLog > srcLog) params->windowLog = srcLog; } - if (params->windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) params->windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ - if (params->contentLog > params->windowLog+btPlus) params->contentLog = params->windowLog+btPlus; /* <= ZSTD_CONTENTLOG_MAX */ + if (params->windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) params->windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */ + if (params->contentLog > params->windowLog+btPlus) params->contentLog = params->windowLog+btPlus; /* <= ZSTD_CONTENTLOG_MAX */ } @@ -174,10 +175,14 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, { /* note : params considered validated here */ const size_t blockSize = MIN(BLOCKSIZE, (size_t)1 << params.windowLog); /* reserve table memory */ - const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog; + const U32 contentLog = (params.strategy == ZSTD_fast) ? 1 : params.contentLog; + const U32 divider = (params.searchLength==3) ? 3 : 4; + const size_t maxNbSeq = blockSize / divider; + const size_t tokenSpace = blockSize + 8*maxNbSeq; const size_t tableSpace = ((1 << contentLog) + (1 << params.hashLog) + (1 << params.hashLog3)) * sizeof(U32); - const size_t neededSpace = tableSpace + (256*sizeof(U32)) + (3*blockSize) - + ((params.strategy == ZSTD_btopt) ? ((1<workSpaceSize < neededSpace) { free(zc->workSpace); @@ -204,13 +209,13 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc, zc->blockSize = blockSize; zc->seqStore.offsetStart = (U32*) (zc->seqStore.buffer); - zc->seqStore.offCodeStart = (BYTE*) (zc->seqStore.offsetStart) + blockSize; - zc->seqStore.litStart = zc->seqStore.offCodeStart + (blockSize>>2); + zc->seqStore.offCodeStart = (BYTE*) (zc->seqStore.offsetStart + maxNbSeq); + zc->seqStore.litStart = zc->seqStore.offCodeStart + maxNbSeq; zc->seqStore.litLengthStart = zc->seqStore.litStart + blockSize; - zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + (blockSize>>2); - zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + (blockSize>>2); + zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + maxNbSeq; + zc->seqStore.dumpsStart = zc->seqStore.matchLengthStart + maxNbSeq; if (params.strategy == ZSTD_btopt) { - zc->seqStore.litFreq = (U32*)((void*)(zc->seqStore.dumpsStart + (blockSize>>2))); + zc->seqStore.litFreq = (U32*)((void*)(zc->seqStore.dumpsStart + maxNbSeq)); zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (1<seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (1<