diff --git a/src/image.rs b/src/image.rs index 228dfad3fa..2dc928d338 100644 --- a/src/image.rs +++ b/src/image.rs @@ -8,7 +8,7 @@ use std::usize; use crate::ImageBuffer; use crate::color::{ColorType, ExtendedColorType}; -use crate::error::{ImageError, ImageResult, LimitError, LimitErrorKind, ParameterError, ParameterErrorKind}; +use crate::error::{ImageError, ImageFormatHint, ImageResult, LimitError, LimitErrorKind, ParameterError, ParameterErrorKind}; use crate::math::Rect; use crate::traits::Pixel; @@ -65,11 +65,46 @@ pub enum ImageFormat { } impl ImageFormat { + /// Return the image format specified by a path's file extension. + pub fn from_extension(ext: &str) -> Option { + let ext = ext.to_ascii_lowercase(); + + Some(match ext.as_str() { + "jpg" | "jpeg" => ImageFormat::Jpeg, + "png" => ImageFormat::Png, + "gif" => ImageFormat::Gif, + "webp" => ImageFormat::WebP, + "tif" | "tiff" => ImageFormat::Tiff, + "tga" => ImageFormat::Tga, + "dds" => ImageFormat::Dds, + "bmp" => ImageFormat::Bmp, + "ico" => ImageFormat::Ico, + "hdr" => ImageFormat::Hdr, + "pbm" | "pam" | "ppm" | "pgm" => ImageFormat::Pnm, + "ff" | "farbfeld" => ImageFormat::Farbfeld, + _ => return None, + }) + } + /// Return the image format specified by the path's file extension. + #[inline] pub fn from_path

(path: P) -> ImageResult where P : AsRef { - // thin wrapper function to strip generics before calling from_path_impl - crate::io::free_functions::guess_format_from_path_impl(path.as_ref()) - .map_err(Into::into) + // thin wrapper function to strip generics + fn inner(path: &Path) -> ImageResult { + let exact_ext = path.extension(); + exact_ext + .and_then(|s| s.to_str()) + .and_then(|ext| ImageFormat::from_extension(ext)) + .ok_or_else(|| { + let format_hint = match exact_ext { + None => ImageFormatHint::Unknown, + Some(os) => ImageFormatHint::PathExtension(os.into()), + }; + ImageError::Unsupported(format_hint.into()) + }) + } + + inner(path.as_ref()) } /// Return a list of applicable extensions for this format. diff --git a/src/io/free_functions.rs b/src/io/free_functions.rs index a34d88484a..95c8e3fdaf 100644 --- a/src/io/free_functions.rs +++ b/src/io/free_functions.rs @@ -1,4 +1,3 @@ -use std::ffi::OsString; use std::fs::File; use std::io::{BufRead, BufReader, BufWriter, Seek}; use std::path::Path; @@ -39,14 +38,6 @@ use crate::image::ImageFormat; #[allow(unused_imports)] // When no features are supported use crate::image::{ImageDecoder, ImageEncoder}; -/// Internal error type for guessing format from path. -pub(crate) enum PathError { - /// The extension did not fit a supported format. - UnknownExtension(OsString), - /// Extension could not be converted to `str`. - NoExtension, -} - pub(crate) fn open_impl(path: &Path) -> ImageResult { let fin = match File::open(path) { Ok(f) => f, @@ -224,37 +215,6 @@ pub(crate) fn save_buffer_with_format_impl( } } -/// Guess format from a path. -/// -/// Returns `PathError::NoExtension` if the path has no extension or returns a -/// `PathError::UnknownExtension` containing the extension if it can not be convert to a `str`. -pub(crate) fn guess_format_from_path_impl(path: &Path) -> Result { - let exact_ext = path.extension(); - let ext = exact_ext - .and_then(|s| s.to_str()) - .map_or("".to_string(), |s| s.to_ascii_lowercase()); - - Ok(match ext.as_str() { - "jpg" | "jpeg" => image::ImageFormat::Jpeg, - "png" => image::ImageFormat::Png, - "gif" => image::ImageFormat::Gif, - "webp" => image::ImageFormat::WebP, - "tif" | "tiff" => image::ImageFormat::Tiff, - "tga" => image::ImageFormat::Tga, - "dds" => image::ImageFormat::Dds, - "bmp" => image::ImageFormat::Bmp, - "ico" => image::ImageFormat::Ico, - "hdr" => image::ImageFormat::Hdr, - "pbm" | "pam" | "ppm" | "pgm" => image::ImageFormat::Pnm, - "ff" | "farbfeld" => image::ImageFormat::Farbfeld, - // The original extension is used, instead of _format - _ => return match exact_ext { - None => Err(PathError::NoExtension), - Some(os) => Err(PathError::UnknownExtension(os.to_owned())), - }, - }) -} - static MAGIC_BYTES: [(&[u8], ImageFormat); 19] = [ (b"\x89PNG\r\n\x1a\n", ImageFormat::Png), (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg), @@ -298,13 +258,3 @@ pub(crate) fn guess_format_impl(buffer: &[u8]) -> Option { None } - -impl From for ImageError { - fn from(path: PathError) -> Self { - let format_hint = match path { - PathError::NoExtension => ImageFormatHint::Unknown, - PathError::UnknownExtension(ext) => ImageFormatHint::PathExtension(ext.into()), - }; - ImageError::Unsupported(format_hint.into()) - } -}