<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>data/images/16bit.alpha</filename>
    </added>
    <added>
      <filename>data/images/16bit.dat</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -185,19 +185,17 @@ module Prawn
         raise Errors::UnsupportedImageType, 'PNG uses unsupported interlace method'
       end
 
-      if png.bits &gt; 8
-        raise Errors::UnsupportedImageType, 'PNG uses more than 8 bits'
-      end
-
       # some PNG types store the colour and alpha channel data together,
       # which the PDF spec doesn't like, so split it out.
       png.split_alpha_channel!
 
-      case png.pixel_bytes
+      case png.colors
       when 1
         color = :DeviceGray
       when 3
         color = :DeviceRGB
+      else
+        raise Errors::UnsupportedImageType, &quot;PNG uses an unsupported number of colors (#{png.colors})&quot;
       end
 
       # build the image dict
@@ -212,7 +210,7 @@ module Prawn
 
       unless png.alpha_channel
         obj.data[:DecodeParms] = {:Predictor =&gt; 15,
-                                  :Colors    =&gt; png.pixel_bytes,
+                                  :Colors    =&gt; png.colors,
                                   :BitsPerComponent =&gt; png.bits,
                                   :Columns   =&gt; png.width}
       end
@@ -269,7 +267,7 @@ module Prawn
                         :Subtype          =&gt; :Image,
                         :Height           =&gt; png.height,
                         :Width            =&gt; png.width,
-                        :BitsPerComponent =&gt; 8,
+                        :BitsPerComponent =&gt; png.bits,
                         :Length           =&gt; png.alpha_channel.size,
                         :Filter           =&gt; :FlateDecode,
                         :ColorSpace       =&gt; :DeviceGray,</diff>
      <filename>lib/prawn/images.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,13 +14,13 @@ module Prawn
   module Images
     # A convenience class that wraps the logic for extracting the parts
     # of a PNG image that we need to embed them in a PDF
-    class PNG 
+    class PNG
       attr_reader :palette, :img_data, :transparency
       attr_reader :width, :height, :bits
       attr_reader :color_type, :compression_method, :filter_method
       attr_reader :interlace_method, :alpha_channel
       attr_accessor :scaled_width, :scaled_height
-      
+
       # Process a new PNG image
       #
       # &lt;tt&gt;data&lt;/tt&gt;:: A string containing a full PNG file
@@ -88,13 +88,30 @@ module Prawn
         end
       end
 
-      def pixel_bytes
-        @pixel_bytes ||= case @color_type
-        when 0, 3, 4 then 1
-        when 1, 2, 6 then 3
+      # number of color components to each pixel
+      #
+      def colors
+        case self.color_type
+        when 0, 3, 4
+          return 1
+        when 2, 6
+          return 3
+        end
+      end
+
+      # number of bits used per pixel
+      #
+      def pixel_bitlength
+        if alpha_channel?
+          self.bits * (self.colors + 1)
+        else
+          self.bits * self.colors
         end
       end
 
+      # split the alpha channel data from the raw image data in images
+      # where it's required.
+      #
       def split_alpha_channel!
         unfilter_image_data if alpha_channel?
       end
@@ -110,11 +127,10 @@ module Prawn
         @img_data = &quot;&quot;
         @alpha_channel = &quot;&quot;
 
-        # 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
+        pixel_bytes     = pixel_bitlength / 8
+        scanline_length = pixel_bytes * self.width + 1
         row = 0
-        pixels = []    
+        pixels = []
         paeth, pa, pb, pc = nil
         until data.empty? do
           row_data = data.slice! 0, scanline_length
@@ -123,42 +139,42 @@ module Prawn
           when 0 # None
           when 1 # Sub
             row_data.each_with_index do |byte, index|
-              left = index &lt; pixel_length ? 0 : row_data[index - pixel_length]
+              left = index &lt; pixel_bytes ? 0 : row_data[index - pixel_bytes]
               row_data[index] = (byte + left) % 256
               #p [byte, left, row_data[index]]
             end
           when 2 # Up
             row_data.each_with_index do |byte, index|
-              col = index / pixel_length
-              upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_length]
+              col = index / pixel_bytes
+              upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_bytes]
               row_data[index] = (upper + byte) % 256
             end
           when 3  # Average
             row_data.each_with_index do |byte, index|
