Encoding of extra samples, roundtrip test
This commit is contained in:
1 parent
8517bb81db
commit
2eef9ac088
5 files changed
+59
-11
No files matched your search
+33
-3
@@ -563,9 +563,6 @@ impl<'a, W: 'a + Write + Seek, T: ColorType, K: TiffKind> ImageEncoder<'a, W, T,
|
|||||||
encoder.write_tag(Tag::Compression, compression.tag().to_u16())?;
|
encoder.write_tag(Tag::Compression, compression.tag().to_u16())?;
|
||||||
encoder.write_tag(Tag::Predictor, predictor.to_u16())?;
|
encoder.write_tag(Tag::Predictor, predictor.to_u16())?;
|
||||||
|
|
||||||
encoder.write_tag(Tag::BitsPerSample, <T>::BITS_PER_SAMPLE)?;
|
|
||||||
let sample_format: Vec<_> = <T>::SAMPLE_FORMAT.iter().map(|s| s.to_u16()).collect();
|
|
||||||
encoder.write_tag(Tag::SampleFormat, &sample_format[..])?;
|
|
||||||
encoder.write_tag(Tag::PhotometricInterpretation, <T>::TIFF_VALUE.to_u16())?;
|
encoder.write_tag(Tag::PhotometricInterpretation, <T>::TIFF_VALUE.to_u16())?;
|
||||||
|
|
||||||
encoder.write_tag(Tag::RowsPerStrip, u32::try_from(rows_per_strip)?)?;
|
encoder.write_tag(Tag::RowsPerStrip, u32::try_from(rows_per_strip)?)?;
|
||||||
@@ -754,6 +751,39 @@ impl<'a, W: 'a + Write + Seek, T: ColorType, K: TiffKind> ImageEncoder<'a, W, T,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn finish_internal(&mut self) -> TiffResult<DirectoryOffset<K>> {
|
fn finish_internal(&mut self) -> TiffResult<DirectoryOffset<K>> {
|
||||||
|
if self.extra_samples.is_empty() {
|
||||||
|
self.encoder
|
||||||
|
.write_tag(Tag::BitsPerSample, <T>::BITS_PER_SAMPLE)?;
|
||||||
|
} else {
|
||||||
|
let mut sample_format: Vec<_> = <T>::BITS_PER_SAMPLE.to_vec();
|
||||||
|
let replicated =
|
||||||
|
core::iter::repeat(<T>::BITS_PER_SAMPLE[0]).take(self.extra_samples.len());
|
||||||
|
sample_format.extend(replicated);
|
||||||
|
|
||||||
|
self.encoder
|
||||||
|
.write_tag(Tag::BitsPerSample, &sample_format[..])?;
|
||||||
|
|
||||||
|
self.encoder.write_tag(
|
||||||
|
Tag::SamplesPerPixel,
|
||||||
|
u16::try_from(<T>::BITS_PER_SAMPLE.len() + self.extra_samples.len())?,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sample_format: Vec<_> = <T>::SAMPLE_FORMAT.iter().map(|s| s.to_u16()).collect();
|
||||||
|
let extra_format = sample_format
|
||||||
|
.first()
|
||||||
|
.copied()
|
||||||
|
// Frankly should not occur, we have no sample format without at least one entry. We
|
||||||
|
// would need an interface upgrade to handle this however. Either decide to support
|
||||||
|
// heterogeneous sample formats or a way to provide fallback that is used for purely
|
||||||
|
// extra samples and not provided via a slice used for samples themselves.
|
||||||
|
.unwrap_or(SampleFormat::Void.to_u16());
|
||||||
|
|
||||||
|
sample_format.extend(core::iter::repeat(extra_format).take(self.extra_samples.len()));
|
||||||
|
|
||||||
|
self.encoder
|
||||||
|
.write_tag(Tag::SampleFormat, &sample_format[..])?;
|
||||||
|
|
||||||
self.encoder
|
self.encoder
|
||||||
.write_tag(Tag::StripOffsets, K::convert_slice(&self.strip_offsets))?;
|
.write_tag(Tag::StripOffsets, K::convert_slice(&self.strip_offsets))?;
|
||||||
self.encoder.write_tag(
|
self.encoder.write_tag(
|
||||||
|
|||||||
+25
-7
@@ -686,19 +686,37 @@ fn test_fax4_white_is_min() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extra_bits_image() {
|
fn write_extra_bits_image() {
|
||||||
use tiff::{encoder, tags::ExtraSamples};
|
use tiff::{encoder, tags::ExtraSamples};
|
||||||
|
|
||||||
let path = PathBuf::from(TEST_IMAGE_DIR).join("extra_bits_gray_4b.tiff");
|
let path = PathBuf::from(TEST_IMAGE_DIR).join("extra_bits_rgb_8b.tiff");
|
||||||
let img_file = File::create(path).expect("Cannot find test image!");
|
let img_file = File::create(path).expect("Cannot find test image!");
|
||||||
|
|
||||||
let mut encoder = encoder::TiffEncoder::new(img_file).expect("Cannot create encoder");
|
let mut encoder = encoder::TiffEncoder::new(img_file).expect("Cannot create encoder");
|
||||||
let mut img = encoder
|
let mut img = encoder.new_image::<encoder::colortype::RGB8>(8, 8).unwrap();
|
||||||
.new_image::<encoder::colortype::Gray8>(8, 8)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
img.extra_samples(&[ExtraSamples::Unspecified]).unwrap();
|
img.extra_samples(&[ExtraSamples::Unspecified]).unwrap();
|
||||||
|
|
||||||
let data: [u8; 128] = core::array::from_fn(|i| i as u8 % 2);
|
// all pixels are supposed to be 0, the extra is 1
|
||||||
img.write_data(&data).expect("correct amount of data to write");
|
let data: [u8; 256] = core::array::from_fn(|i| (i as u8 % 4).saturating_sub(2));
|
||||||
|
|
||||||
|
img.write_data(&data)
|
||||||
|
.expect("correct amount of data to write");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extra_bits_gray() {
|
||||||
|
test_image_sum_u8(
|
||||||
|
"extra_bits_gray_8b.tiff",
|
||||||
|
ColorType::Multiband {
|
||||||
|
bit_depth: 8,
|
||||||
|
num_samples: 2,
|
||||||
|
},
|
||||||
|
64,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn extra_bits_rgb() {
|
||||||
|
test_image_sum_u8("extra_bits_rgb_8b.tiff", ColorType::RGB(8), 0);
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ fn encode_decode() {
|
|||||||
),
|
),
|
||||||
(Tag::Compression, ifd::Value::Short(1)),
|
(Tag::Compression, ifd::Value::Short(1)),
|
||||||
(Tag::PhotometricInterpretation, ifd::Value::Short(2)),
|
(Tag::PhotometricInterpretation, ifd::Value::Short(2)),
|
||||||
(Tag::StripOffsets, ifd::Value::Unsigned(47)),
|
(Tag::StripOffsets, ifd::Value::Unsigned(35)),
|
||||||
(Tag::SamplesPerPixel, ifd::Value::Short(3)),
|
(Tag::SamplesPerPixel, ifd::Value::Short(3)),
|
||||||
(Tag::RowsPerStrip, ifd::Value::Unsigned(3334)),
|
(Tag::RowsPerStrip, ifd::Value::Unsigned(3334)),
|
||||||
(Tag::StripByteCounts, ifd::Value::Unsigned(30000)),
|
(Tag::StripByteCounts, ifd::Value::Unsigned(30000)),
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user