1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
use crate::{image::{ColorType, Image, ImageBase, PixelArr, RGB, RGBA}, reader::FileReader, writer::FileWriter};
impl<T: ColorType> Image<T> for BMPImage
{
fn read_image(reader: &mut FileReader) -> Result<ImageBase<T>, &'static str>
{
let magic: [u8; 2] = reader.read_array();
if magic != [0x42, 0x4d]
{
return Err("Not a bitmap!");
}
let _file_size: u32 = reader.read();
reader.skip(4);
let _offset: u32 = reader.read();
let header_size: u32 = reader.read();
// println!("File header: {file_size} {offset} {header_size}");
let width: u32;
let height: u32;
let bpp: u8;
if header_size == 40
{
width = reader.read();
height = reader.read();
let _color_planes: u16 = reader.read();
bpp = reader.read::<2, u16>() as u8;
let compression_method: u32 = reader.read();
let _image_size: u32 = reader.read();
let _horr_res: u32 = reader.read();
let _vert_res: u32 = reader.read();
let _color_count: u32 = reader.read();
let _impotant_color_count: u32 = reader.read();
if compression_method != 0
{
return Err("Compresssion method not supported");
}
}
else if header_size == 12
{
width = reader.read::<2, u16>() as u32;
height = reader.read::<2, u16>() as u32;
let _color_planes: u16 = reader.read();
bpp = reader.read::<2, u16>() as u8;
}
else
{
return Err("Header size not supported yet");
}
if bpp != 24
{
return Err("Only bpp of 24 is supported so far");
}
let row_size = (((bpp as u32) * width + 31)/32) * 4;
let skip: usize = (row_size - width * 3) as usize;
let mut pixel_arr = PixelArr::new(width, height);
for y in (0..height).rev()
{
for x in 0..width
{
let mut pixel = RGBA::<u8>::DEFAULT;
pixel.b = reader.read();
pixel.g = reader.read();
pixel.r = reader.read();
pixel.a = 255;
pixel_arr[(x as usize, y as usize)] = pixel.convert();
}
reader.skip(skip);
}
return Ok(ImageBase
{
bit_depth: bpp,
pixels: pixel_arr,
})
}
fn write_image(image: &ImageBase<T>, writer: &mut FileWriter) -> () {
writer.write_array([0x42, 0x4d] as [u8; 2]);
let row_size = (((24) * image.pixels.width + 31)/32) * 4;
let file_size: u32 = 14 + 12 + row_size*image.pixels.height;
let offset: u32 = 26;
writer.write(file_size as u32);
writer.write_zeros(4);
writer.write(offset as u32);
writer.write(12 as u32); // Header size
writer.write(image.pixels.width as u16);
writer.write(image.pixels.height as u16);
writer.write(1 as u16); // Color planes
writer.write(24 as u16); // bpp
let skip: usize = (row_size - image.pixels.width * 3) as usize;
for y in (0..image.pixels.height).rev()
{
for x in 0..image.pixels.width
{
let pixel: RGB<u8> = image.pixels[(x as usize, y as usize)].clone().convert();
writer.write(pixel.b);
writer.write(pixel.g);
writer.write(pixel.r);
}
writer.write_zeros(skip);
}
writer.flush();
}
}
pub struct BMPImage
{
}
|