Module: VivlioStarter::Pdf::JpegToPdf::JpegInfo
- Defined in:
- lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb
Overview
JPEG の SOF マーカーから PDF 埋め込みに必要な寸法・色空間を読む。
Constant Summary collapse
- SOF_MARKERS =
[0xC0, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF].freeze
- STANDALONE_MARKERS =
[0x01, *(0xD0..0xD9)].freeze
Class Method Summary collapse
- .color_space_for(components, path:) ⇒ Object
- .jpeg?(data) ⇒ Boolean
- .metadata_from_sof(data, offset, path:) ⇒ Object
- .next_marker_offset(data, offset) ⇒ Object
- .read(data, path: nil) ⇒ Object
- .read_segment_length(data, offset, path:) ⇒ Object
Class Method Details
.color_space_for(components, path:) ⇒ Object
202 203 204 205 206 207 208 209 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 202 def color_space_for(components, path:) case components when 1 then '/DeviceGray' when 3 then '/DeviceRGB' else raise Error, "対応していないJPEG色空間です: components=#{components} #{path}" end end |
.jpeg?(data) ⇒ Boolean
171 172 173 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 171 def jpeg?(data) data.bytesize >= 4 && data.getbyte(0) == 0xFF && data.getbyte(1) == 0xD8 end |
.metadata_from_sof(data, offset, path:) ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 190 def (data, offset, path:) segment_length = read_segment_length(data, offset, path:) raise Error, "JPEG SOF セグメントが壊れています: #{path}" if segment_length < 8 bits = data.getbyte(offset + 2) height = data.byteslice(offset + 3, 2).unpack1('n') width = data.byteslice(offset + 5, 2).unpack1('n') components = data.getbyte(offset + 7) JpegMetadata.new(width:, height:, bits_per_component: bits, color_space: color_space_for(components, path:)) end |
.next_marker_offset(data, offset) ⇒ Object
175 176 177 178 179 180 181 182 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 175 def next_marker_offset(data, offset) index = offset index += 1 while index < data.bytesize && data.getbyte(index) != 0xFF index += 1 while index < data.bytesize && data.getbyte(index) == 0xFF return nil if index >= data.bytesize index - 1 end |
.read(data, path: nil) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 150 def read(data, path: nil) raise Error, "JPEG ではありません: #{path}" unless jpeg?(data) offset = 2 while offset < data.bytesize marker_offset = next_marker_offset(data, offset) raise Error, "JPEG の寸法を取得できませんでした: #{path}" unless marker_offset marker = data.getbyte(marker_offset + 1) offset = marker_offset + 2 next if STANDALONE_MARKERS.include?(marker) segment_length = read_segment_length(data, offset, path:) return (data, offset, path:) if SOF_MARKERS.include?(marker) offset += segment_length end raise Error, "JPEG の寸法を取得できませんでした: #{path}" end |
.read_segment_length(data, offset, path:) ⇒ Object
184 185 186 187 188 |
# File 'lib/vivlio_starter/cli/pdf/jpeg_to_pdf.rb', line 184 def read_segment_length(data, offset, path:) raise Error, "JPEG セグメントが壊れています: #{path}" if offset + 1 >= data.bytesize data.byteslice(offset, 2).unpack1('n') end |