Class: EmbedXMP::PNG

Inherits:
ImageFile show all
Defined in:
lib/embed_xmp/png.rb

Overview

PNG images

Constant Summary collapse

PNG_SIGNATURE =
"\x89PNG\r\n\x1A\n".b.freeze
PNG_HEADER =
'IHDR'
PNG_IMAGE_END =
'IEND'
XMP_CHUNK_SIG =
"iTXtXML:com.adobe.xmp\0\0\0\0\0".b.freeze

Instance Method Summary collapse

Methods inherited from ImageFile

#initialize, #insert_into_file, #read_io_or_string, #write

Constructor Details

This class inherits a constructor from EmbedXMP::ImageFile

Instance Method Details

#check_file_signaturesObject

Quick and dirty test to see if png_data is a PNG image file



31
32
33
34
# File 'lib/embed_xmp/png.rb', line 31

def check_file_signatures
  raise 'NoPNGSignature' if PNG_SIGNATURE != @image_data[0..7]
  raise 'NoPNGEndOfFile' if PNG_IMAGE_END != @image_data[-8..-5]
end

#chunk(offset) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/embed_xmp/png.rb', line 36

def chunk(offset)
  chunk_length = @image_data[offset, 4].b.unpack1('N') + 12

  raise 'ChunkLongerThanFile' if offset + chunk_length > @image_data.length

  chunk_id = @image_data[offset + 4, 4]

  data = @image_data[offset + 8, chunk_length]

  [chunk_id, chunk_length, data]
end

#join_sidecar(sidecar_file, xpacked: false) ⇒ Object

Join an XMP sidecar file into a PNG image file.



20
21
22
23
24
25
26
27
28
# File 'lib/embed_xmp/png.rb', line 20

def join_sidecar(sidecar_file, xpacked: false)
  check_file_signatures
  remove_xmp

  sidecar = read_io_or_string(sidecar_file)
  xmp_chunk = create_xmp_itxt(sidecar, xpacked)

  insert_into_file(find_xmp_insertion_offset, xmp_chunk)
end

#remove_chunk(offset) ⇒ Object

Return chunk at offset from the beginning of the file.



49
50
51
52
53
# File 'lib/embed_xmp/png.rb', line 49

def remove_chunk(offset)
  _, chunk_length, = chunk(offset)

  @image_data.slice!(offset, chunk_length)
end

#remove_xmpObject

rubocop: disable Metrics/MethodLength



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/embed_xmp/png.rb', line 56

def remove_xmp
  offset = PNG_SIGNATURE.length
  while offset < @image_data.length
    chunk_id, chunk_length, = chunk(offset)

    break if [PNG_IMAGE_END, nil].include?(chunk_id)

    if chunk_contains_xmp(offset)
      remove_chunk(offset)
      next
    end

    offset += chunk_length
  end
end