@@ -218,28 +218,23 @@ static double GetBestLengths(ZopfliBlockState *s,
218218 const unsigned char * in ,
219219 size_t instart , size_t inend ,
220220 CostModelFun * costmodel , void * costcontext ,
221- unsigned short * length_array ) {
221+ unsigned short * length_array ,
222+ ZopfliHash * h , float * costs ) {
222223 /* Best cost to get here so far. */
223224 size_t blocksize = inend - instart ;
224- float * costs ;
225225 size_t i = 0 , k , kend ;
226226 unsigned short leng ;
227227 unsigned short dist ;
228228 unsigned short sublen [259 ];
229229 size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
230230 ? instart - ZOPFLI_WINDOW_SIZE : 0 ;
231- ZopfliHash hash ;
232- ZopfliHash * h = & hash ;
233231 double result ;
234232 double mincost = GetCostModelMinCost (costmodel , costcontext );
235233 double mincostaddcostj ;
236234
237235 if (instart == inend ) return 0 ;
238236
239- costs = (float * )malloc (sizeof (float ) * (blocksize + 1 ));
240- if (!costs ) exit (-1 ); /* Allocation failed. */
241-
242- ZopfliInitHash (ZOPFLI_WINDOW_SIZE , h );
237+ ZopfliResetHash (ZOPFLI_WINDOW_SIZE , h );
243238 ZopfliWarmupHash (in , windowstart , inend , h );
244239 for (i = windowstart ; i < instart ; i ++ ) {
245240 ZopfliUpdateHash (in , i , inend , h );
@@ -310,9 +305,6 @@ static double GetBestLengths(ZopfliBlockState *s,
310305 assert (costs [blocksize ] >= 0 );
311306 result = costs [blocksize ];
312307
313- ZopfliCleanHash (h );
314- free (costs );
315-
316308 return result ;
317309}
318310
@@ -346,19 +338,16 @@ static void TraceBackwards(size_t size, const unsigned short* length_array,
346338static void FollowPath (ZopfliBlockState * s ,
347339 const unsigned char * in , size_t instart , size_t inend ,
348340 unsigned short * path , size_t pathsize ,
349- ZopfliLZ77Store * store ) {
341+ ZopfliLZ77Store * store , ZopfliHash * h ) {
350342 size_t i , j , pos = 0 ;
351343 size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
352344 ? instart - ZOPFLI_WINDOW_SIZE : 0 ;
353345
354346 size_t total_length_test = 0 ;
355347
356- ZopfliHash hash ;
357- ZopfliHash * h = & hash ;
358-
359348 if (instart == inend ) return ;
360349
361- ZopfliInitHash (ZOPFLI_WINDOW_SIZE , h );
350+ ZopfliResetHash (ZOPFLI_WINDOW_SIZE , h );
362351 ZopfliWarmupHash (in , windowstart , inend , h );
363352 for (i = windowstart ; i < instart ; i ++ ) {
364353 ZopfliUpdateHash (in , i , inend , h );
@@ -397,8 +386,6 @@ static void FollowPath(ZopfliBlockState* s,
397386
398387 pos += length ;
399388 }
400-
401- ZopfliCleanHash (h );
402389}
403390
404391/* Calculates the entropy of the statistics */
@@ -443,14 +430,15 @@ static double LZ77OptimalRun(ZopfliBlockState* s,
443430 const unsigned char * in , size_t instart , size_t inend ,
444431 unsigned short * * path , size_t * pathsize ,
445432 unsigned short * length_array , CostModelFun * costmodel ,
446- void * costcontext , ZopfliLZ77Store * store ) {
447- double cost = GetBestLengths (
448- s , in , instart , inend , costmodel , costcontext , length_array );
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 );
449437 free (* path );
450438 * path = 0 ;
451439 * pathsize = 0 ;
452440 TraceBackwards (inend - instart , length_array , path , pathsize );
453- FollowPath (s , in , instart , inend , * path , * pathsize , store );
441+ FollowPath (s , in , instart , inend , * path , * pathsize , store , h );
454442 assert (cost < ZOPFLI_LARGE_FLOAT );
455443 return cost ;
456444}
@@ -466,26 +454,31 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,
466454 unsigned short * path = 0 ;
467455 size_t pathsize = 0 ;
468456 ZopfliLZ77Store currentstore ;
457+ ZopfliHash hash ;
458+ ZopfliHash * h = & hash ;
469459 SymbolStats stats , beststats , laststats ;
470460 int i ;
461+ float * costs = (float * )malloc (sizeof (float ) * (blocksize + 1 ));
471462 double cost ;
472463 double bestcost = ZOPFLI_LARGE_FLOAT ;
473464 double lastcost = 0 ;
474465 /* Try randomizing the costs a bit once the size stabilizes. */
475466 RanState ran_state ;
476467 int lastrandomstep = -1 ;
477468
469+ if (!costs ) exit (-1 ); /* Allocation failed. */
478470 if (!length_array ) exit (-1 ); /* Allocation failed. */
479471
480472 InitRanState (& ran_state );
481473 InitStats (& stats );
482474 ZopfliInitLZ77Store (in , & currentstore );
475+ ZopfliAllocHash (ZOPFLI_WINDOW_SIZE , h );
483476
484477 /* Do regular deflate, then loop multiple shortest path runs, each time using
485478 the statistics of the previous run. */
486479
487480 /* Initial run. */
488- ZopfliLZ77Greedy (s , in , instart , inend , & currentstore );
481+ ZopfliLZ77Greedy (s , in , instart , inend , & currentstore , h );
489482 GetStatistics (& currentstore , & stats );
490483
491484 /* Repeat statistics with each time the cost model from the previous stat
@@ -495,7 +488,7 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,
495488 ZopfliInitLZ77Store (in , & currentstore );
496489 LZ77OptimalRun (s , in , instart , inend , & path , & pathsize ,
497490 length_array , GetCostStat , (void * )& stats ,
498- & currentstore );
491+ & currentstore , h , costs );
499492 cost = ZopfliCalculateBlockSize (& currentstore , 0 , currentstore .size , 2 );
500493 if (s -> options -> verbose_more || (s -> options -> verbose && cost < bestcost )) {
501494 fprintf (stderr , "Iteration %d: %d bit\n" , i , (int ) cost );
@@ -527,7 +520,9 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,
527520
528521 free (length_array );
529522 free (path );
523+ free (costs );
530524 ZopfliCleanLZ77Store (& currentstore );
525+ ZopfliCleanHash (h );
531526}
532527
533528void ZopfliLZ77OptimalFixed (ZopfliBlockState * s ,
@@ -541,17 +536,25 @@ void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
541536 (unsigned short * )malloc (sizeof (unsigned short ) * (blocksize + 1 ));
542537 unsigned short * path = 0 ;
543538 size_t pathsize = 0 ;
539+ ZopfliHash hash ;
540+ ZopfliHash * h = & hash ;
541+ float * costs = (float * )malloc (sizeof (float ) * (blocksize + 1 ));
544542
543+ if (!costs ) exit (-1 ); /* Allocation failed. */
545544 if (!length_array ) exit (-1 ); /* Allocation failed. */
546545
546+ ZopfliAllocHash (ZOPFLI_WINDOW_SIZE , h );
547+
547548 s -> blockstart = instart ;
548549 s -> blockend = inend ;
549550
550551 /* Shortest path for fixed tree This one should give the shortest possible
551552 result for fixed tree, no repeated runs are needed since the tree is known. */
552553 LZ77OptimalRun (s , in , instart , inend , & path , & pathsize ,
553- length_array , GetCostFixed , 0 , store );
554+ length_array , GetCostFixed , 0 , store , h , costs );
554555
555556 free (length_array );
556557 free (path );
558+ free (costs );
559+ ZopfliCleanHash (h );
557560}
0 commit comments