class EmbedXMP::PNG
PNG
images
Constants
- PNG_HEADER
- PNG_IMAGE_END
- PNG_SIGNATURE
- XMP_CHUNK_SIG
Public Instance Methods
check_file_signatures()
click to toggle source
Quick and dirty test to see if png_data
is a PNG
image file
# 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)
click to toggle source
# 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)
click to toggle source
Join an XMP
sidecar file into a PNG
image file.
# 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)
click to toggle source
Return chunk at offset
from the beginning of the file.
# File lib/embed_xmp/png.rb, line 49 def remove_chunk(offset) _, chunk_length, = chunk(offset) @image_data.slice!(offset, chunk_length) end
remove_xmp()
click to toggle source
rubocop: disable Metrics/MethodLength
# 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
Private Instance Methods
chunk_contains_xmp(offset)
click to toggle source
# File lib/embed_xmp/png.rb, line 93 def chunk_contains_xmp(offset) XMP_CHUNK_SIG == @image_data[offset + 4, XMP_CHUNK_SIG.length + 3].b end
create_xmp_itxt(xmp_data, xpacked)
click to toggle source
# File lib/embed_xmp/png.rb, line 105 def create_xmp_itxt(xmp_data, xpacked) chunk_id = 'iTXt' chunk_data = ("XML:com.adobe.xmp\0\0\0\0\0" + EmbedXMP::XMP .new(xmp_data, writable: false, xpacked: xpacked) .to_s.gsub("\0", ' ')).b new_chunk(chunk_id, chunk_data) end
find_xmp_insertion_offset()
click to toggle source
rubocop: enable Metrics/MethodLength
# File lib/embed_xmp/png.rb, line 75 def find_xmp_insertion_offset offset = PNG_SIGNATURE.length cursor = offset while offset < @image_data.length chunk_id, chunk_length, = chunk(offset) break if [PNG_IMAGE_END, nil].include?(chunk_id) if PNG_HEADER == chunk_id cursor = offset + chunk_length end offset += chunk_length end cursor end
new_chunk(chunk_id, chunk_data)
click to toggle source
# File lib/embed_xmp/png.rb, line 97 def new_chunk(chunk_id, chunk_data) length = [chunk_data.length].pack('N') checksum = [Digest::CRC32.checksum(chunk_id + chunk_data)].pack('N') length.b + chunk_id + chunk_data + checksum end