Class: Pdfrb::Content::InlineImage

Inherits:
Object
  • Object
show all
Defined in:
lib/pdfrb/content/inline_image.rb

Overview

A BI ... ID ... EI inline image (s8.9.7). Carries the expanded header keys (abbreviations resolved by the parser), the raw encoded byte payload, and decodes on demand via the filter pipeline.

Constant Summary collapse

FILTER_ABBREVIATIONS =

Filter-name abbreviations permitted in inline images (s8.9.7 Table 89).

{
  AHx: :ASCIIHexDecode,
  A85: :ASCII85Decode,
  Fl: :FlateDecode,
  LZW: :LZWDecode,
  CCF: :CCITTFaxDecode,
  DCT: :DCTDecode,
  RL: :RunLengthDecode,
}.freeze
COLOR_SPACE_ABBREVIATIONS =

Color-space-name abbreviations (s8.9.7 Table 89).

{
  G: :DeviceGray,
  RGB: :DeviceRGB,
  CMYK: :DeviceCMYK,
  I: :Indexed,
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(header: {}, data: "") ⇒ InlineImage

Returns a new instance of InlineImage.



32
33
34
35
# File 'lib/pdfrb/content/inline_image.rb', line 32

def initialize(header: {}, data: "")
  @header = header.dup.freeze
  @data = (data || "".b).dup.freeze
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



30
31
32
# File 'lib/pdfrb/content/inline_image.rb', line 30

def data
  @data
end

#headerObject (readonly)

Returns the value of attribute header.



30
31
32
# File 'lib/pdfrb/content/inline_image.rb', line 30

def header
  @header
end

Instance Method Details

#bits_per_componentObject



39
# File 'lib/pdfrb/content/inline_image.rb', line 39

def bits_per_component; header[:BitsPerComponent]; end

#color_spaceObject

/ColorSpace with the inline abbreviation expanded (/G -> /DeviceGray etc.).



50
51
52
53
54
55
# File 'lib/pdfrb/content/inline_image.rb', line 50

def color_space
  cs = header[:ColorSpace]
  return nil unless cs.is_a?(::Symbol)

  COLOR_SPACE_ABBREVIATIONS.fetch(cs, cs)
end

#componentsObject

Number of colour components implied by /ColorSpace.



80
81
82
83
84
85
86
# File 'lib/pdfrb/content/inline_image.rb', line 80

def components
  case color_space
  when :DeviceGray, :Indexed then 1
  when :DeviceRGB then 3
  when :DeviceCMYK then 4
  end
end

#decodeObject



45
# File 'lib/pdfrb/content/inline_image.rb', line 45

def decode; header[:Decode]; end

#decoded_dataObject

Apply the filter chain to the raw payload. Returns the raw data when no filter is declared.



69
70
71
72
73
74
75
76
77
# File 'lib/pdfrb/content/inline_image.rb', line 69

def decoded_data
  list = filters
  return @data if list.empty?

  Pdfrb::Filter.apply(
    @data, filters: list, parms: Array(header[:DecodeParms]),
           direction: :decode
  )
end

#expected_decoded_sizeObject

Expected decoded byte count: rows * width * components * bits, packed per row.



90
91
92
93
94
95
96
97
98
99
100
# File 'lib/pdfrb/content/inline_image.rb', line 90

def expected_decoded_size
  return nil if width.nil? || height.nil? || bits_per_component.nil?
  return nil if image_mask?

  comps = components
  return nil if comps.nil?

  bits = width * comps * bits_per_component
  bytes_per_row = (bits + 7) / 8
  bytes_per_row * height
end

#filtersObject

Decoded filter chain as an array of Symbols; nil when the image data is stored raw.



59
60
61
62
63
64
65
# File 'lib/pdfrb/content/inline_image.rb', line 59

def filters
  f = header[:Filter]
  return [] if f.nil?

  arr = f.is_a?(::Array) ? f : [f]
  arr.map { |name| FILTER_ABBREVIATIONS.fetch(name.to_sym, name.to_sym) }
end

#heightObject



38
# File 'lib/pdfrb/content/inline_image.rb', line 38

def height; header[:Height]; end

#image_mask?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/pdfrb/content/inline_image.rb', line 41

def image_mask?
  [true, 1].include?(header[:ImageMask])
end

#interpolate?Boolean

Returns:

  • (Boolean)


46
# File 'lib/pdfrb/content/inline_image.rb', line 46

def interpolate?; header[:Interpolate] == true; end

#widthObject



37
# File 'lib/pdfrb/content/inline_image.rb', line 37

def width; header[:Width]; end