chunky_png 0.11.1 → 0.12.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.
data/.infinity_test CHANGED
@@ -1,3 +1,8 @@
1
1
  infinity_test do
2
+
2
3
  use :rubies => %w(1.8.7 1.9.2 ree jruby rbx), :test_framework => :rspec
4
+
5
+ before(:each_ruby) do |environment|
6
+ environment.system('bundle install')
7
+ end
3
8
  end
data/Gemfile CHANGED
@@ -1,2 +1,6 @@
1
1
  source :rubygems
2
2
  gemspec
3
+
4
+ platforms :jruby do
5
+ gem 'jruby-openssl'
6
+ end
data/Gemfile.lock CHANGED
@@ -1,21 +1,24 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- chunky_png (0.11.1)
4
+ chunky_png (0.12.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
8
8
  specs:
9
+ bouncy-castle-java (1.5.0145.2)
9
10
  diff-lcs (1.1.2)
11
+ jruby-openssl (0.7.2)
12
+ bouncy-castle-java
10
13
  rake (0.8.7)
11
- rspec (2.1.0)
12
- rspec-core (~> 2.1.0)
13
- rspec-expectations (~> 2.1.0)
14
- rspec-mocks (~> 2.1.0)
15
- rspec-core (2.1.0)
16
- rspec-expectations (2.1.0)
14
+ rspec (2.2.0)
15
+ rspec-core (~> 2.2)
16
+ rspec-expectations (~> 2.2)
17
+ rspec-mocks (~> 2.2)
18
+ rspec-core (2.2.1)
19
+ rspec-expectations (2.2.0)
17
20
  diff-lcs (~> 1.1.2)
18
- rspec-mocks (2.1.0)
21
+ rspec-mocks (2.2.0)
19
22
 
20
23
  PLATFORMS
21
24
  java
@@ -23,5 +26,6 @@ PLATFORMS
23
26
 
24
27
  DEPENDENCIES
25
28
  chunky_png!
29
+ jruby-openssl
26
30
  rake
27
- rspec (~> 2.1)
31
+ rspec (~> 2.2)
data/chunky_png.gemspec CHANGED
@@ -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 = "0.11.1"
7
- s.date = "2010-11-16"
6
+ s.version = "0.12.0"
7
+ s.date = "2010-12-12"
8
8
 
9
9
  s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
10
10
  s.description = <<-EOT
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.homepage = 'http://wiki.github.com/wvanbergen/chunky_png'
32
32
 
33
33
  s.add_development_dependency('rake')
34
- s.add_development_dependency('rspec', '~> 2.1')
34
+ s.add_development_dependency('rspec', '~> 2.2')
35
35
 
36
36
  s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
37
37
  s.extra_rdoc_files = ['README.rdoc', 'BENCHMARKS.rdoc']
data/lib/chunky_png.rb CHANGED
@@ -28,7 +28,7 @@ module ChunkyPNG
28
28
 
29
29
  # The current version of ChunkyPNG. This value will be updated automatically
30
30
  # by them gem:release rake task.
31
- VERSION = "0.11.1"
31
+ VERSION = "0.12.0"
32
32
 
33
33
  ###################################################
34
34
  # PNG international standard defined constants
@@ -64,20 +64,23 @@ module ChunkyPNG
64
64
  # @option constraints [true, false] :interlace Whether to use interlacing.
65
65
  # @option constraints [Fixnum] :compression The compression level for Zlib. This can be a
66
66
  # value between 0 and 9, or a Zlib constant like Zlib::BEST_COMPRESSION.
67
+ # @option constraints [Fixnum] :bit_depth The bit depth to use. This option is only used
68
+ # for indexed images, in which case it overrides the determined minimal bit depth. For
69
+ # all the other color modes, a bit depth of 8 is used.
67
70
  # @return [ChunkyPNG::Datastream] The PNG datastream containing the encoded canvas.
68
71
  # @see ChunkyPNG::Canvas::PNGEncoding#determine_png_encoding
69
72
  def to_datastream(constraints = {})
70
73
  encoding = determine_png_encoding(constraints)
71
74
 
72
75
  ds = Datastream.new
73
- ds.header_chunk = Chunk::Header.new(:width => width, :height => height,
74
- :color => encoding[:color_mode], :interlace => encoding[:interlace])
76
+ ds.header_chunk = Chunk::Header.new(:width => width, :height => height,
77
+ :color => encoding[:color_mode], :depth => encoding[:bit_depth], :interlace => encoding[:interlace])
75
78
 
76
79
  if encoding[:color_mode] == ChunkyPNG::COLOR_INDEXED
77
80
  ds.palette_chunk = encoding_palette.to_plte_chunk
78
81
  ds.transparency_chunk = encoding_palette.to_trns_chunk unless encoding_palette.opaque?
79
82
  end
80
- data = encode_png_pixelstream(encoding[:color_mode], encoding[:interlace], encoding[:filtering])
83
+ data = encode_png_pixelstream(encoding[:color_mode], encoding[:bit_depth], encoding[:interlace], encoding[:filtering])
81
84
  ds.data_chunks = Chunk::ImageData.split_in_chunks(data, encoding[:compression])
82
85
  ds.end_chunk = Chunk::End.new
83
86
  return ds
@@ -119,6 +122,14 @@ module ChunkyPNG
119
122
  self.encoding_palette = self.palette
120
123
  encoding[:color_mode] ||= encoding_palette.best_colormode
121
124
  end
125
+
126
+ # Set the number of bits per color channel. This will always be 8 except for
127
+ # indexed image, which may also use lower bit depths
128
+ if encoding[:color_mode] == ChunkyPNG::COLOR_INDEXED
129
+ encoding[:bit_depth] = [encoding_palette.determine_bit_depth, encoding[:bit_depth] || 1].max
130
+ else
131
+ encoding[:bit_depth] = 8
132
+ end
122
133
 
123
134
  # Use Zlib's default for compression unless otherwise provided.
124
135
  encoding[:compression] ||= Zlib::DEFAULT_COMPRESSION
@@ -140,28 +151,30 @@ module ChunkyPNG
140
151
  # Encodes the canvas according to the PNG format specification with a given color
141
152
  # mode, possibly with interlacing.
142
153
  # @param [Integer] color_mode The color mode to use for encoding.
154
+ # @param [Integer] bit_depth The bit depth of the image.
143
155
  # @param [Integer] interlace The interlacing method to use.
144
156
  # @return [String] The PNG encoded canvas as string.
145
- def encode_png_pixelstream(color_mode = ChunkyPNG::COLOR_TRUECOLOR, interlace = ChunkyPNG::INTERLACING_NONE, filtering = ChunkyPNG::FILTER_NONE)
157
+ def encode_png_pixelstream(color_mode = ChunkyPNG::COLOR_TRUECOLOR, bit_depth = 8, interlace = ChunkyPNG::INTERLACING_NONE, filtering = ChunkyPNG::FILTER_NONE)
146
158
 
147
159
  if color_mode == ChunkyPNG::COLOR_INDEXED && (encoding_palette.nil? || !encoding_palette.can_encode?)
148
160
  raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for encoding!"
149
161
  end
150
162
 
151
163
  case interlace
152
- when ChunkyPNG::INTERLACING_NONE; encode_png_image_without_interlacing(color_mode, filtering)
153
- when ChunkyPNG::INTERLACING_ADAM7; encode_png_image_with_interlacing(color_mode, filtering)
164
+ when ChunkyPNG::INTERLACING_NONE; encode_png_image_without_interlacing(color_mode, bit_depth, filtering)
165
+ when ChunkyPNG::INTERLACING_ADAM7; encode_png_image_with_interlacing(color_mode, bit_depth, filtering)
154
166
  else raise ChunkyPNG::NotSupported, "Unknown interlacing method: #{interlace}!"
155
167
  end
156
168
  end
157
169
 
158
170
  # Encodes the canvas according to the PNG format specification with a given color mode.
159
171
  # @param [Integer] color_mode The color mode to use for encoding.
172
+ # @param [Integer] bit_depth The bit depth of the image.
160
173
  # @param [Integer] filtering The filtering method to use.
161
174
  # @return [String] The PNG encoded canvas as string.
162
- def encode_png_image_without_interlacing(color_mode, filtering = ChunkyPNG::FILTER_NONE)
175
+ def encode_png_image_without_interlacing(color_mode, bit_depth = 8, filtering = ChunkyPNG::FILTER_NONE)
163
176
  stream = ChunkyPNG::Datastream.empty_bytearray
164
- encode_png_image_pass_to_stream(stream, color_mode, filtering)
177
+ encode_png_image_pass_to_stream(stream, color_mode, bit_depth, filtering)
165
178
  stream
166
179
  end
167
180
 
@@ -172,14 +185,15 @@ module ChunkyPNG
172
185
  # one by one, concatenating the resulting strings.
173
186
  #
174
187
  # @param [Integer] color_mode The color mode to use for encoding.
188
+ # @param [Integer] bit_depth The bit depth of the image.
175
189
  # @param [Integer] filtering The filtering method to use.
176
190
  # @return [String] The PNG encoded canvas as string.
177
- def encode_png_image_with_interlacing(color_mode, filtering = ChunkyPNG::FILTER_NONE)
191
+ def encode_png_image_with_interlacing(color_mode, bit_depth = 8, filtering = ChunkyPNG::FILTER_NONE)
178
192
  stream = ChunkyPNG::Datastream.empty_bytearray
179
193
  0.upto(6) do |pass|
180
194
  subcanvas = self.class.adam7_extract_pass(pass, self)
181
195
  subcanvas.encoding_palette = encoding_palette
182
- subcanvas.encode_png_image_pass_to_stream(stream, color_mode, filtering)
196
+ subcanvas.encode_png_image_pass_to_stream(stream, color_mode, bit_depth, filtering)
183
197
  end
184
198
  stream
185
199
  end
@@ -187,24 +201,16 @@ module ChunkyPNG
187
201
  # Encodes the canvas to a stream, in a given color mode.
188
202
  # @param [String] stream The stream to write to.
189
203
  # @param [Integer] color_mode The color mode to use for encoding.
204
+ # @param [Integer] bit_depth The bit depth of the image.
190
205
  # @param [Integer] filtering The filtering method to use.
191
- def encode_png_image_pass_to_stream(stream, color_mode, filtering)
206
+ def encode_png_image_pass_to_stream(stream, color_mode, bit_depth, filtering)
192
207
 
193
208
  start_pos = stream.bytesize
194
209
  pixel_size = Color.pixel_bytesize(color_mode)
195
- line_width = pixel_size * width
196
-
197
- # Encode the whole image without filtering
198
- stream << case color_mode
199
- when ChunkyPNG::COLOR_TRUECOLOR; pixels.pack(('x' + ('NX' * width)) * height)
200
- when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; pixels.pack("xN#{width}" * height)
201
- when ChunkyPNG::COLOR_INDEXED; pixels.map { |p| encoding_palette.index(p) }.pack("xC#{width}" * height)
202
- when ChunkyPNG::COLOR_GRAYSCALE; pixels.map { |p| p >> 8 }.pack("xC#{width}" * height)
203
- when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; pixels.pack("xn#{width}" * height)
204
- else raise ChunkyPNG::NotSupported, "Cannot encode pixels for this mode: #{color_mode}!"
205
- end
210
+ line_width = Color.scanline_bytesize(color_mode, bit_depth, width)
206
211
 
207
212
  # Determine the filter method
213
+ encode_method = encode_png_pixels_to_scanline_method(color_mode, bit_depth)
208
214
  filter_method = case filtering
209
215
  when ChunkyPNG::FILTER_SUB; :encode_png_str_scanline_sub
210
216
  when ChunkyPNG::FILTER_UP; :encode_png_str_scanline_up
@@ -213,6 +219,10 @@ module ChunkyPNG
213
219
  else nil
214
220
  end
215
221
 
222
+ 0.upto(height - 1) do |y|
223
+ stream << send(encode_method, row(y))
224
+ end
225
+
216
226
  # Now, apply filtering if any
217
227
  if filter_method
218
228
  (height - 1).downto(0) do |y|
@@ -222,6 +232,106 @@ module ChunkyPNG
222
232
  end
223
233
  end
224
234
  end
235
+
236
+ # Encodes a line of pixels using 8-bit truecolor mode.
237
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
238
+ # @return [String] The encoded scanline as binary string
239
+ def encode_png_pixels_to_scanline_truecolor_8bit(pixels)
240
+ pixels.pack('x' + ('NX' * width))
241
+ end
242
+
243
+ # Encodes a line of pixels using 8-bit truecolor alpha mode.
244
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
245
+ # @return [String] The encoded scanline as binary string
246
+ def encode_png_pixels_to_scanline_truecolor_alpha_8bit(pixels)
247
+ pixels.pack("xN#{width}")
248
+ end
249
+
250
+ # Encodes a line of pixels using 1-bit indexed mode.
251
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
252
+ # @return [String] The encoded scanline as binary string
253
+ def encode_png_pixels_to_scanline_indexed_1bit(pixels)
254
+ chars = []
255
+ pixels.each_slice(8) do |p1, p2, p3, p4, p5, p6, p7, p8|
256
+ chars << ((encoding_palette.index(p1) << 7) |
257
+ (encoding_palette.index(p2) << 6) |
258
+ (encoding_palette.index(p3) << 5) |
259
+ (encoding_palette.index(p4) << 4) |
260
+ (encoding_palette.index(p5) << 3) |
261
+ (encoding_palette.index(p6) << 2) |
262
+ (encoding_palette.index(p7) << 1) |
263
+ (encoding_palette.index(p8)))
264
+ end
265
+ chars.pack('xC*')
266
+ end
267
+
268
+ # Encodes a line of pixels using 2-bit indexed mode.
269
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
270
+ # @return [String] The encoded scanline as binary string
271
+ def encode_png_pixels_to_scanline_indexed_2bit(pixels)
272
+ chars = []
273
+ pixels.each_slice(4) do |p1, p2, p3, p4|
274
+ chars << ((encoding_palette.index(p1) << 6) |
275
+ (encoding_palette.index(p2) << 4) |
276
+ (encoding_palette.index(p3) << 2) |
277
+ (encoding_palette.index(p4)))
278
+ end
279
+ chars.pack('xC*')
280
+ end
281
+
282
+ # Encodes a line of pixels using 4-bit indexed mode.
283
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
284
+ # @return [String] The encoded scanline as binary string
285
+ def encode_png_pixels_to_scanline_indexed_4bit(pixels)
286
+ chars = []
287
+ pixels.each_slice(2) do |p1, p2|
288
+ chars << ((encoding_palette.index(p1) << 4) | (encoding_palette.index(p2)))
289
+ end
290
+ chars.pack('xC*')
291
+ end
292
+
293
+ # Encodes a line of pixels using 8-bit indexed mode.
294
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
295
+ # @return [String] The encoded scanline as binary string
296
+ def encode_png_pixels_to_scanline_indexed_8bit(pixels)
297
+ pixels.map { |p| encoding_palette.index(p) }.pack("xC#{width}")
298
+ end
299
+
300
+ # Encodes a line of pixels using 8-bit grayscale mode.
301
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
302
+ # @return [String] The encoded scanline as binary string
303
+ def encode_png_pixels_to_scanline_grayscale_8bit(pixels)
304
+ pixels.map { |p| p >> 8 }.pack("xC#{width}")
305
+ end
306
+
307
+ # Encodes a line of pixels using 8-bit grayscale alpha mode.
308
+ # @param [Array<Integer>] pixels A row of pixels of the original image.
309
+ # @return [String] The encoded scanline as binary string
310
+ def encode_png_pixels_to_scanline_grayscale_alpha_8bit(pixels)
311
+ pixels.pack("xn#{width}")
312
+ end
313
+
314
+
315
+ # Returns the method name to use to decode scanlines into pixels.
316
+ # @param [Integer] color_mode The color mode of the image.
317
+ # @param [Integer] depth The bit depth of the image.
318
+ # @return [Symbol] The method name to use for decoding, to be called on the canvas class.
319
+ # @raise [ChunkyPNG::NotSupported] when the color_mode and/or bit depth is not supported.
320
+ def encode_png_pixels_to_scanline_method(color_mode, depth)
321
+ encoder_method = case color_mode
322
+ when ChunkyPNG::COLOR_TRUECOLOR; :"encode_png_pixels_to_scanline_truecolor_#{depth}bit"
323
+ when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; :"encode_png_pixels_to_scanline_truecolor_alpha_#{depth}bit"
324
+ when ChunkyPNG::COLOR_INDEXED; :"encode_png_pixels_to_scanline_indexed_#{depth}bit"
325
+ when ChunkyPNG::COLOR_GRAYSCALE; :"encode_png_pixels_to_scanline_grayscale_#{depth}bit"
326
+ when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; :"encode_png_pixels_to_scanline_grayscale_alpha_#{depth}bit"
327
+ else nil
328
+ end
329
+
330
+ raise ChunkyPNG::NotSupported, "No encoder found for color mode #{color_mode} and #{depth}-bit depth!" unless respond_to?(encoder_method)
331
+ encoder_method
332
+ end
333
+
334
+
225
335
 
226
336
  # Encodes a scanline of a pixelstream without filtering. This is a no-op.
227
337
  # @param [String] stream The pixelstream to work on. This string will be modified.
@@ -130,7 +130,7 @@ module ChunkyPNG
130
130
  # @return [Integer] The 0-based position of the color in the palette.
131
131
  # @see ChunkyPNG::Palette#can_encode?
132
132
  def index(color)
133
- @encoding_map[color]
133
+ color.nil? ? 0 : @encoding_map[color]
134
134
  end
135
135
 
136
136
  # Creates a tRNS chunk that corresponds with this palette to store the
@@ -183,5 +183,18 @@ module ChunkyPNG
183
183
  ChunkyPNG::COLOR_TRUECOLOR_ALPHA
184
184
  end
185
185
  end
186
+
187
+ # Determines the minimal bit depth required for an indexed image
188
+ # @return [Integer] Number of bits per pixel, i.e. 1, 2, 4 or 8, or nil if this
189
+ # image cannot be saved as an indexed image.
190
+ def determine_bit_depth
191
+ case size
192
+ when 1..2; 1
193
+ when 3..4; 2
194
+ when 5..16; 4
195
+ when 17..256; 8
196
+ else nil
197
+ end
198
+ end
186
199
  end
187
200
  end
@@ -19,6 +19,46 @@ describe ChunkyPNG::Canvas::PNGEncoding do
19
19
  end
20
20
  end
21
21
 
22
+ it "should encode an image with 2 colors using 1-bit indexed color mode" do
23
+ @canvas = ChunkyPNG::Canvas.from_file(png_suite_file('basic', 'basn3p01.png'))
24
+ ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
25
+ ds.header_chunk.color.should == ChunkyPNG::COLOR_INDEXED
26
+ ds.header_chunk.depth.should == 1
27
+ @canvas.should == ChunkyPNG::Canvas.from_datastream(ds)
28
+ end
29
+
30
+ it "should encode an image with 4 colors using 2-bit indexed color mode" do
31
+ @canvas = ChunkyPNG::Canvas.from_file(png_suite_file('basic', 'basn3p02.png'))
32
+ ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
33
+ ds.header_chunk.color.should == ChunkyPNG::COLOR_INDEXED
34
+ ds.header_chunk.depth.should == 2
35
+ @canvas.should == ChunkyPNG::Canvas.from_datastream(ds)
36
+ end
37
+
38
+ it "should encode an image with 16 colors using 4-bit indexed color mode" do
39
+ @canvas = ChunkyPNG::Canvas.from_file(png_suite_file('basic', 'basn3p04.png'))
40
+ ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
41
+ ds.header_chunk.color.should == ChunkyPNG::COLOR_INDEXED
42
+ ds.header_chunk.depth.should == 4
43
+ @canvas.should == ChunkyPNG::Canvas.from_datastream(ds)
44
+ end
45
+
46
+ it "should encode an image with 256 colors using 8-bit indexed color mode" do
47
+ @canvas = ChunkyPNG::Canvas.from_file(png_suite_file('basic', 'basn3p08.png'))
48
+ ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob)
49
+ ds.header_chunk.color.should == ChunkyPNG::COLOR_INDEXED
50
+ ds.header_chunk.depth.should == 8
51
+ @canvas.should == ChunkyPNG::Canvas.from_datastream(ds)
52
+ end
53
+
54
+ it "should use a higher bit depth than necessary if requested" do
55
+ @canvas = ChunkyPNG::Canvas.from_file(png_suite_file('basic', 'basn3p01.png'))
56
+ ds = ChunkyPNG::Datastream.from_blob(@canvas.to_blob(:bit_depth => 4))
57
+ ds.header_chunk.color.should == ChunkyPNG::COLOR_INDEXED
58
+ ds.header_chunk.depth.should == 4
59
+ @canvas.should == ChunkyPNG::Canvas.from_datastream(ds)
60
+ end
61
+
22
62
  it "should encode an image with interlacing correctly" do
