Pastey Changes to the image.e to support 24bpp image input/output
- Posted by Insolor
Sep 12, 2011
--- image.e Fri Jun 24 09:55:10 2011
+++ image.e Mon Sep 12 21:10:28 2011
@@ -103,6 +103,22 @@
return floor(((BitCount * Width) + 31) / 32) * 4
end function
+function get_rgb_image(integer BitCount, integer Width, integer Height)
+ sequence pic_2d
+ integer bytes, set_size
+ pic_2d = {}
+ bytes = row_bytes(BitCount, Width)
+ set_size = floor(BitCount/8)
+ for i = 1 to Height do
+ pic_2d = prepend(pic_2d, get_rgb_block(Width, set_size))
+
+ for j = 1 to bytes - Width*set_size do
+ getc(fn)
+ end for
+ end for
+ return pic_2d
+end function
+
function unpack(sequence image, integer BitCount, integer Width, integer Height)
-- unpack the 1-d byte sequence into a 2-d sequence of pixels
sequence pic_2d, row, bits
@@ -202,7 +218,8 @@
integer Planes, BitCount
atom Width, Height, Compression, OffBits, SizeHeader,
NumColors
- sequence Palette, Bits, two_d_bits
+ object Palette
+ sequence Bits, pic_2d
error_code = 0
fn = open(file_name, "rb")
@@ -233,11 +250,15 @@
get_dword() -- Color Used
get_dword() -- Color Important
NumColors = (OffBits - SizeHeader - BMPFILEHDRSIZE) / 4
- if NumColors < 2 or NumColors > 256 then
+ if NumColors < 0 or NumColors > 256 then
close(fn)
return BMP_UNSUPPORTED_FORMAT
end if
- Palette = get_rgb_block(NumColors, 4)
+ if NumColors > 0 then
+ Palette = get_rgb_block(NumColors, 4)
+ else
+ Palette = 0
+ end if
elsif SizeHeader = OLDHDRSIZE then
Width = get_word()
@@ -245,7 +266,11 @@
Planes = get_word()
BitCount = get_word()
NumColors = (OffBits - SizeHeader - BMPFILEHDRSIZE) / 3
- Palette = get_rgb_block(NumColors, 3)
+ if NumColors > 0 then
+ Palette = get_rgb_block(NumColors, 3)
+ else
+ Palette = 0
+ end if
else
close(fn)
return BMP_UNSUPPORTED_FORMAT
@@ -254,13 +279,17 @@
close(fn)
return BMP_UNSUPPORTED_FORMAT
end if
- Bits = get_c_block(row_bytes(BitCount, Width) * Height)
+ if NumColors > 0 then
+ Bits = get_c_block(row_bytes(BitCount, Width) * Height)
+ pic_2d = unpack(Bits, BitCount, Width, Height)
+ else
+ pic_2d = get_rgb_image(BitCount, Width, Height)
+ end if
close(fn)
- two_d_bits = unpack(Bits, BitCount, Width, Height)
if error_code then
return error_code
end if
- return {Palette, two_d_bits}
+ return {Palette, pic_2d}
end function
-- type graphics_point(sequence p)
@@ -289,8 +318,8 @@
end type
type two_seq(sequence s)
- -- a two element sequence, both elements are sequences
- return length(s) = 2 and sequence(s[1]) and sequence(s[2])
+ -- a two element sequence, the second element is sequence
+ return length(s) = 2 and sequence(s[2])
end type
procedure putBmpFileHeader(integer numColors)
@@ -305,7 +334,9 @@
bitCount = 2 -- 2 bits per pixel
elsif numColors = 2 then
bitCount = 1 -- 1 bit per pixel
- else
+ elsif numColors = 0 then
+ bitCount = 24 -- 24 bit per pixel
+ else
error_code = BMP_INVALID_MODE
return
end if
@@ -394,6 +425,33 @@
end for
end procedure
+procedure putOneRowImage24(sequence x)
+ for i = 1 to length(x) do
+ for j = 3 to 1 by -1 do
+ puts(fn, x[i][j])
+ end for
+ end for
+
+ for i = 1 to numRowBytes - length(x)*3 do
+ puts(fn, 0)
+ end for
+end procedure
+
+procedure putImage24(sequence image)
+ object x
+ for i = numYPixels to 1 by -1 do
+ x = image[i]
+ if atom(x) then
+ error_code = BMP_INVALID_MODE
+ return
+ elsif length(x) != numXPixels then
+ error_code = BMP_INVALID_MODE
+ return
+ end if
+ putOneRowImage24(x)
+ end for
+end procedure
+
--**
-- Create a .BMP bitmap file, given a palette and a 2-d sequence of sequences of colors.
--
@@ -433,7 +491,8 @@
-- [[:read_bitmap]]
public function save_bitmap(two_seq palette_n_image, sequence file_name)
- sequence color, image
+ object color
+ sequence image
integer numColors
error_code = BMP_SUCCESS
@@ -446,13 +505,21 @@
image = palette_n_image[2]
numYPixels = length(image)
numXPixels = length(image[1]) -- assume the same length with each row
- numColors = length(color)
+ if sequence(color) then
+ numColors = length(color)
+ else
+ numColors = 0
+ end if
putBmpFileHeader(numColors)
if error_code = BMP_SUCCESS then
- putColorTable(numColors, color)
- putImage1(image)
+ if numColors > 0 then
+ putColorTable(numColors, color)
+ putImage1(image)
+ else
+ putImage24(image)
+ end if
end if
close(fn)
return error_code