mirror of
				https://github.com/Vomitblood/stort.git
				synced 2025-10-31 18:57:21 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			87 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| #[derive(Debug, PartialEq)]
 | |
| enum ImageType {
 | |
|     Jpeg,
 | |
|     Png,
 | |
|     Gif,
 | |
|     WebP,
 | |
|     AnimatedWebP,
 | |
|     Unsupported,
 | |
| }
 | |
| 
 | |
| /// function to interface with the tauri api on the javascript side
 | |
| #[tauri::command]
 | |
| pub fn process_wallpaper_image(file_path_string: String) -> Result<String, String> {
 | |
|     // convert the string to a path
 | |
|     let file_path = std::path::Path::new(&file_path_string);
 | |
| 
 | |
|     // determine the image type
 | |
|     match determine_image_type(file_path) {
 | |
|         Ok(image_type) => match image_type {
 | |
|             ImageType::Jpeg => Ok("jpeg".to_string()),
 | |
|             ImageType::Png => Ok("png".to_string()),
 | |
|             ImageType::Gif => Ok("gif".to_string()),
 | |
|             ImageType::WebP => Ok("webp".to_string()),
 | |
|             ImageType::AnimatedWebP => Ok("webp".to_string()),
 | |
|             ImageType::Unsupported => {
 | |
|                 Err("Unsupported image type (accepts webp, jpg, jpeg, png, gif)".to_string())
 | |
|             }
 | |
|         },
 | |
|         Err(e) => Err(format!("Error determining image type: {e}")),
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// determines the image type of a file that is passed in using the filepath
 | |
| fn determine_image_type(file_path: &std::path::Path) -> Result<ImageType, String> {
 | |
|     // 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];
 | |
|     std::io::Read::read_exact(&mut file, &mut buffer)
 | |
|         .map_err(|e| format!("Failed to read file: {e}"))?;
 | |
| 
 | |
|     // with hopes and prayers, try to guess the format and pray that it is correct haha
 | |
|     match image::guess_format(&buffer) {
 | |
|         Ok(image::ImageFormat::Jpeg) => Ok(ImageType::Jpeg),
 | |
|         Ok(image::ImageFormat::Png) => Ok(ImageType::Png),
 | |
|         Ok(image::ImageFormat::Gif) => Ok(ImageType::Gif),
 | |
|         Ok(image::ImageFormat::WebP) => {
 | |
|             // additional check for webp
 | |
|             is_animated_webp(file_path).map(|animated| {
 | |
|                 if animated {
 | |
|                     ImageType::AnimatedWebP
 | |
|                 } else {
 | |
|                     ImageType::WebP
 | |
|                 }
 | |
|             })
 | |
|         }
 | |
|         _ => 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<bool, String> {
 | |
|     // 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 get_file_extension(file_path: &std::path::Path) -> Result<String, String> {
 | |
|     file_path
 | |
|         .extension()
 | |
|         .and_then(|extension| extension.to_str())
 | |
|         .map(|extension| extension.to_lowercase())
 | |
|         .ok_or_else(|| "Failed to get file extension".to_string())
 | |
| }
 |