Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TIFF variant to ImageOutputFormat #1453

Merged
merged 3 commits into from
Mar 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<W, F>(&self, writer: &mut W, format: F) -> ImageResult<()>
where
W: std::io::Write,
Expand Down
68 changes: 10 additions & 58 deletions src/dynimage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -896,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<W: Write, F: Into<ImageOutputFormat>>(
&self,
w: &mut W,
Expand Down Expand Up @@ -956,56 +945,14 @@ 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);
g.encode_frame(crate::animation::Frame::new(self.to_rgba()))?;
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 => write_buffer_with_format(w, bytes, width, height, color, format)
}
}

Expand Down Expand Up @@ -1297,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<W, F>(
writer: &mut W,
buf: &[u8],
Expand Down
7 changes: 7 additions & 0 deletions src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -275,6 +279,9 @@ impl From<ImageFormat> 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,

Expand Down
21 changes: 18 additions & 3 deletions src/io/free_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -218,10 +218,25 @@ pub(crate) fn write_buffer_impl<W: std::io::Write>(
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) => {
Copy link
Contributor

@fintelia fintelia Mar 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really not sure why Unsupported is a variant of ImageOutputFormat. Though that doesn't really impact this PR

Err(ImageError::Unsupported(UnsupportedError::from_format_and_kind(
ImageFormatHint::Unknown,
UnsupportedErrorKind::Format(ImageFormatHint::Name(msg)))))
}

image::ImageOutputFormat::__NonExhaustive(marker) => match marker._private {},

}
}

Expand Down