-              col = index / pixel_length
-              upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_length]
-              left = index &lt; pixel_length ? 0 : row_data[index - pixel_length]
+              col = index / pixel_bytes
+              upper = row == 0 ? 0 : pixels[row-1][col][index % pixel_bytes]
+              left = index &lt; pixel_bytes ? 0 : row_data[index - pixel_bytes]
 
               row_data[index] = (byte + ((left + upper)/2).floor) % 256
             end
           when 4 # Paeth
             left = upper = upper_left = nil
             row_data.each_with_index do |byte, index|
-              col = index / pixel_length
+              col = index / pixel_bytes
 
-              left = index &lt; pixel_length ? 0 : row_data[index - pixel_length]
+              left = index &lt; pixel_bytes ? 0 : row_data[index - pixel_bytes]
               if row.zero?
                 upper = upper_left = 0
               else
-                upper = pixels[row-1][col][index % pixel_length]
+                upper = pixels[row-1][col][index % pixel_bytes]
                 upper_left = col.zero? ? 0 :
-                  pixels[row-1][col-1][index % pixel_length]
+                  pixels[row-1][col-1][index % pixel_bytes]
               end
 
               p = left + upper - upper_left
               pa = (p - left).abs
               pb = (p - upper).abs
-              pc = (p - upper_left).abs  
+              pc = (p - upper_left).abs
 
               paeth = if pa &lt;= pb &amp;&amp; pa &lt;= pc
                 left
@@ -167,16 +183,15 @@ module Prawn
               else
                 upper_left
               end
-              
+
               row_data[index] = (byte + paeth) % 256
-              #p [byte, paeth, row_data[index]]
             end
           else
             raise ArgumentError, &quot;Invalid filter algorithm #{filter}&quot;
           end
 
           s = []
-          row_data.each_slice pixel_length do |slice|
+          row_data.each_slice pixel_bytes do |slice|
             s &lt;&lt; slice
           end
           pixels &lt;&lt; s
@@ -184,10 +199,12 @@ module Prawn
         end
 
         # convert the pixel data to seperate strings for colours and alpha
+        color_byte_size = self.colors * self.bits / 8
+        alpha_byte_size = self.bits / 8
         pixels.each do |row|
           row.each do |pixel|
-            @img_data &lt;&lt; pixel[0,pixel_bytes].pack(&quot;C*&quot;)
-            @alpha_channel &lt;&lt; pixel.last
+            @img_data &lt;&lt; pixel[0, color_byte_size].pack(&quot;C*&quot;)
+            @alpha_channel &lt;&lt; pixel[color_byte_size, alpha_byte_size].pack(&quot;C*&quot;)
           end
         end
 </diff>
      <filename>lib/prawn/images/png.rb</filename>
    </modified>
    <modified>
      <diff>@@ -45,11 +45,6 @@ describe &quot;the image() function&quot; do
     filename = &quot;#{Prawn::BASEDIR}/data/images/dice_interlaced.png&quot;
     lambda { @pdf.image filename, :at =&gt; [100,100] }.should.raise(Prawn::Errors::UnsupportedImageType)
   end
-
-  it &quot;should raise an UnsupportedImageType if passed a 16 bit PNG&quot; do
-    filename = &quot;#{Prawn::BASEDIR}/data/images/16bit.png&quot;
-    lambda { @pdf.image filename, :at =&gt; [100,100] }.should.raise(Prawn::Errors::UnsupportedImageType)
-  end
   
   describe &quot;:fit option&quot; do
     it &quot;should fit inside the defined constraints&quot; do</diff>
      <filename>spec/images_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,7 +14,7 @@ describe &quot;When reading a greyscale PNG file (color type 0)&quot; do
   before(:each) do
     @filename = &quot;#{Prawn::BASEDIR}/data/images/web-links.png&quot;
     @data_filename = &quot;#{Prawn::BASEDIR}/data/images/web-links.dat&quot;
-    @img_data = File.binread(@filename) 
+    @img_data = File.binread(@filename)
   end
 
   it &quot;should read the attributes from the header chunk correctly&quot; do
