summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bmp.rs86
-rw-r--r--src/byte_encode.rs5
-rw-r--r--src/image.rs63
-rw-r--r--src/main.rs16
4 files changed, 123 insertions, 47 deletions
diff --git a/src/bmp.rs b/src/bmp.rs
index f6c0c7e..8592894 100644
--- a/src/bmp.rs
+++ b/src/bmp.rs
@@ -1,8 +1,8 @@
-use crate::{image::{ColorType, Image, ImageBase, PixelArr, RGB}, reader::FileReader, writer::FileWriter};
+use crate::{image::{ColorType, Image, ImageBase, PixelArr, RGB, RGBA}, reader::FileReader, writer::FileWriter};
-impl Image for BMPImage
+impl<T: ColorType> Image<T> for BMPImage
{
- fn read_image(reader: &mut FileReader) -> Result<ImageBase, &'static str>
+ fn read_image(reader: &mut FileReader) -> Result<ImageBase<T>, &'static str>
{
let magic: [u8; 2] = reader.read_array();
if magic != [0x42, 0x4d]
@@ -18,13 +18,16 @@ impl Image for BMPImage
// println!("File header: {file_size} {offset} {header_size}");
+ let width: u32;
+ let height: u32;
+ let bpp: u8;
+
if header_size == 40
{
-
- let width: u32 = reader.read();
- let height: u32 = reader.read();
+ width = reader.read();
+ height = reader.read();
let _color_planes: u16 = reader.read();
- let bpp = reader.read::<2, u16>() as u8;
+ 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();
@@ -32,44 +35,53 @@ impl Image for BMPImage
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()
+ if compression_method != 0
{
- 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 Err("Compresssion method not supported");
}
-
- return Ok(ImageBase
- {
- bit_depth: bpp,
- pixels: pixel_arr,
- })
+ }
+ 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, writer: &mut FileWriter) -> () {
+ 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;
@@ -90,7 +102,7 @@ impl Image for BMPImage
{
for x in 0..image.pixels.width
{
- let pixel = image.pixels[(x as usize, y as usize)];
+ 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);
diff --git a/src/byte_encode.rs b/src/byte_encode.rs
index 4be57b2..f5cad19 100644
--- a/src/byte_encode.rs
+++ b/src/byte_encode.rs
@@ -2,6 +2,11 @@ pub trait ByteEncode<const N: usize>: Sized + Copy
{
fn from_le_bytes(buffer: &[u8; N]) -> Self;
fn to_le_bytes(&self) -> [u8; N];
+
+ // fn from_be_bytes(buffer: &[u8; N]) -> Self
+ // {
+ // Self::from_le_bytes(buffer.reversed())
+ // }
}
impl ByteEncode<4> for u32
diff --git a/src/image.rs b/src/image.rs
index ab5dc99..9b42b27 100644
--- a/src/image.rs
+++ b/src/image.rs
@@ -2,18 +2,31 @@ use std::ops;
use crate::{reader::FileReader, writer::FileWriter};
+type FullColorDepth = u32;
pub trait ColorDepth: Clone
{
const DEFAULT: Self;
+ fn from_full_color(x: FullColorDepth) -> Self;
+ fn to_full_color(&self) -> FullColorDepth;
+ fn convert<T: ColorDepth>(&self) -> T
+ {
+ T::from_full_color(self.to_full_color())
+ }
}
impl ColorDepth for u8 {
const DEFAULT: Self = 0;
+ fn from_full_color(x: FullColorDepth) -> Self {(x>>24) as Self}
+ fn to_full_color(&self) -> FullColorDepth { (*self as FullColorDepth) << 24 }
}
impl ColorDepth for u16 {
const DEFAULT: Self = 0;
+ fn from_full_color(x: FullColorDepth) -> Self {(x>>16) as Self}
+ fn to_full_color(&self) -> FullColorDepth { (*self as FullColorDepth) << 16 }
}
impl ColorDepth for u32 {
const DEFAULT: Self = 0;
+ fn from_full_color(x: FullColorDepth) -> Self {x}
+ fn to_full_color(&self) -> FullColorDepth { *self }
}
#[derive(Debug, Clone, Copy)]
@@ -32,17 +45,57 @@ pub struct RGB<T: ColorDepth>
pub b: T,
}
+type FullColorPixel = RGBA<FullColorDepth>;
pub trait ColorType: Clone
{
const DEFAULT: Self;
+ fn from_full_color(x: FullColorPixel) -> Self;
+ fn to_full_color(&self) -> FullColorPixel;
+ fn convert<T: ColorType>(&self) -> T
+ {
+ T::from_full_color(self.to_full_color())
+ }
}
impl<T: ColorDepth> ColorType for RGBA<T>
{
const DEFAULT: Self = Self { r: T::DEFAULT, g: T::DEFAULT, b: T::DEFAULT, a: T::DEFAULT };
+ fn from_full_color(x: FullColorPixel) -> Self {
+ Self
+ {
+ r: T::from_full_color(x.r),
+ g: T::from_full_color(x.g),
+ b: T::from_full_color(x.b),
+ a: T::from_full_color(x.a),
+ }
+ }
+ fn to_full_color(&self) -> FullColorPixel {
+ RGBA {
+ r: T::to_full_color(&self.r),
+ g: T::to_full_color(&self.g),
+ b: T::to_full_color(&self.b),
+ a: T::to_full_color(&self.a),
+ }
+ }
}
impl<T: ColorDepth> ColorType for RGB<T>
{
const DEFAULT: Self = Self { r: T::DEFAULT, g: T::DEFAULT, b: T::DEFAULT};
+ fn from_full_color(x: FullColorPixel) -> Self {
+ Self
+ {
+ r: T::from_full_color(x.r),
+ g: T::from_full_color(x.g),
+ b: T::from_full_color(x.b)
+ }
+ }
+ fn to_full_color(&self) -> FullColorPixel {
+ RGBA {
+ r: T::to_full_color(&self.r),
+ g: T::to_full_color(&self.g),
+ b: T::to_full_color(&self.b),
+ a: u32::max_value()
+ }
+ }
}
#[derive(Debug)]
@@ -76,14 +129,14 @@ impl<T: ColorType> ops::IndexMut<(usize, usize)> for PixelArr<T>
}
#[derive(Debug)]
-pub struct ImageBase
+pub struct ImageBase<T: ColorType>
{
pub bit_depth: u8,
- pub pixels: PixelArr<RGB<u8>>
+ pub pixels: PixelArr<T>
}
-pub trait Image
+pub trait Image<T: ColorType>
{
- fn read_image(reader: &mut FileReader) -> Result<ImageBase, &'static str>;
- fn write_image(image: &ImageBase, writer: &mut FileWriter)-> ();
+ fn read_image(reader: &mut FileReader) -> Result<ImageBase<T>, &'static str>;
+ fn write_image(image: &ImageBase<T>, writer: &mut FileWriter)-> ();
}
diff --git a/src/main.rs b/src/main.rs
index 1e78abb..0da4f13 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
-use crate::{bmp::BMPImage, image::Image, reader::FileReader, writer::FileWriter};
-use std::{fs::File, io::{BufReader, BufWriter}};
+use crate::{bmp::BMPImage, image::{Image, ImageBase, RGB}, reader::FileReader, writer::FileWriter};
+use std::{env, fs::File, io::{BufReader, BufWriter}};
mod reader;
mod image;
@@ -8,11 +8,17 @@ mod writer;
mod byte_encode;
fn main() {
- let file = File::open("smiley.bmp").expect("File does not exist");
+ let args: Vec<String> = env::args().collect();
+ if args.len() != 3
+ {
+ panic!("USAGE: <program> infline.bmp outfile.bmp");
+ }
+
+ let file = File::open(args[1].clone()).expect("File does not exist");
let mut reader = FileReader::new(BufReader::new(file));
- let _bmp = BMPImage::read_image(&mut reader).expect("Bitmap had error");
+ let _bmp: ImageBase<RGB<u8>> = BMPImage::read_image(&mut reader).expect("Bitmap had error");
- let out_file = File::create("tmp.bmp").expect("Cannot create fiel");
+ let out_file = File::create(args[2].clone()).expect("Cannot create file");
let mut writer = FileWriter::new(BufWriter::new(out_file));
BMPImage::write_image(&_bmp, &mut writer);
// println!("{_bmp:?}");