chunky_png 0.10.5 → 0.11.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.
Files changed (245) hide show
  1. data/Gemfile.lock +1 -1
  2. data/benchmarks/filesize_benchmark.rb +1 -1
  3. data/chunky_png.gemspec +4 -4
  4. data/lib/chunky_png.rb +4 -11
  5. data/lib/chunky_png/canvas.rb +7 -8
  6. data/lib/chunky_png/canvas/adam7_interlacing.rb +36 -18
  7. data/lib/chunky_png/canvas/png_decoding.rb +258 -36
  8. data/lib/chunky_png/canvas/png_encoding.rb +1 -1
  9. data/lib/chunky_png/color.rb +41 -5
  10. data/lib/chunky_png/compatibility.rb +15 -0
  11. data/lib/chunky_png/datastream.rb +6 -0
  12. data/spec/chunky_png/canvas/adam7_interlacing_spec.rb +7 -7
  13. data/spec/chunky_png/canvas/png_decoding_spec.rb +33 -20
  14. data/spec/chunky_png/canvas/png_encoding_spec.rb +2 -3
  15. data/spec/chunky_png/color_spec.rb +29 -0
  16. data/spec/chunky_png/datastream_spec.rb +0 -5
  17. data/spec/chunky_png/rmagick_spec.rb +3 -3
  18. data/spec/png_suite/background_chunks/bgai4a08.png +0 -0
  19. data/spec/png_suite/background_chunks/bgai4a16.png +0 -0
  20. data/spec/png_suite/background_chunks/bgan6a08.png +0 -0
  21. data/spec/png_suite/background_chunks/bgan6a16.png +0 -0
  22. data/spec/png_suite/background_chunks/bgbn4a08.png +0 -0
  23. data/spec/png_suite/background_chunks/bggn4a16.png +0 -0
  24. data/spec/png_suite/background_chunks/bgwn6a08.png +0 -0
  25. data/spec/png_suite/background_chunks/bgyn6a16.png +0 -0
  26. data/spec/png_suite/basic/basi0g01.png +0 -0
  27. data/spec/png_suite/basic/basi0g01.rgba +0 -0
  28. data/spec/png_suite/basic/basi0g02.png +0 -0
  29. data/spec/png_suite/basic/basi0g02.rgba +0 -0
  30. data/spec/png_suite/basic/basi0g04.png +0 -0
  31. data/spec/png_suite/basic/basi0g04.rgba +0 -0
  32. data/spec/png_suite/basic/basi0g08.png +0 -0
  33. data/spec/png_suite/basic/basi0g08.rgba +0 -0
  34. data/spec/png_suite/basic/basi0g16.png +0 -0
  35. data/spec/png_suite/basic/basi0g16.rgba +0 -0
  36. data/spec/png_suite/basic/basi2c08.png +0 -0
  37. data/spec/png_suite/basic/basi2c08.rgba +0 -0
  38. data/spec/png_suite/basic/basi2c16.png +0 -0
  39. data/spec/png_suite/basic/basi2c16.rgba +0 -0
  40. data/spec/png_suite/basic/basi3p01.png +0 -0
  41. data/spec/png_suite/basic/basi3p01.rgba +1 -0
  42. data/spec/png_suite/basic/basi3p02.png +0 -0
  43. data/spec/png_suite/basic/basi3p02.rgba +0 -0
  44. data/spec/png_suite/basic/basi3p04.png +0 -0
  45. data/spec/png_suite/basic/basi3p04.rgba +0 -0
  46. data/spec/png_suite/basic/basi3p08.png +0 -0
  47. data/spec/png_suite/basic/basi3p08.rgba +0 -0
  48. data/spec/png_suite/basic/basi4a08.png +0 -0
  49. data/spec/png_suite/basic/basi4a08.rgba +0 -0
  50. data/spec/png_suite/basic/basi4a16.png +0 -0
  51. data/spec/png_suite/basic/basi4a16.rgba +0 -0
  52. data/spec/png_suite/basic/basi6a08.png +0 -0
  53. data/spec/png_suite/basic/basi6a08.rgba +0 -0
  54. data/spec/png_suite/basic/basi6a16.png +0 -0
  55. data/spec/png_suite/basic/basi6a16.rgba +0 -0
  56. data/spec/png_suite/basic/basn0g01.png +0 -0
  57. data/spec/png_suite/basic/basn0g01.rgba +0 -0
  58. data/spec/png_suite/basic/basn0g02.png +0 -0
  59. data/spec/png_suite/basic/basn0g02.rgba +0 -0
  60. data/spec/png_suite/basic/basn0g04.png +0 -0
  61. data/spec/png_suite/basic/basn0g04.rgba +0 -0
  62. data/spec/png_suite/basic/basn0g08.png +0 -0
  63. data/spec/png_suite/basic/basn0g08.rgba +0 -0
  64. data/spec/png_suite/basic/basn0g16.png +0 -0
  65. data/spec/png_suite/basic/basn0g16.rgba +0 -0
  66. data/spec/png_suite/basic/basn2c08.png +0 -0
  67. data/spec/png_suite/basic/basn2c08.rgba +0 -0
  68. data/spec/png_suite/basic/basn2c16.png +0 -0
  69. data/spec/png_suite/basic/basn2c16.rgba +0 -0
  70. data/spec/png_suite/basic/basn3p01.png +0 -0
  71. data/spec/png_suite/basic/basn3p01.rgba +1 -0
  72. data/spec/png_suite/basic/basn3p02.png +0 -0
  73. data/spec/png_suite/basic/basn3p02.rgba +0 -0
  74. data/spec/{resources/indexed_4bit.png → png_suite/basic/basn3p04.png} +0 -0
  75. data/spec/png_suite/basic/basn3p04.rgba +0 -0
  76. data/spec/png_suite/basic/basn3p08.png +0 -0
  77. data/spec/png_suite/basic/basn3p08.rgba +0 -0
  78. data/spec/png_suite/basic/basn4a08.png +0 -0
  79. data/spec/png_suite/basic/basn4a08.rgba +0 -0
  80. data/spec/png_suite/basic/basn4a16.png +0 -0
  81. data/spec/png_suite/basic/basn4a16.rgba +0 -0
  82. data/spec/png_suite/basic/basn6a08.png +0 -0
  83. data/spec/png_suite/basic/basn6a08.rgba +0 -0
  84. data/spec/png_suite/basic/basn6a16.png +0 -0
  85. data/spec/png_suite/basic/basn6a16.rgba +0 -0
  86. data/spec/png_suite/broken/x00n0g01.png +0 -0
  87. data/spec/png_suite/broken/xcrn0g04.png +0 -0
  88. data/spec/png_suite/broken/xlfn0g04.png +13 -0
  89. data/spec/png_suite/chunk_ordering/oi1n0g16.png +0 -0
  90. data/spec/png_suite/chunk_ordering/oi1n2c16.png +0 -0
  91. data/spec/png_suite/chunk_ordering/oi2n0g16.png +0 -0
  92. data/spec/png_suite/chunk_ordering/oi2n2c16.png +0 -0
  93. data/spec/png_suite/chunk_ordering/oi4n0g16.png +0 -0
  94. data/spec/png_suite/chunk_ordering/oi4n2c16.png +0 -0
  95. data/spec/png_suite/chunk_ordering/oi9n0g16.png +0 -0
  96. data/spec/png_suite/chunk_ordering/oi9n2c16.png +0 -0
  97. data/spec/png_suite/compression_levels/z00n2c08.png +0 -0
  98. data/spec/png_suite/compression_levels/z03n2c08.png +0 -0
  99. data/spec/png_suite/compression_levels/z06n2c08.png +0 -0
  100. data/spec/png_suite/compression_levels/z09n2c08.png +0 -0
  101. data/spec/png_suite/filtering/f00n0g08.png +0 -0
  102. data/spec/png_suite/filtering/f00n0g08.rgba +0 -0
  103. data/spec/png_suite/filtering/f00n0g08_reference.png +0 -0
  104. data/spec/png_suite/filtering/f00n0g08_reference.rgba +0 -0
  105. data/spec/png_suite/filtering/f00n2c08.png +0 -0
  106. data/spec/png_suite/filtering/f00n2c08.rgba +0 -0
  107. data/spec/png_suite/filtering/f00n2c08_reference.png +0 -0
  108. data/spec/png_suite/filtering/f00n2c08_reference.rgba +0 -0
  109. data/spec/png_suite/filtering/f01n0g08.png +0 -0
  110. data/spec/png_suite/filtering/f01n0g08.rgba +0 -0
  111. data/spec/png_suite/filtering/f01n0g08_reference.png +0 -0
  112. data/spec/png_suite/filtering/f01n0g08_reference.rgba +0 -0
  113. data/spec/png_suite/filtering/f01n2c08.png +0 -0
  114. data/spec/png_suite/filtering/f01n2c08.rgba +0 -0
  115. data/spec/png_suite/filtering/f01n2c08_reference.png +0 -0
  116. data/spec/png_suite/filtering/f01n2c08_reference.rgba +0 -0
  117. data/spec/png_suite/filtering/f02n0g08.png +0 -0
  118. data/spec/png_suite/filtering/f02n0g08.rgba +0 -0
  119. data/spec/png_suite/filtering/f02n0g08_reference.png +0 -0
  120. data/spec/png_suite/filtering/f02n0g08_reference.rgba +0 -0
  121. data/spec/png_suite/filtering/f02n2c08.png +0 -0
  122. data/spec/png_suite/filtering/f02n2c08.rgba +0 -0
  123. data/spec/png_suite/filtering/f02n2c08_reference.png +0 -0
  124. data/spec/png_suite/filtering/f02n2c08_reference.rgba +0 -0
  125. data/spec/png_suite/filtering/f03n0g08.png +0 -0
  126. data/spec/png_suite/filtering/f03n0g08.rgba +0 -0
  127. data/spec/png_suite/filtering/f03n0g08_reference.png +0 -0
  128. data/spec/png_suite/filtering/f03n0g08_reference.rgba +0 -0
  129. data/spec/png_suite/filtering/f03n2c08.png +0 -0
  130. data/spec/png_suite/filtering/f03n2c08.rgba +0 -0
  131. data/spec/png_suite/filtering/f03n2c08_reference.png +0 -0
  132. data/spec/png_suite/filtering/f03n2c08_reference.rgba +0 -0
  133. data/spec/png_suite/filtering/f04n0g08.png +0 -0
  134. data/spec/png_suite/filtering/f04n0g08.rgba +0 -0
  135. data/spec/png_suite/filtering/f04n0g08_reference.png +0 -0
  136. data/spec/png_suite/filtering/f04n0g08_reference.rgba +0 -0
  137. data/spec/png_suite/filtering/f04n2c08.png +0 -0
  138. data/spec/png_suite/filtering/f04n2c08.rgba +0 -0
  139. data/spec/png_suite/filtering/f04n2c08_reference.png +0 -0
  140. data/spec/png_suite/filtering/f04n2c08_reference.rgba +0 -0
  141. data/spec/png_suite/gamma/g03n0g16.png +0 -0
  142. data/spec/png_suite/gamma/g03n2c08.png +0 -0
  143. data/spec/png_suite/gamma/g03n3p04.png +0 -0
  144. data/spec/png_suite/gamma/g04n0g16.png +0 -0
  145. data/spec/png_suite/gamma/g04n2c08.png +0 -0
  146. data/spec/png_suite/gamma/g04n3p04.png +0 -0
  147. data/spec/png_suite/gamma/g05n0g16.png +0 -0
  148. data/spec/png_suite/gamma/g05n2c08.png +0 -0
  149. data/spec/png_suite/gamma/g05n3p04.png +0 -0
  150. data/spec/png_suite/gamma/g07n0g16.png +0 -0
  151. data/spec/png_suite/gamma/g07n2c08.png +0 -0
  152. data/spec/png_suite/gamma/g07n3p04.png +0 -0
  153. data/spec/png_suite/gamma/g10n0g16.png +0 -0
  154. data/spec/png_suite/gamma/g10n2c08.png +0 -0
  155. data/spec/png_suite/gamma/g10n3p04.png +0 -0
  156. data/spec/png_suite/gamma/g25n0g16.png +0 -0
  157. data/spec/png_suite/gamma/g25n2c08.png +0 -0
  158. data/spec/png_suite/gamma/g25n3p04.png +0 -0
  159. data/spec/png_suite/metadata/cm0n0g04.png +0 -0
  160. data/spec/png_suite/metadata/cm7n0g04.png +0 -0
  161. data/spec/png_suite/metadata/cm9n0g04.png +0 -0
  162. data/spec/png_suite/other/ccwn2c08.png +0 -0
  163. data/spec/png_suite/other/ccwn3p08.png +0 -0
  164. data/spec/png_suite/other/cdfn2c08.png +0 -0
  165. data/spec/png_suite/other/cdhn2c08.png +0 -0
  166. data/spec/png_suite/other/cdsn2c08.png +0 -0
  167. data/spec/png_suite/other/cdun2c08.png +0 -0
  168. data/spec/png_suite/other/ch1n3p04.png +0 -0
  169. data/spec/png_suite/other/ch2n3p08.png +0 -0
  170. data/spec/png_suite/other/cs3n2c16.png +0 -0
  171. data/spec/png_suite/other/cs3n3p08.png +0 -0
  172. data/spec/png_suite/other/cs5n2c08.png +0 -0
  173. data/spec/png_suite/other/cs5n3p08.png +0 -0
  174. data/spec/png_suite/other/cs8n2c08.png +0 -0
  175. data/spec/png_suite/other/cs8n3p08.png +0 -0
  176. data/spec/png_suite/other/ct0n0g04.png +0 -0
  177. data/spec/png_suite/other/ct1n0g04.png +0 -0
  178. data/spec/png_suite/other/ctzn0g04.png +0 -0
  179. data/spec/png_suite/other/pp0n2c16.png +0 -0
  180. data/spec/png_suite/other/pp0n6a08.png +0 -0
  181. data/spec/png_suite/other/ps1n0g08.png +0 -0
  182. data/spec/png_suite/other/ps1n2c16.png +0 -0
  183. data/spec/png_suite/other/ps2n0g08.png +0 -0
  184. data/spec/png_suite/other/ps2n2c16.png +0 -0
  185. data/spec/png_suite/sizes/s01i3p01.png +0 -0
  186. data/spec/png_suite/sizes/s01n3p01.png +0 -0
  187. data/spec/png_suite/sizes/s02i3p01.png +0 -0
  188. data/spec/png_suite/sizes/s02n3p01.png +0 -0
  189. data/spec/png_suite/sizes/s03i3p01.png +0 -0
  190. data/spec/png_suite/sizes/s03n3p01.png +0 -0
  191. data/spec/png_suite/sizes/s04i3p01.png +0 -0
  192. data/spec/png_suite/sizes/s04n3p01.png +0 -0
  193. data/spec/png_suite/sizes/s05i3p02.png +0 -0
  194. data/spec/png_suite/sizes/s05n3p02.png +0 -0
  195. data/spec/png_suite/sizes/s06i3p02.png +0 -0
  196. data/spec/png_suite/sizes/s06n3p02.png +0 -0
  197. data/spec/png_suite/sizes/s07i3p02.png +0 -0
  198. data/spec/png_suite/sizes/s07n3p02.png +0 -0
  199. data/spec/png_suite/sizes/s08i3p02.png +0 -0
  200. data/spec/png_suite/sizes/s08n3p02.png +0 -0
  201. data/spec/png_suite/sizes/s09i3p02.png +0 -0
  202. data/spec/png_suite/sizes/s09n3p02.png +0 -0
  203. data/spec/png_suite/sizes/s32i3p04.png +0 -0
  204. data/spec/png_suite/sizes/s32n3p04.png +0 -0
  205. data/spec/png_suite/sizes/s33i3p04.png +0 -0
  206. data/spec/png_suite/sizes/s33n3p04.png +0 -0
  207. data/spec/png_suite/sizes/s34i3p04.png +0 -0
  208. data/spec/png_suite/sizes/s34n3p04.png +0 -0
  209. data/spec/png_suite/sizes/s35i3p04.png +0 -0
  210. data/spec/png_suite/sizes/s35n3p04.png +0 -0
  211. data/spec/png_suite/sizes/s36i3p04.png +0 -0
  212. data/spec/png_suite/sizes/s36n3p04.png +0 -0
  213. data/spec/png_suite/sizes/s37i3p04.png +0 -0
  214. data/spec/png_suite/sizes/s37n3p04.png +0 -0
  215. data/spec/png_suite/sizes/s38i3p04.png +0 -0
  216. data/spec/png_suite/sizes/s38n3p04.png +0 -0
  217. data/spec/png_suite/sizes/s39i3p04.png +0 -0
  218. data/spec/png_suite/sizes/s39n3p04.png +0 -0
  219. data/spec/png_suite/sizes/s40i3p04.png +0 -0
  220. data/spec/png_suite/sizes/s40n3p04.png +0 -0
  221. data/spec/png_suite/transparency/tbbn1g04.png +0 -0
  222. data/spec/png_suite/transparency/tbbn2c16.png +0 -0
  223. data/spec/png_suite/transparency/tbbn3p08.png +0 -0
  224. data/spec/png_suite/transparency/tbgn2c16.png +0 -0
  225. data/spec/png_suite/transparency/tbgn3p08.png +0 -0
  226. data/spec/png_suite/transparency/tbrn2c08.png +0 -0
  227. data/spec/png_suite/transparency/tbwn1g16.png +0 -0
  228. data/spec/png_suite/transparency/tbwn3p08.png +0 -0
  229. data/spec/png_suite/transparency/tbyn3p08.png +0 -0
  230. data/spec/png_suite/transparency/tp0n1g08.png +0 -0
  231. data/spec/png_suite/transparency/tp0n2c08.png +0 -0
  232. data/spec/png_suite/transparency/tp0n3p08.png +0 -0
  233. data/spec/png_suite/transparency/tp1n3p08.png +0 -0
  234. data/spec/png_suite_spec.rb +119 -0
  235. data/spec/spec_helper.rb +26 -16
  236. metadata +240 -25
  237. data/spec/resources/16x16_interlaced.png +0 -0
  238. data/spec/resources/16x16_non_interlaced.png +0 -0
  239. data/spec/resources/gray_10x10.png +0 -0
  240. data/spec/resources/gray_10x10_grayscale.png +0 -0
  241. data/spec/resources/gray_10x10_grayscale_alpha.png +0 -0
  242. data/spec/resources/gray_10x10_indexed.png +0 -0
  243. data/spec/resources/gray_10x10_truecolor.png +0 -0
  244. data/spec/resources/gray_10x10_truecolor_alpha.png +0 -0
  245. data/spec/resources/transparent_gray_10x10.png +0 -0