@@ -105,7 +105,7 @@ describe &quot;When reading an indexed color PNG file (color type 3)&quot; do
   before(:each) do
     @filename = &quot;#{Prawn::BASEDIR}/data/images/rails.png&quot;
     @data_filename = &quot;#{Prawn::BASEDIR}/data/images/rails.dat&quot;
-    @img_data = File.binread(@filename) 
+    @img_data = File.binread(@filename)
   end
 
   it &quot;should read the attributes from the header chunk correctly&quot; do
@@ -158,7 +158,7 @@ describe &quot;When reading a greyscale+alpha PNG file (color type 4)&quot; do
   it &quot;should correctly extract the alpha channel data from the image data chunk&quot; do
     png = Prawn::Images::PNG.new(@img_data)
     png.split_alpha_channel!
-    data = File.binread(@alpha_data_filename) 
+    data = File.binread(@alpha_data_filename)
     png.alpha_channel.should == data
   end
 end
@@ -169,7 +169,7 @@ describe &quot;When reading an RGB+alpha PNG file (color type 6)&quot; do
     @filename = &quot;#{Prawn::BASEDIR}/data/images/dice.png&quot;
     @data_filename = &quot;#{Prawn::BASEDIR}/data/images/dice.dat&quot;
     @alpha_data_filename = &quot;#{Prawn::BASEDIR}/data/images/dice.alpha&quot;
-    @img_data = File.binread(@filename)  
+    @img_data = File.binread(@filename)
   end
 
   it &quot;should read the attributes from the header chunk correctly&quot; do
@@ -187,7 +187,43 @@ describe &quot;When reading an RGB+alpha PNG file (color type 6)&quot; do
   it &quot;should correctly return the raw image data (with no alpha channel) from the image data chunk&quot; do
     png = Prawn::Images::PNG.new(@img_data)
     png.split_alpha_channel!
-    data = File.binread(@data_filename)   
+    data = File.binread(@data_filename)
+    png.img_data.should == data
+  end
+
+  it &quot;should correctly extract the alpha channel data from the image data chunk&quot; do
+    png = Prawn::Images::PNG.new(@img_data)
+    png.split_alpha_channel!
+    data = File.binread(@alpha_data_filename)
+    png.alpha_channel.should == data
+  end
+end
+
+describe &quot;When reading a 16bit RGB+alpha PNG file (color type 6)&quot; do
+
+  before(:each) do
+    @filename = &quot;#{Prawn::BASEDIR}/data/images/16bit.png&quot;
+    @data_filename = &quot;#{Prawn::BASEDIR}/data/images/16bit.dat&quot;
+    @alpha_data_filename = &quot;#{Prawn::BASEDIR}/data/images/16bit.alpha&quot;
+    @img_data = File.binread(@filename)
+  end
+
+  it &quot;should read the attributes from the header chunk correctly&quot; do
+    png = Prawn::Images::PNG.new(@img_data)
+
+    png.width.should == 32
+    png.height.should == 32
+    png.bits.should == 16
+    png.color_type.should == 6
+    png.compression_method.should == 0
+    png.filter_method.should == 0
+    png.interlace_method.should == 0
+  end
+
+  it &quot;should correctly return the raw image data (with no alpha channel) from the image data chunk&quot; do
+    png = Prawn::Images::PNG.new(@img_data)
+    png.split_alpha_channel!
+    data = File.binread(@data_filename)
     png.img_data.should == data
   end
 </diff>
      <filename>spec/png_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>09f19fab7b46cfdf7037f4c4fd0cdeeb90eac6a2</id>
    </parent>
  </parents>
  <author>
    <name>James Healy</name>
    <email>jimmy@deefa.com</email>
  </author>
  <url>http://github.com/sandal/prawn/commit/a1c0c2874d84c13157e6aa6326603d7c5299f5cc</url>
  <id>a1c0c2874d84c13157e6aa6326603d7c5299f5cc</id>
  <committed-date>2009-05-25T10:41:07-07:00</committed-date>
  <authored-date>2009-05-25T10:26:42-07:00</authored-date>
  <message>add support for 16bit PNGs, types 4 and 6</message>
  <tree>904d42b13f76111fc6f7bbfacc772eede98c7bdb</tree>
  <committer>
    <name>James Healy</name>
    <email>jimmy@deefa.com</email>
  </committer>
</commit>
