mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 00:07:09 -06:00
major Lizard fixes
- changed to real Lizard code v1.0 (I used LZ5 v2.0) - add Lizard file handling, so '.liz' files can be used in windows - changed CompressDialog (Lizard has 4 entries in the methods now) - added Lizard icon
This commit is contained in:
163
C/lizard/lizard_decompress_lz4.h
Normal file
163
C/lizard/lizard_decompress_lz4.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*! Lizard_decompress_LZ4() :
|
||||
* This generic decompression function cover all use cases.
|
||||
* It shall be instantiated several times, using different sets of directives
|
||||
* Note that it is important this generic function is really inlined,
|
||||
* in order to remove useless branches during compilation optimization.
|
||||
*/
|
||||
FORCE_INLINE int Lizard_decompress_LZ4(
|
||||
Lizard_dstream_t* ctx,
|
||||
BYTE* const dest,
|
||||
int outputSize, /* this value is the max size of Output Buffer. */
|
||||
|
||||
int partialDecoding, /* full, partial */
|
||||
int targetOutputSize, /* only used if partialDecoding==partial */
|
||||
int dict, /* noDict, withPrefix64k, usingExtDict */
|
||||
const BYTE* const lowPrefix, /* == dest if dict == noDict */
|
||||
const BYTE* const dictStart, /* only if dict==usingExtDict */
|
||||
const size_t dictSize, /* note : = 0 if noDict */
|
||||
int compressionLevel
|
||||
)
|
||||
{
|
||||
/* Local Variables */
|
||||
int inputSize = (int)(ctx->flagsEnd - ctx->flagsPtr);
|
||||
const BYTE* const blockBase = ctx->flagsPtr;
|
||||
const BYTE* const iend = ctx->literalsEnd;
|
||||
BYTE* op = dest;
|
||||
BYTE* const oend = op + outputSize;
|
||||
BYTE* cpy = NULL;
|
||||
BYTE* oexit = op + targetOutputSize;
|
||||
const BYTE* const lowLimit = lowPrefix - dictSize;
|
||||
const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
|
||||
|
||||
const int checkOffset = (dictSize < (int)(LIZARD_DICT_SIZE));
|
||||
|
||||
intptr_t length = 0;
|
||||
(void)compressionLevel;
|
||||
|
||||
/* Special cases */
|
||||
if (unlikely(outputSize==0)) return ((inputSize==1) && (*ctx->flagsPtr==0)) ? 0 : -1; /* Empty output buffer */
|
||||
|
||||
/* Main Loop : decode sequences */
|
||||
while (ctx->flagsPtr < ctx->flagsEnd) {
|
||||
unsigned token;
|
||||
const BYTE* match;
|
||||
size_t offset;
|
||||
|
||||
/* get literal length */
|
||||
token = *ctx->flagsPtr++;
|
||||
if ((length=(token & RUN_MASK_LZ4)) == RUN_MASK_LZ4) {
|
||||
if (unlikely(ctx->literalsPtr > iend - 5)) { LIZARD_LOG_DECOMPRESS_LZ4("0"); goto _output_error; }
|
||||
length = *ctx->literalsPtr;
|
||||
if unlikely(length >= 254) {
|
||||
if (length == 254) {
|
||||
length = MEM_readLE16(ctx->literalsPtr+1);
|
||||
ctx->literalsPtr += 2;
|
||||
} else {
|
||||
length = MEM_readLE24(ctx->literalsPtr+1);
|
||||
ctx->literalsPtr += 3;
|
||||
}
|
||||
}
|
||||
length += RUN_MASK_LZ4;
|
||||
ctx->literalsPtr++;
|
||||
if (unlikely((size_t)(op+length)<(size_t)(op))) { LIZARD_LOG_DECOMPRESS_LZ4("1"); goto _output_error; } /* overflow detection */
|
||||
if (unlikely((size_t)(ctx->literalsPtr+length)<(size_t)(ctx->literalsPtr))) { LIZARD_LOG_DECOMPRESS_LZ4("2"); goto _output_error; } /* overflow detection */
|
||||
}
|
||||
|
||||
/* copy literals */
|
||||
cpy = op + length;
|
||||
if (unlikely(cpy > oend - WILDCOPYLENGTH || ctx->literalsPtr + length > iend - (2 + WILDCOPYLENGTH))) { LIZARD_LOG_DECOMPRESS_LZ4("offset outside buffers\n"); goto _output_error; } /* Error : offset outside buffers */
|
||||
|
||||
#if 1
|
||||
Lizard_wildCopy16(op, ctx->literalsPtr, cpy);
|
||||
op = cpy;
|
||||
ctx->literalsPtr += length;
|
||||
#else
|
||||
Lizard_copy8(op, ctx->literalsPtr);
|
||||
Lizard_copy8(op+8, ctx->literalsPtr+8);
|
||||
if (length > 16)
|
||||
Lizard_wildCopy16(op + 16, ctx->literalsPtr + 16, cpy);
|
||||
op = cpy;
|
||||
ctx->literalsPtr += length;
|
||||
#endif
|
||||
if ((partialDecoding) && (op >= oexit)) return (int) (op-dest);
|
||||
|
||||
/* get offset */
|
||||
offset = MEM_readLE16(ctx->literalsPtr);
|
||||
ctx->literalsPtr += 2;
|
||||
|
||||
match = op - offset;
|
||||
if ((checkOffset) && (unlikely(match < lowLimit))) { LIZARD_LOG_DECOMPRESS_LZ4("lowPrefix[%p]-dictSize[%d]=lowLimit[%p] match[%p]=op[%p]-offset[%d]\n", lowPrefix, (int)dictSize, lowLimit, match, op, (int)offset); goto _output_error; } /* Error : offset outside buffers */
|
||||
|
||||
/* get matchlength */
|
||||
length = token >> RUN_BITS_LZ4;
|
||||
if (length == ML_MASK_LZ4) {
|
||||
if (unlikely(ctx->literalsPtr > iend - 5)) { LIZARD_LOG_DECOMPRESS_LZ4("4"); goto _output_error; }
|
||||
length = *ctx->literalsPtr;
|
||||
if unlikely(length >= 254) {
|
||||
if (length == 254) {
|
||||
length = MEM_readLE16(ctx->literalsPtr+1);
|
||||
ctx->literalsPtr += 2;
|
||||
} else {
|
||||
length = MEM_readLE24(ctx->literalsPtr+1);
|
||||
ctx->literalsPtr += 3;
|
||||
}
|
||||
}
|
||||
length += ML_MASK_LZ4;
|
||||
ctx->literalsPtr++;
|
||||
if (unlikely((size_t)(op+length)<(size_t)(op))) { LIZARD_LOG_DECOMPRESS_LZ4("5"); goto _output_error; } /* overflow detection */
|
||||
}
|
||||
length += MINMATCH;
|
||||
|
||||
/* check external dictionary */
|
||||
if ((dict==usingExtDict) && (match < lowPrefix)) {
|
||||
if (unlikely(op + length > oend - WILDCOPYLENGTH)) { LIZARD_LOG_DECOMPRESS_LZ4("6"); goto _output_error; } /* doesn't respect parsing restriction */
|
||||
|
||||
if (length <= (intptr_t)(lowPrefix - match)) {
|
||||
/* match can be copied as a single segment from external dictionary */
|
||||
memmove(op, dictEnd - (lowPrefix-match), length);
|
||||
op += length;
|
||||
} else {
|
||||
/* match encompass external dictionary and current block */
|
||||
size_t const copySize = (size_t)(lowPrefix-match);
|
||||
size_t const restSize = length - copySize;
|
||||
memcpy(op, dictEnd - copySize, copySize);
|
||||
op += copySize;
|
||||
if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */
|
||||
BYTE* const endOfMatch = op + restSize;
|
||||
const BYTE* copyFrom = lowPrefix;
|
||||
while (op < endOfMatch) *op++ = *copyFrom++;
|
||||
} else {
|
||||
memcpy(op, lowPrefix, restSize);
|
||||
op += restSize;
|
||||
} }
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy match within block */
|
||||
cpy = op + length;
|
||||
if (unlikely(cpy > oend - WILDCOPYLENGTH)) { LIZARD_LOG_DECOMPRESS_LZ4("1match=%p lowLimit=%p\n", match, lowLimit); goto _output_error; } /* Error : offset outside buffers */
|
||||
Lizard_copy8(op, match);
|
||||
Lizard_copy8(op+8, match+8);
|
||||
if (length > 16)
|
||||
Lizard_wildCopy16(op + 16, match + 16, cpy);
|
||||
op = cpy;
|
||||
if ((partialDecoding) && (op >= oexit)) return (int) (op-dest);
|
||||
}
|
||||
|
||||
/* last literals */
|
||||
length = ctx->literalsEnd - ctx->literalsPtr;
|
||||
cpy = op + length;
|
||||
if ((ctx->literalsPtr+length != iend) || (cpy > oend)) { LIZARD_LOG_DECOMPRESS_LZ4("9"); goto _output_error; } /* Error : input must be consumed */
|
||||
memcpy(op, ctx->literalsPtr, length);
|
||||
ctx->literalsPtr += length;
|
||||
op += length;
|
||||
|
||||
/* end of decoding */
|
||||
return (int) (op-dest); /* Nb of output bytes decoded */
|
||||
|
||||
/* Overflow error detected */
|
||||
_output_error:
|
||||
LIZARD_LOG_DECOMPRESS_LZ4("_output_error=%d ctx->flagsPtr=%p blockBase=%p\n", (int) (-(ctx->flagsPtr-blockBase))-1, ctx->flagsPtr, blockBase);
|
||||
LIZARD_LOG_DECOMPRESS_LZ4("cpy=%p oend=%p ctx->literalsPtr+length[%d]=%p iend=%p\n", cpy, oend, (int)length, ctx->literalsPtr+length, iend);
|
||||
return (int) (-(ctx->flagsPtr-blockBase))-1;
|
||||
}
|
||||
Reference in New Issue
Block a user