zopfli 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /*
2
- LodePNG version 20130415
2
+ LodePNG version 20131222
3
3
 
4
4
  Copyright (c) 2005-2013 Lode Vandevenne
5
5
 
@@ -262,7 +262,7 @@ struct LodePNGDecompressSettings
262
262
  const unsigned char*, size_t,
263
263
  const LodePNGDecompressSettings*);
264
264
 
265
- void* custom_context; /*optional custom settings for custom functions*/
265
+ const void* custom_context; /*optional custom settings for custom functions*/
266
266
  };
267
267
 
268
268
  extern const LodePNGDecompressSettings lodepng_default_decompress_settings;
@@ -280,7 +280,7 @@ struct LodePNGCompressSettings /*deflate = compress*/
280
280
  /*LZ77 related settings*/
281
281
  unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
282
282
  unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
283
- unsigned windowsize; /*the maximum is 32768, higher gives more compression but is slower. Typical value: 2048.*/
283
+ unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Typical value: 2048.*/
284
284
  unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
285
285
  unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
286
286
  unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
@@ -296,7 +296,7 @@ struct LodePNGCompressSettings /*deflate = compress*/
296
296
  const unsigned char*, size_t,
297
297
  const LodePNGCompressSettings*);
298
298
 
299
- void* custom_context; /*optional custom settings for custom functions*/
299
+ const void* custom_context; /*optional custom settings for custom functions*/
300
300
  };
301
301
 
302
302
  extern const LodePNGCompressSettings lodepng_default_compress_settings;
@@ -501,10 +501,9 @@ The fix_png value works as described in struct LodePNGDecoderSettings.
501
501
  Note: for 16-bit per channel colors, uses big endian format like PNG does.
502
502
  */
503
503
  unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
504
- LodePNGColorMode* mode_out, LodePNGColorMode* mode_in,
504
+ LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in,
505
505
  unsigned w, unsigned h, unsigned fix_png);
506
506
 
507
-
508
507
  #ifdef LODEPNG_COMPILE_DECODER
509
508
  /*
510
509
  Settings for the decoder. This contains settings for the PNG and the Zlib
@@ -524,7 +523,7 @@ typedef struct LodePNGDecoderSettings
524
523
  interpret it as opaque black.
525
524
  By default this value is 0, which makes it stop with an error on such images.
526
525
  */
527
- unsigned fix_png; /*if 1, try to parse some broken PNG images, e.g. with out of bound palette.*/
526
+ unsigned fix_png;
528
527
  unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
529
528
 
530
529
  #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
@@ -580,6 +579,17 @@ typedef enum LodePNGAutoConvert
580
579
  } LodePNGAutoConvert;
581
580
 
582
581
 
582
+ /*
583
+ Automatically chooses color type that gives smallest amount of bits in the
584
+ output image, e.g. grey if there are only greyscale pixels, palette if there
585
+ are less than 256 colors, ...
586
+ The auto_convert parameter allows limiting it to not use palette, ...
587
+ */
588
+ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
589
+ const unsigned char* image, unsigned w, unsigned h,
590
+ const LodePNGColorMode* mode_in,
591
+ LodePNGAutoConvert auto_convert);
592
+
583
593
  /*Settings for the encoder.*/
584
594
  typedef struct LodePNGEncoderSettings
585
595
  {
@@ -599,7 +609,7 @@ typedef struct LodePNGEncoderSettings
599
609
  the same length as the amount of scanlines in the image, and each value must <= 5. You
600
610
  have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero
601
611
  must be set to 0 to ensure this is also used on palette or low bitdepth images.*/
602
- unsigned char* predefined_filters;
612
+ const unsigned char* predefined_filters;
603
613
 
604
614
  /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette).
605
615
  If colortype is 3, PLTE is _always_ created.*/
@@ -1564,6 +1574,7 @@ yyyymmdd.
1564
1574
  Some changes aren't backwards compatible. Those are indicated with a (!)
1565
1575
  symbol.
1566
1576
 
1577
+ *) 22 dec 2013: Power of two windowsize required for optimization.
1567
1578
  *) 15 apr 2013: Fixed bug with LAC_ALPHA and color key.
1568
1579
  *) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png).
1569
1580
  *) 11 mar 2013 (!): Bugfix with custom free. Changed from "my" to "lodepng_"
@@ -20,6 +20,7 @@
20
20
  #include "zopflipng_lib.h"
21
21
 
22
22
  #include <stdio.h>
23
+ #include <set>
23
24
  #include <vector>
24
25
 
25
26
  #include "lodepng/lodepng.h"
@@ -78,8 +79,29 @@ unsigned CustomPNGDeflate(unsigned char** out, size_t* outsize,
78
79
  return 0; // OK
79
80
  }
80
81
 