23
63
  input_canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
24
64
  filename = resource_file("_tmp_interlaced.png")
@@ -68,42 +108,65 @@ describe ChunkyPNG::Canvas::PNGEncoding do
68
108
  end
69
109
 
70
110
  describe '#encode_png_image_pass_to_stream' do
71
- before { @canvas = ChunkyPNG::Canvas.new(2, 2, ChunkyPNG::Color.rgba(1, 2, 3, 4)) }
111
+ before do
112
+ @canvas = ChunkyPNG::Canvas.new(2, 2, ChunkyPNG::Color.rgba(1, 2, 3, 4))
113
+ @palette_mock = mock('Palette')
114
+ @palette_mock.stub(:index).with(ChunkyPNG::Color.rgba(1, 2, 3, 4)).and_return(1)
115
+ @palette_mock.stub(:index).with(nil).and_return(0)
116
+ end
72
117
 
73
118
  it "should encode using RGBA / no filtering mode correctly" do
74
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_NONE)
119
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8, ChunkyPNG::FILTER_NONE)
75
120
  stream.should == "\0\1\2\3\4\1\2\3\4\0\1\2\3\4\1\2\3\4"
76
121
  end
77
122
 
78
123
  it "should encode using RGBA / SUB filtering mode correctly" do
79
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_SUB)
124
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8, ChunkyPNG::FILTER_SUB)
80
125
  stream.should == "\1\1\2\3\4\0\0\0\0\1\1\2\3\4\0\0\0\0"