@@ -191,7 +191,7 @@ module ChunkyPNG
191
191
  def encode_png_image_pass_to_stream(stream, color_mode, filtering)
192
192
 
193
193
  start_pos = stream.bytesize
194
- pixel_size = Color.bytesize(color_mode)
194
+ pixel_size = Color.pixel_bytesize(color_mode)
195
195
  line_width = pixel_size * width
196
196
 
197
197
  # Encode the whole image without filtering
@@ -386,18 +386,54 @@ module ChunkyPNG
386
386
  # STATIC UTILITY METHODS
387
387
  ####################################################################
388
388
 
389
- # Returns the size in bytes of a pixel when it is stored using a given color mode.
390
- # @param [Integer] color_mode The color mode in which the pixels are stored.
391
- # @return [Integer] The number of bytes used per pixel in a datastream.
392
- def bytesize(color_mode)
389
+ # Returns the number of sample values per pixel.
390
+ # @param [Integer] color_mode The color mode being used.
391
+ # @return [Integer] The number of sample values per pixel.
392
+ def samples_per_pixel(color_mode)
393
393
  case color_mode
394
394
  when ChunkyPNG::COLOR_INDEXED; 1
395
395
  when ChunkyPNG::COLOR_TRUECOLOR; 3
396
396
  when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; 4
