From 14de6db28fb689cdb066c5b01a2885b6a6a35157 Mon Sep 17 00:00:00 2001 From: Dylan Date: Sat, 20 Jun 2026 23:29:58 +1200 Subject: feat: Initial commit --- src/main.rs | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/main.rs (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c348e77 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,185 @@ +// #![allow(dead_code)] + +use crate::reader::FileReader; +use std::{fs::File, io::BufReader, ops::{self}}; + +mod reader; + +// #[derive(Debug)] +// struct RGB + Copy> +// { +// r: T, +// g: T, +// b: T +// } + +trait ColorDepth: Clone +{ + const DEFAULT: Self; +} +impl ColorDepth for u8 { + const DEFAULT: Self = 0; +} +impl ColorDepth for u16 { + const DEFAULT: Self = 0; +} +impl ColorDepth for u32 { + const DEFAULT: Self = 0; +} + +#[derive(Debug, Clone)] +struct RGBA +{ + r: T, + g: T, + b: T, + a: T +} +#[derive(Debug, Clone)] +struct RGB +{ + r: T, + g: T, + b: T, +} + +trait ColorType: Clone +{ + const DEFAULT: Self; +} +impl ColorType for RGBA +{ + const DEFAULT: Self = Self { r: T::DEFAULT, g: T::DEFAULT, b: T::DEFAULT, a: T::DEFAULT }; +} +impl ColorType for RGB +{ + const DEFAULT: Self = Self { r: T::DEFAULT, g: T::DEFAULT, b: T::DEFAULT}; +} + +#[derive(Debug)] +struct PixelArr +{ + width: u32, + height: u32, + raw: Vec +} +impl PixelArr { + fn new(width: u32, height: u32) -> Self { + let raw = vec![T::DEFAULT;(width*height) as usize]; + Self { width, height, raw } + } +} +impl ops::Index<(usize, usize)> for PixelArr +{ + type Output = T; + + fn index(&self, index: (usize, usize)) -> &Self::Output { + let (x, y) = index; + &self.raw[x + y*(self.width as usize)] + } +} +impl ops::IndexMut<(usize, usize)> for PixelArr +{ + fn index_mut(&mut self, index: (usize, usize)) -> &mut T { + let (x, y) = index; + &mut self.raw[x + y*(self.width as usize)] + } +} + +#[derive(Debug)] +struct ImageBase +{ + width: u32, + height: u32, + bit_depth: u8, + pixels: PixelArr> +} + +struct BMPImage +{ +} + + +trait Image +{ + fn read_image(reader: &mut FileReader) -> Result; +} + +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 + { + width, + height, + bit_depth: bpp, + pixels: pixel_arr, + }) + } + else + { + return Err("Header size not supported yet"); + } + + + } +} + +fn main() { + let file = File::open("smiley.bmp").expect("File does not exist"); + let mut reader = FileReader::new(BufReader::new(file)); + let _bmp = BMPImage::read_image(&mut reader).expect("Bitmap had error"); + // println!("{bmp:?}"); +} -- cgit v1.3.1