Skip to content
This repository was archived by the owner on Oct 14, 2025. It is now read-only.

Commit 0dfa6eb

Browse files
committed
Merge branch 'patch-2' of https://github.com/MrKrzYch00/zopfli into MrKrzYch00-patch-2
2 parents 37f6da6 + 365bda1 commit 0dfa6eb

File tree

6 files changed

+59
-45
lines changed

6 files changed

+59
-45
lines changed

src/zopfli/blocksplitter.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,16 +281,19 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
281281
size_t* lz77splitpoints = 0;
282282
size_t nlz77points = 0;
283283
ZopfliLZ77Store store;
284+
ZopfliHash hash;
285+
ZopfliHash* h = &hash;
284286

285287
ZopfliInitLZ77Store(in, &store);
286288
ZopfliInitBlockState(options, instart, inend, 0, &s);
289+
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);
287290

288291
*npoints = 0;
289292
*splitpoints = 0;
290293

291294
/* Unintuitively, Using a simple LZ77 method here instead of ZopfliLZ77Optimal
292295
results in better blocks. */
293-
ZopfliLZ77Greedy(&s, in, instart, inend, &store);
296+
ZopfliLZ77Greedy(&s, in, instart, inend, &store, h);
294297

295298
ZopfliBlockSplitLZ77(options,
296299
&store, maxblocks,
@@ -313,6 +316,7 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
313316
free(lz77splitpoints);
314317
ZopfliCleanBlockState(&s);
315318
ZopfliCleanLZ77Store(&store);
319+
ZopfliCleanHash(h);
316320
}
317321

318322
void ZopfliBlockSplitSimple(const unsigned char* in,

src/zopfli/hash.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,26 @@ Author: [email protected] (Jyrki Alakuijala)
2626
#define HASH_SHIFT 5
2727
#define HASH_MASK 32767
2828

29-
void ZopfliInitHash(size_t window_size, ZopfliHash* h) {
30-
size_t i;
31-
32-
h->val = 0;
29+
void ZopfliAllocHash(size_t window_size, ZopfliHash* h) {
3330
h->head = (int*)malloc(sizeof(*h->head) * 65536);
3431
h->prev = (unsigned short*)malloc(sizeof(*h->prev) * window_size);
3532
h->hashval = (int*)malloc(sizeof(*h->hashval) * window_size);
33+
34+
#ifdef ZOPFLI_HASH_SAME
35+
h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
36+
#endif
37+
38+
#ifdef ZOPFLI_HASH_SAME_HASH
39+
h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
40+
h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
41+
h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
42+
#endif
43+
}
44+
45+
void ZopfliResetHash(size_t window_size, ZopfliHash* h) {
46+
size_t i;
47+
48+
h->val = 0;
3649
for (i = 0; i < 65536; i++) {
3750
h->head[i] = -1; /* -1 indicates no head so far. */
3851
}
@@ -42,17 +55,13 @@ void ZopfliInitHash(size_t window_size, ZopfliHash* h) {
4255
}
4356

4457
#ifdef ZOPFLI_HASH_SAME
45-
h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
4658
for (i = 0; i < window_size; i++) {
4759
h->same[i] = 0;
4860
}
4961
#endif
5062

5163
#ifdef ZOPFLI_HASH_SAME_HASH
5264
h->val2 = 0;
53-
h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
54-
h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
55-
h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
5665
for (i = 0; i < 65536; i++) {
5766
h->head2[i] = -1;
5867
}

src/zopfli/hash.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ typedef struct ZopfliHash {
4646
#endif
4747
} ZopfliHash;
4848

49-
/* Allocates and initializes all fields of ZopfliHash. */
50-
void ZopfliInitHash(size_t window_size, ZopfliHash* h);
49+
/* Allocates ZopfliHash memory. */
50+
void ZopfliAllocHash(size_t window_size, ZopfliHash* h);
5151

52-
/* Frees all fields of ZopfliHash. */
52+
/* Resets all fields of ZopfliHash. */
53+
void ZopfliResetHash(size_t window_size, ZopfliHash* h);
54+
55+
/* Frees ZopfliHash memory. */
5356
void ZopfliCleanHash(ZopfliHash* h);
5457

5558
/*

src/zopfli/lz77.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h,
543543

544544
void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
545545
size_t instart, size_t inend,
546-
ZopfliLZ77Store* store) {
546+
ZopfliLZ77Store* store, ZopfliHash* h) {
547547
size_t i = 0, j;
548548
unsigned short leng;
549549
unsigned short dist;
@@ -552,9 +552,6 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
552552
? instart - ZOPFLI_WINDOW_SIZE : 0;
553553
unsigned short dummysublen[259];
554554

555-
ZopfliHash hash;
556-
ZopfliHash* h = &hash;
557-
558555
#ifdef ZOPFLI_LAZY_MATCHING
559556
/* Lazy matching. */
560557
unsigned prev_length = 0;
@@ -565,7 +562,7 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
565562

566563
if (instart == inend) return;
567564

568-
ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
565+
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
569566
ZopfliWarmupHash(in, windowstart, inend, h);
570567
for (i = windowstart; i < instart; i++) {
571568
ZopfliUpdateHash(in, i, inend, h);
@@ -630,6 +627,4 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
630627
ZopfliUpdateHash(in, i, inend, h);
631628
}
632629
}
633-
634-
ZopfliCleanHash(h);
635630
}

src/zopfli/lz77.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,6 @@ dictionary.
137137
*/
138138
void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
139139
size_t instart, size_t inend,
140-
ZopfliLZ77Store* store);
140+
ZopfliLZ77Store* store, ZopfliHash* h);
141141

142142
#endif /* ZOPFLI_LZ77_H_ */

src/zopfli/squeeze.c

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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,
346338
static 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

533528
void 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

Comments
 (0)