397
397
  when ChunkyPNG::COLOR_GRAYSCALE; 1
398
398
  when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; 2
399
- else raise ChunkyPNG::NotSupported, "Don't know the bytesize of pixels in this colormode: #{color_mode}!"
399
+ else raise ChunkyPNG::NotSupported, "Don't know the numer of samples for this colormode: #{color_mode}!"
400
400
  end
401
401
  end
402
+
403
+ # Returns the size in bytes of a pixel when it is stored using a given color mode.
404
+ # @param [Integer] color_mode The color mode in which the pixels are stored.
405
+ # @return [Integer] The number of bytes used per pixel in a datastream.
406
+ def pixel_bytesize(color_mode, depth = 8)
407
+ return 1 if depth < 8
408
+ (pixel_bitsize(color_mode, depth) + 7) >> 3
409
+ end
410
+
411
+ # Returns the size in bits of a pixel when it is stored using a given color mode.
412
+ # @param [Integer] color_mode The color mode in which the pixels are stored.
413
+ # @param [Integer] depth The color depth of the pixels.
414
+ # @return [Integer] The number of bytes used per pixel in a datastream.
415
+ def pixel_bitsize(color_mode, depth = 8)
416
+ samples_per_pixel(color_mode) * depth
417
+ end
418
+
419
+ # Returns the number of bytes used per scanline.
420
+ # @param [Integer] color_mode The color mode in which the pixels are stored.
421
+ # @param [Integer] depth The color depth of the pixels.
422
+ # @param [Integer] width The number of pixels per scanline.
423
+ # @return [Integer] The number of bytes used per scanline in a datastream.
424
+ def scanline_bytesize(color_mode, depth, width)
425
+ ((pixel_bitsize(color_mode, depth) * width) + 7) >> 3
426
+ end
427
+
428
+ # Returns the number of bytes used for an image pass
429
+ # @param [Integer] color_mode The color mode in which the pixels are stored.
430
+ # @param [Integer] depth The color depth of the pixels.
431
+ # @param [Integer] width The width of the image pass.
432
+ # @param [Integer] width The height of the image pass.
433
+ # @return [Integer] The number of bytes used per scanline in a datastream.
434
+ def pass_bytesize(color_mode, depth, width, height)
435
+ return 0 if width == 0 || height == 0
436
+ (scanline_bytesize(color_mode, depth, width) + 1) * height
437
+ end
402
438
  end
