Skip to content

Commit

Permalink
Merge pull request #36 from KateMorley/ilbm
Browse files Browse the repository at this point in the history
Add support for ILBM
Roughsketch authored Jun 9, 2024
2 parents 6d94263 + 7c4af60 commit fa39d42
Showing 6 changed files with 60 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ imagesize = "0.12"
* HDR
* HEIC / HEIF
* ICO*
* ILBM (IFF)
* JPEG
* JPEG XL
* KTX2
38 changes: 38 additions & 0 deletions src/formats/ilbm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
util::{read_u16, read_u32, Endian},
ImageResult, ImageSize,
};
use std::io::{BufRead, Seek, SeekFrom};

pub fn size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
// skip the IFF header
reader.seek(SeekFrom::Start(12))?;

let mut chunk_id = [0; 4];

loop {
reader.read_exact(&mut chunk_id)?;
let chunk_length = read_u32(reader, &Endian::Big)? as i64;

if &chunk_id == b"BMHD" {
return Ok(ImageSize {
width: read_u16(reader, &Endian::Big)? as usize,
height: read_u16(reader, &Endian::Big)? as usize,
});
}

// the BMHD chunk must occur before the BODY chunk
if &chunk_id == b"BODY" {
return Err(crate::ImageError::CorruptedImage);
}

// skip over the chunk; chunks of odd length have a padding byte
reader.seek(SeekFrom::Current(chunk_length + chunk_length % 2))?;
}
}

pub fn matches(header: &[u8]) -> bool {
header.len() >= 12
&& &header[0..4] == b"FORM"
&& (&header[8..12] == b"ILBM" || &header[8..12] == b"PBM ")
}
5 changes: 5 additions & 0 deletions src/formats/mod.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ pub mod gif;
pub mod hdr;
pub mod heif;
pub mod ico;
pub mod ilbm;
pub mod jpeg;
pub mod jxl;
pub mod ktx2;
@@ -116,6 +117,10 @@ pub fn image_type<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageType> {
return Ok(ImageType::Vtf);
}

if ilbm::matches(&header) {
return Ok(ImageType::Ilbm);
}

// Keep TGA last because it has the highest probability of false positives
if tga::matches(&header, reader) {
return Ok(ImageType::Tga);
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -66,6 +66,8 @@ pub enum ImageType {
Heif,
/// Icon file
Ico,
/// Interleaved Bitmap
Ilbm,
/// Standard JPEG
Jpeg,
/// JPEG XL
@@ -257,6 +259,7 @@ fn dispatch_header<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize>
ImageType::Hdr => hdr::size(reader),
ImageType::Heif => heif::size(reader),
ImageType::Ico => ico::size(reader),
ImageType::Ilbm => ilbm::size(reader),
ImageType::Jpeg => jpeg::size(reader),
ImageType::Jxl => jxl::size(reader),
ImageType::Ktx2 => ktx2::size(reader),
13 changes: 13 additions & 0 deletions tests/ilbm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#[cfg(test)]
use imagesize::{size, ImageSize};

#[test]
fn ilbm_test() {
assert_eq!(
size("tests/images/ilbm/test.iff").unwrap(),
ImageSize {
width: 640,
height: 512
}
);
}
Binary file added tests/images/ilbm/test.iff
Binary file not shown.

0 comments on commit fa39d42

Please sign in to comment.