| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- #define LIZARD_FAST_MIN_OFFSET 8
- #define LIZARD_FAST_LONGOFF_MM 0 /* not used with offsets > 1<<16 */
- /**************************************
- * Hash Functions
- **************************************/
- static size_t Lizard_hashPosition(const void* p)
- {
- if (MEM_64bits())
- return Lizard_hash5Ptr(p, LIZARD_HASHLOG_LZ4);
- return Lizard_hash4Ptr(p, LIZARD_HASHLOG_LZ4);
- }
- static void Lizard_putPositionOnHash(const BYTE* p, size_t h, U32* hashTable, const BYTE* srcBase)
- {
- hashTable[h] = (U32)(p-srcBase);
- }
- static void Lizard_putPosition(const BYTE* p, U32* hashTable, const BYTE* srcBase)
- {
- size_t const h = Lizard_hashPosition(p);
- Lizard_putPositionOnHash(p, h, hashTable, srcBase);
- }
- static U32 Lizard_getPositionOnHash(size_t h, U32* hashTable)
- {
- return hashTable[h];
- }
- static U32 Lizard_getPosition(const BYTE* p, U32* hashTable)
- {
- size_t const h = Lizard_hashPosition(p);
- return Lizard_getPositionOnHash(h, hashTable);
- }
- static const U32 Lizard_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */
- static const U32 Lizard_minLength = (MFLIMIT+1);
- FORCE_INLINE int Lizard_compress_fast(
- Lizard_stream_t* const ctx,
- const BYTE* ip,
- const BYTE* const iend)
- {
- const U32 acceleration = 1;
- const BYTE* base = ctx->base;
- const U32 dictLimit = ctx->dictLimit;
- const BYTE* const lowPrefixPtr = base + dictLimit;
- const BYTE* const dictBase = ctx->dictBase;
- const BYTE* const dictEnd = dictBase + dictLimit;
- const BYTE* const mflimit = iend - MFLIMIT;
- const BYTE* const matchlimit = iend - LASTLITERALS;
- const BYTE* anchor = ip;
- size_t forwardH, matchIndex;
- const U32 maxDistance = (1 << ctx->params.windowLog) - 1;
- const U32 lowLimit = (ctx->lowLimit + maxDistance >= (U32)(ip - base)) ? ctx->lowLimit : (U32)(ip - base) - maxDistance;
- /* Init conditions */
- if ((U32)(iend-ip) > (U32)LIZARD_MAX_INPUT_SIZE) goto _output_error; /* Unsupported inputSize, too large (or negative) */
- if ((U32)(iend-ip) < Lizard_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
- /* First Byte */
- Lizard_putPosition(ip, ctx->hashTable, base);
- ip++; forwardH = Lizard_hashPosition(ip);
- /* Main Loop */
- for ( ; ; ) {
- const BYTE* match;
- size_t matchLength;
- /* Find a match */
- { const BYTE* forwardIp = ip;
- unsigned step = 1;
- unsigned searchMatchNb = acceleration << Lizard_skipTrigger;
- while (1) {
- size_t const h = forwardH;
- ip = forwardIp;
- forwardIp += step;
- step = (searchMatchNb++ >> Lizard_skipTrigger);
- if (unlikely(forwardIp > mflimit)) goto _last_literals;
- matchIndex = Lizard_getPositionOnHash(h, ctx->hashTable);
- forwardH = Lizard_hashPosition(forwardIp);
- Lizard_putPositionOnHash(ip, h, ctx->hashTable, base);
- if ((matchIndex < lowLimit) || (matchIndex >= (U32)(ip - base)) || (base + matchIndex + maxDistance < ip)) continue;
- if (matchIndex >= dictLimit) {
- match = base + matchIndex;
- #if LIZARD_FAST_MIN_OFFSET > 0
- if ((U32)(ip - match) >= LIZARD_FAST_MIN_OFFSET)
- #endif
- if (MEM_read32(match) == MEM_read32(ip))
- {
- int back = 0;
- matchLength = Lizard_count(ip+MINMATCH, match+MINMATCH, matchlimit);
- while ((ip+back > anchor) && (match+back > lowPrefixPtr) && (ip[back-1] == match[back-1])) back--;
- matchLength -= back;
- #if LIZARD_FAST_LONGOFF_MM > 0
- if ((matchLength >= LIZARD_FAST_LONGOFF_MM) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
- #endif
- {
- ip += back;
- match += back;
- break;
- }
- }
- } else {
- match = dictBase + matchIndex;
- #if LIZARD_FAST_MIN_OFFSET > 0
- if ((U32)(ip - (base + matchIndex)) >= LIZARD_FAST_MIN_OFFSET)
- #endif
- if ((U32)((dictLimit-1) - matchIndex) >= 3) /* intentional overflow */
- if (MEM_read32(match) == MEM_read32(ip)) {
- const U32 newLowLimit = (lowLimit + maxDistance >= (U32)(ip-base)) ? lowLimit : (U32)(ip - base) - maxDistance;
- int back = 0;
- matchLength = Lizard_count_2segments(ip+MINMATCH, match+MINMATCH, matchlimit, dictEnd, lowPrefixPtr);
- while ((ip+back > anchor) && (matchIndex+back > newLowLimit) && (ip[back-1] == match[back-1])) back--;
- matchLength -= back;
- match = base + matchIndex + back;
- #if LIZARD_FAST_LONGOFF_MM > 0
- if ((matchLength >= LIZARD_FAST_LONGOFF_MM) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
- #endif
- {
- ip += back;
- break;
- }
- }
- }
- } // while (1)
- }
- _next_match:
- if (Lizard_encodeSequence_LZ4(ctx, &ip, &anchor, matchLength+MINMATCH, match)) goto _output_error;
-
- /* Test end of chunk */
- if (ip > mflimit) break;
- /* Fill table */
- Lizard_putPosition(ip-2, ctx->hashTable, base);
- /* Test next position */
- matchIndex = Lizard_getPosition(ip, ctx->hashTable);
- Lizard_putPosition(ip, ctx->hashTable, base);
- if ((matchIndex >= lowLimit) && (matchIndex < (U32)(ip - base)) && (base + matchIndex + maxDistance >= ip))
- {
- if (matchIndex >= dictLimit) {
- match = base + matchIndex;
- #if LIZARD_FAST_MIN_OFFSET > 0
- if ((U32)(ip - match) >= LIZARD_FAST_MIN_OFFSET)
- #endif
- if (MEM_read32(match) == MEM_read32(ip))
- {
- matchLength = Lizard_count(ip+MINMATCH, match+MINMATCH, matchlimit);
- #if LIZARD_FAST_LONGOFF_MM > 0
- if ((matchLength >= LIZARD_FAST_LONGOFF_MM) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
- #endif
- goto _next_match;
- }
- } else {
- match = dictBase + matchIndex;
- #if LIZARD_FAST_MIN_OFFSET > 0
- if ((U32)(ip - (base + matchIndex)) >= LIZARD_FAST_MIN_OFFSET)
- #endif
- if ((U32)((dictLimit-1) - matchIndex) >= 3) /* intentional overflow */
- if (MEM_read32(match) == MEM_read32(ip)) {
- matchLength = Lizard_count_2segments(ip+MINMATCH, match+MINMATCH, matchlimit, dictEnd, lowPrefixPtr);
- match = base + matchIndex;
- #if LIZARD_FAST_LONGOFF_MM > 0
- if ((matchLength >= LIZARD_FAST_LONGOFF_MM) || ((U32)(ip - match) < LIZARD_MAX_16BIT_OFFSET))
- #endif
- goto _next_match;
- }
- }
- }
- /* Prepare next loop */
- forwardH = Lizard_hashPosition(++ip);
- }
- _last_literals:
- /* Encode Last Literals */
- ip = iend;
- if (Lizard_encodeLastLiterals_LZ4(ctx, &ip, &anchor)) goto _output_error;
- /* End */
- return 1;
- _output_error:
- return 0;
- }
|