403
439
  end
@@ -0,0 +1,15 @@
1
+
2
+ class String
3
+ alias_method :getbyte, :[] unless method_defined?(:getbyte)
4
+ alias_method :setbyte, :[]= unless method_defined?(:setbyte)
5
+ alias_method :bytesize, :size unless method_defined?(:bytesize)
6
+ end
7
+
8
+ class Object
9
+ unless method_defined?(:tap)
10
+ def tap(&block)
11
+ yield(self) if block_given?
12
+ return self
13
+ end
14
+ end
15
+ end
@@ -141,6 +141,12 @@ module ChunkyPNG
141
141
  end
142
142
  metadata
143
143
  end
144
+
145
+ # Returns the uncompressed image data, combined from all the IDAT chunks
146
+ # @return [String] The uncompressed image data for this datastream
147
+ def imagedata
148
+ ChunkyPNG::Chunk::ImageData.combine_chunks(data_chunks)
149
+ end
144
150
 
145
151
  ##################################################################################
146
152
  # WRITING DATASTREAMS
@@ -44,31 +44,31 @@ describe ChunkyPNG::Canvas::Adam7Interlacing do
44
44
 
45
45
  describe '#adam7_multiplier_offset' do
46
46
  it "should get the multiplier and offset values for pass 1 correctly" do
