zopfli 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }