chunk_{offsets,bytes} to replace {tile,strip}_{offsets,bytes}
This commit is contained in:
1 parent
63e6ef8bba
commit
a36cd6bd90
1 file changed
+40
-69
+40
-69
@@ -235,8 +235,6 @@ impl<'a> DecodingBuffer<'a> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct StripDecodeState {
|
struct StripDecodeState {
|
||||||
strip_offsets: Vec<u64>,
|
|
||||||
strip_bytes: Vec<u64>,
|
|
||||||
rows_per_strip: u32,
|
rows_per_strip: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,13 +285,6 @@ impl TileAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
/// Stateful variables for tile decoding
|
|
||||||
struct TileDecodeState {
|
|
||||||
tile_offsets: Vec<u64>,
|
|
||||||
tile_bytes: Vec<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
/// Chunk type of the internal representation
|
/// Chunk type of the internal representation
|
||||||
pub enum ChunkType {
|
pub enum ChunkType {
|
||||||
@@ -374,8 +365,9 @@ where
|
|||||||
jpeg_tables: Option<Vec<u8>>,
|
jpeg_tables: Option<Vec<u8>>,
|
||||||
chunk_type: ChunkType,
|
chunk_type: ChunkType,
|
||||||
strip_decoder: Option<StripDecodeState>,
|
strip_decoder: Option<StripDecodeState>,
|
||||||
tile_decoder: Option<TileDecodeState>,
|
|
||||||
tile_attributes: Option<TileAttributes>,
|
tile_attributes: Option<TileAttributes>,
|
||||||
|
chunk_offsets: Vec<u64>,
|
||||||
|
chunk_bytes: Vec<u64>,
|
||||||
current_chunk: usize,
|
current_chunk: usize,
|
||||||
seen_ifds: HashSet<u64>,
|
seen_ifds: HashSet<u64>,
|
||||||
}
|
}
|
||||||
@@ -588,8 +580,9 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
predictor: Predictor::None,
|
predictor: Predictor::None,
|
||||||
chunk_type: ChunkType::Strip,
|
chunk_type: ChunkType::Strip,
|
||||||
strip_decoder: None,
|
strip_decoder: None,
|
||||||
tile_decoder: None,
|
|
||||||
tile_attributes: None,
|
tile_attributes: None,
|
||||||
|
chunk_offsets: Vec::new(),
|
||||||
|
chunk_bytes: Vec::new(),
|
||||||
current_chunk: 0,
|
current_chunk: 0,
|
||||||
seen_ifds,
|
seen_ifds,
|
||||||
};
|
};
|
||||||
@@ -663,8 +656,9 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
self.width = self.get_tag_u32(Tag::ImageWidth)?;
|
self.width = self.get_tag_u32(Tag::ImageWidth)?;
|
||||||
self.height = self.get_tag_u32(Tag::ImageLength)?;
|
self.height = self.get_tag_u32(Tag::ImageLength)?;
|
||||||
self.strip_decoder = None;
|
self.strip_decoder = None;
|
||||||
self.tile_decoder = None;
|
|
||||||
self.tile_attributes = None;
|
self.tile_attributes = None;
|
||||||
|
self.chunk_offsets.clear();
|
||||||
|
self.chunk_bytes.clear();
|
||||||
self.current_chunk = 0;
|
self.current_chunk = 0;
|
||||||
|
|
||||||
self.photometric_interpretation = self
|
self.photometric_interpretation = self
|
||||||
@@ -681,15 +675,18 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if self.compression_method == CompressionMethod::ModernJPEG {
|
if self.compression_method == CompressionMethod::ModernJPEG {
|
||||||
self.jpeg_tables = self.find_tag(Tag::JPEGTables)?.map(|_|{
|
self.jpeg_tables = self
|
||||||
let vec = self.get_tag_u8_vec(Tag::JPEGTables)?;
|
.find_tag(Tag::JPEGTables)?
|
||||||
if vec.len() < 2 {
|
.map(|_| {
|
||||||
return Err(TiffError::FormatError(
|
let vec = self.get_tag_u8_vec(Tag::JPEGTables)?;
|
||||||
TiffFormatError::InvalidTagValueType(Tag::JPEGTables),
|
if vec.len() < 2 {
|
||||||
));
|
return Err(TiffError::FormatError(
|
||||||
}
|
TiffFormatError::InvalidTagValueType(Tag::JPEGTables),
|
||||||
Ok(vec)
|
));
|
||||||
}).transpose()?;
|
}
|
||||||
|
Ok(vec)
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.samples = self.find_tag_unsigned(Tag::SamplesPerPixel)?.unwrap_or(1);
|
self.samples = self.find_tag_unsigned(Tag::SamplesPerPixel)?.unwrap_or(1);
|
||||||
@@ -740,17 +737,13 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
(true, true, false, false) => {
|
(true, true, false, false) => {
|
||||||
self.chunk_type = ChunkType::Strip;
|
self.chunk_type = ChunkType::Strip;
|
||||||
|
|
||||||
let strip_offsets = self.get_tag_u64_vec(Tag::StripOffsets)?;
|
self.chunk_offsets = self.get_tag_u64_vec(Tag::StripOffsets)?;
|
||||||
let strip_bytes = self.get_tag_u64_vec(Tag::StripByteCounts)?;
|
self.chunk_bytes = self.get_tag_u64_vec(Tag::StripByteCounts)?;
|
||||||
let rows_per_strip = self
|
let rows_per_strip = self
|
||||||
.find_tag(Tag::RowsPerStrip)?
|
.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 { rows_per_strip });
|
||||||
strip_offsets,
|
|
||||||
strip_bytes,
|
|
||||||
rows_per_strip,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
(false, false, true, true) => {
|
(false, false, true, true) => {
|
||||||
self.chunk_type = ChunkType::Tile;
|
self.chunk_type = ChunkType::Tile;
|
||||||
@@ -785,10 +778,8 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
row_samples: (tile_width * samples_per_pixel),
|
row_samples: (tile_width * samples_per_pixel),
|
||||||
tile_strip_samples,
|
tile_strip_samples,
|
||||||
});
|
});
|
||||||
self.tile_decoder = Some(TileDecodeState {
|
self.chunk_offsets = self.get_tag_u64_vec(Tag::TileOffsets)?;
|
||||||
tile_offsets: self.get_tag_u64_vec(Tag::TileOffsets)?,
|
self.chunk_bytes = self.get_tag_u64_vec(Tag::TileByteCounts)?;
|
||||||
tile_bytes: self.get_tag_u64_vec(Tag::TileByteCounts)?,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
(_, _, _, _) => {
|
(_, _, _, _) => {
|
||||||
return Err(TiffError::FormatError(
|
return Err(TiffError::FormatError(
|
||||||
@@ -987,7 +978,11 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
Some(entry) => entry.clone(),
|
Some(entry) => entry.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(entry.val(&self.limits, self.bigtiff, &mut self.reader)?))
|
Ok(Some(entry.val(
|
||||||
|
&self.limits,
|
||||||
|
self.bigtiff,
|
||||||
|
&mut self.reader,
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to retrieve a tag and convert it to the desired unsigned type.
|
/// Tries to retrieve a tag and convert it to the desired unsigned type.
|
||||||
@@ -1446,24 +1441,12 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
pub fn read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()> {
|
pub fn read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()> {
|
||||||
self.check_chunk_type(ChunkType::Strip)?;
|
self.check_chunk_type(ChunkType::Strip)?;
|
||||||
let index = self.current_chunk;
|
let index = self.current_chunk;
|
||||||
let offset = *self
|
let offset = *self.chunk_offsets.get(index).ok_or(TiffError::FormatError(
|
||||||
.strip_decoder
|
TiffFormatError::InconsistentSizesEncountered,
|
||||||
.as_ref()
|
))?;
|
||||||
.unwrap()
|
let byte_count = *self.chunk_bytes.get(index).ok_or(TiffError::FormatError(
|
||||||
.strip_offsets
|
TiffFormatError::InconsistentSizesEncountered,
|
||||||
.get(index)
|
))?;
|
||||||
.ok_or(TiffError::FormatError(
|
|
||||||
TiffFormatError::InconsistentSizesEncountered,
|
|
||||||
))?;
|
|
||||||
let byte_count = *self
|
|
||||||
.strip_decoder
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.strip_bytes
|
|
||||||
.get(index)
|
|
||||||
.ok_or(TiffError::FormatError(
|
|
||||||
TiffFormatError::InconsistentSizesEncountered,
|
|
||||||
))?;
|
|
||||||
let rows_per_strip = usize::try_from(self.strip_decoder.as_ref().unwrap().rows_per_strip)?;
|
let rows_per_strip = usize::try_from(self.strip_decoder.as_ref().unwrap().rows_per_strip)?;
|
||||||
|
|
||||||
let sized_width = usize::try_from(self.width)?;
|
let sized_width = usize::try_from(self.width)?;
|
||||||
@@ -1515,25 +1498,13 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
tile: usize,
|
tile: usize,
|
||||||
output_width: usize,
|
output_width: usize,
|
||||||
) -> TiffResult<()> {
|
) -> TiffResult<()> {
|
||||||
let file_offset = *self
|
let file_offset = *self.chunk_offsets.get(tile).ok_or(TiffError::FormatError(
|
||||||
.tile_decoder
|
TiffFormatError::InconsistentSizesEncountered,
|
||||||
.as_ref()
|
))?;
|
||||||
.unwrap()
|
|
||||||
.tile_offsets
|
|
||||||
.get(tile)
|
|
||||||
.ok_or(TiffError::FormatError(
|
|
||||||
TiffFormatError::InconsistentSizesEncountered,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let compressed_bytes = *self
|
let compressed_bytes = *self.chunk_bytes.get(tile).ok_or(TiffError::FormatError(
|
||||||
.tile_decoder
|
TiffFormatError::InconsistentSizesEncountered,
|
||||||
.as_ref()
|
))?;
|
||||||
.unwrap()
|
|
||||||
.tile_bytes
|
|
||||||
.get(tile)
|
|
||||||
.ok_or(TiffError::FormatError(
|
|
||||||
TiffFormatError::InconsistentSizesEncountered,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let tile_attrs = self.tile_attributes.as_ref().unwrap();
|
let tile_attrs = self.tile_attributes.as_ref().unwrap();
|
||||||
let tile_width = tile_attrs.tile_width;
|
let tile_width = tile_attrs.tile_width;
|
||||||
|
|||||||
Reference in new issue
Block a user