chunky_png 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -63,5 +63,8 @@ The library is written by Willem van Bergen for Floorplanner.com, and released
63
63
  under the MIT license (see LICENSE). Please contact me for questions or
64
64
  remarks. Patches are greatly appreciated!
65
65
 
66
+ Please check out the changelog on https://github.com/wvanbergen/chunky_png/wiki/Changelog
67
+ to see what changed in all versions.
68
+
66
69
  P.S.: The name of this library is intentionally similar to Chunky Bacon and
67
70
  Chunky GIF. Use Google if you want to know _why. :-)
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
3
3
 
4
4
  # Do not change the version and date fields by hand. This will be done
5
5
  # automatically by the gem release script.
6
- s.version = "1.1.2"
7
- s.date = "2011-05-06"
6
+ s.version = "1.2.0"
7
+ s.date = "2011-05-08"
8
8
 
9
9
  s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
10
10
  s.description = <<-EOT
@@ -25,7 +25,7 @@ module ChunkyPNG
25
25
 
26
26
  # The current version of ChunkyPNG. This value will be updated
27
27
  # automatically by them <tt>gem:release</tt> rake task.
28
- VERSION = "1.1.2"
28
+ VERSION = "1.2.0"
29
29
 
30
30
  ###################################################
31
31
  # PNG international standard defined constants
@@ -33,6 +33,9 @@ module ChunkyPNG
33
33
  # tRNS chunk from the PNG stream. For RGB(A) images, no palette is required.
34
34
  # @return [ChunkyPNG::Palette]
35
35
  attr_accessor :decoding_palette
36
+
37
+ # The color to be replaced with fully transparent pixels.
38
+ attr_accessor :transparent_color
36
39
 
37
40
  # Decodes a Canvas from a PNG encoded string.
38
41
  # @param [String] str The string to read from.
@@ -73,7 +76,15 @@ module ChunkyPNG
73
76
  raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
74
77
  end
75
78
 
76
- self.decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
79
+ case color_mode
80
+ when ChunkyPNG::COLOR_INDEXED
81
+ self.decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
82
+ when ChunkyPNG::COLOR_TRUECOLOR
83
+ self.transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
84
+ when ChunkyPNG::COLOR_GRAYSCALE
85
+ self.transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
86
+ end
87
+
77
88
  decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
78
89
  end
79
90
 
@@ -88,11 +99,15 @@ module ChunkyPNG
88
99
  # @return [ChunkyPNG::Canvas] The decoded Canvas instance.
89
100
  def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)
90
101
  raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
91
- case interlace
102
+
103
+ image = case interlace
92
104
  when ChunkyPNG::INTERLACING_NONE; decode_png_without_interlacing(stream, width, height, color_mode, depth)
93
105
  when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
94
106
  else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
95
107
  end
108
+
109
+ image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
110
+ return image
96
111
  end
97
112
 
98
113
  protected
@@ -165,6 +180,13 @@ module ChunkyPNG
165
180
  value >> 8
166
181
  end
167
182
 
183
+ # No-op - available for completeness sake only
184
+ # @param [Integer] value The 8 bit value to resample.
185
+ # @return [Integer] The 8 bit resampled value
186
+ def decode_png_resample_8bit_value(value)
187
+ value
188
+ end
189
+
168
190
  # Resamples a 4 bit value to an 8 bit value.
169
191
  # @param [Integer] value The 4 bit value to resample.
170
192
  # @return [Integer] The 8 bit resampled value.
@@ -200,6 +222,14 @@ module ChunkyPNG
200
222
  when 0x03; 0xff
201
223
  end
202
224
  end
225
+
226
+ # Resamples a 1 bit value to an 8 bit value.
227
+ # @param [Integer] value The 1 bit value to resample.
228
+ # @return [Integer] The 8 bit resampled value
229
+ def decode_png_resample_1bit_value(value)
230
+ value == 0x01 ? 0xff : 0x00
231
+ end
232
+
203
233
 
204
234
  # Decodes a scanline of a 1-bit, indexed image into a row of pixels.
