Struct Decoder

pub struct Decoder<R>
where
    R: Read + Seek, { /* private fields */ }

The representation of a TIFF decoder

Currently does not support decoding of interlaced images

Implementations

impl<R: Read + Seek> Decoder<R>

fn new(r: R) -> TiffResult<Decoder<R>>
fn with_limits(self, limits: Limits) -> Decoder<R>
fn dimensions(&mut self) -> TiffResult<(u32, u32)>
fn colortype(&mut self) -> TiffResult<ColorType>
fn ifd_pointer(&mut self) -> Option<IfdPointer>

The offset of the directory representing the current image.

fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()>

Loads the IFD at the specified index in the list, if one exists

fn next_image(&mut self) -> TiffResult<()>

Reads in the next image. If there is no further image in the TIFF file a format error is returned. To determine whether there are more images call TIFFDecoder::more_images instead.

fn more_images(&self) -> bool

Returns true if there is at least one more image available.

fn byte_order(&self) -> ByteOrder

Returns the byte_order of the file.

Usage

This is only relevant to interpreting raw bytes read from tags. The image decoding methods will correct to the host byte order automatically.

fn read_ifd_offset(&mut self) -> Result<u64, Error>
fn inner(&mut self) -> &mut R

Returns a mutable reference to the stream being decoded.

fn read_byte(&mut self) -> Result<u8, Error>

Reads a TIFF byte value

fn read_short(&mut self) -> Result<u16, Error>

Reads a TIFF short value

fn read_sshort(&mut self) -> Result<i16, Error>

Reads a TIFF sshort value

fn read_long(&mut self) -> Result<u32, Error>

Reads a TIFF long value

fn read_slong(&mut self) -> Result<i32, Error>

Reads a TIFF slong value

fn read_float(&mut self) -> Result<f32, Error>

Reads a TIFF float value

fn read_double(&mut self) -> Result<f64, Error>

Reads a TIFF double value

fn read_long8(&mut self) -> Result<u64, Error>
fn read_slong8(&mut self) -> Result<i64, Error>
fn read_string(&mut self, length: usize) -> TiffResult<String>

Reads a string

fn read_offset(&mut self) -> TiffResult<[u8; 4]>

Reads a TIFF IFA offset/value field

fn read_offset_u64(&mut self) -> Result<[u8; 8], Error>

Reads a TIFF IFA offset/value field

fn goto_offset(&mut self, offset: u32) -> Result<()>

Moves the cursor to the specified offset

fn goto_offset_u64(&mut self, offset: u64) -> Result<()>
fn read_directory(&mut self, ptr: IfdPointer) -> TiffResult<Directory>

Read a tag-entry map from a known offset.

A TIFF Directory, aka. image file directory aka. IFD, refers to a map from tags–identified by a u16–to a typed vector of elements. It is encoded as a list of ascending tag values with the offset and type of their corresponding values. The semantic interpretations of a tag and its type requirements depend on the context of the directory. The main image directories, those iterated over by the Decoder after construction, are represented by Tag and ifd::Value. Other forms are EXIF and GPS data as well as thumbnail Sub-IFD representations associated with each image file.

This method allows the decoding of a directory from an arbitrary offset in the image file with no specific semantic interpretation. Such an offset is usually found as the value of a tag, e.g. Tag::SubIfd, Tag::ExifDirectory, Tag::GpsDirectory and recovered from the associated value by ifd::Value::into_ifd_pointer.

The library will not verify whether the offset overlaps any other directory or would form a cycle with any other directory when calling this method. This will modify the position of the reader, i.e. continuing with direct reads at a later point will require going back with Self::goto_offset.

fn get_chunk_type(&self) -> ChunkType

The chunk type (Strips / Tiles) of the image

fn strip_count(&mut self) -> TiffResult<u32>

Number of strips in image

fn tile_count(&mut self) -> TiffResult<u32>

Number of tiles in image

fn image_chunk_buffer_layout(&mut self, chunk_index: u32) -> TiffResult<BufferLayoutPreference>

Returns the layout preferred to read the specified chunk with Self::read_chunk_bytes.

Returns the layout without being specific as to the underlying type for forward compatibility. Note that, in general, a TIFF may contain an almost arbitrary number of channels of individual bit length and format each.

See Self::colortype to describe the sample types.

fn image_coding_unit_layout(&mut self, code_unit: TiffCodingUnit) -> TiffResult<BufferLayoutPreference>

Return the layout preferred to read several planes corresponding to the specified region.

This is similar to Self::image_chunk_buffer_layout but can read chunks from all planes at the corresponding coordinates of the image.

Bugs

Sub-sampled images are not yet supported properly.

fn read_chunk(&mut self, chunk_index: u32) -> TiffResult<DecodingResult>

Read the specified chunk (at index chunk_index) and return the binary data as a Vector.

Note that for planar images each chunk contains only one sample of the underlying data.

fn read_chunk_bytes(&mut self, chunk_index: u32, buffer: &mut [u8]) -> TiffResult<()>

Read the specified chunk (at index chunk_index) into an allocated buffer.

