| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- #define LIZARD_FREQ_DIV 5
- FORCE_INLINE void Lizard_setLog2Prices(Lizard_stream_t* ctx)
- {
- ctx->log2LitSum = Lizard_highbit32(ctx->litSum+1);
- ctx->log2FlagSum = Lizard_highbit32(ctx->flagSum+1);
- }
- MEM_STATIC void Lizard_rescaleFreqs(Lizard_stream_t* ctx)
- {
- unsigned u;
- ctx->cachedLiterals = NULL;
- ctx->cachedPrice = ctx->cachedLitLength = 0;
-
- ctx->litPriceSum = 0;
- if (ctx->litSum == 0) {
- ctx->litSum = 2 * 256;
- ctx->flagSum = 2 * 256;
- for (u=0; u < 256; u++) {
- ctx->litFreq[u] = 2;
- ctx->flagFreq[u] = 2;
- }
- } else {
- ctx->litSum = 0;
- ctx->flagSum = 0;
- for (u=0; u < 256; u++) {
- ctx->litFreq[u] = 1 + (ctx->litFreq[u]>>LIZARD_FREQ_DIV);
- ctx->litSum += ctx->litFreq[u];
- ctx->flagFreq[u] = 1 + (ctx->flagFreq[u]>>LIZARD_FREQ_DIV);
- ctx->flagSum += ctx->flagFreq[u];
- }
- }
- Lizard_setLog2Prices(ctx);
- }
- FORCE_INLINE int Lizard_encodeSequence_LIZv1 (
- Lizard_stream_t* ctx,
- const BYTE** ip,
- const BYTE** anchor,
- size_t matchLength,
- const BYTE* const match)
- {
- U32 offset = (U32)(*ip - match);
- size_t length = (size_t)(*ip - *anchor);
- BYTE* token = (ctx->flagsPtr)++;
- if (length > 0 || offset < LIZARD_MAX_16BIT_OFFSET) {
- /* Encode Literal length */
- // if ((limitedOutputBuffer) && (ctx->literalsPtr > oend - length - LIZARD_LENGTH_SIZE_LIZv1(length) - WILDCOPYLENGTH)) { LIZARD_LOG_COMPRESS_LIZv1("encodeSequence overflow1\n"); return 1; } /* Check output limit */
- if (length >= MAX_SHORT_LITLEN)
- { size_t len;
- *token = MAX_SHORT_LITLEN;
- len = length - MAX_SHORT_LITLEN;
- if (len >= (1<<16)) { *(ctx->literalsPtr) = 255; MEM_writeLE24(ctx->literalsPtr+1, (U32)(len)); ctx->literalsPtr += 4; }
- else if (len >= 254) { *(ctx->literalsPtr) = 254; MEM_writeLE16(ctx->literalsPtr+1, (U16)(len)); ctx->literalsPtr += 3; }
- else *(ctx->literalsPtr)++ = (BYTE)len;
- }
- else *token = (BYTE)length;
- /* Copy Literals */
- Lizard_wildCopy(ctx->literalsPtr, *anchor, (ctx->literalsPtr) + length);
- #ifndef LIZARD_NO_HUFFMAN
- if (ctx->huffType) {
- ctx->litSum += (U32)length;
- ctx->litPriceSum += (U32)(length * ctx->log2LitSum);
- { U32 u;
- for (u=0; u < length; u++) {
- ctx->litPriceSum -= Lizard_highbit32(ctx->litFreq[ctx->literalsPtr[u]]+1);
- ctx->litFreq[ctx->literalsPtr[u]]++;
- } }
- }
- #endif
- ctx->literalsPtr += length;
- if (offset >= LIZARD_MAX_16BIT_OFFSET) {
- COMPLOG_CODEWORDS_LIZv1("T32+ literal=%u match=%u offset=%d\n", (U32)length, 0, 0);
- *token+=(1<<ML_RUN_BITS);
- #ifndef LIZARD_NO_HUFFMAN
- if (ctx->huffType) {
- ctx->flagFreq[*token]++;
- ctx->flagSum++;
- }
- #endif
- token = (ctx->flagsPtr)++;
- }
- }
- /* Encode Offset */
- if (offset >= LIZARD_MAX_16BIT_OFFSET) // 24-bit offset
- {
- if (matchLength < MM_LONGOFF) printf("ERROR matchLength=%d/%d\n", (int)matchLength, MM_LONGOFF), exit(1);
- // if ((limitedOutputBuffer) && (ctx->literalsPtr > oend - 8 /*LIZARD_LENGTH_SIZE_LIZv1(length)*/)) { LIZARD_LOG_COMPRESS_LIZv1("encodeSequence overflow2\n"); return 1; } /* Check output limit */
- if (matchLength - MM_LONGOFF >= LIZARD_LAST_LONG_OFF)
- {
- size_t len = matchLength - MM_LONGOFF - LIZARD_LAST_LONG_OFF;
- *token = LIZARD_LAST_LONG_OFF;
- if (len >= (1<<16)) { *(ctx->literalsPtr) = 255; MEM_writeLE24(ctx->literalsPtr+1, (U32)(len)); ctx->literalsPtr += 4; }
- else if (len >= 254) { *(ctx->literalsPtr) = 254; MEM_writeLE16(ctx->literalsPtr+1, (U16)(len)); ctx->literalsPtr += 3; }
- else *(ctx->literalsPtr)++ = (BYTE)len;
- COMPLOG_CODEWORDS_LIZv1("T31 literal=%u match=%u offset=%d\n", 0, (U32)matchLength, offset);
- }
- else
- {
- COMPLOG_CODEWORDS_LIZv1("T0-30 literal=%u match=%u offset=%d\n", 0, (U32)matchLength, offset);
- *token = (BYTE)(matchLength - MM_LONGOFF);
- }
- MEM_writeLE24(ctx->offset24Ptr, offset);
- ctx->offset24Ptr += 3;
- ctx->last_off = offset;
- ctx->off24pos = *ip;
- }
- else
- {
- COMPLOG_CODEWORDS_LIZv1("T32+ literal=%u match=%u offset=%d\n", (U32)length, (U32)matchLength, offset);
- if (offset == 0)
- {
- *token+=(1<<ML_RUN_BITS);
- }
- else
- {
- // it should never happen
- if (offset < 8) { printf("ERROR offset=%d\n", (int)offset); exit(1); }
- if (matchLength < MINMATCH) { printf("ERROR matchLength[%d] < MINMATCH offset=%d\n", (int)matchLength, (int)ctx->last_off); exit(1); }
-
- ctx->last_off = offset;
- MEM_writeLE16(ctx->offset16Ptr, (U16)ctx->last_off); ctx->offset16Ptr += 2;
- }
- /* Encode MatchLength */
- length = matchLength;
- // if ((limitedOutputBuffer) && (ctx->literalsPtr > oend - 5 /*LIZARD_LENGTH_SIZE_LIZv1(length)*/)) { LIZARD_LOG_COMPRESS_LIZv1("encodeSequence overflow2\n"); return 1; } /* Check output limit */
- if (length >= MAX_SHORT_MATCHLEN) {
- *token += (BYTE)(MAX_SHORT_MATCHLEN<<RUN_BITS_LIZv1);
- length -= MAX_SHORT_MATCHLEN;
- if (length >= (1<<16)) { *(ctx->literalsPtr) = 255; MEM_writeLE24(ctx->literalsPtr+1, (U32)(length)); ctx->literalsPtr += 4; }
- else if (length >= 254) { *(ctx->literalsPtr) = 254; MEM_writeLE16(ctx->literalsPtr+1, (U16)(length)); ctx->literalsPtr += 3; }
- else *(ctx->literalsPtr)++ = (BYTE)length;
- }
- else *token += (BYTE)(length<<RUN_BITS_LIZv1);
- }
- #ifndef LIZARD_NO_HUFFMAN
- if (ctx->huffType) {
- ctx->flagFreq[*token]++;
- ctx->flagSum++;
- Lizard_setLog2Prices(ctx);
- }
- #endif
- /* Prepare next loop */
- *ip += matchLength;
- *anchor = *ip;
- return 0;
- }
- FORCE_INLINE int Lizard_encodeLastLiterals_LIZv1 (
- Lizard_stream_t* ctx,
- const BYTE** ip,
- const BYTE** anchor)
- {
- size_t length = (int)(*ip - *anchor);
- (void)ctx;
- memcpy(ctx->literalsPtr, *anchor, length);
- ctx->literalsPtr += length;
- return 0;
- }
- #define LIZARD_PRICE_MULT 1
- #define LIZARD_GET_TOKEN_PRICE_LIZv1(token) (LIZARD_PRICE_MULT * (ctx->log2FlagSum - Lizard_highbit32(ctx->flagFreq[token]+1)))
- FORCE_INLINE size_t Lizard_get_price_LIZv1(Lizard_stream_t* const ctx, int rep, const BYTE *ip, const BYTE *off24pos, size_t litLength, U32 offset, size_t matchLength)
- {
- size_t price = 0;
- BYTE token = 0;
- #ifndef LIZARD_NO_HUFFMAN
- const BYTE* literals = ip - litLength;
- U32 u;
- if ((ctx->huffType) && (ctx->params.parserType != Lizard_parser_lowestPrice)) {
- if (ctx->cachedLiterals == literals && litLength >= ctx->cachedLitLength) {
- size_t const additional = litLength - ctx->cachedLitLength;
- const BYTE* literals2 = ctx->cachedLiterals + ctx->cachedLitLength;
- price = ctx->cachedPrice + LIZARD_PRICE_MULT * additional * ctx->log2LitSum;
- for (u=0; u < additional; u++)
- price -= LIZARD_PRICE_MULT * Lizard_highbit32(ctx->litFreq[literals2[u]]+1);
- ctx->cachedPrice = (U32)price;
- ctx->cachedLitLength = (U32)litLength;
- } else {
- price = LIZARD_PRICE_MULT * litLength * ctx->log2LitSum;
- for (u=0; u < litLength; u++)
- price -= LIZARD_PRICE_MULT * Lizard_highbit32(ctx->litFreq[literals[u]]+1);
- if (litLength >= 12) {
- ctx->cachedLiterals = literals;
- ctx->cachedPrice = (U32)price;
- ctx->cachedLitLength = (U32)litLength;
- }
- }
- }
- else
- price += 8*litLength; /* Copy Literals */
- #else
- price += 8*litLength; /* Copy Literals */
- (void)ip;
- (void)ctx;
- #endif
- (void)off24pos;
- (void)rep;
- if (litLength > 0 || offset < LIZARD_MAX_16BIT_OFFSET) {
- /* Encode Literal length */
- if (litLength >= MAX_SHORT_LITLEN)
- { size_t len = litLength - MAX_SHORT_LITLEN;
- token = MAX_SHORT_LITLEN;
- if (len >= (1<<16)) price += 32;
- else if (len >= 254) price += 24;
- else price += 8;
- }
- else token = (BYTE)litLength;
- if (offset >= LIZARD_MAX_16BIT_OFFSET) {
- token+=(1<<ML_RUN_BITS);
- if (ctx->huffType && ctx->params.parserType != Lizard_parser_lowestPrice)
- price += LIZARD_GET_TOKEN_PRICE_LIZv1(token);
- else
- price += 8;
- }
- }
- /* Encode Offset */
- if (offset >= LIZARD_MAX_16BIT_OFFSET) { // 24-bit offset
- if (matchLength < MM_LONGOFF) return LIZARD_MAX_PRICE; // error
- if (matchLength - MM_LONGOFF >= LIZARD_LAST_LONG_OFF) {
- size_t len = matchLength - MM_LONGOFF - LIZARD_LAST_LONG_OFF;
- token = LIZARD_LAST_LONG_OFF;
- if (len >= (1<<16)) price += 32;
- else if (len >= 254) price += 24;
- else price += 8;
- } else {
- token = (BYTE)(matchLength - MM_LONGOFF);
- }
- price += 24;
- } else {
- size_t length;
- if (offset == 0) {
- token+=(1<<ML_RUN_BITS);
- } else {
- if (offset < 8) return LIZARD_MAX_PRICE; // error
- if (matchLength < MINMATCH) return LIZARD_MAX_PRICE; // error
- price += 16;
- }
- /* Encode MatchLength */
- length = matchLength;
- if (length >= MAX_SHORT_MATCHLEN) {
- token += (BYTE)(MAX_SHORT_MATCHLEN<<RUN_BITS_LIZv1);
- length -= MAX_SHORT_MATCHLEN;
- if (length >= (1<<16)) price += 32;
- else if (length >= 254) price += 24;
- else price += 8;
- }
- else token += (BYTE)(length<<RUN_BITS_LIZv1);
- }
- if (offset > 0 || matchLength > 0) {
- int offset_load = Lizard_highbit32(offset);
- if (ctx->huffType) {
- price += ((offset_load>=20) ? ((offset_load-19)*4) : 0);
- price += 4 + (matchLength==1);
- } else {
- price += ((offset_load>=16) ? ((offset_load-15)*4) : 0);
- price += 6 + (matchLength==1);
- }
- if (ctx->huffType && ctx->params.parserType != Lizard_parser_lowestPrice)
- price += LIZARD_GET_TOKEN_PRICE_LIZv1(token);
- else
- price += 8;
- } else {
- if (ctx->huffType && ctx->params.parserType != Lizard_parser_lowestPrice)
- price += LIZARD_GET_TOKEN_PRICE_LIZv1(token); // 1=better ratio
- }
- return price;
- }
|