205
235
  # @param [String] stream The stream to decode from.
@@ -177,12 +177,46 @@ module ChunkyPNG
177
177
  class Palette < Generic
178
178
  end
179
179
 
180
- # A transparency (tRNS) chunk contains the alpha channel for the colors
181
- # defined in the Palette (PLTE) chunk
180
+ # A transparency (tRNS) chunk defines the transparency for an image.
181
+ #
182
+ # * For indexed images, it contains the alpha channel for the colors defined in the Palette (PLTE) chunk.
183
+ # * For grayscale images, it contains the grayscale teint that should be considered fully transparent.
184
+ # * For truecolor images, it contains the color that should be considered fully transparent.
185
+ #
186
+ # Images having a color mode that already includes an alpha channel, this chunk should not be included.
182
187
  #
183
188
  # @see ChunkyPNG::Chunk::Palette
184
189
  # @see ChunkyPNG::Palette
185
190
  class Transparency < Generic
191
+
192
+ # Returns the alpha channel for the palette of an indexed image.
193
+ #
194
+ # This method should only be used for images having color mode ChunkyPNG::COLOR_INDEXED (3).
195
+ #
196
+ # @return [Array<Integer>] Returns an array of alpha channel values [0-255].
197
+ def palette_alpha_channel
198
+ content.unpack('C*')
199
+ end
200
+
201
+ # Returns the truecolor entry to be replaced by transparent pixels,
202
+ #
203
+ # This method should only be used for images having color mode ChunkyPNG::COLOR_TRUECOLOR (2).
204
+ #
205
+ # @return [Integer] The color to replace with fully transparent pixels.
206
+ def truecolor_entry(bit_depth)
207
+ values = content.unpack('nnn').map { |c| ChunkyPNG::Canvas.send(:"decode_png_resample_#{bit_depth}bit_value", c) }
208
+ ChunkyPNG::Color.rgb(*values)
209
+ end
210
+
211
+ # Returns the grayscale entry to be replaced by transparent pixels.
212
+ #
213
+ # This method should only be used for images having color mode ChunkyPNG::COLOR_GRAYSCALE (0).
214
+ #
215
+ # @return [Integer] The (grayscale) color to replace with fully transparent pixels.
216
+ def grayscale_entry(bit_depth)
217
+ value = ChunkyPNG::Canvas.send(:"decode_png_resample_#{bit_depth}bit_value", content.unpack('n')[0])
218
+ ChunkyPNG::Color.grayscale(value)
219
+ end
186
220
  end
187
221
 
188
222
  class ImageData < Generic
@@ -85,6 +85,26 @@ describe 'PNG testuite' do
85
85
  end
86
86
  end
87
87
 
88
+ context 'Decoding transparency' do
89
+ png_suite_files(:transparency, 'tp0*.png').each do |file|
90
+ it "should not have transparency in #{File.basename(file)}" do
91
+ ChunkyPNG::Color.a(ChunkyPNG::Image.from_file(file)[0,0]).should == 255
92
+ end
93
+ end
94
+
95
+ png_suite_files(:transparency, 'tp1*.png').each do |file|
96
+ it "should have transparency in #{File.basename(file)}" do
97
+ ChunkyPNG::Color.a(ChunkyPNG::Image.from_file(file)[0,0]).should == 0
98
+ end
99
+ end
100
+
101
+ png_suite_files(:transparency, 'tb*.png').each do |file|
102
+ it "should have transparency in #{File.basename(file)}" do
103
+ ChunkyPNG::Color.a(ChunkyPNG::Image.from_file(file)[0,0]).should == 0
104
+ end
105
+ end
106
+ end
107
+
88
108
  context 'Decoding different sizes' do
89
109
 
90
110
  png_suite_files(:sizes, '*n*.png').each do |file|
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 1
8
7
  - 2
9
- version: 1.1.2
8
+ - 0
9
+ version: 1.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Willem van Bergen
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-05-06 00:00:00 -04:00
17
+ date: 2011-05-08 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency