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.
- checksums.yaml +5 -5
- data/.github/workflows/main.yml +35 -0
- data/.github/workflows/publish.yml +34 -0
- data/.gitmodules +1 -1
- data/Gemfile +4 -0
- data/README.md +6 -1
- data/Rakefile +14 -10
- data/ext/extconf.rb +36 -32
- data/ext/zopfli.c +52 -20
- data/lib/zopfli/version.rb +1 -1
- data/smoke.sh +9 -0
- data/test/test_helper.rb +7 -0
- data/test/zopfli_test.rb +63 -0
- data/vendor/zopfli/src/zopfli/blocksplitter.c +41 -53
- data/vendor/zopfli/src/zopfli/blocksplitter.h +2 -6
- data/vendor/zopfli/src/zopfli/cache.c +6 -0
- data/vendor/zopfli/src/zopfli/deflate.c +613 -381
- data/vendor/zopfli/src/zopfli/deflate.h +8 -2
- data/vendor/zopfli/src/zopfli/gzip_container.c +54 -47
- data/vendor/zopfli/src/zopfli/hash.c +18 -10
- data/vendor/zopfli/src/zopfli/hash.h +10 -7
- data/vendor/zopfli/src/zopfli/katajainen.c +73 -62
- data/vendor/zopfli/src/zopfli/katajainen.h +1 -1
- data/vendor/zopfli/src/zopfli/lz77.c +190 -42
- data/vendor/zopfli/src/zopfli/lz77.h +39 -23
- data/vendor/zopfli/src/zopfli/squeeze.c +75 -61
- data/vendor/zopfli/src/zopfli/squeeze.h +1 -0
- data/vendor/zopfli/src/zopfli/symbols.h +239 -0
- data/vendor/zopfli/src/zopfli/util.c +0 -178
- data/vendor/zopfli/src/zopfli/util.h +6 -23
- data/vendor/zopfli/src/zopfli/zlib_container.c +1 -1
- data/vendor/zopfli/src/zopfli/zopfli.h +1 -4
- data/vendor/zopfli/src/zopfli/zopfli_bin.c +31 -15
- data/zopfli.gemspec +12 -32
- metadata +20 -68
- data/test/fixtures/alice29.txt +0 -3609
- data/test/test_zopfli_deflate.rb +0 -47
- data/vendor/zopfli/CONTRIBUTORS +0 -7
- data/vendor/zopfli/README +0 -32
- data/vendor/zopfli/README.zopflipng +0 -35
- data/vendor/zopfli/makefile +0 -37
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng.cpp +0 -6253
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng.h +0 -1705
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.cpp +0 -656
- data/vendor/zopfli/src/zopflipng/lodepng/lodepng_util.h +0 -151
- data/vendor/zopfli/src/zopflipng/zopflipng_bin.cc +0 -407
- data/vendor/zopfli/src/zopflipng/zopflipng_lib.cc +0 -376
- data/vendor/zopfli/src/zopflipng/zopflipng_lib.h +0 -79
@@ -1,376 +0,0 @@
|
|
1
|
-
// Copyright 2013 Google Inc. All Rights Reserved.
|
2
|
-
//
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
// you may not use this file except in compliance with the License.
|
5
|
-
// You may obtain a copy of the License at
|
6
|
-
//
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
//
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
// See the License for the specific language governing permissions and
|
13
|
-
// limitations under the License.
|
14
|
-
//
|
15
|
-
// Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
16
|
-
// Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
17
|
-
|
18
|
-
// See zopflipng_lib.h
|
19
|
-
|
20
|
-
#include "zopflipng_lib.h"
|
21
|
-
|
22
|
-
#include <stdio.h>
|
23
|
-
#include <vector>
|
24
|
-
|
25
|
-
#include "lodepng/lodepng.h"
|
26
|
-
#include "lodepng/lodepng_util.h"
|
27
|
-
#include "../zopfli/deflate.h"
|
28
|
-
|
29
|
-
ZopfliPNGOptions::ZopfliPNGOptions()
|
30
|
-
: lossy_transparent(false)
|
31
|
-
, lossy_8bit(false)
|
32
|
-
, auto_filter_strategy(true)
|
33
|
-
, use_zopfli(true)
|
34
|
-
, num_iterations(15)
|
35
|
-
, num_iterations_large(5)
|
36
|
-
, block_split_strategy(1) {
|
37
|
-
}
|
38
|
-
|
39
|
-
// Deflate compressor passed as fuction pointer to LodePNG to have it use Zopfli
|
40
|
-
// as its compression backend.
|
41
|
-
unsigned CustomPNGDeflate(unsigned char** out, size_t* outsize,
|
42
|
-
const unsigned char* in, size_t insize,
|
43
|
-
const LodePNGCompressSettings* settings) {
|
44
|
-
const ZopfliPNGOptions* png_options =
|
45
|
-
static_cast<const ZopfliPNGOptions*>(settings->custom_context);
|
46
|
-
unsigned char bp = 0;
|
47
|
-
ZopfliOptions options;
|
48
|
-
ZopfliInitOptions(&options);
|
49
|
-
|
50
|
-
options.numiterations = insize < 200000
|
51
|
-
? png_options->num_iterations : png_options->num_iterations_large;
|
52
|
-
|
53
|
-
if (png_options->block_split_strategy == 3) {
|
54
|
-
// Try both block splitting first and last.
|
55
|
-
unsigned char* out2 = 0;
|
56
|
-
size_t outsize2 = 0;
|
57
|
-
options.blocksplittinglast = 0;
|
58
|
-
ZopfliDeflate(&options, 2 /* Dynamic */, 1, in, insize, &bp, out, outsize);
|
59
|
-
bp = 0;
|
60
|
-
options.blocksplittinglast = 1;
|
61
|
-
ZopfliDeflate(&options, 2 /* Dynamic */, 1,
|
62
|
-
in, insize, &bp, &out2, &outsize2);
|
63
|
-
|
64
|
-
if (outsize2 < *outsize) {
|
65
|
-
free(*out);
|
66
|
-
*out = out2;
|
67
|
-
*outsize = outsize2;
|
68
|
-
printf("Block splitting last was better\n");
|
69
|
-
} else {
|
70
|
-
free(out2);
|
71
|
-
}
|
72
|
-
} else {
|
73
|
-
if (png_options->block_split_strategy == 0) options.blocksplitting = 0;
|
74
|
-
options.blocksplittinglast = png_options->block_split_strategy == 2;
|
75
|
-
ZopfliDeflate(&options, 2 /* Dynamic */, 1, in, insize, &bp, out, outsize);
|
76
|
-
}
|
77
|
-
|
78
|
-
return 0; // OK
|
79
|
-
}
|
80
|
-
|
81
|
-
// Remove RGB information from pixels with alpha=0
|
82
|
-
void LossyOptimizeTransparent(unsigned char* image, unsigned w, unsigned h) {
|
83
|
-
// First check if we want to preserve potential color-key background color,
|
84
|
-
// or instead use the last encountered RGB value all the time to save bytes.
|
85
|
-
bool key = true;
|
86
|
-
for (size_t i = 0; i < w * h; i++) {
|
87
|
-
if (image[i * 4 + 3] > 0 && image[i * 4 + 3] < 255) {
|
88
|
-
key = false;
|
89
|
-
break;
|
90
|
-
}
|
91
|
-
}
|
92
|
-
|
93
|
-
// Choose the color key if color keying is used.
|
94
|
-
int r = 0, g = 0, b = 0;
|
95
|
-
if (key) {
|
96
|
-
for (size_t i = 0; i < w * h; i++) {
|
97
|
-
if (image[i * 4 + 3] == 0) {
|
98
|
-
// Use first encountered transparent pixel as the color key
|
99
|
-
r = image[i * 4 + 0];
|
100
|
-
g = image[i * 4 + 1];
|
101
|
-
b = image[i * 4 + 2];
|
102
|
-
}
|
103
|
-
}
|
104
|
-
}
|
105
|
-
|
106
|
-
for (size_t i = 0; i < w * h; i++) {
|
107
|
-
// if alpha is 0
|
108
|
-
if (image[i * 4 + 3] == 0) {
|
109
|
-
image[i * 4 + 0] = r;
|
110
|
-
image[i * 4 + 1] = g;
|
111
|
-
image[i * 4 + 2] = b;
|
112
|
-
} else {
|
113
|
-
if (!key) {
|
114
|
-
// Use the last encountered RGB value if no color keying is used.
|
115
|
-
r = image[i * 4 + 0];
|
116
|
-
g = image[i * 4 + 1];
|
117
|
-
b = image[i * 4 + 2];
|
118
|
-
}
|
119
|
-
}
|
120
|
-
}
|
121
|
-
}
|
122
|
-
|
123
|
-
// Tries to optimize given a single PNG filter strategy.
|
124
|
-
// Returns 0 if ok, other value for error
|
125
|
-
unsigned TryOptimize(
|
126
|
-
const std::vector<unsigned char>& image, unsigned w, unsigned h,
|
127
|
-
const lodepng::State& inputstate, bool bit16,
|
128
|
-
const std::vector<unsigned char>& origfile,
|
129
|
-
ZopfliPNGFilterStrategy filterstrategy,
|
130
|
-
bool use_zopfli, int windowsize, const ZopfliPNGOptions* png_options,
|
131
|
-
std::vector<unsigned char>* out) {
|
132
|
-
unsigned error = 0;
|
133
|
-
|
134
|
-
lodepng::State state;
|
135
|
-
state.encoder.zlibsettings.windowsize = windowsize;
|
136
|
-
if (use_zopfli && png_options->use_zopfli) {
|
137
|
-
ZopfliPNGOptions custom_context = *png_options;
|
138
|
-
state.encoder.zlibsettings.custom_deflate = CustomPNGDeflate;
|
139
|
-
state.encoder.zlibsettings.custom_context = &custom_context;
|
140
|
-
}
|
141
|
-
|
142
|
-
if (inputstate.info_png.color.colortype == LCT_PALETTE) {
|
143
|
-
// Make it preserve the original palette order
|
144
|
-
lodepng_color_mode_copy(&state.info_raw, &inputstate.info_png.color);
|
145
|
-
state.info_raw.colortype = LCT_RGBA;
|
146
|
-
state.info_raw.bitdepth = 8;
|
147
|
-
}
|
148
|
-
if (bit16) {
|
149
|
-
state.info_raw.bitdepth = 16;
|
150
|
-
}
|
151
|
-
|
152
|
-
state.encoder.filter_palette_zero = 0;
|
153
|
-
|
154
|
-
std::vector<unsigned char> filters;
|
155
|
-
switch (filterstrategy) {
|
156
|
-
case kStrategyZero:
|
157
|
-
state.encoder.filter_strategy = LFS_ZERO;
|
158
|
-
break;
|
159
|
-
case kStrategyMinSum:
|
160
|
-
state.encoder.filter_strategy = LFS_MINSUM;
|
161
|
-
break;
|
162
|
-
case kStrategyEntropy:
|
163
|
-
state.encoder.filter_strategy = LFS_ENTROPY;
|
164
|
-
break;
|
165
|
-
case kStrategyBruteForce:
|
166
|
-
state.encoder.filter_strategy = LFS_BRUTE_FORCE;
|
167
|
-
break;
|
168
|
-
case kStrategyOne:
|
169
|
-
case kStrategyTwo:
|
170
|
-
case kStrategyThree:
|
171
|
-
case kStrategyFour:
|
172
|
-
// Set the filters of all scanlines to that number.
|
173
|
-
filters.resize(h, filterstrategy);
|
174
|
-
state.encoder.filter_strategy = LFS_PREDEFINED;
|
175
|
-
state.encoder.predefined_filters = &filters[0];
|
176
|
-
break;
|
177
|
-
case kStrategyPredefined:
|
178
|
-
lodepng::getFilterTypes(filters, origfile);
|
179
|
-
state.encoder.filter_strategy = LFS_PREDEFINED;
|
180
|
-
state.encoder.predefined_filters = &filters[0];
|
181
|
-
break;
|
182
|
-
default:
|
183
|
-
break;
|
184
|
-
}
|
185
|
-
|
186
|
-
state.encoder.add_id = false;
|
187
|
-
state.encoder.text_compression = 1;
|
188
|
-
|
189
|
-
error = lodepng::encode(*out, image, w, h, state);
|
190
|
-
|
191
|
-
// For very small output, also try without palette, it may be smaller thanks
|
192
|
-
// to no palette storage overhead.
|
193
|
-
if (!error && out->size() < 4096) {
|
194
|
-
lodepng::State teststate;
|
195
|
-
std::vector<unsigned char> temp;
|
196
|
-
lodepng::decode(temp, w, h, teststate, *out);
|
197
|
-
LodePNGColorMode& color = teststate.info_png.color;
|
198
|
-
if (color.colortype == LCT_PALETTE) {
|
199
|
-
std::vector<unsigned char> out2;
|
200
|
-
state.encoder.auto_convert = LAC_ALPHA;
|
201
|
-
bool grey = true;
|
202
|
-
for (size_t i = 0; i < color.palettesize; i++) {
|
203
|
-
if (color.palette[i * 4 + 0] != color.palette[i * 4 + 2]
|
204
|
-
|| color.palette[i * 4 + 1] != color.palette[i * 4 + 2]) {
|
205
|
-
grey = false;
|
206
|
-
break;
|
207
|
-
}
|
208
|
-
}
|
209
|
-
if (grey) state.info_png.color.colortype = LCT_GREY_ALPHA;
|
210
|
-
|
211
|
-
error = lodepng::encode(out2, image, w, h, state);
|
212
|
-
if (out2.size() < out->size()) out->swap(out2);
|
213
|
-
}
|
214
|
-
}
|
215
|
-
|
216
|
-
if (error) {
|
217
|
-
printf("Encoding error %i: %s\n", error, lodepng_error_text(error));
|
218
|
-
return error;
|
219
|
-
}
|
220
|
-
|
221
|
-
return 0;
|
222
|
-
}
|
223
|
-
|
224
|
-
// Use fast compression to check which PNG filter strategy gives the smallest
|
225
|
-
// output. This allows to then do the slow and good compression only on that
|
226
|
-
// filter type.
|
227
|
-
unsigned AutoChooseFilterStrategy(const std::vector<unsigned char>& image,
|
228
|
-
unsigned w, unsigned h,
|
229
|
-
const lodepng::State& inputstate, bool bit16,
|
230
|
-
const std::vector<unsigned char>& origfile,
|
231
|
-
int numstrategies,
|
232
|
-
ZopfliPNGFilterStrategy* strategies,
|
233
|
-
bool* enable) {
|
234
|
-
std::vector<unsigned char> out;
|
235
|
-
size_t bestsize = 0;
|
236
|
-
int bestfilter = 0;
|
237
|
-
|
238
|
-
// A large window size should still be used to do the quick compression to
|
239
|
-
// try out filter strategies: which filter strategy is the best depends
|
240
|
-
// largely on the window size, the closer to the actual used window size the
|
241
|
-
// better.
|
242
|
-
int windowsize = 8192;
|
243
|
-
|
244
|
-
for (int i = 0; i < numstrategies; i++) {
|
245
|
-
out.clear();
|
246
|
-
unsigned error = TryOptimize(image, w, h, inputstate, bit16, origfile,
|
247
|
-
strategies[i], false, windowsize, 0, &out);
|
248
|
-
if (error) return error;
|
249
|
-
if (bestsize == 0 || out.size() < bestsize) {
|
250
|
-
bestsize = out.size();
|
251
|
-
bestfilter = i;
|
252
|
-
}
|
253
|
-
}
|
254
|
-
|
255
|
-
for (int i = 0; i < numstrategies; i++) {
|
256
|
-
enable[i] = (i == bestfilter);
|
257
|
-
}
|
258
|
-
|
259
|
-
return 0; /* OK */
|
260
|
-
}
|
261
|
-
|
262
|
-
// Keeps chunks with given names from the original png by literally copying them
|
263
|
-
// into the new png
|
264
|
-
void KeepChunks(const std::vector<unsigned char>& origpng,
|
265
|
-
const std::vector<std::string>& keepnames,
|
266
|
-
std::vector<unsigned char>* png) {
|
267
|
-
std::vector<std::string> names[3];
|
268
|
-
std::vector<std::vector<unsigned char> > chunks[3];
|
269
|
-
|
270
|
-
lodepng::getChunks(names, chunks, origpng);
|
271
|
-
std::vector<std::vector<unsigned char> > keepchunks[3];
|
272
|
-
|
273
|
-
// There are 3 distinct locations in a PNG file for chunks: between IHDR and
|
274
|
-
// PLTE, between PLTE and IDAT, and between IDAT and IEND. Keep each chunk at
|
275
|
-
// its corresponding location in the new PNG.
|
276
|
-
for (size_t i = 0; i < 3; i++) {
|
277
|
-
for (size_t j = 0; j < names[i].size(); j++) {
|
278
|
-
for (size_t k = 0; k < keepnames.size(); k++) {
|
279
|
-
if (keepnames[k] == names[i][j]) {
|
280
|
-
keepchunks[i].push_back(chunks[i][j]);
|
281
|
-
}
|
282
|
-
}
|
283
|
-
}
|
284
|
-
}
|
285
|
-
|
286
|
-
lodepng::insertChunks(*png, keepchunks);
|
287
|
-
}
|
288
|
-
|
289
|
-
int ZopfliPNGOptimize(const std::vector<unsigned char>& origpng,
|
290
|
-
const ZopfliPNGOptions& png_options,
|
291
|
-
bool verbose,
|
292
|
-
std::vector<unsigned char>* resultpng) {
|
293
|
-
// Use the largest possible deflate window size
|
294
|
-
int windowsize = 32768;
|
295
|
-
|
296
|
-
ZopfliPNGFilterStrategy filterstrategies[kNumFilterStrategies] = {
|
297
|
-
kStrategyZero, kStrategyOne, kStrategyTwo, kStrategyThree, kStrategyFour,
|
298
|
-
kStrategyMinSum, kStrategyEntropy, kStrategyPredefined, kStrategyBruteForce
|
299
|
-
};
|
300
|
-
bool strategy_enable[kNumFilterStrategies] = {
|
301
|
-
false, false, false, false, false, false, false, false, false
|
302
|
-
};
|
303
|
-
std::string strategy_name[kNumFilterStrategies] = {
|
304
|
-
"zero", "one", "two", "three", "four",
|
305
|
-
"minimum sum", "entropy", "predefined", "brute force"
|
306
|
-
};
|
307
|
-
for (size_t i = 0; i < png_options.filter_strategies.size(); i++) {
|
308
|
-
strategy_enable[png_options.filter_strategies[i]] = true;
|
309
|
-
}
|
310
|
-
|
311
|
-
|
312
|
-
std::vector<unsigned char> image;
|
313
|
-
unsigned w, h;
|
314
|
-
unsigned error;
|
315
|
-
lodepng::State inputstate;
|
316
|
-
error = lodepng::decode(image, w, h, inputstate, origpng);
|
317
|
-
|
318
|
-
if (error) {
|
319
|
-
if (verbose) {
|
320
|
-
printf("Decoding error %i: %s\n", error, lodepng_error_text(error));
|
321
|
-
}
|
322
|
-
return error;
|
323
|
-
}
|
324
|
-
|
325
|
-
bool bit16 = false; // Using 16-bit per channel raw image
|
326
|
-
if (inputstate.info_png.color.bitdepth == 16 && !png_options.lossy_8bit) {
|
327
|
-
// Decode as 16-bit
|
328
|
-
image.clear();
|
329
|
-
error = lodepng::decode(image, w, h, origpng, LCT_RGBA, 16);
|
330
|
-
bit16 = true;
|
331
|
-
}
|
332
|
-
|
333
|
-
if (!error) {
|
334
|
-
// If lossy_transparent, remove RGB information from pixels with alpha=0
|
335
|
-
if (png_options.lossy_transparent && !bit16) {
|
336
|
-
LossyOptimizeTransparent(&image[0], w, h);
|
337
|
-
}
|
338
|
-
|
339
|
-
if (png_options.auto_filter_strategy) {
|
340
|
-
error = AutoChooseFilterStrategy(image, w, h, inputstate, bit16,
|
341
|
-
origpng,
|
342
|
-
/* Don't try brute force */
|
343
|
-
kNumFilterStrategies - 1,
|
344
|
-
filterstrategies, strategy_enable);
|
345
|
-
}
|
346
|
-
}
|
347
|
-
|
348
|
-
if (!error) {
|
349
|
-
size_t bestsize = 0;
|
350
|
-
|
351
|
-
for (int i = 0; i < kNumFilterStrategies; i++) {
|
352
|
-
if (!strategy_enable[i]) continue;
|
353
|
-
|
354
|
-
std::vector<unsigned char> temp;
|
355
|
-
error = TryOptimize(image, w, h, inputstate, bit16, origpng,
|
356
|
-
filterstrategies[i], true /* use_zopfli */,
|
357
|
-
windowsize, &png_options, &temp);
|
358
|
-
if (!error) {
|
359
|
-
if (verbose) {
|
360
|
-
printf("Filter strategy %s: %d bytes\n",
|
361
|
-
strategy_name[i].c_str(), (int) temp.size());
|
362
|
-
}
|
363
|
-
if (bestsize == 0 || temp.size() < bestsize) {
|
364
|
-
bestsize = temp.size();
|
365
|
-
(*resultpng).swap(temp); // Store best result so far in the output.
|
366
|
-
}
|
367
|
-
}
|
368
|
-
}
|
369
|
-
|
370
|
-
if (!png_options.keepchunks.empty()) {
|
371
|
-
KeepChunks(origpng, png_options.keepchunks, resultpng);
|
372
|
-
}
|
373
|
-
}
|
374
|
-
|
375
|
-
return error;
|
376
|
-
}
|
@@ -1,79 +0,0 @@
|
|
1
|
-
// Copyright 2013 Google Inc. All Rights Reserved.
|
2
|
-
//
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
// you may not use this file except in compliance with the License.
|
5
|
-
// You may obtain a copy of the License at
|
6
|
-
//
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
//
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
// See the License for the specific language governing permissions and
|
13
|
-
// limitations under the License.
|
14
|
-
//
|
15
|
-
// Author: lode.vandevenne@gmail.com (Lode Vandevenne)
|
16
|
-
// Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
|
17
|
-
|
18
|
-
// Library to recompress and optimize PNG images. Uses Zopfli as the compression
|
19
|
-
// backend, chooses optimal PNG color model, and tries out several PNG filter
|
20
|
-
// strategies.
|
21
|
-
|
22
|
-
#ifndef UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
|
23
|
-
#define UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
|
24
|
-
|
25
|
-
#include <string>
|
26
|
-
#include <vector>
|
27
|
-
|
28
|
-
enum ZopfliPNGFilterStrategy {
|
29
|
-
kStrategyZero = 0,
|
30
|
-
kStrategyOne = 1,
|
31
|
-
kStrategyTwo = 2,
|
32
|
-
kStrategyThree = 3,
|
33
|
-
kStrategyFour = 4,
|
34
|
-
kStrategyMinSum,
|
35
|
-
kStrategyEntropy,
|
36
|
-
kStrategyPredefined,
|
37
|
-
kStrategyBruteForce,
|
38
|
-
kNumFilterStrategies /* Not a strategy but used for the size of this enum */
|
39
|
-
};
|
40
|
-
|
41
|
-
struct ZopfliPNGOptions {
|
42
|
-
ZopfliPNGOptions();
|
43
|
-
|
44
|
-
// Allow altering hidden colors of fully transparent pixels
|
45
|
-
bool lossy_transparent;
|
46
|
-
// Convert 16-bit per channel images to 8-bit per channel
|
47
|
-
bool lossy_8bit;
|
48
|
-
|
49
|
-
// Filter strategies to try
|
50
|
-
std::vector<ZopfliPNGFilterStrategy> filter_strategies;
|
51
|
-
|
52
|
-
// Automatically choose filter strategy using less good compression
|
53
|
-
bool auto_filter_strategy;
|
54
|
-
|
55
|
-
// PNG chunks to keep
|
56
|
-
// chunks to literally copy over from the original PNG to the resulting one
|
57
|
-
std::vector<std::string> keepchunks;
|
58
|
-
|
59
|
-
// Use Zopfli deflate compression
|
60
|
-
bool use_zopfli;
|
61
|
-
|
62
|
-
// Zopfli number of iterations
|
63
|
-
int num_iterations;
|
64
|
-
|
65
|
-
// Zopfli number of iterations on large images
|
66
|
-
int num_iterations_large;
|
67
|
-
|
68
|
-
// 0=none, 1=first, 2=last, 3=both
|
69
|
-
int block_split_strategy;
|
70
|
-
};
|
71
|
-
|
72
|
-
// Returns 0 on success, error code otherwise.
|
73
|
-
// If verbose is true, it will print some info while working.
|
74
|
-
int ZopfliPNGOptimize(const std::vector<unsigned char>& origpng,
|
75
|
-
const ZopfliPNGOptions& png_options,
|
76
|
-
bool verbose,
|
77
|
-
std::vector<unsigned char>* resultpng);
|
78
|
-
|
79
|
-
#endif // UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
|