Skip to content

Commit

Permalink
graphics/image: implement RGB32 bmp images
Browse files Browse the repository at this point in the history
  • Loading branch information
simonwuelker committed Feb 16, 2024
1 parent 3693811 commit 141ea48
Showing 1 changed file with 35 additions and 22 deletions.
57 changes: 35 additions & 22 deletions crates/graphics/image/src/bmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ impl InfoHeader {
// 24 bits per pixel
3 * self.width as usize
},
ImageType::Rgb32 => {
// 32 bits per pixel
4 * self.width as usize
},
_ => todo!(),
};

Expand Down Expand Up @@ -295,23 +299,22 @@ pub fn decode(bytes: &[u8]) -> Result<DynamicTexture, Error> {
);
}

let texture = match info_header.image_type {
ImageType::Rgb16 => {
todo!("implement .bmp rgb16 format")
},
ImageType::Rgb24 => {
let texture: DynamicTexture = match info_header.image_type {
ImageType::Monochrome => {
let mut texture_data =
Vec::with_capacity(info_header.width as usize * info_header.height as usize * 3);

info_header.for_each_scanline(image_data, |scanline| {
for pixel in scanline.chunks_exact(3).take(info_header.width as usize) {
let blue = pixel[0];
let green = pixel[1];
let red = pixel[2];
for i in 0..info_header.width as usize {
let byte_index = i / 8;
let bit_index = i % 8;
let palette_index = (scanline[byte_index] >> bit_index) & 1;

texture_data.push(red);
texture_data.push(green);
texture_data.push(blue);
let pixel = palette
.get(palette_index as usize)
.ok_or(Error::PaletteTooSmall)?;

texture_data.extend(pixel.channels());
}

Ok(())
Expand All @@ -324,21 +327,31 @@ pub fn decode(bytes: &[u8]) -> Result<DynamicTexture, Error> {
)
.into()
},
ImageType::Monochrome => {
ImageType::Rgb16 => {
todo!("implement .bmp rgb16 format")
},
ImageType::Rgb24 | ImageType::Rgb32 => {
let pixel_width = if info_header.image_type == ImageType::Rgb24 {
3
} else {
4
};

let mut texture_data =
Vec::with_capacity(info_header.width as usize * info_header.height as usize * 3);

info_header.for_each_scanline(image_data, |scanline| {
for i in 0..info_header.width as usize {
let byte_index = i / 8;
let bit_index = i % 8;
let palette_index = (scanline[byte_index] >> bit_index) & 1;

let pixel = palette
.get(palette_index as usize)
.ok_or(Error::PaletteTooSmall)?;
for pixel in scanline
.chunks_exact(pixel_width)
.take(info_header.width as usize)
{
let blue = pixel[0];
let green = pixel[1];
let red = pixel[2];

texture_data.extend(pixel.channels());
texture_data.push(red);
texture_data.push(green);
texture_data.push(blue);
}

Ok(())
Expand Down

0 comments on commit 141ea48

Please sign in to comment.