47
- adam7_multiplier_offset(0).should == { :x_offset => 0, :x_shift => 3, :y_offset => 0, :y_shift => 3 }
47
+ adam7_multiplier_offset(0).should == [3, 0, 3, 0]
48
48
  end
49
49
 
50
50
  it "should get the multiplier and offset values for pass 2 correctly" do
51
- adam7_multiplier_offset(1).should == { :x_offset => 4, :x_shift => 3, :y_offset => 0, :y_shift => 3 }
51
+ adam7_multiplier_offset(1).should == [3, 4, 3, 0]
52
52
  end
53
53
 
54
54
  it "should get the multiplier and offset values for pass 3 correctly" do
55
- adam7_multiplier_offset(2).should == { :x_offset => 0, :x_shift => 2, :y_offset => 4, :y_shift => 3 }
55
+ adam7_multiplier_offset(2).should == [2, 0, 3, 4]
56
56
  end
57
57
 
58
58
  it "should get the multiplier and offset values for pass 4 correctly" do
59
- adam7_multiplier_offset(3).should == { :x_offset => 2, :x_shift => 2, :y_offset => 0, :y_shift => 2 }
59
+ adam7_multiplier_offset(3).should == [2, 2, 2, 0]
60
60
  end
61
61
 
62
62
  it "should get the multiplier and offset values for pass 5 correctly" do