82
+ // Returns 32-bit integer value for RGBA color.
83
+ static unsigned ColorIndex(const unsigned char* color) {
84
+ return color[0] + 256u * color[1] + 65536u * color[1] + 16777216u * color[3];
85
+ }
86
+
87
+ // Counts amount of colors in the image, up to 257. If transparent_counts_as_one
88
+ // is enabled, any color with alpha channel 0 is treated as a single color with
89
+ // index 0.
90
+ void CountColors(std::set<unsigned>* unique,
91
+ const unsigned char* image, unsigned w, unsigned h,
92
+ bool transparent_counts_as_one) {
93
+ unique->clear();
94
+ for (size_t i = 0; i < w * h; i++) {
95
+ unsigned index = ColorIndex(&image[i * 4]);
96
+ if (transparent_counts_as_one && image[i * 4 + 3] == 0) index = 0;
97
+ unique->insert(index);
98
+ if (unique->size() > 256) break;
99
+ }
100
+ }
101
+
81
102
  // Remove RGB information from pixels with alpha=0
82
- void LossyOptimizeTransparent(unsigned char* image, unsigned w, unsigned h) {
103
+ void LossyOptimizeTransparent(lodepng::State* inputstate, unsigned char* image,
104
+ unsigned w, unsigned h) {
83
105
  // First check if we want to preserve potential color-key background color,
84
106
  // or instead use the last encountered RGB value all the time to save bytes.
85
107
  bool key = true;
@@ -89,13 +111,20 @@ void LossyOptimizeTransparent(unsigned char* image, unsigned w, unsigned h) {
89
111
  break;
90
112
  }
91
113
  }
114
+ std::set<unsigned> count; // Color count, up to 257.
115
+ CountColors(&count, image, w, h, true);
116
+ // If true, means palette is possible so avoid using different RGB values for
117
+ // the transparent color.
118
+ bool palette = count.size() <= 256;
92
119
 
93
- // Choose the color key if color keying is used.
120
+ // Choose the color key or first initial background color.
94
121
  int r = 0, g = 0, b = 0;
95
- if (key) {
122
+ if (key || palette) {
96
123
  for (size_t i = 0; i < w * h; i++) {
97
124
  if (image[i * 4 + 3] == 0) {
98
- // Use first encountered transparent pixel as the color key
125
+ // Use RGB value of first encountered transparent pixel. This can be
126
+ // used as a valid color key, or in case of palette ensures a color
127
+ // existing in the input image palette is used.
99
128
  r = image[i * 4 + 0];
100
129
  g = image[i * 4 + 1];
101
130
  b = image[i * 4 + 2];
@@ -104,20 +133,42 @@ void LossyOptimizeTransparent(unsigned char* image, unsigned w, unsigned h) {
104
133
  }
105
134
 
106
135
  for (size_t i = 0; i < w * h; i++) {
107
- // if alpha is 0
136
+ // if alpha is 0, alter the RGB value to a possibly more efficient one.
108
137
  if (image[i * 4 + 3] == 0) {
109
138
  image[i * 4 + 0] = r;
110
139
  image[i * 4 + 1] = g;
111
140
  image[i * 4 + 2] = b;
112
141
  } else {
113
- if (!key) {
114
- // Use the last encountered RGB value if no color keying is used.
142
+ if (!key && !palette) {
143
+ // Use the last encountered RGB value if no key or palette is used: that
144
+ // way more values can be 0 thanks to the PNG filter types.
115
145
  r = image[i * 4 + 0];
116
146
  g = image[i * 4 + 1];
117
147
  b = image[i * 4 + 2];
118
148
  }
119
149
  }
120
150
  }
151
+
152
+ // If there are now less colors, update palette of input image to match this.
153
+ if (palette && inputstate->info_png.color.palettesize > 0) {
154
+ CountColors(&count, image, w, h, false);
155
+ if (count.size() < inputstate->info_png.color.palettesize) {
156
+ std::vector<unsigned char> palette_out;
157
+ unsigned char* palette_in = inputstate->info_png.color.palette;
158
+ for (size_t i = 0; i < inputstate->info_png.color.palettesize; i++) {
159
+ if (count.count(ColorIndex(&palette_in[i * 4])) != 0) {
160
+ palette_out.push_back(palette_in[i * 4 + 0]);
161
+ palette_out.push_back(palette_in[i * 4 + 1]);
162
+ palette_out.push_back(palette_in[i * 4 + 2]);
163
+ palette_out.push_back(palette_in[i * 4 + 3]);
164
+ }
165
+ }
166
+ inputstate->info_png.color.palettesize = palette_out.size() / 4;
167
+ for (size_t i = 0; i < palette_out.size(); i++) {
168
+ palette_in[i] = palette_out[i];
169
+ }
170
+ }
171
+ }
121
172
  }
122
173
 
123
174
  // Tries to optimize given a single PNG filter strategy.
@@ -134,9 +185,8 @@ unsigned TryOptimize(
134
185
  lodepng::State state;
135
186
  state.encoder.zlibsettings.windowsize = windowsize;
136
187
  if (use_zopfli && png_options->use_zopfli) {
137
- ZopfliPNGOptions custom_context = *png_options;
138
188
  state.encoder.zlibsettings.custom_deflate = CustomPNGDeflate;
139
- state.encoder.zlibsettings.custom_context = &custom_context;
189
+ state.encoder.zlibsettings.custom_context = png_options;
140
190
  }
141
191
 
142
192
  if (inputstate.info_png.color.colortype == LCT_PALETTE) {
@@ -214,7 +264,7 @@ unsigned TryOptimize(
214
264
  }
215
265
 
216
266
  if (error) {
217
- printf("Encoding error %i: %s\n", error, lodepng_error_text(error));
267
+ printf("Encoding error %u: %s\n", error, lodepng_error_text(error));
218
268
  return error;
219
269
  }
220
270
 
@@ -308,7 +358,6 @@ int ZopfliPNGOptimize(const std::vector<unsigned char>& origpng,
308
358
  strategy_enable[png_options.filter_strategies[i]] = true;
309
359
  }
310
360
 
311
-
312
361
  std::vector<unsigned char> image;
313
362
  unsigned w, h;
314
363
  unsigned error;
@@ -333,7 +382,7 @@ int ZopfliPNGOptimize(const std::vector<unsigned char>& origpng,
333
382
  if (!error) {
334
383
  // If lossy_transparent, remove RGB information from pixels with alpha=0
335
384
  if (png_options.lossy_transparent && !bit16) {
336
- LossyOptimizeTransparent(&image[0], w, h);
385
+ LossyOptimizeTransparent(&inputstate, &image[0], w, h);
337
386
  }
338
387
 
339
388
  if (png_options.auto_filter_strategy) {
@@ -19,8 +19,8 @@
19
19
  // backend, chooses optimal PNG color model, and tries out several PNG filter
20
20
  // strategies.
21
21
 
22
- #ifndef UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
23
- #define UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
22
+ #ifndef ZOPFLIPNG_LIB_H_
23
+ #define ZOPFLIPNG_LIB_H_
24
24
 
25
25
  #include <string>
26
26
  #include <vector>
@@ -76,4 +76,4 @@ int ZopfliPNGOptimize(const std::vector<unsigned char>& origpng,
76
76
  bool verbose,
77
77
  std::vector<unsigned char>* resultpng);
78
78
 
79
- #endif // UTIL_COMPRESSION_ZOPFLI_PNG_ZOPFLIPNG_LIB_H_
79
+ #endif // ZOPFLIPNG_LIB_H_
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zopfli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - miyucy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-15 00:00:00.000000000 Z
11
+ date: 2014-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: zopfli
@@ -60,8 +60,8 @@ extensions:
60
60
  - ext/extconf.rb
61
61
  extra_rdoc_files: []
62
62
  files:
63
- - .gitignore
64
- - .gitmodules
63
+ - ".gitignore"
64
+ - ".gitmodules"
65
65
  - Gemfile
66
66
  - LICENSE.txt
67
67
  - README.md
@@ -71,12 +71,11 @@ files:
71
71
  - lib/zopfli/version.rb
72
72
  - test/fixtures/alice29.txt
73
73
  - test/test_zopfli_deflate.rb
74
- - zopfli.gemspec
75
74
  - vendor/zopfli/CONTRIBUTORS
76
75
  - vendor/zopfli/COPYING
76
+ - vendor/zopfli/Makefile
77
77
  - vendor/zopfli/README
78
78
  - vendor/zopfli/README.zopflipng
79
- - vendor/zopfli/makefile
80
79
  - vendor/zopfli/src/zopfli/blocksplitter.c
81
80
  - vendor/zopfli/src/zopfli/blocksplitter.h
82
81
  - vendor/zopfli/src/zopfli/cache.c
@@ -109,6 +108,7 @@ files:
109
108
  - vendor/zopfli/src/zopflipng/zopflipng_bin.cc
110
109
  - vendor/zopfli/src/zopflipng/zopflipng_lib.cc
111
110
  - vendor/zopfli/src/zopflipng/zopflipng_lib.h
111
+ - zopfli.gemspec
112
112
  homepage: http://github.com/miyucy/zopfli
113
113
  licenses:
114
114
  - MIT
@@ -119,17 +119,17 @@ require_paths:
119
119
  - lib
120
120
  required_ruby_version: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  requirements:
127
- - - '>='
127
+ - - ">="
128
128
  - !ruby/object:Gem::Version
129
129
  version: '0'
130
130
  requirements: []
131
131
  rubyforge_project:
132
- rubygems_version: 2.1.9
132
+ rubygems_version: 2.2.2
133
133
  signing_key:
134
134
  specification_version: 4
135
135
  summary: zopfli