81
126
  end
82
127
 
83
128
  it "should encode using RGBA / UP filtering mode correctly" do
84
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_UP)
129
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8, ChunkyPNG::FILTER_UP)
85
130
  stream.should == "\2\1\2\3\4\1\2\3\4\2\0\0\0\0\0\0\0\0"
86
131
  end
87
132
 
88
133
  it "should encode using RGBA / AVERAGE filtering mode correctly" do
89
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, ChunkyPNG::FILTER_AVERAGE)
134
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8, ChunkyPNG::FILTER_AVERAGE)
90
135
  stream.should == "\3\1\2\3\4\1\1\2\2\3\1\1\2\2\0\0\0\0"
91
136
  end
92
137
 
93
138
  it "should encode using RGB / no filtering mode correctly" do
94
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_NONE)
139
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_TRUECOLOR, 8, ChunkyPNG::FILTER_NONE)
95
140
  stream.should == "\0\1\2\3\1\2\3\0\1\2\3\1\2\3"
96
141
  end
97
142
 
98
143
  it "should encode using indexed / no filtering mode correctly" do
99
- @canvas.stub(:encoding_palette).and_return(mock('Palette', :index => 1))
100
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, ChunkyPNG::FILTER_NONE)
144
+ @canvas.stub(:encoding_palette).and_return(@palette_mock)
145
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, 8, ChunkyPNG::FILTER_NONE)
101
146
  stream.should == "\0\1\1\0\1\1"
