zopfli 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +35 -0
  3. data/.github/workflows/publish.yml +34 -0
  4. data/.gitmodules +1 -1
  5. data/Gemfile +4 -0
  6. data/README.md +6 -1
  7. data/Rakefile +14 -10
  8. data/ext/extconf.rb +36 -32
  9. data/ext/zopfli.c +52 -20
  10. data/lib/zopfli/version.rb +1 -1
  11. data/smoke.sh +9 -0
  12. data/test/test_helper.rb +7 -0
  13. data/test/zopfli_test.rb +63 -0
  14. data/vendor/zopfli/src/zopfli/blocksplitter.c +41 -53
  15. data/vendor/zopfli/src/zopfli/blocksplitter.h +2 -6
  16. data/vendor/zopfli/src/zopfli/cache.c +6 -0
  17. data/vendor/zopfli/src/zopfli/deflate.c +613 -381
  18. data/vendor/zopfli/src/zopfli/deflate.h +8 -2
  19. data/vendor/zopfli/src/zopfli/gzip_container.c +54 -47
  20. data/vendor/zopfli/src/zopfli/hash.c +18 -10
  21. data/vendor/zopfli/src/zopfli/hash.h +10 -7
  22. data/vendor/zopfli/src/zopfli/katajainen.c +73 -62
  23. data/vendor/zopfli/src/zopfli/katajainen.h +1 -1
  24. data/vendor/zopfli/src/zopfli/lz77.c +190 -42
  25. data/vendor/zopfli/src/zopfli/lz77.h +39 -23
  26. data/vendor/zopfli/src/zopfli/squeeze.c +75 -61
  27. data/vendor/zopfli/src/zopfli/squeeze.h +1 -0
  28. data/vendor/zopfli/src/zopfli/symbols.h +239 -0
  29. data/vendor/zopfli/src/zopfli/util.c +0 -178
  30. data/vendor/zopfli/src/zopfli/util.h +6 -23
  31. data/vendor/zopfli/src/zopfli/zlib_container.c +1 -1
  32. data/vendor/zopfli/src/zopfli/zopfli.h +1 -4
  33. data/vendor/zopfli/src/zopfli/zopfli_bin.c +31 -15
  34. data/zopfli.gemspec +12 -32
  35. metadata +20 -68
  36. data/test/fixtures/alice29.txt +0 -3609
  37. data/test/test_zopfli_deflate.rb +0 -47
  38. data/vendor/zopfli/CONTRIBUTORS +0 -7
  39. data/vendor/zopfli/README +0 -32
  40. data/vendor/zopfli/README.zopflipng +0 -35
  41. data/vendor/zopfli/makefile +0 -37
  42. data/vendor/zopfli/src/zopflipng/lodepng/lodepng.cpp +0 -6253
  43. data/vendor/zopfli/src/zopflipng/lodepng/lodepng.h +0 -1705
  44. data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.cpp +0 -656
  45. data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.h +0 -151
  46. data/vendor/zopfli/src/zopflipng/zopflipng_bin.cc +0 -407
  47. data/vendor/zopfli/src/zopflipng/zopflipng_lib.cc +0 -376
  48. data/vendor/zopfli/src/zopflipng/zopflipng_lib.h +0 -79
@@ -30,21 +30,17 @@ ones that enhance it.
30
30
 
31
31
  #include <stdlib.h>
32
32
 
33
+ #include "lz77.h"
33
34
  #include "zopfli.h"
34
35
 
35
36
 
36
37
  /*
37
38
  Does blocksplitting on LZ77 data.
38
39
  The output splitpoints are indices in the LZ77 data.
39
- litlens: lz77 lit/lengths
40
- dists: lz77 distances
41
- llsize: size of litlens and dists
42
40
  maxblocks: set a limit to the amount of blocks. Set to 0 to mean no limit.
43
41
  */
44
42
  void ZopfliBlockSplitLZ77(const ZopfliOptions* options,
45
- const unsigned short* litlens,
46
- const unsigned short* dists,
47
- size_t llsize, size_t maxblocks,
43
+ const ZopfliLZ77Store* lz77, size_t maxblocks,
48
44
  size_t** splitpoints, size_t* npoints);
49
45
 
50
46
  /*
@@ -31,6 +31,12 @@ void ZopfliInitCache(size_t blocksize, ZopfliLongestMatchCache* lmc) {
31
31
  lmc->dist = (unsigned short*)malloc(sizeof(unsigned short) * blocksize);
32
32
  /* Rather large amount of memory. */
33
33
  lmc->sublen = (unsigned char*)malloc(ZOPFLI_CACHE_LENGTH * 3 * blocksize);
34
+ if(lmc->sublen == NULL) {
35
+ fprintf(stderr,
36
+ "Error: Out of memory. Tried allocating %lu bytes of memory.\n",
37
+ ZOPFLI_CACHE_LENGTH * 3 * blocksize);
38
+ exit (EXIT_FAILURE);
39
+ }
34
40
 
35
41
  /* length > 0 and dist 0 is invalid combination, which indicates on purpose
36
42
  that this cache value is not filled in yet. */
@@ -24,15 +24,22 @@ Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
24
24
  #include <stdlib.h>
25
25
 
26
26
  #include "blocksplitter.h"
27
- #include "lz77.h"
28
27
  #include "squeeze.h"
28
+ #include "symbols.h"
29
29
  #include "tree.h"
30
30
 
31
+ /*
32
+ bp = bitpointer, always in range [0, 7].
33
+ The outsize is number of necessary bytes to encode the bits.
34
+ Given the value of bp and the amount of bytes, the amount of bits represented
35
+ is not simply bytesize * 8 + bp because even representing one bit requires a
36
+ whole byte. It is: (bp == 0) ? (bytesize * 8) : ((bytesize - 1) * 8 + bp)
37
+ */
31
38
  static void AddBit(int bit,
32
39
  unsigned char* bp, unsigned char** out, size_t* outsize) {
33
- if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
34
- (*out)[*outsize - 1] |= bit << ((*bp) & 7);
35
- (*bp)++;
40
+ if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
41
+ (*out)[*outsize - 1] |= bit << *bp;
42
+ *bp = (*bp + 1) & 7;
36
43
  }
37
44
 
