Class: FormatParser::BMPParser
- Inherits:
-
Object
- Object
- FormatParser::BMPParser
- Includes:
- IOUtils
- Defined in:
- lib/parsers/bmp_parser.rb
Overview
Constant Summary collapse
- VALID_BMP =
'BM'
- PERMISSIBLE_PIXEL_ARRAY_LOCATIONS =
26..512
- BMP_MIME_TYPE =
'image/bmp'
Constants included from IOUtils
Instance Method Summary collapse
- #call(io) ⇒ Object
- #likely_match?(filename) ⇒ Boolean
- #parse_bitmap_core_header(dib_header) ⇒ Object
- #parse_modern_header(dib_header) ⇒ Object
Methods included from IOUtils
#read_bytes, #read_fixed_point, #read_int, #safe_read, #safe_skip, #skip_bytes
Instance Method Details
#call(io) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/parsers/bmp_parser.rb', line 14 def call(io) io = FormatParser::IOConstraint.new(io) magic_number, _file_size, _reserved1, _reserved2, pix_array_location = safe_read(io, 14).unpack('A2Vv2V') return unless VALID_BMP == magic_number # The number that gets unpacked can be fairly large, but in practice this offset cannot be too big - # the DIB image header won't be that big anyway/ return unless PERMISSIBLE_PIXEL_ARRAY_LOCATIONS.cover?(pix_array_location) dib_header = safe_read(io, 40) header_size = dib_header.unpack('V')[0] case header_size when 12 # OS21XBITMAPHEADER parse_bitmap_core_header(dib_header) else # More modern implementations parse_modern_header(dib_header) end end |
#likely_match?(filename) ⇒ Boolean
10 11 12 |
# File 'lib/parsers/bmp_parser.rb', line 10 def likely_match?(filename) filename =~ /\.bmp$/i end |
#parse_bitmap_core_header(dib_header) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/parsers/bmp_parser.rb', line 34 def parse_bitmap_core_header(dib_header) _header_size, width, height, _num_color_planes, bit_depth = dib_header.unpack('VSSSS') # In core bitmap format an unsigned int is used for dimensions, # no inverse scan order is possible data_order = :normal FormatParser::Image.new( format: :bmp, width_px: width, height_px: height, color_mode: :rgb, content_type: BMP_MIME_TYPE, intrinsics: { data_order: data_order, bits_per_pixel: bit_depth } ) end |
#parse_modern_header(dib_header) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/parsers/bmp_parser.rb', line 54 def parse_modern_header(dib_header) _header_size, width, height, _planes, bits_per_pixel, _compression_method, _image_size, horizontal_res, vertical_res, _n_colors, _i_colors = dib_header.unpack('Vl<2v2V2l<2V2') # There are cases where the height might by negative indicating the data # is ordered from top to bottom instead of bottom to top data_order = height < 0 ? :inverse : :normal FormatParser::Image.new( format: :bmp, width_px: width, height_px: height.abs, color_mode: :rgb, content_type: BMP_MIME_TYPE, intrinsics: { vertical_resolution: vertical_res, horizontal_resolution: horizontal_res, data_order: data_order, bits_per_pixel: bits_per_pixel, } ) end |