Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51ec671e3a |
+53
-1
@@ -198,6 +198,7 @@ where
|
|||||||
bigtiff: bool,
|
bigtiff: bool,
|
||||||
limits: Limits,
|
limits: Limits,
|
||||||
next_ifd: Option<u64>,
|
next_ifd: Option<u64>,
|
||||||
|
current_ifd: Option<u64>,
|
||||||
ifd: Option<Directory>,
|
ifd: Option<Directory>,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
@@ -209,6 +210,11 @@ where
|
|||||||
strip_decoder: Option<StripDecodeState>,
|
strip_decoder: Option<StripDecodeState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stores state necessary to seek back (or forward) to particular part of the tiff.
|
||||||
|
pub struct Checkpoint {
|
||||||
|
offset: u64,
|
||||||
|
}
|
||||||
|
|
||||||
trait Wrapping {
|
trait Wrapping {
|
||||||
fn wrapping_add(&self, other: Self) -> Self;
|
fn wrapping_add(&self, other: Self) -> Self;
|
||||||
}
|
}
|
||||||
@@ -313,6 +319,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
bigtiff: false,
|
bigtiff: false,
|
||||||
limits: Default::default(),
|
limits: Default::default(),
|
||||||
next_ifd: None,
|
next_ifd: None,
|
||||||
|
current_ifd: None,
|
||||||
ifd: None,
|
ifd: None,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
@@ -585,6 +592,44 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
self.reader.seek(io::SeekFrom::Start(offset)).map(|_| ())
|
self.reader.seek(io::SeekFrom::Start(offset)).map(|_| ())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve a checkpoint that allows seeking before the TIFF header.
|
||||||
|
///
|
||||||
|
/// This is a special checkpoint where the caller should call `init` after restoring the
|
||||||
|
/// checkpoint and no ifd is being read.
|
||||||
|
pub fn checkpoint_init(&self) -> Checkpoint {
|
||||||
|
Checkpoint { offset: Checkpoint::INITIAL_OFFSET }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve a `Checkpoint` that can be used to seek to the current image directory.
|
||||||
|
pub fn checkpoint(&self) -> Checkpoint {
|
||||||
|
match self.current_ifd {
|
||||||
|
None => self.checkpoint_init(),
|
||||||
|
Some(offset) => Checkpoint { offset },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the next image directory as a checkpoint.
|
||||||
|
///
|
||||||
|
/// This allows jumping forward to the next image directory later, without needing to pay the
|
||||||
|
/// additional cost of parsing it right away.
|
||||||
|
pub fn checkpoint_next(&self) -> Option<Checkpoint> {
|
||||||
|
match self.next_ifd {
|
||||||
|
None => None,
|
||||||
|
Some(offset) => Some(Checkpoint { offset })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restore the state of a previous checkpoint.
|
||||||
|
pub fn restore(&mut self, checkpoint: &Checkpoint) -> TiffResult<()> {
|
||||||
|
if checkpoint.offset == Checkpoint::INITIAL_OFFSET {
|
||||||
|
self.goto_offset_u64(0)?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
self.next_ifd = Some(checkpoint.offset);
|
||||||
|
self.next_image()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reads a IFD entry.
|
/// Reads a IFD entry.
|
||||||
// An IFD entry has four fields:
|
// An IFD entry has four fields:
|
||||||
//
|
//
|
||||||
@@ -620,7 +665,10 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
TiffFormatError::ImageFileDirectoryNotFound,
|
TiffFormatError::ImageFileDirectoryNotFound,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Some(offset) => self.goto_offset_u64(offset)?,
|
Some(offset) => {
|
||||||
|
self.goto_offset_u64(offset)?;
|
||||||
|
self.current_ifd = Some(offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let num_tags = if self.bigtiff {
|
let num_tags = if self.bigtiff {
|
||||||
self.read_long8()?
|
self.read_long8()?
|
||||||
@@ -1117,3 +1165,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Checkpoint {
|
||||||
|
const INITIAL_OFFSET: u64 = 0;
|
||||||
|
}
|
||||||
Reference in new issue
Block a user