Class: EmbedXMP::RIFF

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

Overview

Resource Interchange File Format (container format for WebP)

Direct Known Subclasses

WebP

Constant Summary collapse

RIFF_HEAD =
'RIFF'

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

#chunk(offset) ⇒ Object

rubocop: disable Metrics/AbcSize Return chunk at offset from the beginning of the file.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/embed_xmp/riff.rb', line 32

def chunk(offset)
  raise 'ChunksMustBeTwoBytesAligned' if offset.odd?

  chunk_id = @image_data[offset, 4]

  data_length = @image_data[offset + 4, 4].b.unpack1('V')
  chunk_length = data_length + (data_length % 2) + 8

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

  data = @image_data[offset + 8, data_length]

  [chunk_id, chunk_length, data]
end

#file_headerObject

Return the RIFF file header.



14
15
16
17
18
19
20
21
22
23
# File 'lib/embed_xmp/riff.rb', line 14

def file_header
  riff_id, file_length, data = chunk(0)
  form_type = data[0, 4]
  real_file_length = @image_data.length

  raise 'NoRIFFHeader' if RIFF_HEAD != riff_id
  raise 'FileHeaderLongerThanFile' if real_file_length != file_length

  [riff_id, file_length, form_type]
end

#new_chunk(chunk_id, data) ⇒ Object

Create a new RIFF chunk with data with pad byte when needed.



70
71
72
73
74
75
76
77
78
79
# File 'lib/embed_xmp/riff.rb', line 70

def new_chunk(chunk_id, data)
  unless chunk_id.match?(/[a-zA-Z0-9 ]{4}/)
    raise 'RIFFChunkIdentifierMustBeFourChar'
  end

  data_length = data.length
  data += '\0'.b if data_length.odd?

  chunk_id.b + [data_length].pack('V') + data
end

#remove_chunk(offset) ⇒ Object

Remove the chunk at offset from the beginning of the file.



49
50
51
52
53
54
55
# File 'lib/embed_xmp/riff.rb', line 49

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

  @image_data.slice!(offset, chunk_length)

  update_file_length_header
end

#replace_chunk(offset, chunk_id, data) ⇒ Object

Replace the chunk at offset from the beginning of the file with a new chunk



59
60
61
62
63
64
65
66
67
# File 'lib/embed_xmp/riff.rb', line 59

def replace_chunk(offset, chunk_id, data)
  remove_chunk(offset)

  chunk = new_chunk(chunk_id, data)

  insert_into_file(offset, chunk)

  update_file_length_header
end

#update_file_length_headerObject

Updates the file length value in the WebP file header.



26
27
28
# File 'lib/embed_xmp/riff.rb', line 26

def update_file_length_header
  @image_data[4, 4] = [@image_data.length - 8].pack('V')
end