Class: ImDataBmpRecord

Inherits:
BiffRecord show all
Defined in:
lib/surpass/bitmap.rb

Constant Summary collapse

RECORD_ID =
0x007F

Constants inherited from BiffRecord

BiffRecord::BIFF_LIMIT, BiffRecord::CONTINUE_RECORD_ID

Instance Attribute Summary collapse

Attributes inherited from BiffRecord

#record_data

Instance Method Summary collapse

Methods inherited from BiffRecord

#record_header, #to_biff

Constructor Details

#initialize(filename) ⇒ ImDataBmpRecord

Insert a 24bit bitmap image in a worksheet. The main record required is IMDATA but it must be proceeded by a OBJ record to define its position.



160
161
162
163
164
165
166
167
168
# File 'lib/surpass/bitmap.rb', line 160

def initialize(filename)
  @width, @height, @size, data = process_bitmap(filename)
  
  cf = 0x09
  env = 0x01
  lcb = @size
  
  @record_data =  [cf, env, lcb].pack('v2L') + data
end

Instance Attribute Details

#heightObject

Returns the value of attribute height.



155
156
157
# File 'lib/surpass/bitmap.rb', line 155

def height
  @height
end

#sizeObject

Returns the value of attribute size.



156
157
158
# File 'lib/surpass/bitmap.rb', line 156

def size
  @size
end

#widthObject

Returns the value of attribute width.



154
155
156
# File 'lib/surpass/bitmap.rb', line 154

def width
  @width
end

Instance Method Details

#process_bitmap(filename) ⇒ Object

Convert a 24 bit bitmap into the modified internal format used by Windows. This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the MSDN library.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/surpass/bitmap.rb', line 173

def process_bitmap(filename)
  data = nil
  File.open(filename, "rb") do |f|
    data = f.read
  end
  
  raise "bitmap #{filename} doesn't contain enough data" if data.length <= 0x36
  raise "bitmap #{filename} is not valid" unless data[0, 2] === "BM"
  
  # Remove bitmap data: ID.
  data = data[2..-1]

  # Read and remove the bitmap size. This is more reliable than reading
  # the data size at offset 0x22.
  size = data[0,4].unpack('L')[0]
  size -=  0x36   # Subtract size of bitmap header.
  size +=  0x0C   # Add size of BIFF header.

  data = data[4..-1]
  # Remove bitmap data: reserved, offset, header length.
  data = data[12..-1]
  # Read and remove the bitmap width and height. Verify the sizes.
  width, height = data[0,8].unpack('L2')
  data = data[8..-1]
  raise "bitmap #{filename} largest image width supported is 65k." if (width > 0xFFFF)
  raise "bitmap #{filename} largest image height supported is 65k." if (height > 0xFFFF)
  
  # Read and remove the bitmap planes and bpp data. Verify them.
  planes, bitcount = data[0,4].unpack('v2')
  data = data[4..-1]
  raise "bitmap #{filename} isn't a 24bit true color bitmap." if (bitcount != 24)
  raise "bitmap #{filename} only 1 plane supported in bitmap image." if (planes != 1)

  # Read and remove the bitmap compression. Verify compression.
  compression = data[0,4].unpack('L')[0]
  data = data[4..-1]
  raise "bitmap #{filename} compression not supported in bitmap image." if (compression != 0)
      
  # Remove bitmap data: data size, hres, vres, colours, imp. colours.
  data = data[20..-1]
  # Add the BITMAPCOREHEADER data
  header = [0x000c, width, height, 0x01, 0x18].pack('Lv4')
  
  [width, height, size, header + data]
end