lizard_compress_lz4.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #define LIZARD_LENGTH_SIZE_LZ4(len) ((len >= (1<<16)+RUN_MASK_LZ4) ? 5 : ((len >= 254+RUN_MASK_LZ4) ? 3 : ((len >= RUN_MASK_LZ4) ? 1 : 0)))
  2. FORCE_INLINE int Lizard_encodeSequence_LZ4 (
  3. Lizard_stream_t* ctx,
  4. const BYTE** ip,
  5. const BYTE** anchor,
  6. size_t matchLength,
  7. const BYTE* const match)
  8. {
  9. size_t length = (size_t)(*ip - *anchor);
  10. BYTE* token = (ctx->flagsPtr)++;
  11. (void) ctx;
  12. COMPLOG_CODEWORDS_LZ4("literal : %u -- match : %u -- offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));
  13. /* Encode Literal length */
  14. // if (ctx->literalsPtr > ctx->literalsEnd - length - LIZARD_LENGTH_SIZE_LZ4(length) - 2 - WILDCOPYLENGTH) { LIZARD_LOG_COMPRESS_LZ4("encodeSequence overflow1\n"); return 1; } /* Check output limit */
  15. if (length >= RUN_MASK_LZ4)
  16. { size_t len = length - RUN_MASK_LZ4;
  17. *token = RUN_MASK_LZ4;
  18. if (len >= (1<<16)) { *(ctx->literalsPtr) = 255; MEM_writeLE24(ctx->literalsPtr+1, (U32)(len)); ctx->literalsPtr += 4; }
  19. else if (len >= 254) { *(ctx->literalsPtr) = 254; MEM_writeLE16(ctx->literalsPtr+1, (U16)(len)); ctx->literalsPtr += 3; }
  20. else *(ctx->literalsPtr)++ = (BYTE)len;
  21. }
  22. else *token = (BYTE)length;
  23. /* Copy Literals */
  24. if (length > 0) {
  25. Lizard_wildCopy(ctx->literalsPtr, *anchor, (ctx->literalsPtr) + length);
  26. #if 0 //def LIZARD_USE_HUFFMAN
  27. ctx->litSum += (U32)length;
  28. ctx->litPriceSum += (U32)(length * ctx->log2LitSum);
  29. { U32 u;
  30. for (u=0; u < length; u++) {
  31. ctx->litPriceSum -= Lizard_highbit32(ctx->litFreq[ctx->literalsPtr[u]]+1);
  32. ctx->litFreq[ctx->literalsPtr[u]]++;
  33. } }
  34. #endif
  35. ctx->literalsPtr += length;
  36. }
  37. /* Encode Offset */
  38. MEM_writeLE16(ctx->literalsPtr, (U16)(*ip-match));
  39. ctx->literalsPtr+=2;
  40. /* Encode MatchLength */
  41. length = matchLength - MINMATCH;
  42. // if (ctx->literalsPtr > ctx->literalsEnd - 5 /*LIZARD_LENGTH_SIZE_LZ4(length)*/) { LIZARD_LOG_COMPRESS_LZ4("encodeSequence overflow2\n"); return 1; } /* Check output limit */
  43. if (length >= ML_MASK_LZ4) {
  44. *token += (BYTE)(ML_MASK_LZ4<<RUN_BITS_LZ4);
  45. length -= ML_MASK_LZ4;
  46. if (length >= (1<<16)) { *(ctx->literalsPtr) = 255; MEM_writeLE24(ctx->literalsPtr+1, (U32)(length)); ctx->literalsPtr += 4; }
  47. else if (length >= 254) { *(ctx->literalsPtr) = 254; MEM_writeLE16(ctx->literalsPtr+1, (U16)(length)); ctx->literalsPtr += 3; }
  48. else *(ctx->literalsPtr)++ = (BYTE)length;
  49. }
  50. else *token += (BYTE)(length<<RUN_BITS_LZ4);
  51. #ifndef LIZARD_NO_HUFFMAN
  52. if (ctx->huffType) {
  53. ctx->flagFreq[*token]++;
  54. ctx->flagSum++;
  55. Lizard_setLog2Prices(ctx);
  56. }
  57. #endif
  58. /* Prepare next loop */
  59. *ip += matchLength;
  60. *anchor = *ip;
  61. return 0;
  62. }
  63. FORCE_INLINE int Lizard_encodeLastLiterals_LZ4 (
  64. Lizard_stream_t* ctx,
  65. const BYTE** ip,
  66. const BYTE** anchor)
  67. {
  68. size_t length = (int)(*ip - *anchor);
  69. (void)ctx;
  70. memcpy(ctx->literalsPtr, *anchor, length);
  71. ctx->literalsPtr += length;
  72. return 0;
  73. }
  74. #define LIZARD_GET_TOKEN_PRICE_LZ4(token) (ctx->log2FlagSum - Lizard_highbit32(ctx->flagFreq[token]+1))
  75. FORCE_INLINE size_t Lizard_get_price_LZ4(Lizard_stream_t* const ctx, const BYTE *ip, const size_t litLength, U32 offset, size_t matchLength)
  76. {
  77. size_t price = 0;
  78. BYTE token = 0;
  79. #if 0 //def LIZARD_USE_HUFFMAN
  80. const BYTE* literals = ip - litLength;
  81. U32 u;
  82. if (ctx->cachedLiterals == literals && litLength >= ctx->cachedLitLength) {
  83. size_t const additional = litLength - ctx->cachedLitLength;
  84. const BYTE* literals2 = ctx->cachedLiterals + ctx->cachedLitLength;
  85. price = ctx->cachedPrice + additional * ctx->log2LitSum;
  86. for (u=0; u < additional; u++)
  87. price -= Lizard_highbit32(ctx->litFreq[literals2[u]]+1);
  88. ctx->cachedPrice = (U32)price;
  89. ctx->cachedLitLength = (U32)litLength;
  90. } else {
  91. price = litLength * ctx->log2LitSum;
  92. for (u=0; u < litLength; u++)
  93. price -= Lizard_highbit32(ctx->litFreq[literals[u]]+1);
  94. if (litLength >= 12) {
  95. ctx->cachedLiterals = literals;
  96. ctx->cachedPrice = (U32)price;
  97. ctx->cachedLitLength = (U32)litLength;
  98. }
  99. }
  100. #else
  101. price += 8*litLength; /* Copy Literals */
  102. (void)ip;
  103. (void)ctx;
  104. #endif
  105. /* Encode Literal length */
  106. if (litLength >= RUN_MASK_LZ4) {
  107. size_t len = litLength - RUN_MASK_LZ4;
  108. token = RUN_MASK_LZ4;
  109. if (len >= (1<<16)) price += 32;
  110. else if (len >= 254) price += 24;
  111. else price += 8;
  112. }
  113. else token = (BYTE)litLength;
  114. /* Encode MatchLength */
  115. if (offset) {
  116. size_t length;
  117. price += 16; /* Encode Offset */
  118. if (offset < 8) return LIZARD_MAX_PRICE; // error
  119. if (matchLength < MINMATCH) return LIZARD_MAX_PRICE; // error
  120. length = matchLength - MINMATCH;
  121. if (length >= ML_MASK_LZ4) {
  122. token += (BYTE)(ML_MASK_LZ4<<RUN_BITS_LZ4);
  123. length -= ML_MASK_LZ4;
  124. if (length >= (1<<16)) price += 32;
  125. else if (length >= 254) price += 24;
  126. else price += 8;
  127. }
  128. else token += (BYTE)(length<<RUN_BITS_LZ4);
  129. }
  130. if (ctx->huffType) {
  131. if (offset > 0 || matchLength > 0) price += 2;
  132. price += LIZARD_GET_TOKEN_PRICE_LZ4(token);
  133. } else {
  134. price += 8; // token
  135. }
  136. return price;
  137. }