Read predictor ahead of time

This commit is contained in:
Jonathan Behrens committed 2022-01-12 19:50:06 -05:00
1 parent dc95ce10ac
commit a19d35233a
1 file changed
+38 -44
+38 -44
View File
@@ -373,6 +373,7 @@ where
sample_format: Vec<SampleFormat>, sample_format: Vec<SampleFormat>,
photometric_interpretation: PhotometricInterpretation, photometric_interpretation: PhotometricInterpretation,
compression_method: CompressionMethod, compression_method: CompressionMethod,
predictor: Predictor,
chunk_type: ChunkType, chunk_type: ChunkType,
strip_decoder: Option<StripDecodeState>, strip_decoder: Option<StripDecodeState>,
tile_decoder: Option<TileDecodeState>, tile_decoder: Option<TileDecodeState>,
@@ -529,12 +530,8 @@ impl<R: Read + Seek> Decoder<R> {
let mut endianess = Vec::with_capacity(2); let mut endianess = Vec::with_capacity(2);
(&mut r).take(2).read_to_end(&mut endianess)?; (&mut r).take(2).read_to_end(&mut endianess)?;
let byte_order = match &*endianess { let byte_order = match &*endianess {
b"II" => { b"II" => ByteOrder::LittleEndian,
ByteOrder::LittleEndian b"MM" => ByteOrder::BigEndian,
}
b"MM" => {
ByteOrder::BigEndian
}
_ => { _ => {
return Err(TiffError::FormatError( return Err(TiffError::FormatError(
TiffFormatError::TiffSignatureNotFound, TiffFormatError::TiffSignatureNotFound,
@@ -589,6 +586,7 @@ impl<R: Read + Seek> Decoder<R> {
sample_format: vec![SampleFormat::Uint], sample_format: vec![SampleFormat::Uint],
photometric_interpretation: PhotometricInterpretation::BlackIsZero, photometric_interpretation: PhotometricInterpretation::BlackIsZero,
compression_method: CompressionMethod::None, compression_method: CompressionMethod::None,
predictor: Predictor::None,
chunk_type: ChunkType::Strip, chunk_type: ChunkType::Strip,
strip_decoder: None, strip_decoder: None,
tile_decoder: None, tile_decoder: None,
@@ -710,6 +708,15 @@ impl<R: Read + Seek> Decoder<R> {
_ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()), _ => return Err(TiffUnsupportedError::UnsupportedSampleDepth(self.samples).into()),
}; };
self.predictor = self
.find_tag_unsigned(Tag::Predictor)?
.map(|p| {
Predictor::from_u16(p)
.ok_or(TiffError::FormatError(TiffFormatError::UnknownPredictor(p)))
})
.transpose()?
.unwrap_or(Predictor::None);
let ifd = self.ifd.as_ref().unwrap(); let ifd = self.ifd.as_ref().unwrap();
match ( match (
ifd.contains_key(&Tag::StripByteCounts), ifd.contains_key(&Tag::StripByteCounts),
@@ -722,7 +729,8 @@ impl<R: Read + Seek> Decoder<R> {
let strip_offsets = self.get_tag_u64_vec(Tag::StripOffsets)?; let strip_offsets = self.get_tag_u64_vec(Tag::StripOffsets)?;
let strip_bytes = self.get_tag_u64_vec(Tag::StripByteCounts)?; let strip_bytes = self.get_tag_u64_vec(Tag::StripByteCounts)?;
let rows_per_strip = self.find_tag(Tag::RowsPerStrip)? let rows_per_strip = self
.find_tag(Tag::RowsPerStrip)?
.unwrap_or(ifd::Value::Unsigned(self.height)) .unwrap_or(ifd::Value::Unsigned(self.height))
.into_u32()?; .into_u32()?;
self.strip_decoder = Some(StripDecodeState { self.strip_decoder = Some(StripDecodeState {
@@ -1495,24 +1503,17 @@ impl<R: Read + Seek> Decoder<R> {
if u32::try_from(index)? == self.strip_count()? { if u32::try_from(index)? == self.strip_count()? {
self.strip_decoder = None; self.strip_decoder = None;
} }
if let Ok(predictor) = self.get_tag_unsigned(Tag::Predictor) { match self.predictor {
match Predictor::from_u16(predictor) { Predictor::None => {}
Some(Predictor::None) => (), Predictor::Horizontal => {
Some(Predictor::Horizontal) => { rev_hpredict(
rev_hpredict( buffer.copy(),
buffer.copy(), (self.width, u32::try_from(strip_height)?),
(self.width, u32::try_from(strip_height)?), usize::try_from(self.width)?,
usize::try_from(self.width)?, self.colortype()?,
self.colortype()?, )?;
)?;
}
None => {
return Err(TiffError::FormatError(TiffFormatError::UnknownPredictor(
predictor,
)))
}
Some(Predictor::__NonExhaustive) => unreachable!(),
} }
Predictor::__NonExhaustive => unreachable!(),
} }
Ok(()) Ok(())
} }
@@ -1557,27 +1558,20 @@ impl<R: Read + Seek> Decoder<R> {
output_width, output_width,
)?; )?;
if let Ok(predictor) = self.get_tag_unsigned(Tag::Predictor) { match self.predictor {
match Predictor::from_u16(predictor) { Predictor::None => {}
Some(Predictor::None) => (), Predictor::Horizontal => {
Some(Predictor::Horizontal) => { rev_hpredict(
rev_hpredict( result.copy(),
result.copy(), (
( u32::try_from(tile_width - padding_right)?,
u32::try_from(tile_width - padding_right)?, u32::try_from(tile_length - padding_down)?,
u32::try_from(tile_length - padding_down)?, ),
), output_width,
output_width, self.colortype()?,
self.colortype()?, )?;
)?;
}
None => {
return Err(TiffError::FormatError(TiffFormatError::UnknownPredictor(
predictor,
)))
}
Some(Predictor::__NonExhaustive) => unreachable!(),
} }
Predictor::__NonExhaustive => unreachable!(),
} }
Ok(()) Ok(())
} }