Skip to content

Commit

Permalink
Merge branch 'patch-2' of https://github.com/MrKrzYch00/zopfli into M…
Browse files Browse the repository at this point in the history
…rKrzYch00-patch-2
  • Loading branch information
lvandeve committed Apr 22, 2016
2 parents 37f6da6 + 365bda1 commit 0dfa6eb
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 45 deletions.
6 changes: 5 additions & 1 deletion src/zopfli/blocksplitter.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,19 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
size_t* lz77splitpoints = 0;
size_t nlz77points = 0;
ZopfliLZ77Store store;
ZopfliHash hash;
ZopfliHash* h = &hash;

ZopfliInitLZ77Store(in, &store);
ZopfliInitBlockState(options, instart, inend, 0, &s);
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);

*npoints = 0;
*splitpoints = 0;

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

ZopfliBlockSplitLZ77(options,
&store, maxblocks,
Expand All @@ -313,6 +316,7 @@ void ZopfliBlockSplit(const ZopfliOptions* options,
free(lz77splitpoints);
ZopfliCleanBlockState(&s);
ZopfliCleanLZ77Store(&store);
ZopfliCleanHash(h);
}

void ZopfliBlockSplitSimple(const unsigned char* in,
Expand Down
25 changes: 17 additions & 8 deletions src/zopfli/hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,26 @@ Author: [email protected] (Jyrki Alakuijala)
#define HASH_SHIFT 5
#define HASH_MASK 32767

void ZopfliInitHash(size_t window_size, ZopfliHash* h) {
size_t i;

h->val = 0;
void ZopfliAllocHash(size_t window_size, ZopfliHash* h) {
h->head = (int*)malloc(sizeof(*h->head) * 65536);
h->prev = (unsigned short*)malloc(sizeof(*h->prev) * window_size);
h->hashval = (int*)malloc(sizeof(*h->hashval) * window_size);

#ifdef ZOPFLI_HASH_SAME
h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
#endif

#ifdef ZOPFLI_HASH_SAME_HASH
h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
#endif
}

void ZopfliResetHash(size_t window_size, ZopfliHash* h) {
size_t i;

h->val = 0;
for (i = 0; i < 65536; i++) {
h->head[i] = -1; /* -1 indicates no head so far. */
}
Expand All @@ -42,17 +55,13 @@ void ZopfliInitHash(size_t window_size, ZopfliHash* h) {
}

#ifdef ZOPFLI_HASH_SAME
h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
for (i = 0; i < window_size; i++) {
h->same[i] = 0;
}
#endif

#ifdef ZOPFLI_HASH_SAME_HASH
h->val2 = 0;
h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
for (i = 0; i < 65536; i++) {
h->head2[i] = -1;
}
Expand Down
9 changes: 6 additions & 3 deletions src/zopfli/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ typedef struct ZopfliHash {
#endif
} ZopfliHash;

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

/* Frees all fields of ZopfliHash. */
/* Resets all fields of ZopfliHash. */
void ZopfliResetHash(size_t window_size, ZopfliHash* h);

/* Frees ZopfliHash memory. */
void ZopfliCleanHash(ZopfliHash* h);

/*
Expand Down
9 changes: 2 additions & 7 deletions src/zopfli/lz77.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ void ZopfliFindLongestMatch(ZopfliBlockState* s, const ZopfliHash* h,

void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
size_t instart, size_t inend,
ZopfliLZ77Store* store) {
ZopfliLZ77Store* store, ZopfliHash* h) {
size_t i = 0, j;
unsigned short leng;
unsigned short dist;
Expand All @@ -552,9 +552,6 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
? instart - ZOPFLI_WINDOW_SIZE : 0;
unsigned short dummysublen[259];

ZopfliHash hash;
ZopfliHash* h = &hash;

#ifdef ZOPFLI_LAZY_MATCHING
/* Lazy matching. */
unsigned prev_length = 0;
Expand All @@ -565,7 +562,7 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,

if (instart == inend) return;

ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliWarmupHash(in, windowstart, inend, h);
for (i = windowstart; i < instart; i++) {
ZopfliUpdateHash(in, i, inend, h);
Expand Down Expand Up @@ -630,6 +627,4 @@ void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
ZopfliUpdateHash(in, i, inend, h);
}
}

ZopfliCleanHash(h);
}
2 changes: 1 addition & 1 deletion src/zopfli/lz77.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,6 @@ dictionary.
*/
void ZopfliLZ77Greedy(ZopfliBlockState* s, const unsigned char* in,
size_t instart, size_t inend,
ZopfliLZ77Store* store);
ZopfliLZ77Store* store, ZopfliHash* h);

#endif /* ZOPFLI_LZ77_H_ */
53 changes: 28 additions & 25 deletions src/zopfli/squeeze.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,28 +218,23 @@ static double GetBestLengths(ZopfliBlockState *s,
const unsigned char* in,
size_t instart, size_t inend,
CostModelFun* costmodel, void* costcontext,
unsigned short* length_array) {
unsigned short* length_array,
ZopfliHash* h, float* costs) {
/* Best cost to get here so far. */
size_t blocksize = inend - instart;
float* costs;
size_t i = 0, k, kend;
unsigned short leng;
unsigned short dist;
unsigned short sublen[259];
size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
? instart - ZOPFLI_WINDOW_SIZE : 0;
ZopfliHash hash;
ZopfliHash* h = &hash;
double result;
double mincost = GetCostModelMinCost(costmodel, costcontext);
double mincostaddcostj;

if (instart == inend) return 0;

costs = (float*)malloc(sizeof(float) * (blocksize + 1));
if (!costs) exit(-1); /* Allocation failed. */

ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliWarmupHash(in, windowstart, inend, h);
for (i = windowstart; i < instart; i++) {
ZopfliUpdateHash(in, i, inend, h);
Expand Down Expand Up @@ -310,9 +305,6 @@ static double GetBestLengths(ZopfliBlockState *s,
assert(costs[blocksize] >= 0);
result = costs[blocksize];

ZopfliCleanHash(h);
free(costs);

return result;
}

Expand Down Expand Up @@ -346,19 +338,16 @@ static void TraceBackwards(size_t size, const unsigned short* length_array,
static void FollowPath(ZopfliBlockState* s,
const unsigned char* in, size_t instart, size_t inend,
unsigned short* path, size_t pathsize,
ZopfliLZ77Store* store) {
ZopfliLZ77Store* store, ZopfliHash *h) {
size_t i, j, pos = 0;
size_t windowstart = instart > ZOPFLI_WINDOW_SIZE
? instart - ZOPFLI_WINDOW_SIZE : 0;

size_t total_length_test = 0;

ZopfliHash hash;
ZopfliHash* h = &hash;

if (instart == inend) return;

ZopfliInitHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliResetHash(ZOPFLI_WINDOW_SIZE, h);
ZopfliWarmupHash(in, windowstart, inend, h);
for (i = windowstart; i < instart; i++) {
ZopfliUpdateHash(in, i, inend, h);
Expand Down Expand Up @@ -397,8 +386,6 @@ static void FollowPath(ZopfliBlockState* s,

pos += length;
}

ZopfliCleanHash(h);
}

/* Calculates the entropy of the statistics */
Expand Down Expand Up @@ -443,14 +430,15 @@ static double 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) {
double cost = GetBestLengths(
s, in, instart, inend, costmodel, costcontext, length_array);
void* costcontext, ZopfliLZ77Store* store,
ZopfliHash* h, float* costs) {
double cost = GetBestLengths(s, in, instart, inend, costmodel,
costcontext, length_array, h, costs);
free(*path);
*path = 0;
*pathsize = 0;
TraceBackwards(inend - instart, length_array, path, pathsize);
FollowPath(s, in, instart, inend, *path, *pathsize, store);
FollowPath(s, in, instart, inend, *path, *pathsize, store, h);
assert(cost < ZOPFLI_LARGE_FLOAT);
return cost;
}
Expand All @@ -466,26 +454,31 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,
unsigned short* path = 0;
size_t pathsize = 0;
ZopfliLZ77Store currentstore;
ZopfliHash hash;
ZopfliHash* h = &hash;
SymbolStats stats, beststats, laststats;
int i;
float* costs = (float*)malloc(sizeof(float) * (blocksize + 1));
double cost;
double bestcost = ZOPFLI_LARGE_FLOAT;
double lastcost = 0;
/* Try randomizing the costs a bit once the size stabilizes. */
RanState ran_state;
int lastrandomstep = -1;

if (!costs) exit(-1); /* Allocation failed. */
if (!length_array) exit(-1); /* Allocation failed. */

InitRanState(&ran_state);
InitStats(&stats);
ZopfliInitLZ77Store(in, &currentstore);
ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);

/* Do regular deflate, then loop multiple shortest path runs, each time using
the statistics of the previous run. */

/* Initial run. */
ZopfliLZ77Greedy(s, in, instart, inend, &currentstore);
ZopfliLZ77Greedy(s, in, instart, inend, &currentstore, h);
GetStatistics(&currentstore, &stats);

/* Repeat statistics with each time the cost model from the previous stat
Expand All @@ -495,7 +488,7 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,
ZopfliInitLZ77Store(in, &currentstore);
LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
length_array, GetCostStat, (void*)&stats,
&currentstore);
&currentstore, h, costs);
cost = ZopfliCalculateBlockSize(&currentstore, 0, currentstore.size, 2);
if (s->options->verbose_more || (s->options->verbose && cost < bestcost)) {
fprintf(stderr, "Iteration %d: %d bit\n", i, (int) cost);
Expand Down Expand Up @@ -527,7 +520,9 @@ void ZopfliLZ77Optimal(ZopfliBlockState *s,

free(length_array);
free(path);
free(costs);
ZopfliCleanLZ77Store(&currentstore);
ZopfliCleanHash(h);
}

void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
Expand All @@ -541,17 +536,25 @@ void ZopfliLZ77OptimalFixed(ZopfliBlockState *s,
(unsigned short*)malloc(sizeof(unsigned short) * (blocksize + 1));
unsigned short* path = 0;
size_t pathsize = 0;
ZopfliHash hash;
ZopfliHash* h = &hash;
float* costs = (float*)malloc(sizeof(float) * (blocksize + 1));

if (!costs) exit(-1); /* Allocation failed. */
if (!length_array) exit(-1); /* Allocation failed. */

ZopfliAllocHash(ZOPFLI_WINDOW_SIZE, h);

s->blockstart = instart;
s->blockend = inend;

/* Shortest path for fixed tree This one should give the shortest possible
result for fixed tree, no repeated runs are needed since the tree is known. */
LZ77OptimalRun(s, in, instart, inend, &path, &pathsize,
length_array, GetCostFixed, 0, store);
length_array, GetCostFixed, 0, store, h, costs);

free(length_array);
free(path);
free(costs);
ZopfliCleanHash(h);
}

0 comments on commit 0dfa6eb

Please sign in to comment.