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_SOF_BLOCKS

Attributes

bits[R]

@group Extension API

channels[R]

@group Extension API

height[R]

@group Extension API

scaled_height[RW]
scaled_width[RW]
width[R]

@group Extension API

Public Class Methods

can_render?(image_blob) click to toggle source
# File lib/prawn/images/jpg.rb, line 26
def self.can_render?(image_blob)
  image_blob[0, 3].unpack('C*') == [255, 216, 255]
end
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 34
def initialize(data)
  @data = data
  d = StringIO.new(@data)
  d.binmode

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

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

    d.seek(length - 2, IO::SEEK_CUR)
  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 57
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,
    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.stream << @data
  obj.stream.filters << :DCTDecode
  obj
end