63
- adam7_multiplier_offset(4).should == { :x_offset => 0, :x_shift => 1, :y_offset => 2, :y_shift => 2 }
63
+ adam7_multiplier_offset(4).should == [1, 0, 2, 2]
64
64
  end
65
65
 
66
66
  it "should get the multiplier and offset values for pass 6 correctly" do
67
- adam7_multiplier_offset(5).should == { :x_offset => 1, :x_shift => 1, :y_offset => 0, :y_shift => 1 }
67
+ adam7_multiplier_offset(5).should == [1, 1, 1, 0]
68
68
  end
69
69
 
70
70
  it "should get the multiplier and offset values for pass 7 correctly" do
71
- adam7_multiplier_offset(6).should == { :x_offset => 0, :x_shift => 0, :y_offset => 1, :y_shift => 1 }
71
+ adam7_multiplier_offset(6).should == [0, 0, 1, 1]
72
72
  end
73
73
  end
74
74
 
@@ -53,32 +53,45 @@ describe ChunkyPNG::Canvas::PNGDecoding do
53
53
  stream.unpack('@14C12').should == [10, 20, 40, 60, 60, 60, 70, 120, 90, 120, 54, 120]
54
54
  end
55
55
  end
56
-
57
- describe '.from_datastream' do
58
-
59
- [:indexed, :grayscale, :grayscale_alpha, :truecolor, :truecolor_alpha].each do |color_mode|
60
- it "should decode an image with color mode #{color_mode} correctly" do
61
- reference = ChunkyPNG::Canvas.new(10, 10, ChunkyPNG::Color.rgb(100, 100, 100))
62
- canvas = ChunkyPNG::Canvas.from_file(resource_file("gray_10x10_#{color_mode}.png"))
63
- canvas.should == reference
64
- end
56
+
57
+ describe '#decode_png_extract_4bit_value' do
58
+ it "should extract the high bits successfully" do
59
+ decode_png_extract_4bit_value('10010110'.to_i(2), 0).should == '1001'.to_i(2)
60
+ end
61
+
62
+ it "should extract the low bits successfully" do
63
+ decode_png_extract_4bit_value('10010110'.to_i(2), 17).should == '0110'.to_i(2)
64
+ end
65
+ end
66
+
67
+ describe '#decode_png_extract_2bit_value' do
68
+ it "should extract the first 2 bits successfully" do
69
+ decode_png_extract_2bit_value('10010110'.to_i(2), 0).should == '10'.to_i(2)
65
70
  end
