Repository: foresterre/sic (language: rust)

Issue:
Enable `webp` encoding support
`webp` encoder is available since `image 0.24.4`:
https://github.com/image-rs/image/releases/tag/v0.24.4


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dda74e0d5..63033b208 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,10 @@ The changelog below lists notable changes for [sic](https://github.com/foresterr
 
 ## [Unreleased]
 
+### Added
+
+- Added `webp` encoding support
+
 [unreleased]: https://github.com/foresterre/sic/compare/v0.20.1...HEAD
 
 ## [0.20.1] - 2022-12-12
diff --git a/Cargo.lock b/Cargo.lock
index e462730e7..2f9fa5996 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -689,6 +689,7 @@ dependencies = [
  "rgb",
  "scoped_threadpool",
  "tiff",
+ "webp",
 ]
 
 [[package]]
@@ -815,6 +816,15 @@ dependencies = [
  "cc",
 ]
 
+[[package]]
+name = "libwebp-sys"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439fd1885aa28937e7edcd68d2e793cb4a22f8733460d2519fbafd2b215672bf"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "link-cplusplus"
 version = "1.0.8"
@@ -1971,6 +1981,15 @@ version = "0.2.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
 
+[[package]]
+name = "webp"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf022f821f166079a407d000ab57e84de020e66ffbbf4edde999bc7d6e371cae"
+dependencies = [
+ "libwebp-sys",
+]
+
 [[package]]
 name = "weezl"
 version = "0.1.7"
diff --git a/crates/sic_core/Cargo.toml b/crates/sic_core/Cargo.toml
index ecc7205ac..591da194a 100644
--- a/crates/sic_core/Cargo.toml
+++ b/crates/sic_core/Cargo.toml
@@ -11,12 +11,16 @@ edition = "2021"
 rust-version = "1.61"
 
 [dependencies]
-image = { version = "0.24.5", features = ["avif"] }
-
 imageproc = { version = "0.23.0", optional = true }
 rusttype = { version = "0.9.3", optional = true }
-
 thiserror = "1"
 
+[dependencies.image]
+version = "0.24.5"
+features = [
+    "avif", # requires (exe: nasm >= 2.14)
+    "webp-encoder", # requires (native_dependency: libwebp)
+]
+
 [features]
 imageproc-ops = ["imageproc", "rusttype"]
diff --git a/crates/sic_io/src/conversion.rs b/crates/sic_io/src/conversion.rs
index d95454bab..658eb0379 100644
--- a/crates/sic_io/src/conversion.rs
+++ b/crates/sic_io/src/conversion.rs
@@ -2,7 +2,6 @@ use crate::errors::{FormatError, SicIoError};
 use crate::export::ExportSettings;
 use crate::WriteSeek;
 use image::buffer::ConvertBuffer;
-use image::DynamicImage;
 use sic_core::image::codecs::gif::Repeat;
 use sic_core::image::codecs::pnm;
 use sic_core::{image, AnimatedImage, SicImage};
@@ -119,7 +118,9 @@ impl<'a> ConversionWriter<'a> {
 fn adjust_dynamic_image(
     image: &image::DynamicImage,
     output_format: &image::ImageOutputFormat,
-) -> Option<DynamicImage> {
+) -> Option<image::DynamicImage> {
+    use image::DynamicImage;
+
     // A remaining open question: does a user expect for an image to be able to convert to a format even if the color type is not supported?
     // And even if the user does, should we?
     // I suspect that users expect that color type conversions should happen automatically.
@@ -138,7 +139,7 @@ fn adjust_dynamic_image(
             Some(DynamicImage::ImageLuma8(image.to_luma8()))
         }
         image::ImageOutputFormat::Pnm(pnm::PnmSubtype::Pixmap(_)) => {
-            Some(image::DynamicImage::ImageRgb8(image.to_rgb8()))
+            Some(DynamicImage::ImageRgb8(image.to_rgb8()))
         }
         _ => None,
     }
diff --git a/crates/sic_io/src/format.rs b/crates/sic_io/src/format.rs
index 0d33a1069..a07fb28d2 100644
--- a/crates/sic_io/src/format.rs
+++ b/crates/sic_io/src/format.rs
@@ -105,6 +105,7 @@ impl EncodingFormatByIdentifier for DetermineEncodingFormat {
                 self.pnm_encoding_type()?,
             ))),
             "tga" => Ok(image::ImageOutputFormat::Tga),
+            "webp" => Ok(image::ImageOutputFormat::WebP),
             _ => Err(SicIoError::UnknownImageIdentifier(identifier.to_string())),
         }
     }


Test patch:
diff --git a/tests/cli_convert.rs b/tests/cli_convert.rs
index 2aac8717e..552bf2050 100644
--- a/tests/cli_convert.rs
+++ b/tests/cli_convert.rs
@@ -74,6 +74,7 @@ mod convert_to_x {
         "pgm",
         "ppm",
         "pam",
+        "webp",
     }, expected_format = {
         image::ImageFormat::Bmp,
         image::ImageFormat::Farbfeld,
@@ -86,6 +87,7 @@ mod convert_to_x {
         image::ImageFormat::Pnm,
         image::ImageFormat::Pnm,
         image::ImageFormat::Pnm,
+        image::ImageFormat::WebP,
 
     })]
     fn convert_to_x_by_extension(ext: &str, expected_format: image::ImageFormat) {
@@ -144,6 +146,7 @@ mod convert_to_x_by_ff {
         "pgm",
         "ppm",
         "pam",
+        "webp",
     }, expected_format = {
         image::ImageFormat::Bmp,
         image::ImageFormat::Farbfeld,
@@ -156,6 +159,7 @@ mod convert_to_x_by_ff {
         image::ImageFormat::Pnm,
         image::ImageFormat::Pnm,
         image::ImageFormat::Pnm,
+        image::ImageFormat::WebP,
     })]
     fn convert_to_bmp_by_ff(which: &str, expected_format: image::ImageFormat) {
         let input_path = setup_input_path("palette_4x4.png");