lib/prawn/images/png.rb in prawn-0.1.1 vs lib/prawn/images/png.rb in prawn-0.1.2

- old
+ new

@@ -1,6 +1,6 @@ -# encoding: utf-8 +# encoding: ASCII-8BIT # png.rb : Extracts the data from a PNG that is needed for embedding # # Based on some similar code in PDF::Writer by Austin Ziegler # @@ -82,15 +82,26 @@ data.read(4) # Skip the CRC end # if our img_data contains alpha channel data, split it out - unfilter_image_data if @color_type == 6 + unfilter_image_data if alpha_channel? end + def pixel_bytes + case @color_type + when 0, 4 then 1 + when 1, 2, 6 then 3 + end + end + private + def alpha_channel? + @color_type == 4 || @color_type == 6 + end + def paeth(a, b, c) # left, above, upper left p = a + b - c pa = (p - a).abs pb = (p - b).abs pc = (p - c).abs @@ -102,50 +113,53 @@ def unfilter_image_data data = Zlib::Inflate.inflate(@img_data).unpack 'C*' @img_data = "" @alpha_channel = "" - scanline_length = 4 * @width + 1 # for filter + + # each pixel has the color bytes, plus a byte of alpha channel + pixel_length = pixel_bytes + 1 + scanline_length = pixel_length * @width + 1 # for filter row = 0 pixels = [] until data.empty? do row_data = data.slice! 0, scanline_length filter = row_data.shift case filter - when 0 then # None - when 1 then # Sub + when 0 # None + when 1 # Sub row_data.each_with_index do |byte, index| - left = index < 4 ? 0 : row_data[index - 4] + left = index < pixel_length ? 0 : row_data[index - pixel_length] row_data[index] = (byte + left) % 256 #p [byte, left, row_data[index]] end - when 2 then # Up + when 2 # Up row_data.each_with_index do |byte, index| - col = index / 4 - upper = row == 0 ? 0 : pixels[row-1][col][index % 4] + col = index / pixel_length + upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_length] row_data[index] = (upper + byte) % 256 end - when 3 then # Average + when 3 # Average row_data.each_with_index do |byte, index| - col = index / 4 - upper = row == 0 ? 0 : pixels[row-1][col][index % 4] - left = index < 4 ? 0 : row_data[index - 4] + col = index / pixel_length + upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_length] + left = index < pixel_length ? 0 : row_data[index - pixel_length] row_data[index] = (byte + ((left + upper)/2).floor) % 256 end - when 4 then # Paeth + when 4 # Paeth left = upper = upper_left = nil row_data.each_with_index do |byte, index| - col = index / 4 + col = index / pixel_length - left = index < 4 ? 0 : row_data[index - 4] + left = index < pixel_length ? 0 : row_data[index - pixel_length] if row == 0 then upper = upper_left = 0 else - upper = pixels[row-1][col][index % 4] + upper = pixels[row-1][col][index % pixel_length] upper_left = col == 0 ? 0 : - pixels[row-1][col-1][index % 4] + pixels[row-1][col-1][index % pixel_length] end paeth = paeth left, upper, upper_left row_data[index] = (byte + paeth) % 256 #p [byte, paeth, row_data[index]] @@ -153,20 +167,20 @@ else raise ArgumentError, "Invalid filter algorithm #{filter}" end pixels << [] - row_data.each_slice 4 do |slice| + row_data.each_slice pixel_length do |slice| pixels.last << slice end row += 1 end # convert the pixel data to seperate strings for colours and alpha pixels.each do |row| row.each do |pixel| - @img_data << pixel[0,3].pack("C*") - @alpha_channel << pixel[3] + @img_data << pixel[0,pixel_bytes].pack("C*") + @alpha_channel << pixel.last end end # compress the data @img_data = Zlib::Deflate.deflate(@img_data)