102
147
  end
148
+
149
+ it "should encode using 1-bit indexed / no filtering mode correctly" do
150
+ @canvas.stub(:encoding_palette).and_return(@palette_mock)
151
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, 1, ChunkyPNG::FILTER_NONE)
152
+ stream.should == "\0\xc0\0\xc0"
153
+ end
154
+
155
+ it "should encode using 2-bit indexed / no filtering mode correctly" do
156
+ @canvas.stub(:encoding_palette).and_return(@palette_mock)
157
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, 2, ChunkyPNG::FILTER_NONE)
158
+ stream.should == "\x00\x50\x00\x50"
159
+ end
160
+
161
+ it "should encode using 4-bit indexed / no filtering mode correctly" do
162
+ @canvas.stub(:encoding_palette).and_return(@palette_mock)
163
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, 4, ChunkyPNG::FILTER_NONE)
164
+ stream.should == "\0\x11\0\x11"
165
+ end
103
166
 
104
167
  it "should encode using indexed / PAETH filtering mode correctly" do
105
- @canvas.stub(:encoding_palette).and_return(mock('Palette', :index => 1))
106
- @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, ChunkyPNG::FILTER_PAETH)
168
+ @canvas.stub(:encoding_palette).and_return(@palette_mock)
169
+ @canvas.encode_png_image_pass_to_stream(stream = ChunkyPNG::Datastream.empty_bytearray, ChunkyPNG::COLOR_INDEXED, 8, ChunkyPNG::FILTER_PAETH)
107
170
  stream.should == "\4\1\0\4\0\0"
108
171
  end
109
172
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 11
8
- - 1
9
- version: 0.11.1
7
+ - 12
8
+ - 0
9
+ version: 0.12.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: 2010-11-16 00:00:00 -05:00
17
+ date: 2010-12-12 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -39,8 +39,8 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  segments:
41
41
  - 2
42
- - 1
43
- version: "2.1"
42
+ - 2
43
+ version: "2.2"
44
44
  type: :development
45
45
  prerelease: false
46
46
  version_requirements: *id002
@@ -360,7 +360,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
360
360
  requirements:
361
361
  - - ">="
362
362
  - !ruby/object:Gem::Version
363
- hash: -3047594374404254656
363
+ hash: 1966366750719945677
364
364
  segments:
365
365
  - 0
366
366
  version: "0"
@@ -369,7 +369,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
369
369
  requirements:
370
370
  - - ">="
371
371
  - !ruby/object:Gem::Version
372
- hash: -3047594374404254656
372
+ hash: 1966366750719945677
373
373
  segments:
374
374
  - 0
375
375
  version: "0"