66
71
 
67
- it "should decode a transparent image correctly" do
68
- reference = ChunkyPNG::Canvas.new(10, 10, ChunkyPNG::Color.rgba(100, 100, 100, 128))
69
- canvas = ChunkyPNG::Canvas.from_file(resource_file("transparent_gray_10x10.png"))
70
- canvas.should == reference
72
+ it "should extract the second 2 bits successfully" do
73
+ decode_png_extract_2bit_value('10010110'.to_i(2), 5).should == '01'.to_i(2)
71
74
  end
72
75
 
73
- it "should decode an interlaced image correctly" do
74
- canvas_i = ChunkyPNG::Canvas.from_file(resource_file("16x16_interlaced.png"))
75
- canvas_ni = ChunkyPNG::Canvas.from_file(resource_file("16x16_non_interlaced.png"))
76
- canvas_i.should == canvas_ni
76
+ it "should extract the third 2 bits successfully" do
77
+ decode_png_extract_2bit_value('10010110'.to_i(2), 2).should == '01'.to_i(2)
77
78
  end
78
79
 
79
- it "should raise an error if the color depth is not supported" do
80
- filename = resource_file('indexed_4bit.png')
81
- lambda { ChunkyPNG::Canvas.from_file(filename) }.should raise_error
80
+ it "should extract the low two bits successfully" do
81
+ decode_png_extract_2bit_value('10010110'.to_i(2), 7).should == '10'.to_i(2)
82
+ end
83
+ end
84
+
85
+ describe '#decode_png_extract_1bit_value' do
86
+ it "should extract all separate bits correctly" do
87
+ decode_png_extract_1bit_value('10010110'.to_i(2), 0).should == 1
88
+ decode_png_extract_1bit_value('10010110'.to_i(2), 1).should == 0
89
+ decode_png_extract_1bit_value('10010110'.to_i(2), 2).should == 0
90
+ decode_png_extract_1bit_value('10010110'.to_i(2), 3).should == 1
91
+ decode_png_extract_1bit_value('10010110'.to_i(2), 4).should == 0
92
+ decode_png_extract_1bit_value('10010110'.to_i(2), 5).should == 1
93
+ decode_png_extract_1bit_value('10010110'.to_i(2), 6).should == 1
94
+ decode_png_extract_1bit_value('10010110'.to_i(2), 7).should == 0
82
95
  end
83
96
  end
84
97
  end
@@ -13,14 +13,14 @@ describe ChunkyPNG::Canvas::PNGEncoding do
13
13
 
14
14
  ds = ChunkyPNG::Datastream.from_file(filename)
15
15
  ds.header_chunk.color.should == color_mode
16
- ChunkyPNG::Canvas.from_datastream(ds).should == reference_canvas('gray_10x10')
16
+ ChunkyPNG::Canvas.from_datastream(ds).should == ChunkyPNG::Canvas.new(10, 10, ChunkyPNG::Color.rgb(100, 100, 100))
17
17
 
18
18
  File.unlink(filename)
19
19
  end
20
20
  end
21
21
 
22
22
  it "should encode an image with interlacing correctly" do
