From de471c3f735455ed2160c5d0b21360ee67bb02a0 Mon Sep 17 00:00:00 2001 From: Vomitblood Date: Thu, 8 Aug 2024 00:31:49 +0800 Subject: [PATCH] added rust backend webp animation checker --- src-tauri/Cargo.lock | 22 ++++++++++ src-tauri/Cargo.toml | 2 + src-tauri/src/bin/testing.rs | 82 ++++++++++++++++++++++++++++++++++++ src-tauri/src/main.rs | 6 --- 4 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 src-tauri/src/bin/testing.rs diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 739c3d7..504777d 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -72,11 +72,13 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" name = "app" version = "0.1.0" dependencies = [ + "gif", "image 0.25.2", "serde", "serde_json", "tauri", "tauri-build", + "webp", ] [[package]] @@ -1998,6 +2000,16 @@ dependencies = [ "libc", ] +[[package]] +name = "libwebp-sys" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829b6b604f31ed6d2bccbac841fe0788de93dbd87e4eb1ba2c4adfe8c012a838" +dependencies = [ + "cc", + "glob", +] + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -4323,6 +4335,16 @@ dependencies = [ "system-deps 6.2.2", ] +[[package]] +name = "webp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f53152f51fb5af0c08484c33d16cca96175881d1f3dec068c23b31a158c2d99" +dependencies = [ + "image 0.25.2", + "libwebp-sys", +] + [[package]] name = "webview2-com" version = "0.19.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 3da4d72..b9ca760 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -19,6 +19,8 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tauri = { version = "1.7.0", features = [ "protocol-all", "fs-all", "path-all", "window-all", "process-all", "notification-all", "dialog-all"] } image = "0.25.2" +webp = "0.3.0" +gif = "0.13.1" [features] # this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. diff --git a/src-tauri/src/bin/testing.rs b/src-tauri/src/bin/testing.rs new file mode 100644 index 0000000..f6aea5e --- /dev/null +++ b/src-tauri/src/bin/testing.rs @@ -0,0 +1,82 @@ +#[derive(Debug, PartialEq)] +enum ImageType { + Jpeg, + Png, + Gif, + WebP, + AnimatedWebP, + Unsupported, +} + +// fn process_image(file_path_string: String) -> Result { +// // convert string to path to use in rust +// let file_path = std::path::Path::new(&file_path_string); + +// // get the data directory path +// let data_dir = tauri::api::path::data_dir().ok_or("Failed to get data directory")?; +// let mut destination = data_dir.clone(); +// // we can hardcode the file name since +// // 1. we are only dealing with one wallpaper image at a time +// // 2. we will be converting all images to the webp format +// destination.push("wallpaper.webp"); + +// // determine the file format +// } + +// fn determine_image_type(file_path: &std::path::Path) -> Result { +// // open the file +// let mut file = +// std::fs::File::open(file_path).map_err(|e| format!("Failed to open file: {e}"))?; + +// // read the first few bytes to determine the format +// let mut buffer = [0; 12]; +// file.read_exact(&mut buffer) +// .map_err(|e| format!("Failed to read file: {e}"))?; + +// // check statis formats +// if let Some(format) = image::guess_format(&buffer).ok() { +// match format { +// image::ImageFormat::Jpeg => return Ok(ImageType::Jpeg), +// image::ImageFormat::Png => return Ok(ImageType::Png), +// image::ImageFormat::Gif => return Ok(ImageType::Gif), +// image::ImageFormat::WebP => { +// // additional check if is animated +// if is_animated_webp(file_path) { +// return Ok(ImageType::AnimatedWebP); +// } else { +// return Ok(ImageType::WebP); +// } +// } +// _ => return Ok(ImageType::Unsupported), +// } +// } else { +// return Ok(ImageType::Unsupported); +// } +// } + +/// check if the file is a valid webp image and if it is animated +/// returns `Ok(true)` if it is animated, `Ok(false)` if it is not +/// and errors out if the file cannot be read or is not a webp +fn is_animated_webp(file_path: &std::path::Path) -> Result { + // open the file and read its contents into a buffer + let mut buffer = Vec::new(); + std::fs::File::open(file_path) + .and_then(|mut file| std::io::Read::read_to_end(&mut file, &mut buffer)) + .map_err(|e| format!("Failed to read file: {}", e))?; + + // use the webp crate to decode the image and check for animation + webp::AnimDecoder::new(&buffer) + .decode() + .map(|anim| anim.has_animation()) + .map_err(|_| "File is not a valid WebP image".to_string()) +} + +fn main() { + // Example usage + let path = std::path::Path::new("/home/vomitblood/Downloads/Win10_22H2_English_x64v1.iso"); + match is_animated_webp(path) { + Ok(true) => println!("The WebP is animated."), + Ok(false) => println!("The WebP is not animated."), + Err(e) => println!("Error: {}", e), + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index edc5b4c..e6ad770 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,14 +1,8 @@ // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] -#[tauri::command] -fn hello(content: &str) -> String { - format!("Hello {}, what is your name?!", content) -} - fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![hello]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }