From 17db4620f2a4b228bfb83cecad124dc0215814f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Carlos=20Mour=C3=A3o=20Paes=20de=20Carvalho?= Date: Fri, 12 Mar 2021 16:31:06 -0300 Subject: [PATCH 1/3] feat: add TIFF variant for ImageOutputFormat --- src/buffer.rs | 8 +++++--- src/image.rs | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index da4788cdd9..33c02c2b96 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -948,9 +948,11 @@ where { /// Writes the buffer to a writer in the specified format. /// - /// The image format is derived from the file extension. - /// Currently only jpeg, png, ico, bmp, pnm, - /// gif, tga, farbfeld and avif formats are supported. + /// See [`ImageOutputFormat`](./enum.ImageOutputFormat.html) for + /// supported types. + /// + /// **Note**: TIFF encoding uses buffered writing, + /// which can lead to unexpected use of resources pub fn write_to(&self, writer: &mut W, format: F) -> ImageResult<()> where W: std::io::Write, diff --git a/src/image.rs b/src/image.rs index c241d66f5a..5fc96a8009 100644 --- a/src/image.rs +++ b/src/image.rs @@ -243,6 +243,10 @@ pub enum ImageOutputFormat { /// An Image in TGA Format Tga, + #[cfg(feature = "tiff")] + /// An Image in TIFF Format + Tiff, + #[cfg(feature = "avif-encoder")] /// An image in AVIF Format Avif, @@ -275,6 +279,9 @@ impl From for ImageOutputFormat { ImageFormat::Farbfeld => ImageOutputFormat::Farbfeld, #[cfg(feature = "tga")] ImageFormat::Tga => ImageOutputFormat::Tga, + #[cfg(feature = "tiff")] + ImageFormat::Tiff => ImageOutputFormat::Tiff, + #[cfg(feature = "avif-encoder")] ImageFormat::Avif => ImageOutputFormat::Avif, From aeaf0127c811dcdb267658557fb270fea7015886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Carlos=20Mour=C3=A3o=20Paes=20de=20Carvalho?= Date: Fri, 12 Mar 2021 16:52:51 -0300 Subject: [PATCH 2/3] refactor: merge DynamicImage's write_to with free_functions::write_buffer_impl --- src/dynimage.rs | 57 +--------------------------------------- src/io/free_functions.rs | 21 ++++++++++++--- 2 files changed, 19 insertions(+), 59 deletions(-) diff --git a/src/dynimage.rs b/src/dynimage.rs index b55d5d19a6..c718b6a6d6 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -3,24 +3,12 @@ use std::io::Write; use std::path::Path; use std::u32; -#[cfg(feature = "bmp")] -use crate::codecs::bmp; #[cfg(feature = "gif")] use crate::codecs::gif; -#[cfg(feature = "ico")] -use crate::codecs::ico; -#[cfg(feature = "jpeg")] -use crate::codecs::jpeg; #[cfg(feature = "png")] use crate::codecs::png; #[cfg(feature = "pnm")] use crate::codecs::pnm; -#[cfg(feature = "farbfeld")] -use crate::codecs::farbfeld; -#[cfg(feature = "tga")] -use crate::codecs::tga; -#[cfg(feature = "avif-encoder")] -use crate::codecs::avif; use crate::buffer_::{ BgrImage, BgraImage, ConvertBuffer, GrayAlphaImage, GrayAlpha16Image, @@ -32,7 +20,6 @@ use crate::error::{ImageError, ImageFormatHint, ImageResult, ParameterError, Par use crate::flat::FlatSamples; use crate::image; use crate::image::{GenericImage, GenericImageView, ImageDecoder, ImageFormat, ImageOutputFormat}; -use crate::image::ImageEncoder; use crate::io::free_functions; use crate::imageops; use crate::math::resize_dimensions; @@ -956,13 +943,6 @@ impl DynamicImage { Ok(()) } - #[cfg(feature = "jpeg")] - image::ImageOutputFormat::Jpeg(quality) => { - let j = jpeg::JpegEncoder::new_with_quality(w, quality); - j.write_image(bytes, width, height, color)?; - Ok(()) - } - #[cfg(feature = "gif")] image::ImageOutputFormat::Gif => { let mut g = gif::GifEncoder::new(w); @@ -970,42 +950,7 @@ impl DynamicImage { Ok(()) } - #[cfg(feature = "ico")] - image::ImageOutputFormat::Ico => { - let i = ico::IcoEncoder::new(w); - i.encode(bytes, width, height, color)?; - Ok(()) - } - - #[cfg(feature = "bmp")] - image::ImageOutputFormat::Bmp => { - let mut b = bmp::BmpEncoder::new(w); - b.encode(bytes, width, height, color)?; - Ok(()) - } - - #[cfg(feature = "farbfeld")] - image::ImageOutputFormat::Farbfeld => { - farbfeld::FarbfeldEncoder::new(w).write_image(bytes, width, height, color) - } - - #[cfg(feature = "tga")] - image::ImageOutputFormat::Tga => { - tga::TgaEncoder::new(w).write_image(bytes, width, height, color) - } - - #[cfg(feature = "avif-encoder")] - image::ImageOutputFormat::Avif => { - avif::AvifEncoder::new(w).write_image(bytes, width, height, color) - } - - image::ImageOutputFormat::Unsupported(msg) => { - Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind( - ImageFormatHint::Unknown, - UnsupportedErrorKind::Format(ImageFormatHint::Name(msg))))) - }, - - image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {}, + format => free_functions::write_buffer_impl(w, bytes, width, height, color, format) } } diff --git a/src/io/free_functions.rs b/src/io/free_functions.rs index 9d184ab88a..ea72599424 100644 --- a/src/io/free_functions.rs +++ b/src/io/free_functions.rs @@ -30,7 +30,7 @@ use crate::codecs::farbfeld; #[cfg(any(feature = "avif-encoder", feature = "avif-decoder"))] use crate::codecs::avif; -use crate::{ImageOutputFormat, color}; +use crate::{ImageOutputFormat, color, error::{UnsupportedError, UnsupportedErrorKind}}; use crate::image; use crate::dynimage::DynamicImage; use crate::error::{ImageError, ImageFormatHint, ImageResult}; @@ -218,10 +218,25 @@ pub(crate) fn write_buffer_impl( ImageOutputFormat::Farbfeld => farbfeld::FarbfeldEncoder::new(fout).write_image(buf, width, height, color), #[cfg(feature = "tga")] ImageOutputFormat::Tga => tga::TgaEncoder::new(fout).write_image(buf, width, height, color), + #[cfg(feature = "tiff")] + ImageOutputFormat::Tiff => { + let mut cursor = std::io::Cursor::new(Vec::new()); + tiff::TiffEncoder::new(&mut cursor).write_image(buf, width, height, color)?; + fout.write(&cursor.into_inner()[..]) + .map(|_| ()) + .map_err(ImageError::IoError) + } #[cfg(feature = "avif-encoder")] ImageOutputFormat::Avif => avif::AvifEncoder::new(fout).write_image(buf, width, height, color), - ImageOutputFormat::Unsupported(format) => Err(ImageError::Unsupported(ImageFormatHint::Name(format).into())), - format => Err(ImageError::Unsupported(ImageFormatHint::Name(format!("{:?}", format)).into())) + + image::ImageOutputFormat::Unsupported(msg) => { + Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind( + ImageFormatHint::Unknown, + UnsupportedErrorKind::Format(ImageFormatHint::Name(msg))))) + } + + image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {}, + } } From 11724d6c57e60c301c9ea58138f927967e82dd02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luiz=20Carlos=20Mour=C3=A3o=20Paes=20de=20Carvalho?= Date: Fri, 12 Mar 2021 16:58:58 -0300 Subject: [PATCH 3/3] fix: add warning about TIFF encoding --- src/buffer.rs | 2 +- src/dynimage.rs | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/buffer.rs b/src/buffer.rs index 33c02c2b96..596fe29258 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -948,7 +948,7 @@ where { /// Writes the buffer to a writer in the specified format. /// - /// See [`ImageOutputFormat`](./enum.ImageOutputFormat.html) for + /// See [`ImageOutputFormat`](../enum.ImageOutputFormat.html) for /// supported types. /// /// **Note**: TIFF encoding uses buffered writing, diff --git a/src/dynimage.rs b/src/dynimage.rs index c718b6a6d6..014f7dcdef 100644 --- a/src/dynimage.rs +++ b/src/dynimage.rs @@ -883,6 +883,8 @@ impl DynamicImage { } /// Encode this image and write it to ```w``` + /// **Note**: TIFF encoding uses buffered writing, + /// which can lead to unexpected use of resources pub fn write_to>( &self, w: &mut W, @@ -950,7 +952,7 @@ impl DynamicImage { Ok(()) } - format => free_functions::write_buffer_impl(w, bytes, width, height, color, format) + format => write_buffer_with_format(w, bytes, width, height, color, format) } } @@ -1242,8 +1244,13 @@ where /// The buffer is assumed to have the correct format according /// to the specified color type. /// This will lead to corrupted writers if the buffer contains -/// malformed data. Currently only jpeg, png, ico, bmp, -/// pnm, gif, tga, farbfeld and avif formats are supported. +/// malformed data. +/// +/// See [`ImageOutputFormat`](../enum.ImageOutputFormat.html) for +/// supported types. +/// +/// **Note**: TIFF encoding uses buffered writing, +/// which can lead to unexpected use of resources pub fn write_buffer_with_format( writer: &mut W, buf: &[u8],