Add ColorType::Multiband enum variant to support samples>1 per pixel (#224)
Co-authored-by: tromper <scott@hopkinsunderground.com>
This commit is contained in:
1 parent
90ae5b8e54
commit
0c54a18e21
4 files changed
+94
-10
No files matched your search
+28
-10
@@ -346,14 +346,19 @@ impl Image {
|
|||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero
|
PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero => {
|
||||||
if self.samples == 1 =>
|
match self.samples {
|
||||||
{
|
1 => Ok(ColorType::Gray(self.bits_per_sample)),
|
||||||
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
|
// 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(
|
TiffUnsupportedError::InterpretationWithBits(
|
||||||
self.photometric_interpretation,
|
self.photometric_interpretation,
|
||||||
vec![self.bits_per_sample; self.samples as usize],
|
vec![self.bits_per_sample; self.samples as usize],
|
||||||
@@ -555,13 +560,26 @@ impl Image {
|
|||||||
| (ColorType::CMYK(n), _)
|
| (ColorType::CMYK(n), _)
|
||||||
| (ColorType::YCbCr(n), _)
|
| (ColorType::YCbCr(n), _)
|
||||||
| (ColorType::Gray(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::None => {}
|
||||||
Predictor::Horizontal => {
|
Predictor::Horizontal => {
|
||||||
return Err(TiffError::UnsupportedError(
|
return Err(TiffError::UnsupportedError(
|
||||||
TiffUnsupportedError::HorizontalPredictor(color_type),
|
TiffUnsupportedError::HorizontalPredictor(color_type),
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
Predictor::FloatingPoint => {
|
Predictor::FloatingPoint => {
|
||||||
return Err(TiffError::UnsupportedError(
|
return Err(TiffError::UnsupportedError(
|
||||||
@@ -572,7 +590,7 @@ impl Image {
|
|||||||
(type_, _) => {
|
(type_, _) => {
|
||||||
return Err(TiffError::UnsupportedError(
|
return Err(TiffError::UnsupportedError(
|
||||||
TiffUnsupportedError::UnsupportedColorType(type_),
|
TiffUnsupportedError::UnsupportedColorType(type_),
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,4 +40,7 @@ pub enum ColorType {
|
|||||||
|
|
||||||
/// Pixel is YCbCr
|
/// Pixel is YCbCr
|
||||||
YCbCr(u8),
|
YCbCr(u8),
|
||||||
|
|
||||||
|
/// Pixel has multiple bands/channels
|
||||||
|
Multiband { bit_depth: u8, num_samples: u16 },
|
||||||
}
|
}
|
||||||
@@ -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 not shown.
Reference in new issue
Block a user