Class: Pruim::BMP
Defined Under Namespace
Classes: BGR, BGRX, ColorTableRGBX, CoreHeader, ExtraHeader, Header
Constant Summary collapse
- BI_RGB =
0
- BI_RLE8 =
RLE 8-bit/pixel Can be used only with 8-bit/pixel bitmaps
1
- BI_RLE4 =
RLE 4-bit/pixel Can be used only with 4-bit/pixel bitmaps
2
- BI_BITFIELDS =
Bit field or Huffman 1D compression for BITMAPCOREHEADER2
3
- BI_JPEG =
JPEG or RLE-24 compression for BITMAPCOREHEADER2
4
- BI_PNG =
PNG The bitmap contains a PNG image.
5
- BITMAPINFOHEADER =
Commonly used
40
- BITMAPV5HEADER =
Latest version
124
- HEADER_SIZE =
14
Instance Method Summary collapse
-
#calc_padding(wide, palette = true) ⇒ Object
Calculate padding size.
- #can_decode?(io) ⇒ Boolean
- #decode(io) ⇒ Object
- #decode_bpp8(io, header, core, extra) ⇒ Object
- #decode_bpp8_rgb(io, header, core, extra, padding) ⇒ Object
- #encode(image, io) ⇒ Object
- #encode_bpp24(image, io, padding) ⇒ Object
- #encode_bpp8(image, io, padding) ⇒ Object
- #encode_bpp8_rgb(image, io, padding) ⇒ Object
- #encode_palette(image, io) ⇒ Object
- #read_palette(io, header, core, extra) ⇒ Object
Methods included from Codec
#can_encode?, #encode_will_degrade?, for_filename, for_filename_name, for_name, new_for_filename, new_for_filename_name, new_for_name, register, #text
Instance Method Details
#calc_padding(wide, palette = true) ⇒ Object
Calculate padding size
134 135 136 137 138 139 |
# File 'lib/pruim/bmp.rb', line 134 def calc_padding(wide, palette = true) bs = palette ? 1 : 3 padding = (1 * bs * wide) % 4; padding = 4 - padding if padding != 0 return padding end |
#can_decode?(io) ⇒ Boolean
98 99 100 101 102 |
# File 'lib/pruim/bmp.rb', line 98 def can_decode?(io) header = Header.read(io) io.rewind return header && header.magic == 'BM' end |
#decode(io) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/pruim/bmp.rb', line 162 def decode(io) header = Header.read(io) core = CoreHeader.read(io) extra = nil if (core.header_size == BITMAPINFOHEADER) extra = ExtraHeader.read(io) end io.seek(HEADER_SIZE + core.header_size) # skip rest of header that we don't support if core.bitspp == 8 return decode_bpp8(io, header, core, extra) end # TODO: real color bitmaps. return nil end |
#decode_bpp8(io, header, core, extra) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/pruim/bmp.rb', line 142 def decode_bpp8(io, header, core, extra) # p header, core, extra io.seek(HEADER_SIZE + core.header_size) palette = read_palette(io, header, core, extra) # Skip to the bitmap, gap may be there... io.seek(header.bitmap_offset) # Calculate padding size padding = calc_padding(core.width, true) data = nil case extra.compress_type when BI_RGB data = decode_bpp8_rgb(io, header, core, extra, padding) else return nil end image = Image.new(core.width, core.height, :depth => core.bitspp, :palette => palette, :pages => 1, :data => [data]) return image end |
#decode_bpp8_rgb(io, header, core, extra, padding) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/pruim/bmp.rb', line 117 def decode_bpp8_rgb(io, header, core, extra, padding) data = [] for ypos in (0...core.height) size = core.width + padding # read a line with padding raise "End of file when reading BMP btyes!" if io.eof? str = io.read(size) raise "Short read when reading BMP bytes!" unless str && str.bytesize == size # make an array out of it and drop the padding arr = str.bytes.to_a arr.pop(padding) data = arr + data # prepend data end return data end |
#encode(image, io) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/pruim/bmp.rb', line 207 def encode(image, io) bitcount = (image.palette? ? 8 : 24) bitmap_size = ((image.w * bitcount) / 8) * image.h info_size = BITMAPINFOHEADER # Data for the palette if image.palette? info_size += image.palette.size * 4 end total_size = 14 + info_size + bitmap_size # write bmp header info header = Header.new.set('BM', total_size, 0, 0, 14 + info_size) header.write(io) core = CoreHeader.new.set(BITMAPINFOHEADER, image.w, image.h, 1, bitcount) core.write(io) extra = ExtraHeader.new.set(BI_RGB, 0, 0, bitcount, image.palette.size, 0) extra.write(io) # Calculate padding size padding = calc_padding(image.active.w, image.palette?) if image.palette? encode_bpp8(image, io, padding) else encode_bpp24(image, io, padding) end return image end |
#encode_bpp24(image, io, padding) ⇒ Object
204 205 |
# File 'lib/pruim/bmp.rb', line 204 def encode_bpp24(image, io, padding) end |
#encode_bpp8(image, io, padding) ⇒ Object
199 200 201 202 |
# File 'lib/pruim/bmp.rb', line 199 def encode_bpp8(image, io, padding) encode_palette(image, io) encode_bpp8_rgb(image, io, padding) end |
#encode_bpp8_rgb(image, io, padding) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/pruim/bmp.rb', line 186 def encode_bpp8_rgb(image, io, padding) page = image.active ypos = image.h - 1 while ypos >= 0 row = page.row(ypos) row = row + [0] * padding str = row.pack('C*') io.write(str) ypos -= 1 end end |
#encode_palette(image, io) ⇒ Object
178 179 180 181 182 183 184 |
# File 'lib/pruim/bmp.rb', line 178 def encode_palette(image, io) image.palette.each do |color| r, g, b = *Color.to_rgb(color) bgrx = BGRX.new.set(b, g, r, 0) bgrx.write(io) end end |
#read_palette(io, header, core, extra) ⇒ Object
105 106 107 108 109 110 111 112 113 114 |
# File 'lib/pruim/bmp.rb', line 105 def read_palette(io, header, core, extra) palette = Pruim::Palette.new ncolors = 2 ** core.bitspp for i in 0..255 color = BGRX.read(io) palette.new_rgb(color.r, color.g, color.b) raise "Unexpected end of file whilst reading bmp palette!" if io.eof? end return palette end |