diff options
Diffstat (limited to 'vendor/image/src/io/reader.rs')
-rw-r--r-- | vendor/image/src/io/reader.rs | 239 |
1 files changed, 0 insertions, 239 deletions
diff --git a/vendor/image/src/io/reader.rs b/vendor/image/src/io/reader.rs deleted file mode 100644 index 660780f..0000000 --- a/vendor/image/src/io/reader.rs +++ /dev/null @@ -1,239 +0,0 @@ -use std::fs::File; -use std::io::{self, BufRead, BufReader, Cursor, Read, Seek, SeekFrom}; -use std::path::Path; - -use crate::dynimage::DynamicImage; -use crate::error::{ImageFormatHint, UnsupportedError, UnsupportedErrorKind}; -use crate::image::ImageFormat; -use crate::{ImageError, ImageResult}; - -use super::free_functions; - -/// A multi-format image reader. -/// -/// Wraps an input reader to facilitate automatic detection of an image's format, appropriate -/// decoding method, and dispatches into the set of supported [`ImageDecoder`] implementations. -/// -/// ## Usage -/// -/// Opening a file, deducing the format based on the file path automatically, and trying to decode -/// the image contained can be performed by constructing the reader and immediately consuming it. -/// -/// ```no_run -/// # use image::ImageError; -/// # use image::io::Reader; -/// # fn main() -> Result<(), ImageError> { -/// let image = Reader::open("path/to/image.png")? -/// .decode()?; -/// # Ok(()) } -/// ``` -/// -/// It is also possible to make a guess based on the content. This is especially handy if the -/// source is some blob in memory and you have constructed the reader in another way. Here is an -/// example with a `pnm` black-and-white subformat that encodes its pixel matrix with ascii values. -/// -/// ``` -/// # use image::ImageError; -/// # use image::io::Reader; -/// # fn main() -> Result<(), ImageError> { -/// use std::io::Cursor; -/// use image::ImageFormat; -/// -/// let raw_data = b"P1 2 2\n\ -/// 0 1\n\ -/// 1 0\n"; -/// -/// let mut reader = Reader::new(Cursor::new(raw_data)) -/// .with_guessed_format() -/// .expect("Cursor io never fails"); -/// assert_eq!(reader.format(), Some(ImageFormat::Pnm)); -/// -/// # #[cfg(feature = "pnm")] -/// let image = reader.decode()?; -/// # Ok(()) } -/// ``` -/// -/// As a final fallback or if only a specific format must be used, the reader always allows manual -/// specification of the supposed image format with [`set_format`]. -/// -/// [`set_format`]: #method.set_format -/// [`ImageDecoder`]: ../trait.ImageDecoder.html -pub struct Reader<R: Read> { - /// The reader. Should be buffered. - inner: R, - /// The format, if one has been set or deduced. - format: Option<ImageFormat>, - /// Decoding limits - limits: super::Limits, -} - -impl<R: Read> Reader<R> { - /// Create a new image reader without a preset format. - /// - /// Assumes the reader is already buffered. For optimal performance, - /// consider wrapping the reader with a `BufReader::new()`. - /// - /// It is possible to guess the format based on the content of the read object with - /// [`with_guessed_format`], or to set the format directly with [`set_format`]. - /// - /// [`with_guessed_format`]: #method.with_guessed_format - /// [`set_format`]: method.set_format - pub fn new(buffered_reader: R) -> Self { - Reader { - inner: buffered_reader, - format: None, - limits: super::Limits::default(), - } - } - - /// Construct a reader with specified format. - /// - /// Assumes the reader is already buffered. For optimal performance, - /// consider wrapping the reader with a `BufReader::new()`. - pub fn with_format(buffered_reader: R, format: ImageFormat) -> Self { - Reader { - inner: buffered_reader, - format: Some(format), - limits: super::Limits::default(), - } - } - - /// Get the currently determined format. - pub fn format(&self) -> Option<ImageFormat> { - self.format - } - - /// Supply the format as which to interpret the read image. - pub fn set_format(&mut self, format: ImageFormat) { - self.format = Some(format); - } - - /// Remove the current information on the image format. - /// - /// Note that many operations require format information to be present and will return e.g. an - /// `ImageError::Unsupported` when the image format has not been set. - pub fn clear_format(&mut self) { - self.format = None; - } - - /// Disable all decoding limits. - pub fn no_limits(&mut self) { - self.limits = super::Limits::no_limits(); - } - - /// Set a custom set of decoding limits. - pub fn limits(&mut self, limits: super::Limits) { - self.limits = limits; - } - - /// Unwrap the reader. - pub fn into_inner(self) -> R { - self.inner - } -} - -impl Reader<BufReader<File>> { - /// Open a file to read, format will be guessed from path. - /// - /// This will not attempt any io operation on the opened file. - /// - /// If you want to inspect the content for a better guess on the format, which does not depend - /// on file extensions, follow this call with a call to [`with_guessed_format`]. - /// - /// [`with_guessed_format`]: #method.with_guessed_format - pub fn open<P>(path: P) -> io::Result<Self> - where - P: AsRef<Path>, - { - Self::open_impl(path.as_ref()) - } - - fn open_impl(path: &Path) -> io::Result<Self> { - Ok(Reader { - inner: BufReader::new(File::open(path)?), - format: ImageFormat::from_path(path).ok(), - limits: super::Limits::default(), - }) - } -} - -impl<R: BufRead + Seek> Reader<R> { - /// Make a format guess based on the content, replacing it on success. - /// - /// Returns `Ok` with the guess if no io error occurs. Additionally, replaces the current - /// format if the guess was successful. If the guess was unable to determine a format then - /// the current format of the reader is unchanged. - /// - /// Returns an error if the underlying reader fails. The format is unchanged. The error is a - /// `std::io::Error` and not `ImageError` since the only error case is an error when the - /// underlying reader seeks. - /// - /// When an error occurs, the reader may not have been properly reset and it is potentially - /// hazardous to continue with more io. - /// - /// ## Usage - /// - /// This supplements the path based type deduction from [`open`](Reader::open) with content based deduction. - /// This is more common in Linux and UNIX operating systems and also helpful if the path can - /// not be directly controlled. - /// - /// ```no_run - /// # use image::ImageError; - /// # use image::io::Reader; - /// # fn main() -> Result<(), ImageError> { - /// let image = Reader::open("image.unknown")? - /// .with_guessed_format()? - /// .decode()?; - /// # Ok(()) } - /// ``` - pub fn with_guessed_format(mut self) -> io::Result<Self> { - let format = self.guess_format()?; - // Replace format if found, keep current state if not. - self.format = format.or(self.format); - Ok(self) - } - - fn guess_format(&mut self) -> io::Result<Option<ImageFormat>> { - let mut start = [0; 16]; - - // Save current offset, read start, restore offset. - let cur = self.inner.stream_position()?; - let len = io::copy( - // Accept shorter files but read at most 16 bytes. - &mut self.inner.by_ref().take(16), - &mut Cursor::new(&mut start[..]), - )?; - self.inner.seek(SeekFrom::Start(cur))?; - - Ok(free_functions::guess_format_impl(&start[..len as usize])) - } - - /// Read the image dimensions. - /// - /// Uses the current format to construct the correct reader for the format. - /// - /// If no format was determined, returns an `ImageError::Unsupported`. - pub fn into_dimensions(mut self) -> ImageResult<(u32, u32)> { - let format = self.require_format()?; - free_functions::image_dimensions_with_format_impl(self.inner, format) - } - - /// Read the image (replaces `load`). - /// - /// Uses the current format to construct the correct reader for the format. - /// - /// If no format was determined, returns an `ImageError::Unsupported`. - pub fn decode(mut self) -> ImageResult<DynamicImage> { - let format = self.require_format()?; - free_functions::load_inner(self.inner, self.limits, format) - } - - fn require_format(&mut self) -> ImageResult<ImageFormat> { - self.format.ok_or_else(|| { - ImageError::Unsupported(UnsupportedError::from_format_and_kind( - ImageFormatHint::Unknown, - UnsupportedErrorKind::Format(ImageFormatHint::Unknown), - )) - }) - } -} |