Skip to content

Commit

Permalink
Add ColorType::Multiband enum variant to support samples>1 per pixel (#…
Browse files Browse the repository at this point in the history
…224)

Co-authored-by: tromper <scott@hopkinsunderground.com>
  • Loading branch information
weiji14 and tromper authored Mar 24, 2024
1 parent 90ae5b8 commit 0c54a18
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 10 deletions.
38 changes: 28 additions & 10 deletions src/decoder/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,14 +346,19 @@ impl Image {
),
)),
},
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero
if self.samples == 1 =>
{
Ok(ColorType::Gray(self.bits_per_sample))
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero => {
match self.samples {
1 => Ok(ColorType::Gray(self.bits_per_sample)),
_ => Ok(ColorType::Multiband {
bit_depth: self.bits_per_sample,
num_samples: self.samples,
}),
}
}

// TODO: this is bad we should not fail at this point
_ => Err(TiffError::UnsupportedError(
PhotometricInterpretation::RGBPalette
| PhotometricInterpretation::TransparencyMask
| PhotometricInterpretation::CIELab => Err(TiffError::UnsupportedError(
TiffUnsupportedError::InterpretationWithBits(
self.photometric_interpretation,
vec![self.bits_per_sample; self.samples as usize],
Expand Down Expand Up @@ -555,13 +560,26 @@ impl Image {
| (ColorType::CMYK(n), _)
| (ColorType::YCbCr(n), _)
| (ColorType::Gray(n), _)
if usize::from(n) == buffer.byte_len() * 8 => {}
(ColorType::Gray(n), DecodingBuffer::U8(_)) if n < 8 => match self.predictor {
| (
ColorType::Multiband {
bit_depth: n,
num_samples: _,
},
_,
) if usize::from(n) == buffer.byte_len() * 8 => {}
(
ColorType::Gray(n)
| ColorType::Multiband {
bit_depth: n,
num_samples: _,
},
DecodingBuffer::U8(_),
) if n < 8 => match self.predictor {
Predictor::None => {}
Predictor::Horizontal => {
return Err(TiffError::UnsupportedError(
TiffUnsupportedError::HorizontalPredictor(color_type),
))
));
}
Predictor::FloatingPoint => {
return Err(TiffError::UnsupportedError(
Expand All @@ -572,7 +590,7 @@ impl Image {
(type_, _) => {
return Err(TiffError::UnsupportedError(
TiffUnsupportedError::UnsupportedColorType(type_),
))
));
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,7 @@ pub enum ColorType {

/// Pixel is YCbCr
YCbCr(u8),

/// Pixel has multiple bands/channels
Multiband { bit_depth: u8, num_samples: u16 },
}
63 changes: 63 additions & 0 deletions tests/decode_geotiff_images.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
extern crate tiff;

use tiff::decoder::{Decoder, DecodingResult};
use tiff::tags::Tag;
use tiff::ColorType;

use std::fs::File;
use std::path::PathBuf;

const TEST_IMAGE_DIR: &str = "./tests/images";

#[test]
fn test_geo_tiff() {
let filenames = ["geo-5b.tif"];
for filename in filenames.iter() {
let path = PathBuf::from(TEST_IMAGE_DIR).join(filename);
let img_file = File::open(path).expect("Cannot find test image!");
let mut decoder = Decoder::new(img_file).expect("Cannot create decoder");
decoder = decoder.with_limits(tiff::decoder::Limits::unlimited());

assert_eq!(
decoder.dimensions().expect("Cannot get dimensions"),
(10, 10)
);
assert_eq!(
decoder.colortype().expect("Cannot get colortype"),
ColorType::Multiband {
bit_depth: 16,
num_samples: 5
}
);
assert_eq!(
decoder
.get_tag_u64(Tag::StripOffsets)
.expect("Cannot get StripOffsets"),
418
);
assert_eq!(
decoder
.get_tag_u64(Tag::RowsPerStrip)
.expect("Cannot get RowsPerStrip"),
10
);
assert_eq!(
decoder
.get_tag_u64(Tag::StripByteCounts)
.expect("Cannot get StripByteCounts"),
1000
);
assert_eq!(
decoder
.get_tag(Tag::ModelPixelScaleTag)
.expect("Cannot get pixel scale")
.into_f64_vec()
.expect("Cannot get pixel scale"),
vec![60.0, 60.0, 0.0]
);
let DecodingResult::I16(data) = decoder.read_image().unwrap() else {
panic!("Cannot read band data")
};
assert_eq!(data.len(), 500);
}
}
Binary file added tests/images/geo-5b.tif
Binary file not shown.

0 comments on commit 0c54a18

Please sign in to comment.