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