38
45
  static void AddBits(unsigned symbol, unsigned length,
@@ -41,9 +48,9 @@ static void AddBits(unsigned symbol, unsigned length,
41
48
  unsigned i;
42
49
  for (i = 0; i < length; i++) {
43
50
  unsigned bit = (symbol >> i) & 1;
44
- if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
45
- (*out)[*outsize - 1] |= bit << ((*bp) & 7);
46
- (*bp)++;
51
+ if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
52
+ (*out)[*outsize - 1] |= bit << *bp;
53
+ *bp = (*bp + 1) & 7;
47
54
  }
48
55
  }
49
56
 
@@ -58,9 +65,9 @@ static void AddHuffmanBits(unsigned symbol, unsigned length,
58
65
  unsigned i;
59
66
  for (i = 0; i < length; i++) {
60
67
  unsigned bit = (symbol >> (length - i - 1)) & 1;
61
- if (((*bp) & 7) == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
62
- (*out)[*outsize - 1] |= bit << ((*bp) & 7);
63
- (*bp)++;
68
+ if (*bp == 0) ZOPFLI_APPEND_DATA(0, out, outsize);
69
+ (*out)[*outsize - 1] |= bit << *bp;
70
+ *bp = (*bp + 1) & 7;
64
71
  }
65
72
  }
66
73
 
@@ -91,141 +98,195 @@ static void PatchDistanceCodesForBuggyDecoders(unsigned* d_lengths) {
91
98
  }
92
99
  }
93
100
 
94
- static void AddDynamicTree(const unsigned* ll_lengths,
95
- const unsigned* d_lengths,
96
- unsigned char* bp,
97
- unsigned char** out, size_t* outsize) {
98
- unsigned* lld_lengths = 0; /* All litlen and dist lengthts with ending zeros
99
- trimmed together in one array. */
100
- unsigned lld_total; /* Size of lld_lengths. */
101
- unsigned* rle = 0; /* Runlength encoded version of lengths of litlen and dist
102
- trees. */
101
+ /*
102
+ Encodes the Huffman tree and returns how many bits its encoding takes. If out
103
+ is a null pointer, only returns the size and runs faster.
104
+ */
105
+ static size_t EncodeTree(const unsigned* ll_lengths,
106
+ const unsigned* d_lengths,
107
+ int use_16, int use_17, int use_18,
108
+ unsigned char* bp,
109
+ unsigned char** out, size_t* outsize) {
110
+ unsigned lld_total; /* Total amount of literal, length, distance codes. */
111
+ /* Runlength encoded version of lengths of litlen and dist trees. */
112
+ unsigned* rle = 0;
103
113
  unsigned* rle_bits = 0; /* Extra bits for rle values 16, 17 and 18. */
104
114
  size_t rle_size = 0; /* Size of rle array. */
105
115
  size_t rle_bits_size = 0; /* Should have same value as rle_size. */
106
- unsigned hlit = 29; /* 286 - 257 */
116
+ unsigned hlit = 29; /* 286 - 257 */
107
117
  unsigned hdist = 29; /* 32 - 1, but gzip does not like hdist > 29.*/
108
118
  unsigned hclen;
119
+ unsigned hlit2;
109
120
  size_t i, j;
110
121
  size_t clcounts[19];
111
122
  unsigned clcl[19]; /* Code length code lengths. */
112
123
  unsigned clsymbols[19];
113
124
  /* The order in which code length code lengths are encoded as per deflate. */
114
- unsigned order[19] = {
125
+ static const unsigned order[19] = {
115
126
  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
116
127
  };
128
+ int size_only = !out;
129
+ size_t result_size = 0;
130
+
131
+ for(i = 0; i < 19; i++) clcounts[i] = 0;
117
132
 
118
133
  /* Trim zeros. */
119
134
  while (hlit > 0 && ll_lengths[257 + hlit - 1] == 0) hlit--;
120
135
  while (hdist > 0 && d_lengths[1 + hdist - 1] == 0) hdist--;
136
+ hlit2 = hlit + 257;
121
137
 
122
- lld_total = hlit + 257 + hdist + 1;
123
- lld_lengths = (unsigned*)malloc(sizeof(*lld_lengths) * lld_total);
124
- if (!lld_lengths) exit(-1); /* Allocation failed. */
138
+ lld_total = hlit2 + hdist + 1;
125
139
 
126
140
  for (i = 0; i < lld_total; i++) {
127
- lld_lengths[i] = i < 257 + hlit
128
- ? ll_lengths[i] : d_lengths[i - 257 - hlit];
129
- assert(lld_lengths[i] < 16);
130
- }
131
-
132
- for (i = 0; i < lld_total; i++) {
133
- size_t count = 0;
134
- for (j = i; j < lld_total && lld_lengths[i] == lld_lengths[j]; j++) {
135
- count++;
141
+ /* This is an encoding of a huffman tree, so now the length is a symbol */
142
+ unsigned char symbol = i < hlit2 ? ll_lengths[i] : d_lengths[i - hlit2];
143
+ unsigned count = 1;
144
+ if(use_16 || (symbol == 0 && (use_17 || use_18))) {
145
+ for (j = i + 1; j < lld_total && symbol ==
146
+ (j < hlit2 ? ll_lengths[j] : d_lengths[j - hlit2]); j++) {
147
+ count++;
148
+ }
136
149
  }
137
- if (count >= 4 || (count >= 3 && lld_lengths[i] == 0)) {
138
- if (lld_lengths[i] == 0) {
139
- if (count > 10) {
140
- if (count > 138) count = 138;
141
- ZOPFLI_APPEND_DATA(18, &rle, &rle_size);
142
- ZOPFLI_APPEND_DATA(count - 11, &rle_bits, &rle_bits_size);
143
- } else {
144
- ZOPFLI_APPEND_DATA(17, &rle, &rle_size);
145
- ZOPFLI_APPEND_DATA(count - 3, &rle_bits, &rle_bits_size);
150
+ i += count - 1;
151
+
152
+ /* Repetitions of zeroes */
153
+ if (symbol == 0 && count >= 3) {
154
+ if (use_18) {
155
+ while (count >= 11) {
156
+ unsigned count2 = count > 138 ? 138 : count;
157
+ if (!size_only) {
158
+ ZOPFLI_APPEND_DATA(18, &rle, &rle_size);
159
+ ZOPFLI_APPEND_DATA(count2 - 11, &rle_bits, &rle_bits_size);
160
+ }
161
+ clcounts[18]++;
162
+ count -= count2;
146
163
  }
147
- } else {
148
- unsigned repeat = count - 1; /* Since the first one is hardcoded. */
149
- ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
150
- ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
151
- while (repeat >= 6) {
152
- ZOPFLI_APPEND_DATA(16, &rle, &rle_size);
153
- ZOPFLI_APPEND_DATA(6 - 3, &rle_bits, &rle_bits_size);
154
- repeat -= 6;
164
+ }
165
+ if (use_17) {
166
+ while (count >= 3) {
167
+ unsigned count2 = count > 10 ? 10 : count;
168
+ if (!size_only) {
169
+ ZOPFLI_APPEND_DATA(17, &rle, &rle_size);
170
+ ZOPFLI_APPEND_DATA(count2 - 3, &rle_bits, &rle_bits_size);
171
+ }
172
+ clcounts[17]++;
173
+ count -= count2;
155
174
  }
156
- if (repeat >= 3) {
175
+ }
176
+ }
177
+
178
+ /* Repetitions of any symbol */
179
+ if (use_16 && count >= 4) {
180
+ count--; /* Since the first one is hardcoded. */
181
+ clcounts[symbol]++;
182
+ if (!size_only) {
183
+ ZOPFLI_APPEND_DATA(symbol, &rle, &rle_size);
184
+ ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
185
+ }
186
+ while (count >= 3) {
187
+ unsigned count2 = count > 6 ? 6 : count;
188
+ if (!size_only) {
157
189
  ZOPFLI_APPEND_DATA(16, &rle, &rle_size);
158
- ZOPFLI_APPEND_DATA(repeat - 3, &rle_bits, &rle_bits_size);
159
- repeat = 0;
160
- }
161
- while (repeat != 0) {
162
- ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
163
- ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
164
- repeat--;
190
+ ZOPFLI_APPEND_DATA(count2 - 3, &rle_bits, &rle_bits_size);
165
191
  }
192
+ clcounts[16]++;
193
+ count -= count2;
166
194
  }
167
-
168
- i += count - 1;
169
- } else {
170
- ZOPFLI_APPEND_DATA(lld_lengths[i], &rle, &rle_size);
171
- ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
172
195
  }
173
- assert(rle[rle_size - 1] <= 18);
174
- }
175
196
 
176
- for (i = 0; i < 19; i++) {
177
- clcounts[i] = 0;
178
- }
179
- for (i = 0; i < rle_size; i++) {
180
- clcounts[rle[i]]++;
197
+ /* No or insufficient repetition */
198
+ clcounts[symbol] += count;
199
+ while (count > 0) {
200
+ if (!size_only) {
201
+ ZOPFLI_APPEND_DATA(symbol, &rle, &rle_size);
202
+ ZOPFLI_APPEND_DATA(0, &rle_bits, &rle_bits_size);
203
+ }
204
+ count--;
205
+ }
181
206
  }
182
207
 
183
208
  ZopfliCalculateBitLengths(clcounts, 19, 7, clcl);
184
- ZopfliLengthsToSymbols(clcl, 19, 7, clsymbols);
209
+ if (!size_only) ZopfliLengthsToSymbols(clcl, 19, 7, clsymbols);
185
210
 
186
211
  hclen = 15;
187
212
  /* Trim zeros. */
188
213
  while (hclen > 0 && clcounts[order[hclen + 4 - 1]] == 0) hclen--;
189
214
 
190
- AddBits(hlit, 5, bp, out, outsize);
191
- AddBits(hdist, 5, bp, out, outsize);
192
- AddBits(hclen, 4, bp, out, outsize);
215
+ if (!size_only) {
216
+ AddBits(hlit, 5, bp, out, outsize);
217
+ AddBits(hdist, 5, bp, out, outsize);
218
+ AddBits(hclen, 4, bp, out, outsize);
219
+
220
+ for (i = 0; i < hclen + 4; i++) {
221
+ AddBits(clcl[order[i]], 3, bp, out, outsize);
222
+ }
193
223
 
194
- for (i = 0; i < hclen + 4; i++) {
195
- AddBits(clcl[order[i]], 3, bp, out, outsize);
224
+ for (i = 0; i < rle_size; i++) {
225
+ unsigned symbol = clsymbols[rle[i]];
226
+ AddHuffmanBits(symbol, clcl[rle[i]], bp, out, outsize);
227
+ /* Extra bits. */
228
+ if (rle[i] == 16) AddBits(rle_bits[i], 2, bp, out, outsize);
229
+ else if (rle[i] == 17) AddBits(rle_bits[i], 3, bp, out, outsize);
230
+ else if (rle[i] == 18) AddBits(rle_bits[i], 7, bp, out, outsize);
231
+ }
196
232
  }
197
233
 
198
- for (i = 0; i < rle_size; i++) {
199
- unsigned symbol = clsymbols[rle[i]];
200
- AddHuffmanBits(symbol, clcl[rle[i]], bp, out, outsize);
201
- /* Extra bits. */
202
- if (rle[i] == 16) AddBits(rle_bits[i], 2, bp, out, outsize);
203
- else if (rle[i] == 17) AddBits(rle_bits[i], 3, bp, out, outsize);
204
- else if (rle[i] == 18) AddBits(rle_bits[i], 7, bp, out, outsize);
234
+ result_size += 14; /* hlit, hdist, hclen bits */
235
+ result_size += (hclen + 4) * 3; /* clcl bits */
236
+ for(i = 0; i < 19; i++) {
237
+ result_size += clcl[i] * clcounts[i];
205
238
  }
239
+ /* Extra bits. */
240
+ result_size += clcounts[16] * 2;
241
+ result_size += clcounts[17] * 3;
242
+ result_size += clcounts[18] * 7;
206
243
 
207
- free(lld_lengths);
244
+ /* Note: in case of "size_only" these are null pointers so no effect. */
208
245
  free(rle);
209
246
  free(rle_bits);
247
+
248
+ return result_size;
249
+ }
250
+
251
+ static void AddDynamicTree(const unsigned* ll_lengths,
252
+ const unsigned* d_lengths,
253
+ unsigned char* bp,
254
+ unsigned char** out, size_t* outsize) {
255
+ int i;
256
+ int best = 0;
257
+ size_t bestsize = 0;
258
+
259
+ for(i = 0; i < 8; i++) {
260
+ size_t size = EncodeTree(ll_lengths, d_lengths,
261
+ i & 1, i & 2, i & 4,
262
+ 0, 0, 0);
263
+ if (bestsize == 0 || size < bestsize) {
264
+ bestsize = size;
265
+ best = i;
266
+ }
267
+ }
268
+
269
+ EncodeTree(ll_lengths, d_lengths,
270
+ best & 1, best & 2, best & 4,
271
+ bp, out, outsize);
210
272
  }
211
273
 
212
274
  /*
213
275
  Gives the exact size of the tree, in bits, as it will be encoded in DEFLATE.
214
276
  */
215
277
  static size_t CalculateTreeSize(const unsigned* ll_lengths,
216
- const unsigned* d_lengths,
217
- size_t* ll_counts, size_t* d_counts) {
218
- unsigned char* dummy = 0;
219
- size_t dummysize = 0;
220
- unsigned char bp = 0;
221
-
222
- (void)ll_counts;
223
- (void)d_counts;
278
+ const unsigned* d_lengths) {
279
+ size_t result = 0;
280
+ int i;
224
281
 
225
- AddDynamicTree(ll_lengths, d_lengths, &bp, &dummy, &dummysize);
226
- free(dummy);
282
+ for(i = 0; i < 8; i++) {
283
+ size_t size = EncodeTree(ll_lengths, d_lengths,
284
+ i & 1, i & 2, i & 4,
285
+ 0, 0, 0);
286
+ if (result == 0 || size < result) result = size;
287
+ }
227
288
 
228
- return dummysize * 8 + (bp & 7);
289
+ return result;
229
290
  }
230
291
 
231
292
  /*
@@ -233,8 +294,7 @@ Adds all lit/len and dist codes from the lists as huffman symbols. Does not add
233
294
  end code 256. expected_data_size is the uncompressed block size, used for
234
295
  assert, but you can set it to 0 to not do the assertion.
235
296
  */
236
- static void AddLZ77Data(const unsigned short* litlens,
237
- const unsigned short* dists,
297
+ static void AddLZ77Data(const ZopfliLZ77Store* lz77,
238
298
  size_t lstart, size_t lend,
239
299
  size_t expected_data_size,
240
300
  const unsigned* ll_symbols, const unsigned* ll_lengths,
@@ -245,8 +305,8 @@ static void AddLZ77Data(const unsigned short* litlens,
245
305
  size_t i;
246
306
 
247
307
  for (i = lstart; i < lend; i++) {
248
- unsigned dist = dists[i];
249
- unsigned litlen = litlens[i];
308
+ unsigned dist = lz77->dists[i];
309
+ unsigned litlen = lz77->litlens[i];
250
310
  if (dist == 0) {
251
311
  assert(litlen < 256);
252
312
  assert(ll_lengths[litlen] > 0);
@@ -282,58 +342,326 @@ static void GetFixedTree(unsigned* ll_lengths, unsigned* d_lengths) {
282
342
  }
283
343
 
284
344
  /*
285
- Calculates size of the part after the header and tree of an LZ77 block, in bits.
345
+ Same as CalculateBlockSymbolSize, but for block size smaller than histogram
346
+ size.
286
347
  */
287
- static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths,
288
- const unsigned* d_lengths,
289
- const unsigned short* litlens,
290
- const unsigned short* dists,
291
- size_t lstart, size_t lend) {
348
+ static size_t CalculateBlockSymbolSizeSmall(const unsigned* ll_lengths,
349
+ const unsigned* d_lengths,
350
+ const ZopfliLZ77Store* lz77,
351
+ size_t lstart, size_t lend) {
292
352
  size_t result = 0;
293
353
  size_t i;
294
354
  for (i = lstart; i < lend; i++) {
295
- if (dists[i] == 0) {
296
- result += ll_lengths[litlens[i]];
355
+ assert(i < lz77->size);
356
+ assert(lz77->litlens[i] < 259);
357
+ if (lz77->dists[i] == 0) {
358
+ result += ll_lengths[lz77->litlens[i]];
297
359
  } else {
298
- result += ll_lengths[ZopfliGetLengthSymbol(litlens[i])];
299
- result += d_lengths[ZopfliGetDistSymbol(dists[i])];
300
- result += ZopfliGetLengthExtraBits(litlens[i]);
301
- result += ZopfliGetDistExtraBits(dists[i]);
360
+ int ll_symbol = ZopfliGetLengthSymbol(lz77->litlens[i]);
361
+ int d_symbol = ZopfliGetDistSymbol(lz77->dists[i]);
362
+ result += ll_lengths[ll_symbol];
363
+ result += d_lengths[d_symbol];
364
+ result += ZopfliGetLengthSymbolExtraBits(ll_symbol);
365
+ result += ZopfliGetDistSymbolExtraBits(d_symbol);
302
366
  }
303
367
  }
304
368
  result += ll_lengths[256]; /*end symbol*/
305
369
  return result;
306
370
  }
307
371
 
308
- double ZopfliCalculateBlockSize(const unsigned short* litlens,
309
- const unsigned short* dists,
310
- size_t lstart, size_t lend, int btype) {
311
- size_t ll_counts[288];
312
- size_t d_counts[32];
372
+ /*
373
+ Same as CalculateBlockSymbolSize, but with the histogram provided by the caller.
374
+ */
375
+ static size_t CalculateBlockSymbolSizeGivenCounts(const size_t* ll_counts,
376
+ const size_t* d_counts,
377
+ const unsigned* ll_lengths,
378
+ const unsigned* d_lengths,
379
+ const ZopfliLZ77Store* lz77,
380
+ size_t lstart, size_t lend) {
381
+ size_t result = 0;
382
+ size_t i;
383
+ if (lstart + ZOPFLI_NUM_LL * 3 > lend) {
384
+ return CalculateBlockSymbolSizeSmall(
385
+ ll_lengths, d_lengths, lz77, lstart, lend);
386
+ } else {
387
+ for (i = 0; i < 256; i++) {
388
+ result += ll_lengths[i] * ll_counts[i];
389
+ }
390
+ for (i = 257; i < 286; i++) {
391
+ result += ll_lengths[i] * ll_counts[i];
392
+ result += ZopfliGetLengthSymbolExtraBits(i) * ll_counts[i];
393
+ }
394
+ for (i = 0; i < 30; i++) {
395
+ result += d_lengths[i] * d_counts[i];
396
+ result += ZopfliGetDistSymbolExtraBits(i) * d_counts[i];
397
+ }
398
+ result += ll_lengths[256]; /*end symbol*/
399
+ return result;
400
+ }
401
+ }
313
402
 
314
- unsigned ll_lengths[288];
315
- unsigned d_lengths[32];
403
+ /*
404
+ Calculates size of the part after the header and tree of an LZ77 block, in bits.
405
+ */
406
+ static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths,
407
+ const unsigned* d_lengths,
408
+ const ZopfliLZ77Store* lz77,
409
+ size_t lstart, size_t lend) {
410
+ if (lstart + ZOPFLI_NUM_LL * 3 > lend) {
411
+ return CalculateBlockSymbolSizeSmall(
412
+ ll_lengths, d_lengths, lz77, lstart, lend);
413
+ } else {
414
+ size_t ll_counts[ZOPFLI_NUM_LL];
415
+ size_t d_counts[ZOPFLI_NUM_D];
416
+ ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts);
417
+ return CalculateBlockSymbolSizeGivenCounts(
418
+ ll_counts, d_counts, ll_lengths, d_lengths, lz77, lstart, lend);
419
+ }
420
+ }
316
421
 
317
- double result = 3; /*bfinal and btype bits*/
422
+ static size_t AbsDiff(size_t x, size_t y) {
423
+ if (x > y)
424
+ return x - y;
425
+ else
426
+ return y - x;
427
+ }
318
428
 
319
- assert(btype == 1 || btype == 2); /* This is not for uncompressed blocks. */
429
+ /*
430
+ Changes the population counts in a way that the consequent Huffman tree
431
+ compression, especially its rle-part, will be more likely to compress this data
432
+ more efficiently. length contains the size of the histogram.
433
+ */
434
+ void OptimizeHuffmanForRle(int length, size_t* counts) {
435
+ int i, k, stride;
436
+ size_t symbol, sum, limit;
437
+ int* good_for_rle;
438
+
439
+ /* 1) We don't want to touch the trailing zeros. We may break the
440
+ rules of the format by adding more data in the distance codes. */
441
+ for (; length >= 0; --length) {
442
+ if (length == 0) {
443
+ return;
444
+ }
445
+ if (counts[length - 1] != 0) {
446
+ /* Now counts[0..length - 1] does not have trailing zeros. */
447
+ break;
448
+ }
449
+ }
450
+ /* 2) Let's mark all population counts that already can be encoded
451
+ with an rle code.*/
452
+ good_for_rle = (int*)malloc((unsigned)length * sizeof(int));
453
+ for (i = 0; i < length; ++i) good_for_rle[i] = 0;
454
+
455
+ /* Let's not spoil any of the existing good rle codes.
456
+ Mark any seq of 0's that is longer than 5 as a good_for_rle.
457
+ Mark any seq of non-0's that is longer than 7 as a good_for_rle.*/
458
+ symbol = counts[0];
459
+ stride = 0;
460
+ for (i = 0; i < length + 1; ++i) {
461
+ if (i == length || counts[i] != symbol) {
462
+ if ((symbol == 0 && stride >= 5) || (symbol != 0 && stride >= 7)) {
463
+ for (k = 0; k < stride; ++k) {
464
+ good_for_rle[i - k - 1] = 1;
465
+ }
466
+ }
467
+ stride = 1;
468
+ if (i != length) {
469
+ symbol = counts[i];
470
+ }
471
+ } else {
472
+ ++stride;
473
+ }
474
+ }
320
475
 
321
- if(btype == 1) {
476
+ /* 3) Let's replace those population counts that lead to more rle codes. */
477
+ stride = 0;
478
+ limit = counts[0];
479
+ sum = 0;
480
+ for (i = 0; i < length + 1; ++i) {
481
+ if (i == length || good_for_rle[i]
482
+ /* Heuristic for selecting the stride ranges to collapse. */
483
+ || AbsDiff(counts[i], limit) >= 4) {
484
+ if (stride >= 4 || (stride >= 3 && sum == 0)) {
485
+ /* The stride must end, collapse what we have, if we have enough (4). */
486
+ int count = (sum + stride / 2) / stride;
487
+ if (count < 1) count = 1;
488
+ if (sum == 0) {
489
+ /* Don't make an all zeros stride to be upgraded to ones. */
490
+ count = 0;
491
+ }
492
+ for (k = 0; k < stride; ++k) {
493
+ /* We don't want to change value at counts[i],
494
+ that is already belonging to the next stride. Thus - 1. */
495
+ counts[i - k - 1] = count;
496
+ }
497
+ }
498
+ stride = 0;
499
+ sum = 0;
500
+ if (i < length - 3) {
501
+ /* All interesting strides have a count of at least 4,
502
+ at least when non-zeros. */
503
+ limit = (counts[i] + counts[i + 1] +
504
+ counts[i + 2] + counts[i + 3] + 2) / 4;
505
+ } else if (i < length) {
506
+ limit = counts[i];
507
+ } else {
508
+ limit = 0;
509
+ }
510
+ }
511
+ ++stride;
512
+ if (i != length) {
513
+ sum += counts[i];
514
+ }
515
+ }
516
+
517
+ free(good_for_rle);
518
+ }
519
+
520
+ /*
521
+ Tries out OptimizeHuffmanForRle for this block, if the result is smaller,
522
+ uses it, otherwise keeps the original. Returns size of encoded tree and data in
523
+ bits, not including the 3-bit block header.
524
+ */
525
+ static double TryOptimizeHuffmanForRle(
526
+ const ZopfliLZ77Store* lz77, size_t lstart, size_t lend,
527
+ const size_t* ll_counts, const size_t* d_counts,
528
+ unsigned* ll_lengths, unsigned* d_lengths) {
529
+ size_t ll_counts2[ZOPFLI_NUM_LL];
530
+ size_t d_counts2[ZOPFLI_NUM_D];
531
+ unsigned ll_lengths2[ZOPFLI_NUM_LL];
532
+ unsigned d_lengths2[ZOPFLI_NUM_D];
533
+ double treesize;
534
+ double datasize;
535
+ double treesize2;
536
+ double datasize2;
537
+
538
+ treesize = CalculateTreeSize(ll_lengths, d_lengths);
539
+ datasize = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
540
+ ll_lengths, d_lengths, lz77, lstart, lend);
541
+
542
+ memcpy(ll_counts2, ll_counts, sizeof(ll_counts2));
543
+ memcpy(d_counts2, d_counts, sizeof(d_counts2));
544
+ OptimizeHuffmanForRle(ZOPFLI_NUM_LL, ll_counts2);
545
+ OptimizeHuffmanForRle(ZOPFLI_NUM_D, d_counts2);
546
+ ZopfliCalculateBitLengths(ll_counts2, ZOPFLI_NUM_LL, 15, ll_lengths2);
547
+ ZopfliCalculateBitLengths(d_counts2, ZOPFLI_NUM_D, 15, d_lengths2);
548
+ PatchDistanceCodesForBuggyDecoders(d_lengths2);
549
+
550
+ treesize2 = CalculateTreeSize(ll_lengths2, d_lengths2);
551
+ datasize2 = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts,
552
+ ll_lengths2, d_lengths2, lz77, lstart, lend);
553
+
554
+ if (treesize2 + datasize2 < treesize + datasize) {
555
+ memcpy(ll_lengths, ll_lengths2, sizeof(ll_lengths2));
556
+ memcpy(d_lengths, d_lengths2, sizeof(d_lengths2));
557
+ return treesize2 + datasize2;
558
+ }
559
+ return treesize + datasize;
560
+ }
561
+
562
+ /*
563
+ Calculates the bit lengths for the symbols for dynamic blocks. Chooses bit
564
+ lengths that give the smallest size of tree encoding + encoding of all the
565
+ symbols to have smallest output size. This are not necessarily the ideal Huffman
566
+ bit lengths. Returns size of encoded tree and data in bits, not including the
567
+ 3-bit block header.
568
+ */
569
+ static double GetDynamicLengths(const ZopfliLZ77Store* lz77,
570
+ size_t lstart, size_t lend,
571
+ unsigned* ll_lengths, unsigned* d_lengths) {
572
+ size_t ll_counts[ZOPFLI_NUM_LL];
573
+ size_t d_counts[ZOPFLI_NUM_D];
574
+
575
+ ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts);
576
+ ll_counts[256] = 1; /* End symbol. */
577
+ ZopfliCalculateBitLengths(ll_counts, ZOPFLI_NUM_LL, 15, ll_lengths);
578
+ ZopfliCalculateBitLengths(d_counts, ZOPFLI_NUM_D, 15, d_lengths);
579
+ PatchDistanceCodesForBuggyDecoders(d_lengths);
580
+ return TryOptimizeHuffmanForRle(
581
+ lz77, lstart, lend, ll_counts, d_counts, ll_lengths, d_lengths);
582
+ }
583
+
584
+ double ZopfliCalculateBlockSize(const ZopfliLZ77Store* lz77,
585
+ size_t lstart, size_t lend, int btype) {
586
+ unsigned ll_lengths[ZOPFLI_NUM_LL];
587
+ unsigned d_lengths[ZOPFLI_NUM_D];
588
+
589
+ double result = 3; /* bfinal and btype bits */
590
+
591
+ if (btype == 0) {
592
+ size_t length = ZopfliLZ77GetByteRange(lz77, lstart, lend);
593
+ size_t rem = length % 65535;
594
+ size_t blocks = length / 65535 + (rem ? 1 : 0);
595
+ /* An uncompressed block must actually be split into multiple blocks if it's
596
+ larger than 65535 bytes long. Eeach block header is 5 bytes: 3 bits,
597
+ padding, LEN and NLEN (potential less padding for first one ignored). */
598
+ return blocks * 5 * 8 + length * 8;
599
+ } if (btype == 1) {
322
600
  GetFixedTree(ll_lengths, d_lengths);
601
+ result += CalculateBlockSymbolSize(
602
+ ll_lengths, d_lengths, lz77, lstart, lend);
323
603
  } else {
324
- ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts);
325
- ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths);
326
- ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths);
327
- PatchDistanceCodesForBuggyDecoders(d_lengths);
328
- result += CalculateTreeSize(ll_lengths, d_lengths, ll_counts, d_counts);
604
+ result += GetDynamicLengths(lz77, lstart, lend, ll_lengths, d_lengths);
329
605
  }
330
606
 
331
- result += CalculateBlockSymbolSize(
332
- ll_lengths, d_lengths, litlens, dists, lstart, lend);
333
-
334
607
  return result;
335
608
  }
336
609
 
610
+ double ZopfliCalculateBlockSizeAutoType(const ZopfliLZ77Store* lz77,
611
+ size_t lstart, size_t lend) {
612
+ double uncompressedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 0);
613
+ /* Don't do the expensive fixed cost calculation for larger blocks that are
614
+ unlikely to use it. */
615
+ double fixedcost = (lz77->size > 1000) ?
616
+ uncompressedcost : ZopfliCalculateBlockSize(lz77, lstart, lend, 1);
617
+ double dyncost = ZopfliCalculateBlockSize(lz77, lstart, lend, 2);
618
+ return (uncompressedcost < fixedcost && uncompressedcost < dyncost)
619
+ ? uncompressedcost
620
+ : (fixedcost < dyncost ? fixedcost : dyncost);
621
+ }
622
+
623
+ /* Since an uncompressed block can be max 65535 in size, it actually adds
624
+ multible blocks if needed. */
625
+ static void AddNonCompressedBlock(const ZopfliOptions* options, int final,
626
+ const unsigned char* in, size_t instart,
627
+ size_t inend,
628
+ unsigned char* bp,
629
+ unsigned char** out, size_t* outsize) {
630
+ size_t pos = instart;
631
+ (void)options;
632
+ for (;;) {
633
+ size_t i;
634
+ unsigned short blocksize = 65535;
635
+ unsigned short nlen;
636
+ int currentfinal;
637
+
638
+ if (pos + blocksize > inend) blocksize = inend - pos;
639
+ currentfinal = pos + blocksize >= inend;
640
+
641
+ nlen = ~blocksize;
642
+
643
+ AddBit(final && currentfinal, bp, out, outsize);
644
+ /* BTYPE 00 */
645
+ AddBit(0, bp, out, outsize);
646
+ AddBit(0, bp, out, outsize);
647
+
648
+ /* Any bits of input up to the next byte boundary are ignored. */
649
+ *bp = 0;
650
+
651
+ ZOPFLI_APPEND_DATA(blocksize % 256, out, outsize);
652
+ ZOPFLI_APPEND_DATA((blocksize / 256) % 256, out, outsize);
653
+ ZOPFLI_APPEND_DATA(nlen % 256, out, outsize);
654
+ ZOPFLI_APPEND_DATA((nlen / 256) % 256, out, outsize);
655
+
656
+ for (i = 0; i < blocksize; i++) {
657
+ ZOPFLI_APPEND_DATA(in[pos + i], out, outsize);
658
+ }
659
+
660
+ if (currentfinal) break;
661
+ pos += blocksize;
662
+ }
663
+ }
664
+
337
665
  /*
338
666
  Adds a deflate block with the given LZ77 data to the output.
339
667
  options: global program options
@@ -352,22 +680,27 @@ out: dynamic output array to append to
352
680
  outsize: dynamic output array size
353
681
  */
354
682
  static void AddLZ77Block(const ZopfliOptions* options, int btype, int final,
355
- const unsigned short* litlens,
356
- const unsigned short* dists,
683
+ const ZopfliLZ77Store* lz77,
357
684
  size_t lstart, size_t lend,
358
685
  size_t expected_data_size,
359
686
  unsigned char* bp,
360
687
  unsigned char** out, size_t* outsize) {
361
- size_t ll_counts[288];
362
- size_t d_counts[32];
363
- unsigned ll_lengths[288];
364
- unsigned d_lengths[32];
365
- unsigned ll_symbols[288];
366
- unsigned d_symbols[32];
688
+ unsigned ll_lengths[ZOPFLI_NUM_LL];
689
+ unsigned d_lengths[ZOPFLI_NUM_D];
690
+ unsigned ll_symbols[ZOPFLI_NUM_LL];
691
+ unsigned d_symbols[ZOPFLI_NUM_D];
367
692
  size_t detect_block_size = *outsize;
368
693
  size_t compressed_size;
369
694
  size_t uncompressed_size = 0;
370
695
  size_t i;
696
+ if (btype == 0) {
697
+ size_t length = ZopfliLZ77GetByteRange(lz77, lstart, lend);
698
+ size_t pos = lstart == lend ? 0 : lz77->pos[lstart];
699
+ size_t end = pos + length;
700
+ AddNonCompressedBlock(options, final,
701
+ lz77->data, pos, end, bp, out, outsize);
702
+ return;
703
+ }
371
704
 
372
705
  AddBit(final, bp, out, outsize);
373
706
  AddBit(btype & 1, bp, out, outsize);
@@ -380,34 +713,28 @@ static void AddLZ77Block(const ZopfliOptions* options, int btype, int final,
380
713
  /* Dynamic block. */
381
714
  unsigned detect_tree_size;
382
715
  assert(btype == 2);
383
- ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts);
384
- ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths);
385
- ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths);
386
- PatchDistanceCodesForBuggyDecoders(d_lengths);
716
+
717
+ GetDynamicLengths(lz77, lstart, lend, ll_lengths, d_lengths);
718
+
387
719
  detect_tree_size = *outsize;
388
720
  AddDynamicTree(ll_lengths, d_lengths, bp, out, outsize);
389
721
  if (options->verbose) {
390
722
  fprintf(stderr, "treesize: %d\n", (int)(*outsize - detect_tree_size));
391
723
  }
392
-
393
- /* Assert that for every present symbol, the code length is non-zero. */
394
- /* TODO(lode): remove this in release version. */
395
- for (i = 0; i < 288; i++) assert(ll_counts[i] == 0 || ll_lengths[i] > 0);
396
- for (i = 0; i < 32; i++) assert(d_counts[i] == 0 || d_lengths[i] > 0);
397
724
  }
398
725
 
399
- ZopfliLengthsToSymbols(ll_lengths, 288, 15, ll_symbols);
400
- ZopfliLengthsToSymbols(d_lengths, 32, 15, d_symbols);
726
+ ZopfliLengthsToSymbols(ll_lengths, ZOPFLI_NUM_LL, 15, ll_symbols);
727
+ ZopfliLengthsToSymbols(d_lengths, ZOPFLI_NUM_D, 15, d_symbols);
401
728
 
402
729
  detect_block_size = *outsize;
403
- AddLZ77Data(litlens, dists, lstart, lend, expected_data_size,
730
+ AddLZ77Data(lz77, lstart, lend, expected_data_size,
404
731
  ll_symbols, ll_lengths, d_symbols, d_lengths,
405
732
  bp, out, outsize);
406
733
  /* End symbol. */
407
734
  AddHuffmanBits(ll_symbols[256], ll_lengths[256], bp, out, outsize);
408
735
 
409
736
  for (i = lstart; i < lend; i++) {
410
- uncompressed_size += dists[i] == 0 ? 1 : litlens[i];
737
+ uncompressed_size += lz77->dists[i] == 0 ? 1 : lz77->litlens[i];
411
738
  }
412
739
  compressed_size = *outsize - detect_block_size;
413
740
  if (options->verbose) {
@@ -417,283 +744,188 @@ static void AddLZ77Block(const ZopfliOptions* options, int btype, int final,
417
744
  }
418
745
  }
419
746
 
420
- static void DeflateDynamicBlock(const ZopfliOptions* options, int final,
421
- const unsigned char* in,
422
- size_t instart, size_t inend,
423
- unsigned char* bp,
424
- unsigned char** out, size_t* outsize) {
425
- ZopfliBlockState s;
426
- size_t blocksize = inend - instart;
427
- ZopfliLZ77Store store;
428
- int btype = 2;
429
-
430
- ZopfliInitLZ77Store(&store);
431
-
432
- s.options = options;
433
- s.blockstart = instart;
434
- s.blockend = inend;
435
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
436
- s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
437
- ZopfliInitCache(blocksize, s.lmc);
438
- #endif
439
-
440
- ZopfliLZ77Optimal(&s, in, instart, inend, &store);
441
-
442
- /* For small block, encoding with fixed tree can be smaller. For large block,
443
- don't bother doing this expensive test, dynamic tree will be better.*/
444
- if (store.size < 1000) {
445
- double dyncost, fixedcost;
446
- ZopfliLZ77Store fixedstore;
447
- ZopfliInitLZ77Store(&fixedstore);
448
- ZopfliLZ77OptimalFixed(&s, in, instart, inend, &fixedstore);
449
- dyncost = ZopfliCalculateBlockSize(store.litlens, store.dists,
450
- 0, store.size, 2);
451
- fixedcost = ZopfliCalculateBlockSize(fixedstore.litlens, fixedstore.dists,
452
- 0, fixedstore.size, 1);
453
- if (fixedcost < dyncost) {
454
- btype = 1;
455
- ZopfliCleanLZ77Store(&store);
456
- store = fixedstore;
457
- } else {
458
- ZopfliCleanLZ77Store(&fixedstore);
459
- }
747
+ static void AddLZ77BlockAutoType(const ZopfliOptions* options, int final,
748
+ const ZopfliLZ77Store* lz77,
749
+ size_t lstart, size_t lend,
750
+ size_t expected_data_size,
751
+ unsigned char* bp,
752
+ unsigned char** out, size_t* outsize) {
753
+ double uncompressedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 0);
754
+ double fixedcost = ZopfliCalculateBlockSize(lz77, lstart, lend, 1);
755
+ double dyncost = ZopfliCalculateBlockSize(lz77, lstart, lend, 2);
756
+
757
+ /* Whether to perform the expensive calculation of creating an optimal block
758
+ with fixed huffman tree to check if smaller. Only do this for small blocks or
759
+ blocks which already are pretty good with fixed huffman tree. */
760
+ int expensivefixed = (lz77->size < 1000) || fixedcost <= dyncost * 1.1;
761
+
762
+ ZopfliLZ77Store fixedstore;
763
+ if (lstart == lend) {
764
+ /* Smallest empty block is represented by fixed block */
765
+ AddBits(final, 1, bp, out, outsize);
766
+ AddBits(1, 2, bp, out, outsize); /* btype 01 */
767
+ AddBits(0, 7, bp, out, outsize); /* end symbol has code 0000000 */
768
+ return;
460
769
  }
461
-
462
- AddLZ77Block(s.options, btype, final,
463
- store.litlens, store.dists, 0, store.size,
464
- blocksize, bp, out, outsize);
465
-
466
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
467
- ZopfliCleanCache(s.lmc);
468
- free(s.lmc);
469
- #endif
470
- ZopfliCleanLZ77Store(&store);
471
- }
472
-
473
- static void DeflateFixedBlock(const ZopfliOptions* options, int final,
474
- const unsigned char* in,
475
- size_t instart, size_t inend,
476
- unsigned char* bp,
477
- unsigned char** out, size_t* outsize) {
478
- ZopfliBlockState s;
479
- size_t blocksize = inend - instart;
480
- ZopfliLZ77Store store;
481
-
482
- ZopfliInitLZ77Store(&store);
483
-
484
- s.options = options;
485
- s.blockstart = instart;
486
- s.blockend = inend;
487
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
488
- s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
489
- ZopfliInitCache(blocksize, s.lmc);
490
- #endif
491
-
492
- ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
493
-
494
- AddLZ77Block(s.options, 1, final, store.litlens, store.dists, 0, store.size,
495
- blocksize, bp, out, outsize);
496
-
497
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
498
- ZopfliCleanCache(s.lmc);
499
- free(s.lmc);
500
- #endif
501
- ZopfliCleanLZ77Store(&store);
502
- }
503
-
504
- static void DeflateNonCompressedBlock(const ZopfliOptions* options, int final,
505
- const unsigned char* in, size_t instart,
506
- size_t inend,
507
- unsigned char* bp,
508
- unsigned char** out, size_t* outsize) {
509
- size_t i;
510
- size_t blocksize = inend - instart;
511
- unsigned short nlen = ~blocksize;
512
-
513
- (void)options;
514
- assert(blocksize < 65536); /* Non compressed blocks are max this size. */
515
-
516
- AddBit(final, bp, out, outsize);
517
- /* BTYPE 00 */
518
- AddBit(0, bp, out, outsize);
519
- AddBit(0, bp, out, outsize);
520
-
521
- /* Any bits of input up to the next byte boundary are ignored. */
522
- *bp = 0;
523
-
524
- ZOPFLI_APPEND_DATA(blocksize % 256, out, outsize);
525
- ZOPFLI_APPEND_DATA((blocksize / 256) % 256, out, outsize);
526
- ZOPFLI_APPEND_DATA(nlen % 256, out, outsize);
527
- ZOPFLI_APPEND_DATA((nlen / 256) % 256, out, outsize);
528
-
529
- for (i = instart; i < inend; i++) {
530
- ZOPFLI_APPEND_DATA(in[i], out, outsize);
770
+ ZopfliInitLZ77Store(lz77->data, &fixedstore);
771
+ if (expensivefixed) {
772
+ /* Recalculate the LZ77 with ZopfliLZ77OptimalFixed */
773
+ size_t instart = lz77->pos[lstart];
774
+ size_t inend = instart + ZopfliLZ77GetByteRange(lz77, lstart, lend);
775
+
776
+ ZopfliBlockState s;
777
+ ZopfliInitBlockState(options, instart, inend, 1, &s);
778
+ ZopfliLZ77OptimalFixed(&s, lz77->data, instart, inend, &fixedstore);
779
+ fixedcost = ZopfliCalculateBlockSize(&fixedstore, 0, fixedstore.size, 1);
780
+ ZopfliCleanBlockState(&s);
531
781
  }
532
- }
533
782
 
534
- static void DeflateBlock(const ZopfliOptions* options,
535
- int btype, int final,
536
- const unsigned char* in, size_t instart, size_t inend,
537
- unsigned char* bp,
538
- unsigned char** out, size_t* outsize) {
539
- if (btype == 0) {
540
- DeflateNonCompressedBlock(
541
- options, final, in, instart, inend, bp, out, outsize);
542
- } else if (btype == 1) {
543
- DeflateFixedBlock(options, final, in, instart, inend, bp, out, outsize);
783
+ if (uncompressedcost < fixedcost && uncompressedcost < dyncost) {
784
+ AddLZ77Block(options, 0, final, lz77, lstart, lend,
785
+ expected_data_size, bp, out, outsize);
786
+ } else if (fixedcost < dyncost) {
787
+ if (expensivefixed) {
788
+ AddLZ77Block(options, 1, final, &fixedstore, 0, fixedstore.size,
789
+ expected_data_size, bp, out, outsize);
790
+ } else {
791
+ AddLZ77Block(options, 1, final, lz77, lstart, lend,
792
+ expected_data_size, bp, out, outsize);
793
+ }
544
794
  } else {
545
- assert (btype == 2);
546
- DeflateDynamicBlock(options, final, in, instart, inend, bp, out, outsize);
795
+ AddLZ77Block(options, 2, final, lz77, lstart, lend,
796
+ expected_data_size, bp, out, outsize);
547
797
  }
798
+
799
+ ZopfliCleanLZ77Store(&fixedstore);
548
800
  }
549
801
 
550
802
  /*
551
- Does squeeze strategy where first block splitting is done, then each block is
552
- squeezed.
553
- Parameters: see description of the ZopfliDeflate function.
803
+ Deflate a part, to allow ZopfliDeflate() to use multiple master blocks if
804
+ needed.
805
+ It is possible to call this function multiple times in a row, shifting
806
+ instart and inend to next bytes of the data. If instart is larger than 0, then
807
+ previous bytes are used as the initial dictionary for LZ77.
808
+ This function will usually output multiple deflate blocks. If final is 1, then
809
+ the final bit will be set on the last block.
554
810
  */
555
- static void DeflateSplittingFirst(const ZopfliOptions* options,
556
- int btype, int final,
557
- const unsigned char* in,
558
- size_t instart, size_t inend,
559
- unsigned char* bp,
560
- unsigned char** out, size_t* outsize) {
811
+ void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
812
+ const unsigned char* in, size_t instart, size_t inend,
813
+ unsigned char* bp, unsigned char** out,
814
+ size_t* outsize) {
561
815
  size_t i;
562
- size_t* splitpoints = 0;
816
+ /* byte coordinates rather than lz77 index */
817
+ size_t* splitpoints_uncompressed = 0;
563
818
  size_t npoints = 0;
819
+ size_t* splitpoints = 0;
820
+ double totalcost = 0;
821
+ ZopfliLZ77Store lz77;
822
+
823
+ /* If btype=2 is specified, it tries all block types. If a lesser btype is
824
+ given, then however it forces that one. Neither of the lesser types needs
825
+ block splitting as they have no dynamic huffman trees. */
564
826
  if (btype == 0) {
565
- ZopfliBlockSplitSimple(in, instart, inend, 65535, &splitpoints, &npoints);
827
+ AddNonCompressedBlock(options, final, in, instart, inend, bp, out, outsize);
828
+ return;
566
829
  } else if (btype == 1) {
567
- /* If all blocks are fixed tree, splitting into separate blocks only
568
- increases the total size. Leave npoints at 0, this represents 1 block. */
569
- } else {
570
- ZopfliBlockSplit(options, in, instart, inend,
571
- options->blocksplittingmax, &splitpoints, &npoints);
572
- }
830
+ ZopfliLZ77Store store;
831
+ ZopfliBlockState s;
832
+ ZopfliInitLZ77Store(in, &store);
833
+ ZopfliInitBlockState(options, instart, inend, 1, &s);
573
834
 
574
- for (i = 0; i <= npoints; i++) {
575
- size_t start = i == 0 ? instart : splitpoints[i - 1];
576
- size_t end = i == npoints ? inend : splitpoints[i];
577
- DeflateBlock(options, btype, i == npoints && final, in, start, end,
835
+ ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
836
+ AddLZ77Block(options, btype, final, &store, 0, store.size, 0,
578
837
  bp, out, outsize);
579
- }
580
838
 
581
- free(splitpoints);
582
- }
583
-
584
- /*
585
- Does squeeze strategy where first the best possible lz77 is done, and then based
586
- on that data, block splitting is done.
587
- Parameters: see description of the ZopfliDeflate function.
588
- */
589
- static void DeflateSplittingLast(const ZopfliOptions* options,
590
- int btype, int final,
591
- const unsigned char* in,
592
- size_t instart, size_t inend,
593
- unsigned char* bp,
594
- unsigned char** out, size_t* outsize) {
595
- size_t i;
596
- ZopfliBlockState s;
597
- ZopfliLZ77Store store;
598
- size_t* splitpoints = 0;
599
- size_t npoints = 0;
839
+ ZopfliCleanBlockState(&s);
840
+ ZopfliCleanLZ77Store(&store);
841
+ return;
842
+ }
600
843
 
601
- if (btype == 0) {
602
- /* This function only supports LZ77 compression. DeflateSplittingFirst
603
- supports the special case of noncompressed data. Punt it to that one. */
604
- DeflateSplittingFirst(options, btype, final,
605
- in, instart, inend,
606
- bp, out, outsize);
607
- }
608
- assert(btype == 1 || btype == 2);
609
-
610
- ZopfliInitLZ77Store(&store);
611
-
612
- s.options = options;
613
- s.blockstart = instart;
614
- s.blockend = inend;
615
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
616
- s.lmc = (ZopfliLongestMatchCache*)malloc(sizeof(ZopfliLongestMatchCache));
617
- ZopfliInitCache(inend - instart, s.lmc);
618
- #endif
619
844
 
620
- if (btype == 2) {
621
- ZopfliLZ77Optimal(&s, in, instart, inend, &store);
622
- } else {
623
- assert (btype == 1);
624
- ZopfliLZ77OptimalFixed(&s, in, instart, inend, &store);
845
+ if (options->blocksplitting) {
846
+ ZopfliBlockSplit(options, in, instart, inend,
847
+ options->blocksplittingmax,
848
+ &splitpoints_uncompressed, &npoints);
849
+ splitpoints = (size_t*)malloc(sizeof(*splitpoints) * npoints);
625
850
  }
626
851
 
627
- if (btype == 1) {
628
- /* If all blocks are fixed tree, splitting into separate blocks only
629
- increases the total size. Leave npoints at 0, this represents 1 block. */
630
- } else {
631
- ZopfliBlockSplitLZ77(options, store.litlens, store.dists, store.size,
632
- options->blocksplittingmax, &splitpoints, &npoints);
633
- }
852
+ ZopfliInitLZ77Store(in, &lz77);
634
853
 
635
854
  for (i = 0; i <= npoints; i++) {
636
- size_t start = i == 0 ? 0 : splitpoints[i - 1];
637
- size_t end = i == npoints ? store.size : splitpoints[i];
638
- AddLZ77Block(options, btype, i == npoints && final,
639
- store.litlens, store.dists, start, end, 0,
640
- bp, out, outsize);
855
+ size_t start = i == 0 ? instart : splitpoints_uncompressed[i - 1];
856
+ size_t end = i == npoints ? inend : splitpoints_uncompressed[i];
857
+ ZopfliBlockState s;
858
+ ZopfliLZ77Store store;
859
+ ZopfliInitLZ77Store(in, &store);
860
+ ZopfliInitBlockState(options, start, end, 1, &s);
861
+ ZopfliLZ77Optimal(&s, in, start, end, options->numiterations, &store);
862
+ totalcost += ZopfliCalculateBlockSizeAutoType(&store, 0, store.size);
863
+
864
+ ZopfliAppendLZ77Store(&store, &lz77);
865
+ if (i < npoints) splitpoints[i] = lz77.size;
866
+
867
+ ZopfliCleanBlockState(&s);
868
+ ZopfliCleanLZ77Store(&store);
641
869
  }
642
870
 
643
- #ifdef ZOPFLI_LONGEST_MATCH_CACHE
644
- ZopfliCleanCache(s.lmc);
645
- free(s.lmc);
646
- #endif
871
+ /* Second block splitting attempt */
872
+ if (options->blocksplitting && npoints > 1) {
873
+ size_t* splitpoints2 = 0;
874
+ size_t npoints2 = 0;
875
+ double totalcost2 = 0;
647
876
 
648
- ZopfliCleanLZ77Store(&store);
649
- }
877
+ ZopfliBlockSplitLZ77(options, &lz77,
878
+ options->blocksplittingmax, &splitpoints2, &npoints2);
650
879
 
651
- /*
652
- Deflate a part, to allow ZopfliDeflate() to use multiple master blocks if
653
- needed.
654
- It is possible to call this function multiple times in a row, shifting
655
- instart and inend to next bytes of the data. If instart is larger than 0, then
656
- previous bytes are used as the initial dictionary for LZ77.
657
- This function will usually output multiple deflate blocks. If final is 1, then
658
- the final bit will be set on the last block.
659
- */
660
- void ZopfliDeflatePart(const ZopfliOptions* options, int btype, int final,
661
- const unsigned char* in, size_t instart, size_t inend,
662
- unsigned char* bp, unsigned char** out,
663
- size_t* outsize) {
664
- if (options->blocksplitting) {
665
- if (options->blocksplittinglast) {
666
- DeflateSplittingLast(options, btype, final, in, instart, inend,
667
- bp, out, outsize);
880
+ for (i = 0; i <= npoints2; i++) {
881
+ size_t start = i == 0 ? 0 : splitpoints2[i - 1];
882
+ size_t end = i == npoints2 ? lz77.size : splitpoints2[i];
883
+ totalcost2 += ZopfliCalculateBlockSizeAutoType(&lz77, start, end);
884
+ }
885
+
886
+ if (totalcost2 < totalcost) {
887
+ free(splitpoints);
888
+ splitpoints = splitpoints2;
889
+ npoints = npoints2;
668
890
  } else {
669
- DeflateSplittingFirst(options, btype, final, in, instart, inend,
670
- bp, out, outsize);
891
+ free(splitpoints2);
671
892
  }
672
- } else {
673
- DeflateBlock(options, btype, final, in, instart, inend, bp, out, outsize);
674
893
  }
894
+
895
+ for (i = 0; i <= npoints; i++) {
896
+ size_t start = i == 0 ? 0 : splitpoints[i - 1];
897
+ size_t end = i == npoints ? lz77.size : splitpoints[i];
898
+ AddLZ77BlockAutoType(options, i == npoints && final,
899
+ &lz77, start, end, 0,
900
+ bp, out, outsize);
901
+ }
902
+
903
+ ZopfliCleanLZ77Store(&lz77);
904
+ free(splitpoints);
905
+ free(splitpoints_uncompressed);
675
906
  }
676
907
 
677
908
  void ZopfliDeflate(const ZopfliOptions* options, int btype, int final,
678
909
  const unsigned char* in, size_t insize,
679
910
  unsigned char* bp, unsigned char** out, size_t* outsize) {
911
+ size_t offset = *outsize;
680
912
  #if ZOPFLI_MASTER_BLOCK_SIZE == 0
681
913
  ZopfliDeflatePart(options, btype, final, in, 0, insize, bp, out, outsize);
682
914
  #else
683
915
  size_t i = 0;
684
- while (i < insize) {
916
+ do {
685
917
  int masterfinal = (i + ZOPFLI_MASTER_BLOCK_SIZE >= insize);
686
918
  int final2 = final && masterfinal;
687
919
  size_t size = masterfinal ? insize - i : ZOPFLI_MASTER_BLOCK_SIZE;
688
920
  ZopfliDeflatePart(options, btype, final2,
689
921
  in, i, i + size, bp, out, outsize);
690
922
  i += size;
691
- }
923
+ } while (i < insize);
692
924
  #endif
693
925
  if (options->verbose) {
694
926
  fprintf(stderr,
695
- "Original Size: %d, Deflate: %d, Compression: %f%% Removed\n",
696
- (int)insize, (int)*outsize,
697
- 100.0 * (double)(insize - *outsize) / (double)insize);
927
+ "Original Size: %lu, Deflate: %lu, Compression: %f%% Removed\n",
928
+ (unsigned long)insize, (unsigned long)(*outsize - offset),
929
+ 100.0 * (double)(insize - (*outsize - offset)) / (double)insize);
698
930
  }
699
931
  }