chunky_png 0.11.1 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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"