23
- input_canvas = ChunkyPNG::Canvas.from_file(resource_file('16x16_non_interlaced.png'))
23
+ input_canvas = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))
24
24
  filename = resource_file("_tmp_interlaced.png")
25
25
  input_canvas.save(filename, :interlace => true)
26
26
 
@@ -37,7 +37,6 @@ describe ChunkyPNG::Canvas::PNGEncoding do
37
37
  canvas.to_blob
38
38
  end
39
39
 
40
-
41
40
  it "should save an image using the :fast_rgba routine correctly" do
42
41
  canvas = reference_canvas('operations')
43
42
  canvas.should_not_receive(:encode_png_str_scanline_none)
@@ -11,6 +11,35 @@ describe ChunkyPNG::Color do
11
11
  @fully_transparent = 0x0a649600
12
12
  end
13
13
 
14
+ describe '#pixel_bytesize' do
15
+ it "should return the normal amount of bytes with a bit depth of 8" do
16
+ pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8).should == 3
17
+ end
18
+
19
+ it "should return a multiple of the normal amount of bytes with a bit depth greater than 8" do
20
+ pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 16).should == 6
21
+ pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 16).should == 8
22
+ pixel_bytesize(ChunkyPNG::COLOR_GRAYSCALE_ALPHA, 16).should == 4
23
+ end
24
+
25
+ it "should return 1 with a bit depth lower than 0" do
26
+ pixel_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 4).should == 1
27
+ pixel_bytesize(ChunkyPNG::COLOR_INDEXED, 2).should == 1
28
+ pixel_bytesize(ChunkyPNG::COLOR_GRAYSCALE_ALPHA, 1).should == 1
29
+ end
30
+ end
31
+
32
+ describe '#pass_bytesize' do
33
+ it "should calculate a pass size correctly" do
34
+ pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 10, 10).should == 310
35
+ end
36
+
37
+ it "should return 0 if one of the dimensions is zero" do
38
+ pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 0, 10).should == 0
39
+ pass_bytesize(ChunkyPNG::COLOR_TRUECOLOR, 8, 10, 0).should == 0
40
+ end
41
+ end
42
+
14
43
  describe '#rgba' do
15
44
  it "should represent pixels as the correct number" do
16
45
  rgba(255, 255, 255, 255).should == @white
@@ -12,11 +12,6 @@ describe ChunkyPNG::Datastream do
12
12
  filename = resource_file('damaged_chunk.png')
13
13
  lambda { ChunkyPNG::Datastream.from_file(filename) }.should raise_error
14
14
  end
15
-
16
- it "should not raise an error for an unsupported color depth when only reading the datastream" do
17
- filename = resource_file('indexed_4bit.png')
18
- lambda { ChunkyPNG::Datastream.from_file(filename) }.should_not raise_error
19
- end
20
15
  end
21
16
 
22
17
  describe '#metadata' do
@@ -6,13 +6,13 @@ begin
6
6
  describe ChunkyPNG::RMagick do
7
7
 
8
8
  it "should import an image from RMagick correctly" do
9
- image = Magick::Image.read(resource_file('16x16_non_interlaced.png')).first
9
+ image = Magick::Image.read(resource_file('composited.png')).first
10
10
  canvas = ChunkyPNG::RMagick.import(image)
11
- canvas.should == reference_canvas('16x16_non_interlaced')
11
+ canvas.should == reference_canvas('composited')
12
12
  end
13
13
 
14
14
  it "should export an image to RMagick correctly" do
15
- canvas = reference_canvas('16x16_non_interlaced')
15
+ canvas = reference_canvas('composited')
16
16
  image = ChunkyPNG::RMagick.export(canvas)
17
17
  image.format = 'PNG32'
18
18
  canvas.should == ChunkyPNG::Canvas.from_blob(image.to_blob)
@@ -0,0 +1 @@
1
+ ��"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�
@@ -0,0 +1 @@
1
+ ��"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"���"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f��"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�"f��"f��"f��"f����"���"���"���"�
@@ -0,0 +1,13 @@
1
+ �PNG
2
+
3
+
4
+ 
5
+
6
+
7
+ IHDR ���)�IDATx�]��
8
+ �0 P*@��#�
9
+
10
+ #T��10lPF`ؠF=���IQ�*��u�`%qk�
11
+ H�񚈩�m�����ߟ э=,�f�OK
12
+
13
+ ���t��(������F ;�P����{xp�]9�/p�*$(�*�y�Ճ�������@�C�  c�q��N�U#�)11�.��r��f�0���gh(��t���E���kIEND�B`