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