From a472b1cdaa8a1f72b96988009b3d4d9820e7128f Mon Sep 17 00:00:00 2001 From: Dylan Date: Sun, 21 Jun 2026 15:01:28 +1200 Subject: feat: Added bitmap writing --- src/bmp.rs | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/bmp.rs (limited to 'src/bmp.rs') diff --git a/src/bmp.rs b/src/bmp.rs new file mode 100644 index 0000000..f6c0c7e --- /dev/null +++ b/src/bmp.rs @@ -0,0 +1,107 @@ +use crate::{image::{ColorType, Image, ImageBase, PixelArr, RGB}, reader::FileReader, writer::FileWriter}; + +impl Image for BMPImage +{ + fn read_image(reader: &mut FileReader) -> Result + { + 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}"); + + if header_size == 40 + { + + let width: u32 = reader.read(); + let height: u32 = reader.read(); + let _color_planes: u16 = reader.read(); + let 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 + bpp != 24 + || compression_method != 0 + { + return Err("bpp or compresssion method not supported") + } + + 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 = RGB::DEFAULT; + pixel.b = reader.read(); + pixel.g = reader.read(); + pixel.r = reader.read(); + pixel_arr[(x as usize, y as usize)] = pixel; + } + reader.skip(skip); + } + + return Ok(ImageBase + { + bit_depth: bpp, + pixels: pixel_arr, + }) + } + else + { + return Err("Header size not supported yet"); + } + + + } + + fn write_image(image: &ImageBase, 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 = image.pixels[(x as usize, y as usize)]; + writer.write(pixel.b); + writer.write(pixel.g); + writer.write(pixel.r); + } + writer.write_zeros(skip); + } + writer.flush(); + } +} + + +pub struct BMPImage +{ +} -- cgit v1.3.1