Skip to content

Commit

Permalink
Fix adding support for AVIF through the image crate
Browse files Browse the repository at this point in the history
This is a bit of a hack, since we depend on the ImageOutputFormat which did not yet have an Avif entry for image crate v0.23.10. This has been contributed, but it is not released yet. Thus we have to call the encoder separately, which would require quite a bit of refactoring for a simple change (or we could wait I suppose), which would then revert the refactoring. For now however, I decided to add support, but use a environment variable to signal that the ImageOutputFormat is actually not Farb when the id "avif" is found, but Avif instead. Obviously this should be fixed when image crate `>v0.23.10` will be released.
  • Loading branch information
foresterre committed Oct 4, 2020
1 parent f6a28f3 commit ab8ebf6
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 13 deletions.
20 changes: 19 additions & 1 deletion components/sic_io/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::errors::SicIoError;
use image::buffer::ConvertBuffer;
use image::DynamicImage;
use sic_core::image;
use sic_core::image::GenericImageView;
use std::io::Write;

#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -44,7 +45,24 @@ impl<'a> ConversionWriter<'a> {
None => &self.image,
};

ConversionWriter::save_to(writer, &export_buffer, output_format)
// FIXME remove: https://github.com/foresterre/sic/issues/597
if std::env::var("SIC_AVIF_HACK").is_ok() {
let avif_encoder = image::avif::AvifEncoder::new(writer);
avif_encoder
.write_image(
&export_buffer.to_bytes(),
export_buffer.width(),
export_buffer.height(),
export_buffer.color(),
)
.map_err(SicIoError::ImageError)?;

std::env::remove_var("SIC_AVIF_HACK");

Ok(())
} else {
ConversionWriter::save_to(writer, &export_buffer, output_format)
}
}

/// Some image output format types require color type pre-processing.
Expand Down
12 changes: 9 additions & 3 deletions components/sic_io/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ impl EncodingFormatByIdentifier for DetermineEncodingFormat {
/// Identifiers are based on common output file extensions.
fn by_identifier(&self, identifier: &str) -> Result<image::ImageOutputFormat, SicIoError> {
match identifier.to_ascii_lowercase().as_str() {
"avif" => Ok(image::ImageOutputFormat::Avif),
"avif" => {
// FIXME: Dirty hack
// - https://github.com/foresterre/sic/issues/597
std::env::set_var("SIC_AVIF_HACK", "1");
Ok(image::ImageOutputFormat::Farbfeld)
}
"bmp" => Ok(image::ImageOutputFormat::Bmp),
"farbfeld" => Ok(image::ImageOutputFormat::Farbfeld),
"gif" => Ok(image::ImageOutputFormat::Gif),
Expand Down Expand Up @@ -143,11 +148,12 @@ mod tests {
use super::*;

const INPUT_FORMATS: &[&str] = &[
"avif", "bmp", "farbfeld", "gif", "ico", "jpg", "jpeg", "png", "pbm", "pgm", "ppm", "pam",
//"avif",
"bmp", "farbfeld", "gif", "ico", "jpg", "jpeg", "png", "pbm", "pgm", "ppm", "pam",
];

const EXPECTED_VALUES: &[image::ImageOutputFormat] = &[
image::ImageOutputFormat::Avif,
// image::ImageOutputFormat::Avif,
image::ImageOutputFormat::Bmp,
image::ImageOutputFormat::Farbfeld,
image::ImageOutputFormat::Gif,
Expand Down
Binary file added resources/wh1616.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 7 additions & 9 deletions src/cli/pipeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ fn create_format_decider(
io_device: &PathVariant,
config: &Config,
) -> anyhow::Result<image::ImageOutputFormat> {
let encoding_format_determiner = DetermineEncodingFormat {
let format_resolver = DetermineEncodingFormat {
pnm_sample_encoding: if config.encoding_settings.pnm_use_ascii_format {
Some(image::pnm::SampleEncoding::Ascii)
} else {
Expand All @@ -163,15 +163,13 @@ fn create_format_decider(
};

let format = match &config.forced_output_format {
Some(format) => encoding_format_determiner
.by_identifier(format)
.fallback_if(
config.encoding_settings.image_output_format_fallback,
guess_output_by_identifier,
format,
)?,
Some(format) => format_resolver.by_identifier(format).fallback_if(
config.encoding_settings.image_output_format_fallback,
guess_output_by_identifier,
format,
)?,
None => match io_device {
PathVariant::Path(out) => encoding_format_determiner.by_extension(out).fallback_if(
PathVariant::Path(out) => format_resolver.by_extension(out).fallback_if(
config.encoding_settings.image_output_format_fallback,
guess_output_by_path,
out,
Expand Down

0 comments on commit ab8ebf6

Please sign in to comment.