class Prawn::Images::JPG

A convenience class that wraps the logic for extracting the parts of a JPG image that we need to embed them in a PDF

Constants

JPEG_APP_BLOCKS
JPEG_SOF_BLOCKS

Attributes

bits[R]
channels[R]
height[R]
scaled_height[RW]
scaled_width[RW]
width[R]

Public Class Methods

new(data) click to toggle source

Process a new JPG image

:data

A binary string of JPEG data

# File lib/prawn/images/jpg.rb, line 26
def initialize(data)
  @data = data.dup
  ruby_19 { data.force_encoding("binary") }
  data = StringIO.new(data)

  c_marker = "\xff" # Section marker.
  data.read(2)   # Skip the first two bytes of JPEG identifier.
  loop do
    marker, code, length = data.read(4).unpack('aan')
    raise "JPEG marker not found!" if marker != c_marker

    if JPEG_SOF_BLOCKS.include?(code)
      @bits, @height, @width, @channels = data.read(6).unpack("CnnC")
      break
    end

    buffer = data.read(length - 2)
  end
end

Public Instance Methods

build_pdf_object(document) click to toggle source

Build a PDF object representing this image in document, and return a Reference to it.

# File lib/prawn/images/jpg.rb, line 49
def build_pdf_object(document)
  color_space = case channels
  when 1
    :DeviceGray
  when 3
    :DeviceRGB
  when 4
    :DeviceCMYK
  else
    raise ArgumentError, 'JPG uses an unsupported number of channels'
  end

  obj = document.ref!(
    :Type             => :XObject,
    :Subtype          => :Image,
    :Filter           => :DCTDecode,
    :ColorSpace       => color_space,
    :BitsPerComponent => bits,
    :Width            => width,
    :Height           => height
  ) 

  # add extra decode params for CMYK images. By swapping the
  # min and max values from the default, we invert the colours. See
  # section 4.8.4 of the spec.
  if color_space == :DeviceCMYK
    obj.data[:Decode] = [ 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0 ]
  end

  obj << @data
  obj
end