Home | History | Annotate | Line # | Download | only in zopfli
lz77.c revision 1.1.1.1.12.2
      1  1.1.1.1.12.2  snj /*
      2  1.1.1.1.12.2  snj Copyright 2011 Google Inc. All Rights Reserved.
      3  1.1.1.1.12.2  snj 
      4  1.1.1.1.12.2  snj Licensed under the Apache License, Version 2.0 (the "License");
      5  1.1.1.1.12.2  snj you may not use this file except in compliance with the License.
      6  1.1.1.1.12.2  snj You may obtain a copy of the License at
      7  1.1.1.1.12.2  snj 
      8  1.1.1.1.12.2  snj     http://www.apache.org/licenses/LICENSE-2.0
      9  1.1.1.1.12.2  snj 
     10  1.1.1.1.12.2  snj Unless required by applicable law or agreed to in writing, software
     11  1.1.1.1.12.2  snj distributed under the License is distributed on an "AS IS" BASIS,
     12  1.1.1.1.12.2  snj WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  1.1.1.1.12.2  snj See the License for the specific language governing permissions and
     14  1.1.1.1.12.2  snj limitations under the License.
     15  1.1.1.1.12.2  snj 
     16  1.1.1.1.12.2  snj Author: lode.vandevenne (at) gmail.com (Lode Vandevenne)
     17  1.1.1.1.12.2  snj Author: jyrki.alakuijala (at) gmail.com (Jyrki Alakuijala)
     18  1.1.1.1.12.2  snj */
     19  1.1.1.1.12.2  snj 
     20  1.1.1.1.12.2  snj #include "lz77.h"
     21  1.1.1.1.12.2  snj #include "util.h"
     22  1.1.1.1.12.2  snj 
     23  1.1.1.1.12.2  snj #include <assert.h>
     24  1.1.1.1.12.2  snj #include <stdio.h>
     25  1.1.1.1.12.2  snj #include <stdlib.h>
     26  1.1.1.1.12.2  snj 
     27  1.1.1.1.12.2  snj void ZopfliInitLZ77Store(ZopfliLZ77Store* store) {
     28  1.1.1.1.12.2  snj   store->size = 0;
     29  1.1.1.1.12.2  snj   store->litlens = 0;
     30  1.1.1.1.12.2  snj   store->dists = 0;
     31  1.1.1.1.12.2  snj }
     32  1.1.1.1.12.2  snj 
     33  1.1.1.1.12.2  snj void ZopfliCleanLZ77Store(ZopfliLZ77Store* store) {
     34  1.1.1.1.12.2  snj   free(store->litlens);
     35  1.1.1.1.12.2  snj   free(store->dists);
     36  1.1.1.1.12.2  snj }
     37  1.1.1.1.12.2  snj 
     38  1.1.1.1.12.2  snj void ZopfliCopyLZ77Store(
     39  1.1.1.1.12.2  snj     const ZopfliLZ77Store* source, ZopfliLZ77Store* dest) {
     40  1.1.1.1.12.2  snj   size_t i;
     41  1.1.1.1.12.2  snj   ZopfliCleanLZ77Store(dest);
     42  1.1.1.1.12.2  snj   dest->litlens =
     43  1.1.1.1.12.2  snj       (unsigned short*)malloc(sizeof(*dest->litlens) * source->size);
     44  1.1.1.1.12.2  snj   dest->dists = (unsigned short*)malloc(sizeof(*dest->dists) * source->size);
     45  1.1.1.1.12.2  snj 
     46  1.1.1.1.12.2  snj   if (!dest->litlens || !dest->dists) exit(-1); /* Allocation failed. */
     47  1.1.1.1.12.2  snj 
     48  1.1.1.1.12.2  snj   dest->size = source->size;
     49  1.1.1.1.12.2  snj   for (i = 0; i < source->size; i++) {
     50  1.1.1.1.12.2  snj     dest->litlens[i] = source->litlens[i];
     51  1.1.1.1.12.2  snj     dest->dists[i] = source->dists[i];
     52  1.1.1.1.12.2  snj   }
     53  1.1.1.1.12.2  snj }
     54  1.1.1.1.12.2  snj 
     55  1.1.1.1.12.2  snj /*
     56  1.1.1.1.12.2  snj Appends the length and distance to the LZ77 arrays of the ZopfliLZ77Store.
     57  1.1.1.1.12.2  snj context must be a ZopfliLZ77Store*.
     58  1.1.1.1.12.2  snj */
     59  1.1.1.1.12.2  snj void ZopfliStoreLitLenDist(unsigned short length, unsigned short dist,
     60  1.1.1.1.12.2  snj                            ZopfliLZ77Store* store) {
     61  1.1.1.1.12.2  snj   size_t size2 = store->size;  /* Needed for using ZOPFLI_APPEND_DATA twice. */
     62  1.1.1.1.12.2  snj   ZOPFLI_APPEND_DATA(length, &store->litlens, &store->size);
     63  1.1.1.1.12.2  snj   ZOPFLI_APPEND_DATA(dist, &store->dists, &size2);
     64  1.1.1.1.12.2  snj }
     65  1.1.1.1.12.2  snj 
     66  1.1.1.1.12.2  snj /*
     67  1.1.1.1.12.2  snj Gets the value of the length given the distance. Typically, the value of the
     68  1.1.1.1.12.2  snj length is the length, but if the distance is very long, decrease the value of
     69  1.1.1.1.12.2  snj the length a bit to make up for the fact that long distances use large amounts
     70  1.1.1.1.12.2  snj of extra bits.
     71  1.1.1.1.12.2  snj */
     72  1.1.1.1.12.2  snj static int GetLengthValue(int length, int distance) {
     73  1.1.1.1.12.2  snj   /*
     74  1.1.1.1.12.2  snj   At distance > 1024, using length 3 is no longer good, due to the large amount
     75  1.1.1.1.12.2  snj   of extra bits for the distance code. distance > 1024 uses 9+ extra bits, and
     76  1.1.1.1.12.2  snj   this seems to be the sweet spot.
     77  1.1.1.1.12.2  snj   */
     78  1.1.1.1.12.2  snj   return distance > 1024 ? length - 1 : length;
     79  1.1.1.1.12.2  snj }
     80  1.1.1.1.12.2  snj 
     81  1.1.1.1.12.2  snj void ZopfliVerifyLenDist(const unsigned char* data, size_t datasize, size_t pos,
     82  1.1.1.1.12.2  snj                          unsigned short dist, unsigned short length) {
     83  1.1.1.1.12.2  snj 
     84  1.1.1.1.12.2  snj   /* TODO(lode): make this only run in a debug compile, it's for assert only. */
     85  1.1.1.1.12.2  snj   size_t i;
     86  1.1.1.1.12.2  snj 
     87  1.1.1.1.12.2  snj   assert(pos + length <= datasize);
     88  1.1.1.1.12.2  snj   for (i = 0; i < length; i++) {
     89  1.1.1.1.12.2  snj     if (data[pos - dist + i] != data[pos + i]) {
     90  1.1.1.1.12.2  snj       assert(data[pos - dist + i] == data[pos + i]);
     91  1.1.1.1.12.2  snj       break;
     92  1.1.1.1.12.2  snj     }
     93  1.1.1.1.12.2  snj   }
     94  1.1.1.1.12.2  snj }
     95  1.1.1.1.12.2  snj 
     96  1.1.1.1.12.2  snj /*
     97  1.1.1.1.12.2  snj Finds how long the match of scan and match is. Can be used to find how many
     98  1.1.1.1.12.2  snj bytes starting from scan, and from match, are equal. Returns the last byte
     99  1.1.1.1.12.2  snj after scan, which is still equal to the correspondinb byte after match.
    100  1.1.1.1.12.2  snj scan is the position to compare
    101  1.1.1.1.12.2  snj match is the earlier position to compare.
    102  1.1.1.1.12.2  snj end is the last possible byte, beyond which to stop looking.
    103  1.1.1.1.12.2  snj safe_end is a few (8) bytes before end, for comparing multiple bytes at once.
    104  1.1.1.1.12.2  snj */
    105  1.1.1.1.12.2  snj static const unsigned char* GetMatch(const unsigned char* scan,
    106  1.1.1.1.12.2  snj                                      const unsigned char* match,
    107  1.1.1.1.12.2  snj                                      const unsigned char* end,
    108  1.1.1.1.12.2  snj                                      const unsigned char* safe_end) {
    109  1.1.1.1.12.2  snj 
    110  1.1.1.1.12.2  snj   if (sizeof(size_t) == 8) {
    111  1.1.1.1.12.2  snj     /* 8 checks at once per array bounds check (size_t is 64-bit). */
    112  1.1.1.1.12.2  snj     while (scan < safe_end && *((size_t*)scan) == *((size_t*)match)) {
    113  1.1.1.1.12.2  snj       scan += 8;
    114  1.1.1.1.12.2  snj       match += 8;
    115  1.1.1.1.12.2  snj     }
    116  1.1.1.1.12.2  snj   } else if (sizeof(unsigned int) == 4) {
    117  1.1.1.1.12.2  snj     /* 4 checks at once per array bounds check (unsigned int is 32-bit). */
    118  1.1.1.1.12.2  snj     while (scan < safe_end
    119  1.1.1.1.12.2  snj         && *((unsigned int*)scan) == *((unsigned int*)match)) {
    120  1.1.1.1.12.2  snj       scan += 4;
    121  1.1.1.1.12.2  snj       match += 4;
    122  1.1.1.1.12.2  snj     }
    123  1.1.1.1.12.2  snj   } else {
    124  1.1.1.1.12.2  snj     /* do 8 checks at once per array bounds check. */
    125  1.1.1.1.12.2  snj     while (scan < safe_end && *scan == *match && *++scan == *++match
    126  1.1.1.1.12.2  snj           && *++scan == *++match && *++scan == *++match
    127  1.1.1.1.12.2  snj           && *++scan == *++match && *++scan == *++match
    128  1.1.1.1.12.2  snj           && *++scan == *++match && *++scan == *++match) {
    129  1.1.1.1.12.2  snj       scan++; match++;
    130  1.1.1.1.12.2  snj     }
    131  1.1.1.1.12.2  snj   }
    132  1.1.1.1.12.2  snj 
    133  1.1.1.1.12.2  snj   /* The remaining few bytes. */
    134  1.1.1.1.12.2  snj   while (scan != end && *scan == *match) {
    135  1.1.1.1.12.2  snj     scan++; match++;
    136  1.1.1.1.12.2  snj   }
    137  1.1.1.1.12.2  snj 
    138  1.1.1.1.12.2  snj   return scan;
    139  1.1.1.1.12.2  snj }
    140  1.1.1.1.12.2  snj 
    141  1.1.1.1.12.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    142  1.1.1.1.12.2  snj /*
    143  1.1.1.1.12.2  snj Gets distance, length and sublen values from the cache if possible.
    144  1.1.1.1.12.2  snj Returns 1 if it got the values from the cache, 0 if not.
    145  1.1.1.1.12.2  snj Updates the limit value to a smaller one if possible with more limited
    146  1.1.1.1.12.2  snj information from the cache.
    147  1.1.1.1.12.2  snj */
    148  1.1.1.1.12.2  snj static int TryGetFromLongestMatchCache(ZopfliBlockState* s,
    149  1.1.1.1.12.2  snj     size_t pos, size_t* limit,
    150  1.1.1.1.12.2  snj     unsigned short* sublen, unsigned short* distance, unsigned short* length) {
    151  1.1.1.1.12.2  snj   /* The LMC cache starts at the beginning of the block rather than the
    152  1.1.1.1.12.2  snj      beginning of the whole array. */
    153  1.1.1.1.12.2  snj   size_t lmcpos = pos - s->blockstart;
    154  1.1.1.1.12.2  snj 
    155  1.1.1.1.12.2  snj   /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
    156  1.1.1.1.12.2  snj      that this cache value is not filled in yet. */
    157  1.1.1.1.12.2  snj   unsigned char cache_available = s->lmc && (s->lmc->length[lmcpos] == 0 ||
    158  1.1.1.1.12.2  snj       s->lmc->dist[lmcpos] != 0);
    159  1.1.1.1.12.2  snj   unsigned char limit_ok_for_cache = cache_available &&
    160  1.1.1.1.12.2  snj       (*limit == ZOPFLI_MAX_MATCH || s->lmc->length[lmcpos] <= *limit ||
    161  1.1.1.1.12.2  snj       (sublen && ZopfliMaxCachedSublen(s->lmc,
    162  1.1.1.1.12.2  snj           lmcpos, s->lmc->length[lmcpos]) >= *limit));
    163  1.1.1.1.12.2  snj 
    164  1.1.1.1.12.2  snj   if (s->lmc && limit_ok_for_cache && cache_available) {
    165  1.1.1.1.12.2  snj     if (!sublen || s->lmc->length[lmcpos]
    166  1.1.1.1.12.2  snj         <= ZopfliMaxCachedSublen(s->lmc, lmcpos, s->lmc->length[lmcpos])) {
    167  1.1.1.1.12.2  snj       *length = s->lmc->length[lmcpos];
    168  1.1.1.1.12.2  snj       if (*length > *limit) *length = *limit;
    169  1.1.1.1.12.2  snj       if (sublen) {
    170  1.1.1.1.12.2  snj         ZopfliCacheToSublen(s->lmc, lmcpos, *length, sublen);
    171  1.1.1.1.12.2  snj         *distance = sublen[*length];
    172  1.1.1.1.12.2  snj         if (*limit == ZOPFLI_MAX_MATCH && *length >= ZOPFLI_MIN_MATCH) {
    173  1.1.1.1.12.2  snj           assert(sublen[*length] == s->lmc->dist[lmcpos]);
    174  1.1.1.1.12.2  snj         }
    175  1.1.1.1.12.2  snj       } else {
    176  1.1.1.1.12.2  snj         *distance = s->lmc->dist[lmcpos];
    177  1.1.1.1.12.2  snj       }
    178  1.1.1.1.12.2  snj       return 1;
    179  1.1.1.1.12.2  snj     }
    180  1.1.1.1.12.2  snj     /* Can't use much of the cache, since the "sublens" need to be calculated,
    181  1.1.1.1.12.2  snj        but at  least we already know when to stop. */
    182  1.1.1.1.12.2  snj     *limit = s->lmc->length[lmcpos];
    183  1.1.1.1.12.2  snj   }
    184  1.1.1.1.12.2  snj 
    185  1.1.1.1.12.2  snj   return 0;
    186  1.1.1.1.12.2  snj }
    187  1.1.1.1.12.2  snj 
    188  1.1.1.1.12.2  snj /*
    189  1.1.1.1.12.2  snj Stores the found sublen, distance and length in the longest match cache, if
    190  1.1.1.1.12.2  snj possible.
    191  1.1.1.1.12.2  snj */
    192  1.1.1.1.12.2  snj static void StoreInLongestMatchCache(ZopfliBlockState* s,
    193  1.1.1.1.12.2  snj     size_t pos, size_t limit,
    194  1.1.1.1.12.2  snj     const unsigned short* sublen,
    195  1.1.1.1.12.2  snj     unsigned short distance, unsigned short length) {
    196  1.1.1.1.12.2  snj   /* The LMC cache starts at the beginning of the block rather than the
    197  1.1.1.1.12.2  snj      beginning of the whole array. */
    198  1.1.1.1.12.2  snj   size_t lmcpos = pos - s->blockstart;
    199  1.1.1.1.12.2  snj 
    200  1.1.1.1.12.2  snj   /* Length > 0 and dist 0 is invalid combination, which indicates on purpose
    201  1.1.1.1.12.2  snj      that this cache value is not filled in yet. */
    202  1.1.1.1.12.2  snj   unsigned char cache_available = s->lmc && (s->lmc->length[lmcpos] == 0 ||
    203  1.1.1.1.12.2  snj       s->lmc->dist[lmcpos] != 0);
    204  1.1.1.1.12.2  snj 
    205  1.1.1.1.12.2  snj   if (s->lmc && limit == ZOPFLI_MAX_MATCH && sublen && !cache_available) {
    206  1.1.1.1.12.2  snj     assert(s->lmc->length[lmcpos] == 1 && s->lmc->dist[lmcpos] == 0);
    207  1.1.1.1.12.2  snj     s->lmc->dist[lmcpos] = length < ZOPFLI_MIN_MATCH ? 0 : distance;
    208  1.1.1.1.12.2  snj     s->lmc->length[lmcpos] = length < ZOPFLI_MIN_MATCH ? 0 : length;
    209  1.1.1.1.12.2  snj     assert(!(s->lmc->length[lmcpos] == 1 && s->lmc->dist[lmcpos] == 0));
    210  1.1.1.1.12.2  snj     ZopfliSublenToCache(sublen, lmcpos, length, s->lmc);
    211  1.1.1.1.12.2  snj   }
    212  1.1.1.1.12.2  snj }
    213  1.1.1.1.12.2  snj #endif
    214  1.1.1.1.12.2  snj 
    215  1.1.1.1.12.2  snj void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h,
    216  1.1.1.1.12.2  snj     const unsigned char* array,
    217  1.1.1.1.12.2  snj     size_t pos, size_t size, size_t limit,
    218  1.1.1.1.12.2  snj     unsigned short* sublen, unsigned short* distance, unsigned short* length) {
    219  1.1.1.1.12.2  snj   unsigned short hpos = pos & ZOPFLI_WINDOW_MASK, p, pp;
    220  1.1.1.1.12.2  snj   unsigned short bestdist = 0;
    221  1.1.1.1.12.2  snj   unsigned short bestlength = 1;
    222  1.1.1.1.12.2  snj   const unsigned char* scan;
    223  1.1.1.1.12.2  snj   const unsigned char* match;
    224  1.1.1.1.12.2  snj   const unsigned char* arrayend;
    225  1.1.1.1.12.2  snj   const unsigned char* arrayend_safe;
    226  1.1.1.1.12.2  snj #if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE
    227  1.1.1.1.12.2  snj   int chain_counter = ZOPFLI_MAX_CHAIN_HITS;  /* For quitting early. */
    228  1.1.1.1.12.2  snj #endif
    229  1.1.1.1.12.2  snj 
    230  1.1.1.1.12.2  snj   unsigned dist = 0;  /* Not unsigned short on purpose. */
    231  1.1.1.1.12.2  snj 
    232  1.1.1.1.12.2  snj   int* hhead = h->head;
    233  1.1.1.1.12.2  snj   unsigned short* hprev = h->prev;
    234  1.1.1.1.12.2  snj   int* hhashval = h->hashval;
    235  1.1.1.1.12.2  snj   int hval = h->val;
    236  1.1.1.1.12.2  snj 
    237  1.1.1.1.12.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    238  1.1.1.1.12.2  snj   if (TryGetFromLongestMatchCache(s, pos, &limit, sublen, distance, length)) {
    239  1.1.1.1.12.2  snj     assert(pos + *length <= size);
    240  1.1.1.1.12.2  snj     return;
    241  1.1.1.1.12.2  snj   }
    242  1.1.1.1.12.2  snj #endif
    243  1.1.1.1.12.2  snj 
    244  1.1.1.1.12.2  snj   assert(limit <= ZOPFLI_MAX_MATCH);
    245  1.1.1.1.12.2  snj   assert(limit >= ZOPFLI_MIN_MATCH);
    246  1.1.1.1.12.2  snj   assert(pos < size);
    247  1.1.1.1.12.2  snj 
    248  1.1.1.1.12.2  snj   if (size - pos < ZOPFLI_MIN_MATCH) {
    249  1.1.1.1.12.2  snj     /* The rest of the code assumes there are at least ZOPFLI_MIN_MATCH bytes to
    250  1.1.1.1.12.2  snj        try. */
    251  1.1.1.1.12.2  snj     *length = 0;
    252  1.1.1.1.12.2  snj     *distance = 0;
    253  1.1.1.1.12.2  snj     return;
    254  1.1.1.1.12.2  snj   }
    255  1.1.1.1.12.2  snj 
    256  1.1.1.1.12.2  snj   if (pos + limit > size) {
    257  1.1.1.1.12.2  snj     limit = size - pos;
    258  1.1.1.1.12.2  snj   }
    259  1.1.1.1.12.2  snj   arrayend = &array[pos] + limit;
    260  1.1.1.1.12.2  snj   arrayend_safe = arrayend - 8;
    261  1.1.1.1.12.2  snj 
    262  1.1.1.1.12.2  snj   assert(hval < 65536);
    263  1.1.1.1.12.2  snj 
    264  1.1.1.1.12.2  snj   pp = hhead[hval];  /* During the whole loop, p == hprev[pp]. */
    265  1.1.1.1.12.2  snj   p = hprev[pp];
    266  1.1.1.1.12.2  snj 
    267  1.1.1.1.12.2  snj   assert(pp == hpos);
    268  1.1.1.1.12.2  snj 
    269  1.1.1.1.12.2  snj   dist = p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp);
    270  1.1.1.1.12.2  snj 
    271  1.1.1.1.12.2  snj   /* Go through all distances. */
    272  1.1.1.1.12.2  snj   while (dist < ZOPFLI_WINDOW_SIZE) {
    273  1.1.1.1.12.2  snj     unsigned short currentlength = 0;
    274  1.1.1.1.12.2  snj 
    275  1.1.1.1.12.2  snj     assert(p < ZOPFLI_WINDOW_SIZE);
    276  1.1.1.1.12.2  snj     assert(p == hprev[pp]);
    277  1.1.1.1.12.2  snj     assert(hhashval[p] == hval);
    278  1.1.1.1.12.2  snj 
    279  1.1.1.1.12.2  snj     if (dist > 0) {
    280  1.1.1.1.12.2  snj       assert(pos < size);
    281  1.1.1.1.12.2  snj       assert(dist <= pos);
    282  1.1.1.1.12.2  snj       scan = &array[pos];
    283  1.1.1.1.12.2  snj       match = &array[pos - dist];
    284  1.1.1.1.12.2  snj 
    285  1.1.1.1.12.2  snj       /* Testing the byte at position bestlength first, goes slightly faster. */
    286  1.1.1.1.12.2  snj       if (pos + bestlength >= size
    287  1.1.1.1.12.2  snj           || *(scan + bestlength) == *(match + bestlength)) {
    288  1.1.1.1.12.2  snj 
    289  1.1.1.1.12.2  snj #ifdef ZOPFLI_HASH_SAME
    290  1.1.1.1.12.2  snj         unsigned short same0 = h->same[pos & ZOPFLI_WINDOW_MASK];
    291  1.1.1.1.12.2  snj         if (same0 > 2 && *scan == *match) {
    292  1.1.1.1.12.2  snj           unsigned short same1 = h->same[(pos - dist) & ZOPFLI_WINDOW_MASK];
    293  1.1.1.1.12.2  snj           unsigned short same = same0 < same1 ? same0 : same1;
    294  1.1.1.1.12.2  snj           if (same > limit) same = limit;
    295  1.1.1.1.12.2  snj           scan += same;
    296  1.1.1.1.12.2  snj           match += same;
    297  1.1.1.1.12.2  snj         }
    298  1.1.1.1.12.2  snj #endif
    299  1.1.1.1.12.2  snj         scan = GetMatch(scan, match, arrayend, arrayend_safe);
    300  1.1.1.1.12.2  snj         currentlength = scan - &array[pos];  /* The found length. */
    301  1.1.1.1.12.2  snj       }
    302  1.1.1.1.12.2  snj 
    303  1.1.1.1.12.2  snj       if (currentlength > bestlength) {
    304  1.1.1.1.12.2  snj         if (sublen) {
    305  1.1.1.1.12.2  snj           unsigned short j;
    306  1.1.1.1.12.2  snj           for (j = bestlength + 1; j <= currentlength; j++) {
    307  1.1.1.1.12.2  snj             sublen[j] = dist;
    308  1.1.1.1.12.2  snj           }
    309  1.1.1.1.12.2  snj         }
    310  1.1.1.1.12.2  snj         bestdist = dist;
    311  1.1.1.1.12.2  snj         bestlength = currentlength;
    312  1.1.1.1.12.2  snj         if (currentlength >= limit) break;
    313  1.1.1.1.12.2  snj       }
    314  1.1.1.1.12.2  snj     }
    315  1.1.1.1.12.2  snj 
    316  1.1.1.1.12.2  snj 
    317  1.1.1.1.12.2  snj #ifdef ZOPFLI_HASH_SAME_HASH
    318  1.1.1.1.12.2  snj     /* Switch to the other hash once this will be more efficient. */
    319  1.1.1.1.12.2  snj     if (hhead != h->head2 && bestlength >= h->same[hpos] &&
    320  1.1.1.1.12.2  snj         h->val2 == h->hashval2[p]) {
    321  1.1.1.1.12.2  snj       /* Now use the hash that encodes the length and first byte. */
    322  1.1.1.1.12.2  snj       hhead = h->head2;
    323  1.1.1.1.12.2  snj       hprev = h->prev2;
    324  1.1.1.1.12.2  snj       hhashval = h->hashval2;
    325  1.1.1.1.12.2  snj       hval = h->val2;
    326  1.1.1.1.12.2  snj     }
    327  1.1.1.1.12.2  snj #endif
    328  1.1.1.1.12.2  snj 
    329  1.1.1.1.12.2  snj     pp = p;
    330  1.1.1.1.12.2  snj     p = hprev[p];
    331  1.1.1.1.12.2  snj     if (p == pp) break;  /* Uninited prev value. */
    332  1.1.1.1.12.2  snj 
    333  1.1.1.1.12.2  snj     dist += p < pp ? pp - p : ((ZOPFLI_WINDOW_SIZE - p) + pp);
    334  1.1.1.1.12.2  snj 
    335  1.1.1.1.12.2  snj #if ZOPFLI_MAX_CHAIN_HITS < ZOPFLI_WINDOW_SIZE
    336  1.1.1.1.12.2  snj     chain_counter--;
    337  1.1.1.1.12.2  snj     if (chain_counter <= 0) break;
    338  1.1.1.1.12.2  snj #endif
    339  1.1.1.1.12.2  snj   }
    340  1.1.1.1.12.2  snj 
    341  1.1.1.1.12.2  snj #ifdef ZOPFLI_LONGEST_MATCH_CACHE
    342  1.1.1.1.12.2  snj   StoreInLongestMatchCache(s, pos, limit, sublen, bestdist, bestlength);
    343  1.1.1.1.12.2  snj #endif
    344  1.1.1.1.12.2  snj 
    345  1.1.1.1.12.2  snj   assert(bestlength <= limit);
    346  1.1.1.1.12.2  snj 
    347  1.1.1.1.12.2  snj   *distance = bestdist;
    348  1.1.1.1.12.2  snj   *length = bestlength;
    349  1.1.1.1.12.2  snj   assert(pos + *length <= size);
    350  1.1.1.1.12.2  snj }
    351  1.1.1.1.12.2  snj 
    352  1.1.1.1.12.2  snj void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
    353  1.1.1.1.12.2  snj                       size_t instart, size_t inend,
    354  1.1.1.1.12.2  snj                       ZopfliLZ77Store* store) {
    355  1.1.1.1.12.2  snj   size_t i = 0, j;
    356  1.1.1.1.12.2  snj   unsigned short leng;
    357  1.1.1.1.12.2  snj   unsigned short dist;
    358  1.1.1.1.12.2  snj   int lengvalue;
    359  1.1.1.1.12.2  snj   size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
    360  1.1.1.1.12.2  snj       ? instart - ZOPFLI_WINDOW_SIZE : 0;
    361  1.1.1.1.12.2  snj   unsigned short dummysublen[259];
    362  1.1.1.1.12.2  snj 
    363  1.1.1.1.12.2  snj   ZopfliHash hash;
    364  1.1.1.1.12.2  snj   ZopfliHash* h = &hash;
    365  1.1.1.1.12.2  snj 
    366  1.1.1.1.12.2  snj #ifdef ZOPFLI_LAZY_MATCHING
    367  1.1.1.1.12.2  snj   /* Lazy matching. */
    368  1.1.1.1.12.2  snj   unsigned prev_length = 0;
    369  1.1.1.1.12.2  snj   unsigned prev_match = 0;
    370  1.1.1.1.12.2  snj   int prevlengvalue;
    371  1.1.1.1.12.2  snj   int match_available = 0;
    372  1.1.1.1.12.2  snj #endif
    373  1.1.1.1.12.2  snj 
    374  1.1.1.1.12.2  snj   if (instart == inend) return;
    375  1.1.1.1.12.2  snj 
    376  1.1.1.1.12.2  snj   ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
    377  1.1.1.1.12.2  snj   ZopfliWarmupHash(in, windowstart, inend, h);
    378  1.1.1.1.12.2  snj   for (i = windowstart; i < instart; i++) {
    379  1.1.1.1.12.2  snj     ZopfliUpdateHash(in, i, inend, h);
    380  1.1.1.1.12.2  snj   }
    381  1.1.1.1.12.2  snj 
    382  1.1.1.1.12.2  snj   for (i = instart; i < inend; i++) {
    383  1.1.1.1.12.2  snj     ZopfliUpdateHash(in, i, inend, h);
    384  1.1.1.1.12.2  snj 
    385  1.1.1.1.12.2  snj     ZopfliFindLongestMatch(s, h, in, i, inend, ZOPFLI_MAX_MATCH, dummysublen,
    386  1.1.1.1.12.2  snj                            &dist, &leng);
    387  1.1.1.1.12.2  snj     lengvalue = GetLengthValue(leng, dist);
    388  1.1.1.1.12.2  snj 
    389  1.1.1.1.12.2  snj #ifdef ZOPFLI_LAZY_MATCHING
    390  1.1.1.1.12.2  snj     /* Lazy matching. */
    391  1.1.1.1.12.2  snj     prevlengvalue = GetLengthValue(prev_length, prev_match);
    392  1.1.1.1.12.2  snj     if (match_available) {
    393  1.1.1.1.12.2  snj       match_available = 0;
    394  1.1.1.1.12.2  snj       if (lengvalue > prevlengvalue + 1) {
    395  1.1.1.1.12.2  snj         ZopfliStoreLitLenDist(in[i - 1], 0, store);
    396  1.1.1.1.12.2  snj         if (lengvalue >= ZOPFLI_MIN_MATCH && lengvalue < ZOPFLI_MAX_MATCH) {
    397  1.1.1.1.12.2  snj           match_available = 1;
    398  1.1.1.1.12.2  snj           prev_length = leng;
    399  1.1.1.1.12.2  snj           prev_match = dist;
    400  1.1.1.1.12.2  snj           continue;
    401  1.1.1.1.12.2  snj         }
    402  1.1.1.1.12.2  snj       } else {
    403  1.1.1.1.12.2  snj         /* Add previous to output. */
    404  1.1.1.1.12.2  snj         leng = prev_length;
    405  1.1.1.1.12.2  snj         dist = prev_match;
    406  1.1.1.1.12.2  snj         lengvalue = prevlengvalue;
    407  1.1.1.1.12.2  snj         /* Add to output. */
    408  1.1.1.1.12.2  snj         ZopfliVerifyLenDist(in, inend, i - 1, dist, leng);
    409  1.1.1.1.12.2  snj         ZopfliStoreLitLenDist(leng, dist, store);
    410  1.1.1.1.12.2  snj         for (j = 2; j < leng; j++) {
    411  1.1.1.1.12.2  snj           assert(i < inend);
    412  1.1.1.1.12.2  snj           i++;
    413  1.1.1.1.12.2  snj           ZopfliUpdateHash(in, i, inend, h);
    414  1.1.1.1.12.2  snj         }
    415  1.1.1.1.12.2  snj         continue;
    416  1.1.1.1.12.2  snj       }
    417  1.1.1.1.12.2  snj     }
    418  1.1.1.1.12.2  snj     else if (lengvalue >= ZOPFLI_MIN_MATCH && leng < ZOPFLI_MAX_MATCH) {
    419  1.1.1.1.12.2  snj       match_available = 1;
    420  1.1.1.1.12.2  snj       prev_length = leng;
    421  1.1.1.1.12.2  snj       prev_match = dist;
    422  1.1.1.1.12.2  snj       continue;
    423  1.1.1.1.12.2  snj     }
    424  1.1.1.1.12.2  snj     /* End of lazy matching. */
    425  1.1.1.1.12.2  snj #endif
    426  1.1.1.1.12.2  snj 
    427  1.1.1.1.12.2  snj     /* Add to output. */
    428  1.1.1.1.12.2  snj     if (lengvalue >= ZOPFLI_MIN_MATCH) {
    429  1.1.1.1.12.2  snj       ZopfliVerifyLenDist(in, inend, i, dist, leng);
    430  1.1.1.1.12.2  snj       ZopfliStoreLitLenDist(leng, dist, store);
    431  1.1.1.1.12.2  snj     } else {
    432  1.1.1.1.12.2  snj       leng = 1;
    433  1.1.1.1.12.2  snj       ZopfliStoreLitLenDist(in[i], 0, store);
    434  1.1.1.1.12.2  snj     }
    435  1.1.1.1.12.2  snj     for (j = 1; j < leng; j++) {
    436  1.1.1.1.12.2  snj       assert(i < inend);
    437  1.1.1.1.12.2  snj       i++;
    438  1.1.1.1.12.2  snj       ZopfliUpdateHash(in, i, inend, h);
    439  1.1.1.1.12.2  snj     }
    440  1.1.1.1.12.2  snj   }
    441  1.1.1.1.12.2  snj 
    442  1.1.1.1.12.2  snj   ZopfliCleanHash(h);
    443  1.1.1.1.12.2  snj }
    444  1.1.1.1.12.2  snj 
    445  1.1.1.1.12.2  snj void ZopfliLZ77Counts(const unsigned short* litlens,
    446  1.1.1.1.12.2  snj                       const unsigned short* dists,
    447  1.1.1.1.12.2  snj                       size_t start, size_t end,
    448  1.1.1.1.12.2  snj                       size_t* ll_count, size_t* d_count) {
    449  1.1.1.1.12.2  snj   size_t i;
    450  1.1.1.1.12.2  snj 
    451  1.1.1.1.12.2  snj   for (i = 0; i < 288; i++) {
    452  1.1.1.1.12.2  snj     ll_count[i] = 0;
    453  1.1.1.1.12.2  snj   }
    454  1.1.1.1.12.2  snj   for (i = 0; i < 32; i++) {
    455  1.1.1.1.12.2  snj     d_count[i] = 0;
    456  1.1.1.1.12.2  snj   }
    457  1.1.1.1.12.2  snj 
    458  1.1.1.1.12.2  snj   for (i = start; i < end; i++) {
    459  1.1.1.1.12.2  snj     if (dists[i] == 0) {
    460  1.1.1.1.12.2  snj       ll_count[litlens[i]]++;
    461  1.1.1.1.12.2  snj     } else {
    462  1.1.1.1.12.2  snj       ll_count[ZopfliGetLengthSymbol(litlens[i])]++;
    463  1.1.1.1.12.2  snj       d_count[ZopfliGetDistSymbol(dists[i])]++;
    464  1.1.1.1.12.2  snj     }
    465  1.1.1.1.12.2  snj   }
    466  1.1.1.1.12.2  snj 
    467  1.1.1.1.12.2  snj   ll_count[256] = 1;  /* End symbol. */
    468  1.1.1.1.12.2  snj }
    469