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)