diff --git a/Cargo.lock b/Cargo.lock index 38bb2eec..4d9d1222 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,6 +120,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytemuck" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41aa2ec95ca3b5c54cf73c91acf06d24f4495d5f1b1c12506ae3483d646177ac" + [[package]] name = "byteorder" version = "1.3.4" @@ -567,6 +573,16 @@ dependencies = [ "lzw", ] +[[package]] +name = "gif" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02efba560f227847cb41463a7395c514d127d4f74fff12ef0137fff1b84b96c4" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "git2" version = "0.13.11" @@ -722,15 +738,33 @@ checksum = "545f000e8aa4e569e93f49c446987133452e0091c2494ac3efd3606aa3d309f2" dependencies = [ "byteorder", "enum_primitive", - "gif", + "gif 0.9.2", "jpeg-decoder", "num-iter", - "num-rational", + "num-rational 0.1.42", "num-traits 0.1.43", "png 0.11.0", "scoped_threadpool", ] +[[package]] +name = "image" +version = "0.23.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985fc06b1304d19c28d5c562ed78ef5316183f2b0053b46763a0b94862373c34" +dependencies = [ + "bytemuck", + "byteorder", + "gif 0.11.1", + "jpeg-decoder", + "num-iter", + "num-rational 0.3.0", + "num-traits 0.2.12", + "png 0.16.7", + "scoped_threadpool", + "tiff", +] + [[package]] name = "indexmap" version = "1.6.0" @@ -1123,7 +1157,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "337525774dd8a197b613a01ea88058ef0ed023e5ed1e4b7e93de478e1f2bf770" dependencies = [ - "image", + "image 0.18.0", "rand 0.5.6", ] @@ -1169,6 +1203,17 @@ dependencies = [ "num-traits 0.2.12", ] +[[package]] +name = "num-rational" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138" +dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.12", +] + [[package]] name = "num-traits" version = "0.1.43" @@ -1539,6 +1584,7 @@ dependencies = [ "flume", "git2", "hex", + "image 0.23.10", "lazy_static", "md-5", "mysql", @@ -1901,6 +1947,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tiff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f" +dependencies = [ + "byteorder", + "lzw", + "miniz_oxide 0.3.7", +] + [[package]] name = "time" version = "0.1.44" @@ -2235,6 +2292,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "weezl" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e26e7a4d998e3d7949c69444b8b4916bac810da0d3a82ae612c89e952782f4" + [[package]] name = "winapi" version = "0.2.8" diff --git a/Cargo.toml b/Cargo.toml index 89fd48dc..9c69b324 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ hex = { version = "0.4", optional = true } percent-encoding = { version = "2.1", optional = true } url-dep = { version = "2.1", package = "url", optional = true } png = { version = "0.16", optional = true } +image = { version = "0.23.10", optional = true } git2 = { version = "0.13", optional = true, default-features = false } noise = { version = "0.6", optional = true} reqwest = { version = "0.10", optional = true, default-features = false, features = ["blocking", "rustls-tls"] } @@ -39,7 +40,7 @@ dashmap = { version = "3.11", optional = true } [features] default = ["dmi", "log", "git", "http", "json", "sql", "noise"] -dmi = ["png"] +dmi = ["png", "image"] file = [] hash = ["md-5", "sha-1", "sha2", "hex"] json = ["serde", "serde_json"] diff --git a/build.rs b/build.rs index f4a2bae2..1e7de627 100644 --- a/build.rs +++ b/build.rs @@ -66,6 +66,7 @@ fn main() { write!(f, r#" #define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname) #define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data) +#define rustg_dmi_resize_png(path, width, height) call(RUST_G, "dmi_resize_png")(path, width, height) "#).unwrap(); } diff --git a/src/dmi.rs b/src/dmi.rs index d642b191..9630b3c0 100644 --- a/src/dmi.rs +++ b/src/dmi.rs @@ -1,4 +1,5 @@ use crate::error::{Error, Result}; +use image::error::ImageError; use png::{Decoder, Encoder, OutputInfo}; use std::{ fs::{create_dir_all, File}, @@ -10,7 +11,11 @@ byond_fn! { dmi_strip_metadata(path) { } } byond_fn! { dmi_create_png(path, width, height, data) { - create_png(path, width, height , data).err() + create_png(path, width, height, data).err() +} } + +byond_fn! { dmi_resize_png(path, width, height) { + resize_png(path, width, height).err().map(|e| format!("{:?}", e)) } } fn strip_metadata(path: &str) -> Result<()> { @@ -63,3 +68,32 @@ fn create_png(path: &str, width: &str, height: &str, data: &str) -> Result<()> { let mut writer = encoder.write_header()?; Ok(writer.write_image_data(&result)?) } + +#[derive(Debug)] +enum ResizePngError { + StringParse(std::num::ParseIntError), + Image(ImageError), +} + +impl From for ResizePngError { + fn from(error: std::num::ParseIntError) -> Self { + ResizePngError::StringParse(error) + } +} + +impl From for ResizePngError { + fn from(error: ImageError) -> Self { + ResizePngError::Image(error) + } +} + +fn resize_png(path: &str, width: &str, height: &str) -> std::result::Result<(), ResizePngError> { + let width = u32::from_str_radix(width, 10)?; + let height = u32::from_str_radix(height, 10)?; + + let img = image::open(path)?; + + let newimg = img.resize(width, height, image::imageops::Nearest); + + Ok(newimg.save_with_format(&path, image::ImageFormat::Png)?) +}