Skip to content

Commit fa39d42

Browse files
authored
Merge pull request #36 from KateMorley/ilbm
Add support for ILBM
2 parents 6d94263 + 7c4af60 commit fa39d42

File tree

6 files changed

+60
-0
lines changed

6 files changed

+60
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ imagesize = "0.12"
2323
* HDR
2424
* HEIC / HEIF
2525
* ICO*
26+
* ILBM (IFF)
2627
* JPEG
2728
* JPEG XL
2829
* KTX2

src/formats/ilbm.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use crate::{
2+
util::{read_u16, read_u32, Endian},
3+
ImageResult, ImageSize,
4+
};
5+
use std::io::{BufRead, Seek, SeekFrom};
6+
7+
pub fn size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
8+
// skip the IFF header
9+
reader.seek(SeekFrom::Start(12))?;
10+
11+
let mut chunk_id = [0; 4];
12+
13+
loop {
14+
reader.read_exact(&mut chunk_id)?;
15+
let chunk_length = read_u32(reader, &Endian::Big)? as i64;
16+
17+
if &chunk_id == b"BMHD" {
18+
return Ok(ImageSize {
19+
width: read_u16(reader, &Endian::Big)? as usize,
20+
height: read_u16(reader, &Endian::Big)? as usize,
21+
});
22+
}
23+
24+
// the BMHD chunk must occur before the BODY chunk
25+
if &chunk_id == b"BODY" {
26+
return Err(crate::ImageError::CorruptedImage);
27+
}
28+
29+
// skip over the chunk; chunks of odd length have a padding byte
30+
reader.seek(SeekFrom::Current(chunk_length + chunk_length % 2))?;
31+
}
32+
}
33+
34+
pub fn matches(header: &[u8]) -> bool {
35+
header.len() >= 12
36+
&& &header[0..4] == b"FORM"
37+
&& (&header[8..12] == b"ILBM" || &header[8..12] == b"PBM ")
38+
}

src/formats/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod gif;
88
pub mod hdr;
99
pub mod heif;
1010
pub mod ico;
11+
pub mod ilbm;
1112
pub mod jpeg;
1213
pub mod jxl;
1314
pub mod ktx2;
@@ -116,6 +117,10 @@ pub fn image_type<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageType> {
116117
return Ok(ImageType::Vtf);
117118
}
118119

120+
if ilbm::matches(&header) {
121+
return Ok(ImageType::Ilbm);
122+
}
123+
119124
// Keep TGA last because it has the highest probability of false positives
120125
if tga::matches(&header, reader) {
121126
return Ok(ImageType::Tga);

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ pub enum ImageType {
6666
Heif,
6767
/// Icon file
6868
Ico,
69+
/// Interleaved Bitmap
70+
Ilbm,
6971
/// Standard JPEG
7072
Jpeg,
7173
/// JPEG XL
@@ -257,6 +259,7 @@ fn dispatch_header<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize>
257259
ImageType::Hdr => hdr::size(reader),
258260
ImageType::Heif => heif::size(reader),
259261
ImageType::Ico => ico::size(reader),
262+
ImageType::Ilbm => ilbm::size(reader),
260263
ImageType::Jpeg => jpeg::size(reader),
261264
ImageType::Jxl => jxl::size(reader),
262265
ImageType::Ktx2 => ktx2::size(reader),

tests/ilbm.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#[cfg(test)]
2+
use imagesize::{size, ImageSize};
3+
4+
#[test]
5+
fn ilbm_test() {
6+
assert_eq!(
7+
size("tests/images/ilbm/test.iff").unwrap(),
8+
ImageSize {
9+
width: 640,
10+
height: 512
11+
}
12+
);
13+
}

tests/images/ilbm/test.iff

48 KB
Binary file not shown.

0 commit comments

Comments
 (0)