Class: BMPDecoder

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-doom.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, debug = false) ⇒ BMPDecoder

Returns a new instance of BMPDecoder.



134
135
136
137
138
139
# File 'lib/ruby-doom.rb', line 134

def initialize(filename, debug=false)
  @debug = debug
  @filename = filename
  @scale_factor = 1
  @thinning_factor = 5
end

Instance Attribute Details

#bit_planesObject (readonly)

Returns the value of attribute bit_planes.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def bit_planes
  @bit_planes
end

#bits_per_pixelObject (readonly)

Returns the value of attribute bits_per_pixel.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def bits_per_pixel
  @bits_per_pixel
end

#colors_importantObject (readonly)

Returns the value of attribute colors_important.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def colors_important
  @colors_important
end

#colors_usedObject (readonly)

Returns the value of attribute colors_used.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def colors_used
  @colors_used
end

#compressionObject (readonly)

Returns the value of attribute compression.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def compression
  @compression
end

#heightObject (readonly)

Returns the value of attribute height.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def height
  @height
end

#info_header_sizeObject (readonly)

Returns the value of attribute info_header_size.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def info_header_size
  @info_header_size
end

#offset_to_image_dataObject (readonly)

Returns the value of attribute offset_to_image_data.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def offset_to_image_data
  @offset_to_image_data
end

#scale_factorObject

Returns the value of attribute scale_factor.



133
134
135
# File 'lib/ruby-doom.rb', line 133

def scale_factor
  @scale_factor
end

#sizeObject (readonly)

Returns the value of attribute size.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def size
  @size
end

#size_of_imageObject (readonly)

Returns the value of attribute size_of_image.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def size_of_image
  @size_of_image
end

#thinning_factorObject

Returns the value of attribute thinning_factor.



133
134
135
# File 'lib/ruby-doom.rb', line 133

def thinning_factor
  @thinning_factor
end

#typeObject (readonly)

Returns the value of attribute type.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def type
  @type
end

#widthObject (readonly)

Returns the value of attribute width.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def width
  @width
end

#xpixels_per_meterObject (readonly)

Returns the value of attribute xpixels_per_meter.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def xpixels_per_meter
  @xpixels_per_meter
end

#ypixels_per_meterObject (readonly)

Returns the value of attribute ypixels_per_meter.



132
133
134
# File 'lib/ruby-doom.rb', line 132

def ypixels_per_meter
  @ypixels_per_meter
end

Instance Method Details

#decodeObject



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/ruby-doom.rb', line 140

def decode
  # hm, wouldn't File.read(filename, "rb") do this?
  bytes = []
  File.open(@filename, "r").each_byte {|x| bytes << x }
  
  # decode BITMAPFILEHEADER 
  @type = decode_word(bytes.slice(0,2))
  raise "Can only decode bitmaps" unless @type == 19778

  @size = decode_dword(bytes.slice(2,4))
  res1 = decode_word(bytes.slice(6,2))
  res1 = decode_word(bytes.slice(8,2))
  @offset_to_image_data = decode_dword(bytes.slice(10,4))
  
  # decode BITMAPINFOHEADER
  @info_header_size = decode_dword(bytes.slice(14,4))
  @width = decode_dword(bytes.slice(18,4)) # specified as a LONG... but DWORD works... (?)
  @height = decode_dword(bytes.slice(22,4)) #  specified as a LONG... but DWORD works... (?)
  @bit_planes = decode_word(bytes.slice(26,2))
  @bits_per_pixel = decode_word(bytes.slice(28,2))
  raise "Can't process bitmaps with more than one bit per pixel.  Save it as a monochrome bitmap to fix this." unless @bits_per_pixel == 1

  @compression = decode_dword(bytes.slice(30,4))
  raise "Can't process compressed bitmaps" unless @compression == 0

  @size_of_image = decode_dword(bytes.slice(34,4))
  @xpixels_per_meter = decode_dword(bytes.slice(38,4)) # specified as a LONG... but DWORD works... (?)
  @ypixels_per_meter = decode_dword(bytes.slice(42,4)) # specified as a LONG... but DWORD works... (?)
  @colors_used = decode_dword(bytes.slice(46,4))
  @colors_important = decode_dword(bytes.slice(50,4))
  
  # color table - assume monochrome bitmap for now
  rgb1 = RGBQuad.new(bytes.slice(54,4))
  rgb2 = RGBQuad.new(bytes.slice(58,4))

  @raw_image = bytes.slice(62, bytes.size-62)
  self
end

#decode_dword(bytes) ⇒ Object



192
193
194
# File 'lib/ruby-doom.rb', line 192

def decode_dword(bytes)
  bytes.pack("C4").unpack("L")[0] 
end

#decode_word(bytes) ⇒ Object



189
190
191
# File 'lib/ruby-doom.rb', line 189

def decode_word(bytes)
  bytes.pack("C2").unpack("S")[0] 
end

#lineObject



182
183
184
# File 'lib/ruby-doom.rb', line 182

def line
  PointsToLine.new(raw_points, @debug).line
end

#raw_pointsObject



178
179
180
181
# File 'lib/ruby-doom.rb', line 178

def raw_points
  decode if @raw_image.nil?
  ArrayToPoints.new(@width, @height, @raw_image).points
end

#thinObject



185
186
187
188
# File 'lib/ruby-doom.rb', line 185

def thin
  pts = PointThinner.new(line, @thinning_factor).thin
  pts.collect {|p| p.scale(@scale_factor) }  
end