Read predictor ahead of time
This commit is contained in:
1 parent
dc95ce10ac
commit
a19d35233a
1 file changed
+38
-44
+38
-44
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user