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 "squeeze.h"
     21 
     22 #include <assert.h>
     23 #include <math.h>
     24 #include <stdio.h>
     25 
     26 #include "blocksplitter.h"
     27 #include "deflate.h"
     28 #include "tree.h"
     29 #include "util.h"
     30 
     31 typedef struct SymbolStats {
     32   /* The literal and length symbols. */
     33   size_t litlens[288];
     34   /* The 32 unique dist symbols, not the 32768 possible dists. */
     35   size_t dists[32];
     36 
     37   double ll_symbols[288];  /* Length of each lit/len symbol in bits. */
     38   double d_symbols[32];  /* Length of each dist symbol in bits. */
     39 } SymbolStats;
     40 
     41 /* Sets everything to 0. */
     42 static void InitStats(SymbolStats* stats) {
     43   memset(stats->litlens, 0, 288 * sizeof(stats->litlens[0]));
     44   memset(stats->dists, 0, 32 * sizeof(stats->dists[0]));
     45 
     46   memset(stats->ll_symbols, 0, 288 * sizeof(stats->ll_symbols[0]));
     47   memset(stats->d_symbols, 0, 32 * sizeof(stats->d_symbols[0]));
     48 }
     49 
     50 static void CopyStats(SymbolStats* source, SymbolStats* dest) {
     51   memcpy(dest->litlens, source->litlens, 288 * sizeof(dest->litlens[0]));
     52   memcpy(dest->dists, source->dists, 32 * sizeof(dest->dists[0]));
     53 
     54   memcpy(dest->ll_symbols, source->ll_symbols,
     55          288 * sizeof(dest->ll_symbols[0]));
     56   memcpy(dest->d_symbols, source->d_symbols, 32 * sizeof(dest->d_symbols[0]));
     57 }
     58 
     59 /* Adds the bit lengths. */
     60 static void AddWeighedStatFreqs(const SymbolStats* stats1, double w1,
     61                                 const SymbolStats* stats2, double w2,
     62                                 SymbolStats* result) {
     63   size_t i;
     64   for (i = 0; i < 288; i++) {
     65     result->litlens[i] =
     66         (size_t) (stats1->litlens[i] * w1 + stats2->litlens[i] * w2);
     67   }
     68   for (i = 0; i < 32; i++) {
     69     result->dists[i] =
     70         (size_t) (stats1->dists[i] * w1 + stats2->dists[i] * w2);
     71   }
     72   result->litlens[256] = 1;  /* End symbol. */
     73 }
     74 
     75 typedef struct RanState {
     76   unsigned int m_w, m_z;
     77 } RanState;
     78 
     79 static void InitRanState(RanState* state) {
     80   state->m_w = 1;
     81   state->m_z = 2;
     82 }
     83 
     84 /* Get random number: "Multiply-With-Carry" generator of G. Marsaglia */
     85 static unsigned int Ran(RanState* state) {
     86   state->m_z = 36969 * (state->m_z & 65535) + (state->m_z >> 16);
     87   state->m_w = 18000 * (state->m_w & 65535) + (state->m_w >> 16);
     88   return (state->m_z << 16) + state->m_w;  /* 32-bit result. */
     89 }
     90 
     91 static void RandomizeFreqs(RanState* state, size_t* freqs, int n) {
     92   int i;
     93   for (i = 0; i < n; i++) {
     94     if ((Ran(state) >> 4) % 3 == 0) freqs[i] = freqs[Ran(state) % n];
     95   }
     96 }
     97 
     98 static void RandomizeStatFreqs(RanState* state, SymbolStats* stats) {
     99   RandomizeFreqs(state, stats->litlens, 288);
    100   RandomizeFreqs(state, stats->dists, 32);
    101   stats->litlens[256] = 1;  /* End symbol. */
    102 }
    103 
    104 static void ClearStatFreqs(SymbolStats* stats) {
    105   size_t i;
    106   for (i = 0; i < 288; i++) stats->litlens[i] = 0;
    107   for (i = 0; i < 32; i++) stats->dists[i] = 0;
    108 }
    109 
    110 /*
    111 Function that calculates a cost based on a model for the given LZ77 symbol.
    112 litlen: means literal symbol if dist is 0, length otherwise.
    113 */
    114 typedef double CostModelFun(unsigned litlen, unsigned dist, void* context);
    115 
    116 /*
    117 Cost model which should exactly match fixed tree.
    118 type: CostModelFun
    119 */
    120 static double GetCostFixed(unsigned litlen, unsigned dist, void* unused) {
    121   (void)unused;
    122   if (dist == 0) {
    123     if (litlen <= 143) return 8;
    124     else return 9;
    125   } else {
    126     int dbits = ZopfliGetDistExtraBits(dist);
    127     int lbits = ZopfliGetLengthExtraBits(litlen);
    128     int lsym = ZopfliGetLengthSymbol(litlen);
    129     double cost = 0;
    130     if (lsym <= 279) cost += 7;
    131     else cost += 8;
    132     cost += 5;  /* Every dist symbol has length 5. */
    133     return cost + dbits + lbits;
    134   }
    135 }
    136 
    137 /*
    138 Cost model based on symbol statistics.
    139 type: CostModelFun
    140 */
    141 static double GetCostStat(unsigned litlen, unsigned dist, void* context) {
    142   SymbolStats* stats = (SymbolStats*)context;
    143   if (dist == 0) {
    144     return stats->ll_symbols[litlen];
    145   } else {
    146     int lsym = ZopfliGetLengthSymbol(litlen);
    147     int lbits = ZopfliGetLengthExtraBits(litlen);
    148     int dsym = ZopfliGetDistSymbol(dist);
    149     int dbits = ZopfliGetDistExtraBits(dist);
    150     return stats->ll_symbols[lsym] + lbits + stats->d_symbols[dsym] + dbits;
    151   }
    152 }
    153 
    154 /*
    155 Finds the minimum possible cost this cost model can return for valid length and
    156 distance symbols.
    157 */
    158 static double GetCostModelMinCost(CostModelFun* costmodel, void* costcontext) {
    159   double mincost;
    160   int bestlength = 0; /* length that has lowest cost in the cost model */
    161   int bestdist = 0; /* distance that has lowest cost in the cost model */
    162   int i;
    163   /*
    164   Table of distances that have a different distance symbol in the deflate
    165   specification. Each value is the first distance that has a new symbol. Only
    166   different symbols affect the cost model so only these need to be checked.
    167   See RFC 1951 section 3.2.5. Compressed blocks (length and distance codes).
    168   */
    169   static const int dsymbols[30] = {
    170     1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513,
    171     769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
    172   };
    173 
    174   mincost = ZOPFLI_LARGE_FLOAT;
    175   for (i = 3; i < 259; i++) {
    176     double c = costmodel(i, 1, costcontext);
    177     if (c < mincost) {
    178       bestlength = i;
    179       mincost = c;
    180     }
    181   }
    182 
    183   mincost = ZOPFLI_LARGE_FLOAT;
    184   for (i = 0; i < 30; i++) {
    185     double c = costmodel(3, dsymbols[i], costcontext);
    186     if (c < mincost) {
    187       bestdist = dsymbols[i];
    188       mincost = c;
    189     }
    190   }
    191 
    192   return costmodel(bestlength, bestdist, costcontext);
    193 }
    194 
    195 /*
    196 Performs the forward pass for "squeeze". Gets the most optimal length to reach
    197 every byte from a previous byte, using cost calculations.
    198 s: the ZopfliBlockState
    199 in: the input data array
    200 instart: where to start
    201 inend: where to stop (not inclusive)
    202 costmodel: function to calculate the cost of some lit/len/dist pair.
    203 costcontext: abstract context for the costmodel function
    204 length_array: output array of size (inend - instart) which will receive the best
    205     length to reach this byte from a previous byte.
    206 returns the cost that was, according to the costmodel, needed to get to the end.
    207 */
    208 static double GetBestLengths(ZopfliBlockState *s,
    209                              const unsigned char* in,
    210                              size_t instart, size_t inend,
    211                              CostModelFun* costmodel, void* costcontext,
    212                              unsigned short* length_array) {
    213   /* Best cost to get here so far. */
    214   size_t blocksize = inend - instart;
    215   float* costs;
    216   size_t i = 0, k;
    217   unsigned short leng;
    218   unsigned short dist;
    219   unsigned short sublen[259];
    220   size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
    221       ? instart - ZOPFLI_WINDOW_SIZE : 0;
    222   ZopfliHash hash;
    223   ZopfliHash* h = &hash;
    224   double result;
    225   double mincost = GetCostModelMinCost(costmodel, costcontext);
    226 
    227   if (instart == inend) return 0;
    228 
    229   costs = (float*)malloc(sizeof(float) * (blocksize + 1));
    230   if (!costs) exit(-1); /* Allocation failed. */
    231 
    232   ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
    233   ZopfliWarmupHash(in, windowstart, inend, h);
    234   for (i = windowstart; i < instart; i++) {
    235     ZopfliUpdateHash(in, i, inend, h);
    236   }
    237 
    238   for (i = 1; i < blocksize + 1; i++) costs[i] = ZOPFLI_LARGE_FLOAT;
    239   costs[0] = 0;  /* Because it's the start. */
    240   length_array[0] = 0;
    241 
    242   for (i = instart; i < inend; i++) {
    243     size_t j = i - instart;  /* Index in the costs array and length_array. */
    244     ZopfliUpdateHash(in, i, inend, h);
    245 
    246 #ifdef ZOPFLI_SHORTCUT_LONG_REPETITIONS
    247     /* If we're in a long repetition of the same character and have more than
    248     ZOPFLI_MAX_MATCH characters before and after our position. */
    249     if (h->same[i & ZOPFLI_WINDOW_MASK] > ZOPFLI_MAX_MATCH * 2
    250         && i > instart + ZOPFLI_MAX_MATCH + 1
    251         && i + ZOPFLI_MAX_MATCH * 2 + 1 < inend
    252         && h->same[(i - ZOPFLI_MAX_MATCH) & ZOPFLI_WINDOW_MASK]
    253             > ZOPFLI_MAX_MATCH) {
    254       double symbolcost = costmodel(ZOPFLI_MAX_MATCH, 1, costcontext);
    255       /* Set the length to reach each one to ZOPFLI_MAX_MATCH, and the cost to
    256       the cost corresponding to that length. Doing this, we skip
    257       ZOPFLI_MAX_MATCH values to avoid calling ZopfliFindLongestMatch. */
    258       for (k = 0; k < ZOPFLI_MAX_MATCH; k++) {
    259         costs[j + ZOPFLI_MAX_MATCH] = costs[j] + symbolcost;
    260         length_array[j + ZOPFLI_MAX_MATCH] = ZOPFLI_MAX_MATCH;
    261         i++;
    262         j++;
    263         ZopfliUpdateHash(in, i, inend, h);
    264       }
    265     }
    266 #endif
    267 
    268     ZopfliFindLongestMatch(s, h, in, i, inend, ZOPFLI_MAX_MATCH, sublen,
    269                            &dist, &leng);
    270 
    271     /* Literal. */
    272     if (i + 1 <= inend) {
    273       double newCost = costs[j] + costmodel(in[i], 0, costcontext);
    274       assert(newCost >= 0);
    275       if (newCost < costs[j + 1]) {
    276         costs[j + 1] = newCost;
    277         length_array[j + 1] = 1;
    278       }
    279     }
    280     /* Lengths. */
    281     for (k = 3; k <= leng && i + k <= inend; k++) {
    282       double newCost;
    283 
    284       /* Calling the cost model is expensive, avoid this if we are already at
    285       the minimum possible cost that it can return. */
    286      if (costs[j + k] - costs[j] <= mincost) continue;
    287 
    288       newCost = costs[j] + costmodel(k, sublen[k], costcontext);
    289       assert(newCost >= 0);
    290       if (newCost < costs[j + k]) {
    291         assert(k <= ZOPFLI_MAX_MATCH);
    292         costs[j + k] = newCost;
    293         length_array[j + k] = k;
    294       }
    295     }
    296   }
    297 
    298   assert(costs[blocksize] >= 0);
    299   result = costs[blocksize];
    300 
    301   ZopfliCleanHash(h);
    302   free(costs);
    303 
    304   return result;
    305 }
    306 
    307 /*
    308 Calculates the optimal path of lz77 lengths to use, from the calculated
    309 length_array. The length_array must contain the optimal length to reach that
    310 byte. The path will be filled with the lengths to use, so its data size will be
    311 the amount of lz77 symbols.
    312 */
    313 static void TraceBackwards(size_t size, const unsigned short* length_array,
    314                            unsigned short** path, size_t* pathsize) {
    315   size_t index = size;
    316   if (size == 0) return;
    317   for (;;) {
    318     ZOPFLI_APPEND_DATA(length_array[index], path, pathsize);
    319     assert(length_array[index] <= index);
    320     assert(length_array[index] <= ZOPFLI_MAX_MATCH);
    321     assert(length_array[index] != 0);
    322     index -= length_array[index];
    323     if (index == 0) break;
    324   }
    325 
    326   /* Mirror result. */
    327   for (index = 0; index < *pathsize / 2; index++) {
    328     unsigned short temp = (*path)[index];
    329     (*path)[index] = (*path)[*pathsize - index - 1];
    330     (*path)[*pathsize - index - 1] = temp;
    331   }
    332 }
    333 
    334 static void FollowPath(ZopfliBlockState* s,
    335                        const unsigned char* in, size_t instart, size_t inend,
    336                        unsigned short* path, size_t pathsize,
    337                        ZopfliLZ77Store* store) {
    338   size_t i, j, pos = 0;
    339   size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
    340       ? instart - ZOPFLI_WINDOW_SIZE : 0;
    341 
    342   size_t total_length_test = 0;
    343 
    344   ZopfliHash hash;
    345   ZopfliHash* h = &hash;
    346 
    347   if (instart == inend) return;
    348 
    349   ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
    350   ZopfliWarmupHash(in, windowstart, inend, h);
    351   for (i = windowstart; i < instart; i++) {
    352     ZopfliUpdateHash(in, i, inend, h);
    353   }
    354 
    355   pos = instart;
    356   for (i = 0; i < pathsize; i++) {
    357     unsigned short length = path[i];
    358     unsigned short dummy_length;
    359     unsigned short dist;
    360     assert(pos < inend);
    361 
    362     ZopfliUpdateHash(in, pos, inend, h);
    363 
    364     /* Add to output. */
    365     if (length >= ZOPFLI_MIN_MATCH) {
    366       /* Get the distance by recalculating longest match. The found length
    367       should match the length from the path. */
    368       ZopfliFindLongestMatch(s, h, in, pos, inend, length, 0,
    369                              &dist, &dummy_length);
    370       assert(!(dummy_length != length && length > 2 && dummy_length > 2));
    371       ZopfliVerifyLenDist(in, inend, pos, dist, length);
    372       ZopfliStoreLitLenDist(length, dist, store);
    373       total_length_test += length;
    374     } else {
    375       length = 1;
    376       ZopfliStoreLitLenDist(in[pos], 0, store);
    377       total_length_test++;
    378     }
    379 
    380 
    381     assert(pos + length <= inend);
    382     for (j = 1; j < length; j++) {
    383       ZopfliUpdateHash(in, pos + j, inend, h);
    384     }
    385 
    386     pos += length;
    387   }
    388 
    389   ZopfliCleanHash(h);
    390 }
    391 
    392 /* Calculates the entropy of the statistics */
    393 static void CalculateStatistics(SymbolStats* stats) {
    394   ZopfliCalculateEntropy(stats->litlens, 288, stats->ll_symbols);
    395   ZopfliCalculateEntropy(stats->dists, 32, stats->d_symbols);
    396 }
    397 
    398 /* Appends the symbol statistics from the store. */
    399 static void GetStatistics(const ZopfliLZ77Store* store, SymbolStats* stats) {
    400   size_t i;
    401   for (i = 0; i < store->size; i++) {
    402     if (store->dists[i] == 0) {
    403       stats->litlens[store->litlens[i]]++;
    404     } else {
    405       stats->litlens[ZopfliGetLengthSymbol(store->litlens[i])]++;
    406       stats->dists[ZopfliGetDistSymbol(store->dists[i])]++;
    407     }
    408   }
    409   stats->litlens[256] = 1;  /* End symbol. */
    410 
    411   CalculateStatistics(stats);
    412 }
    413 
    414 /*
    415 Does a single run for ZopfliLZ77Optimal. For good compression, repeated runs
    416 with updated statistics should be performed.
    417 
    418 s: the block state
    419 in: the input data array
    420 instart: where to start
    421 inend: where to stop (not inclusive)
    422 path: pointer to dynamically allocated memory to store the path
    423 pathsize: pointer to the size of the dynamic path array
    424 length_array: array if size (inend - instart) used to store lengths
    425 costmodel: function to use as the cost model for this squeeze run
    426 costcontext: abstract context for the costmodel function
    427 store: place to output the LZ77 data
    428 returns the cost that was, according to the costmodel, needed to get to the end.
    429     This is not the actual cost.
    430 */
    431 static double LZ77OptimalRun(ZopfliBlockState* s,
    432     const unsigned char* in, size_t instart, size_t inend,
    433     unsigned short** path, size_t* pathsize,
    434     unsigned short* length_array, CostModelFun* costmodel,
    435     void* costcontext, ZopfliLZ77Store* store) {
    436   double cost = GetBestLengths(
    437       s, in, instart, inend, costmodel, costcontext, length_array);
    438   free(*path);
    439   *path = 0;
    440   *pathsize = 0;
    441   TraceBackwards(inend - instart, length_array, path, pathsize);
    442   FollowPath(s, in, instart, inend, *path, *pathsize, store);
    443   assert(cost < ZOPFLI_LARGE_FLOAT);
    444   return cost;
    445 }
    446 
    447 void ZopfliLZ77Optimal(ZopfliBlockState *s,
    448                        const unsigned char* in, size_t instart, size_t inend,
    449                        ZopfliLZ77Store* store) {
    450   /* Dist to get to here with smallest cost. */
    451   size_t blocksize = inend - instart;
    452   unsigned short* length_array =
    453       (unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
    454   unsigned short* path = 0;
    455   size_t pathsize = 0;
    456   ZopfliLZ77Store currentstore;
    457   SymbolStats stats, beststats, laststats;
    458   int i;
    459   double cost;
    460   double bestcost = ZOPFLI_LARGE_FLOAT;
    461   double lastcost = 0;
    462   /* Try randomizing the costs a bit once the size stabilizes. */
    463   RanState ran_state;
    464   int lastrandomstep = -1;
    465 
    466   if (!length_array) exit(-1); /* Allocation failed. */
    467 
    468   InitRanState(&ran_state);
    469   InitStats(&stats);
    470   ZopfliInitLZ77Store(&currentstore);
    471 
    472   /* Do regular deflate, then loop multiple shortest path runs, each time using
    473   the statistics of the previous run. */
    474 
    475   /* Initial run. */
    476   ZopfliLZ77Greedy(s, in, instart, inend, &currentstore);
    477   GetStatistics(&currentstore, &stats);
    478 
    479   /* Repeat statistics with each time the cost model from the previous stat
    480   run. */
    481   for (i = 0; i < s->options->numiterations; i++) {
    482     ZopfliCleanLZ77Store(&currentstore);
    483     ZopfliInitLZ77Store(&currentstore);
    484     LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
    485                    length_array, GetCostStat, (void*)&stats,
    486                    &currentstore);
    487     cost = ZopfliCalculateBlockSize(currentstore.litlens, currentstore.dists,
    488                                     0, currentstore.size, 2);
    489     if (s->options->verbose_more || (s->options->verbose && cost < bestcost)) {
    490       fprintf(stderr, "Iteration %d: %d bit\n", i, (int) cost);
    491     }
    492     if (cost < bestcost) {
    493       /* Copy to the output store. */
    494       ZopfliCopyLZ77Store(&currentstore, store);
    495       CopyStats(&stats, &beststats);
    496       bestcost = cost;
    497     }
    498     CopyStats(&stats, &laststats);
    499     ClearStatFreqs(&stats);
    500     GetStatistics(&currentstore, &stats);
    501     if (lastrandomstep != -1) {
    502       /* This makes it converge slower but better. Do it only once the
    503       randomness kicks in so that if the user does few iterations, it gives a
    504       better result sooner. */
    505       AddWeighedStatFreqs(&stats, 1.0, &laststats, 0.5, &stats);
    506       CalculateStatistics(&stats);
    507     }
    508     if (i > 5 && cost == lastcost) {
    509       CopyStats(&beststats, &stats);
    510       RandomizeStatFreqs(&ran_state, &stats);
    511       CalculateStatistics(&stats);
    512       lastrandomstep = i;
    513     }
    514     lastcost = cost;
    515   }
    516 
    517   free(length_array);
    518   free(path);
    519   ZopfliCleanLZ77Store(&currentstore);
    520 }
    521 
    522 void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
    523                             const unsigned char* in,
    524                             size_t instart, size_t inend,
    525                             ZopfliLZ77Store* store)
    526 {
    527   /* Dist to get to here with smallest cost. */
    528   size_t blocksize = inend - instart;
    529   unsigned short* length_array =
    530       (unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
    531   unsigned short* path = 0;
    532   size_t pathsize = 0;
    533 
    534   if (!length_array) exit(-1); /* Allocation failed. */
    535 
    536   s->blockstart = instart;
    537   s->blockend = inend;
    538 
    539   /* Shortest path for fixed tree This one should give the shortest possible
    540   result for fixed tree, no repeated runs are needed since the tree is known. */
    541   LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
    542                  length_array, GetCostFixed, 0, store);
    543 
    544   free(length_array);
    545   free(path);
    546 }
    547