Returns a TiffError::UsageError if the chunk is smaller than the size indicated with a call to Self::image_chunk_buffer_layout. Note that the alignment may be arbitrary, but an alignment smaller than the preferred alignment may perform worse.

Note that for planar images each chunk contains only one sample of the underlying data.

fn read_chunk_to_buffer(&mut self, buffer: &mut DecodingResult, chunk_index: u32, output_width: usize) -> TiffResult<()>

Read the specified chunk (at index chunk_index) into a provide buffer.

It will re-allocate the buffer into the correct type and size, within the decoder's configured limits, and then pass it to the underlying method. This is essentially a type-safe wrapper around the raw Self::read_chunk_bytes method.

Note that for planar images each chunk contains only one sample of the underlying data.

fn read_coding_unit_bytes(&mut self, slice: TiffCodingUnit, buffer: &mut [u8]) -> TiffResult<()>

Read chunks corresponding to several planes of a region of pixels.

For non planar images this is equivalent to Self::read_chunk_bytes as there is only one plane in the image. For planar images the planes are stored consecutively into the output buffer. Returns an error if not enough space for at least one plane is provided. Otherwise reads all planes that can be stored completely in the provided output buffer.

A region is a rectangular assortment of pixels in the image, depending on the chunk type either strips or tiles. Borrowing terminology from JPEG we call the collection of all chunks from all planes that encode samples from the same region a "coding unit".

Bugs

Sub-sampled images are not yet supported properly.

fn chunk_dimensions(&self) -> (u32, u32)

Returns the default chunk size for the current image. Any given chunk in the image is at most as large as the value returned here. For the size of the data (chunk minus padding), use chunk_data_dimensions.

fn chunk_data_dimensions(&self, chunk_index: u32) -> (u32, u32)

Returns the size of the data in the chunk with the specified index. This is the default size of the chunk, minus any padding.

fn image_buffer_layout(&mut self) -> TiffResult<BufferLayoutPreference>

Returns the preferred buffer required to read the whole image with Self::read_image_bytes.

Returns the layout without being specific as to the underlying type for forward compatibility. Note that, in general, a TIFF may contain an almost arbitrary number of channels of individual bit length and format each.

See Self::colortype to describe the sample types.

Bugs

When the image is stored as a planar configuration, this method will currently only indicate the layout needed to read the first data plane. This will be fixed in a future major version of tiff.

fn read_image(&mut self) -> TiffResult<DecodingResult>

Decodes the entire image and return it as a Vector

Examples

This method is deprecated. For replacement usage see examples/decode.rs.

Bugs

When the image is stored as a planar configuration, this method will currently only read the first sample's plane. This will be fixed in a future major version of tiff. To read multiple planes, Self::read_image_to_buffer can be used instead.

Intent to deprecate

Use Self::read_image_to_buffer or a combination of DecodingResult::resize_to and Self::read_image_bytes instead where possible, preserving the buffer across multiple calls. This old method will likely keep its bugged planar behavior until it is fully replaced, to ensure that existing code will not run into unexpectedly large allocations that will error on limits instead.

fn read_image_to_buffer(&mut self, result: &mut DecodingResult) -> TiffResult<BufferLayoutPreference>

Decodes the entire image into a provided buffer.

It will re-allocate the buffer into the correct type and size, within the decoder's configured limits, and then pass it to the underlying method. This is essentially a type-safe wrapper around the raw Self::read_image_bytes method.

Planar behavior

If the image is stored as a planar configuration, an attempt is made to resize the buffer to hold all planes. If that does not fit then only the first plane is read. Check the buffer size against BufferLayoutPreference::complete_len to ensure that all planes were read:

use tiff::decoder::{Decoder, DecodingResult};
let mut result = DecodingResult::U8(vec![]);

let mut reader = /* */
# Decoder::new(std::io::Cursor::new(include_bytes!(concat!(
#   env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif"
# )))).unwrap();
let layout = reader.read_image_to_buffer(&mut result)?;

if result.as_buffer(0).as_bytes().len() < layout.complete_len {
   println!("Only the first plane was read");
}

# Ok::<_, tiff::TiffError>(())

Examples

use tiff::decoder::{Decoder, DecodingResult, Limits};

let mut result = DecodingResult::I8(vec![]);

let mut reader = /* */
# Decoder::new(std::io::Cursor::new(include_bytes!(concat!(
#   env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif"
# )))).unwrap();

reader.read_image_to_buffer(&mut result)?;

# Ok::<_, tiff::TiffError>(())
fn read_image_bytes(&mut self, buffer: &mut [u8]) -> TiffResult<()>

Decodes the entire image into a provided buffer.

Returns a TiffError::UsageError if the chunk is smaller than the size indicated with a call to Self::image_buffer_layout. Note that the alignment may be arbitrary, but an alignment smaller than the preferred alignment may perform worse.

Error

Returns an error if the buffer fits less than one plane. In particular, for non-planar images returns an error if the buffer does not fit the required size.

fn image_ifd(&mut self) -> IfdDecoder<'_>

Get the IFD decoder for our current image IFD.

fn read_directory_tags<'ifd>(&'ifd mut self, ifd: &'ifd Directory) -> IfdDecoder<'ifd>

Prepare reading values for tags of a given directory.

Examples

This method may be used to read the values of tags in directories that have been previously read with Decoder::read_directory.

use tiff::decoder::Decoder;
use tiff::tags::Tag;

# use std::io::Cursor;
# let mut data = Cursor::new(vec![0]);
let mut decoder = Decoder::new(&mut data).unwrap();
let sub_ifds = decoder.get_tag(Tag::SubIfd)?.into_ifd_vec()?;

for ifd in sub_ifds {
    let subdir = decoder.read_directory(ifd)?;
    let subfile = decoder.read_directory_tags(&subdir).find_tag(Tag::SubfileType)?;
    // omitted: handle the subfiles, e.g. thumbnails
}

# Ok::<_, tiff::TiffError>(())
fn find_tag(&mut self, tag: Tag) -> TiffResult<Option<Value>>

Tries to retrieve a tag from the current image directory. Return Ok(None) if the tag is not present.

fn find_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<T>>

Tries to retrieve a tag in the current image directory and convert it to the desired unsigned type.

fn find_tag_unsigned_vec<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<Option<Vec<T>>>

Tries to retrieve a vector of all a tag's values and convert them to the desired unsigned type.

fn get_tag_unsigned<T: TryFrom<u64>>(&mut self, tag: Tag) -> TiffResult<T>

Tries to retrieve a tag from the current image directory and convert it to the desired unsigned type. Returns an error if the tag is not present.

fn get_tag(&mut self, tag: Tag) -> TiffResult<Value>

Tries to retrieve a tag from the current image directory. Returns an error if the tag is not present

fn get_tag_u32(&mut self, tag: Tag) -> TiffResult<u32>
fn get_tag_u64(&mut self, tag: Tag) -> TiffResult<u64>
fn get_tag_f32(&mut self, tag: Tag) -> TiffResult<f32>

Tries to retrieve a tag and convert it to the desired type.

fn get_tag_f64(&mut self, tag: Tag) -> TiffResult<f64>

Tries to retrieve a tag and convert it to the desired type.

fn get_tag_u32_vec(&mut self, tag: Tag) -> TiffResult<Vec<u32>>

Tries to retrieve a tag and convert it to the desired type.

fn get_tag_u16_vec(&mut self, tag: Tag) -> TiffResult<Vec<u16>>
fn get_tag_u64_vec(&mut self, tag: Tag) -> TiffResult<Vec<u64>>
fn get_tag_f32_vec(&mut self, tag: Tag) -> TiffResult<Vec<f32>>

Tries to retrieve a tag and convert it to the desired type.

fn get_tag_f64_vec(&mut self, tag: Tag) -> TiffResult<Vec<f64>>

Tries to retrieve a tag and convert it to the desired type.

fn get_tag_u8_vec(&mut self, tag: Tag) -> TiffResult<Vec<u8>>

Tries to retrieve a tag and convert it to a 8bit vector.

fn get_tag_ascii_string(&mut self, tag: Tag) -> TiffResult<String>

Tries to retrieve a tag and convert it to a ascii vector.

fn tag_iter(&mut self) -> impl Iterator<Item = TiffResult<(Tag, Value)>> + '_

Trait Implementations

impl<R> Debug for Decoder<R> where R: Read + Seek + Debug,

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Auto Trait Implementations

impl<R> Freeze for Decoder<R> where ValueReader<R>: Freeze,

impl<R> RefUnwindSafe for Decoder<R> where ValueReader<R>: RefUnwindSafe,

impl<R> Send for Decoder<R> where ValueReader<R>: Send,

impl<R> Sync for Decoder<R> where ValueReader<R>: Sync,

impl<R> Unpin for Decoder<R> where ValueReader<R>: Unpin,

impl<R> UnsafeUnpin for Decoder<R> where ValueReader<R>: UnsafeUnpin,

impl<R> UnwindSafe for Decoder<R> where ValueReader<R>: UnwindSafe,

Blanket Implementations

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for Decoder<R> where ST: ?Sized, DT: ?Sized,

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for Decoder<R> where ST: ?Sized, DT: ?Sized,

impl<T> Any for Decoder<R> where T: 'static + ?Sized,

fn type_id(&self) -> TypeId

impl<T> Borrow<T> for Decoder<R> where T: ?Sized,

fn borrow(&self) -> &T

impl<T> BorrowMut<T> for Decoder<R> where T: ?Sized,

fn borrow_mut(&mut self) -> &mut T

impl<T> From<T> for Decoder<R>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> Read<Exclusive, BecauseExclusive> for Decoder<R> where T: ?Sized,

impl<T, U> Into<U> for Decoder<R> where U: From<T>,

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom<U> for Decoder<R> where U: Into<T>,

type Error = never;
fn try_from(value: U) -> Result<T, never>

impl<T, U> TryInto<U> for Decoder<R> where U: TryFrom<T>,

type Error = <U as TryFrom<T>>::Error;
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>