diff --git a/src/gif.rs b/src/gif.rs index dbb83f2..c48061f 100644 --- a/src/gif.rs +++ b/src/gif.rs @@ -1,7 +1,8 @@ use std::ffi::CString; use std::os::raw::{c_int, c_void}; -use crate::{CaesiumError, CSParameters}; +use crate::utils::CaesiumError; +use crate::CSParameters; pub fn compress( input_path: String, @@ -9,7 +10,10 @@ pub fn compress( parameters: &CSParameters, ) -> Result<(), CaesiumError> { if parameters.width > 0 || parameters.height > 0 { - return Err(CaesiumError { message: "GIF resizing is not supported".to_string(), code: 20400 }); + return Err(CaesiumError { + message: "GIF resizing is not supported".to_string(), + code: 20400, + }); } if parameters.optimize { @@ -21,10 +25,22 @@ pub fn compress( fn lossless(input_path: String, output_path: String) -> Result<(), CaesiumError> { let args: Vec = vec![ - CString::new(format!("{:?}", std::env::current_exe())).map_err(|e| CaesiumError { message: e.to_string(), code: 20401 })?, - CString::new(input_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20402 })?, - CString::new(format!("--output={}", output_path)).map_err(|e| CaesiumError { message: e.to_string(), code: 20403 })?, - CString::new("--optimize=3").map_err(|e| CaesiumError { message: e.to_string(), code: 20404 })?, + CString::new(format!("{:?}", std::env::current_exe())).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20401, + })?, + CString::new(input_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20402, + })?, + CString::new(format!("--output={}", output_path)).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20403, + })?, + CString::new("--optimize=3").map_err(|e| CaesiumError { + message: e.to_string(), + code: 20404, + })?, ]; let argv: Vec<_> = args.iter().map(|a| a.as_ptr()).collect(); @@ -34,7 +50,10 @@ fn lossless(input_path: String, output_path: String) -> Result<(), CaesiumError> match result { 0 => Ok(()), - _ => Err(CaesiumError { message: "GIF optimization failed!".to_string(), code: 20405 }), + _ => Err(CaesiumError { + message: "GIF optimization failed!".to_string(), + code: 20405, + }), } } } @@ -46,12 +65,32 @@ pub fn lossy( ) -> Result<(), CaesiumError> { unsafe { let input_file = libc::fopen( - CString::new(input_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20406 })?.as_ptr(), - CString::new("r").map_err(|e| CaesiumError { message: e.to_string(), code: 20407 })?.as_ptr(), + CString::new(input_path) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20406, + })? + .as_ptr(), + CString::new("r") + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20407, + })? + .as_ptr(), ); let output_file = libc::fopen( - CString::new(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20408 })?.as_ptr(), - CString::new("w+").map_err(|e| CaesiumError { message: e.to_string(), code: 20409 })?.as_ptr(), + CString::new(output_path) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20408, + })? + .as_ptr(), + CString::new("w+") + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20409, + })? + .as_ptr(), ); let input_stream = gifsicle::Gif_ReadFile(input_file); libc::fclose(input_file); @@ -69,7 +108,10 @@ pub fn lossy( match write_result { 1 => Ok(()), - _ => Err(CaesiumError { message: "GIF optimization failed!".to_string(), code: 20410 }), + _ => Err(CaesiumError { + message: "GIF optimization failed!".to_string(), + code: 20410, + }), } } } diff --git a/src/jpeg.rs b/src/jpeg.rs index 247c84a..5892410 100644 --- a/src/jpeg.rs +++ b/src/jpeg.rs @@ -1,16 +1,17 @@ -use std::{fs, ptr}; -use std::{mem}; use std::fs::File; use std::io::Write; +use std::mem; use std::panic::catch_unwind; +use std::{fs, ptr}; use image::ImageOutputFormat::Jpeg; use img_parts::{DynImage, ImageEXIF, ImageICC}; use libc::free; use mozjpeg_sys::*; -use crate::{CaesiumError, CSParameters}; use crate::resize::resize; +use crate::utils::CaesiumError; +use crate::CSParameters; static mut JPEG_ERROR: c_int = 0; @@ -28,16 +29,27 @@ pub fn compress( output_path: String, parameters: &CSParameters, ) -> Result<(), CaesiumError> { - let in_file = fs::read(input_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20100 })?; + let in_file = fs::read(input_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20100, + })?; let out_buffer = compress_to_memory(in_file, parameters)?; - let mut out_file = File::create(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20101 })?; - out_file.write_all(&out_buffer).map_err(|e| CaesiumError { message: e.to_string(), code: 20102 })?; + let mut out_file = File::create(output_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20101, + })?; + out_file.write_all(&out_buffer).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20102, + })?; Ok(()) } -pub fn compress_to_memory(mut in_file: Vec, parameters: &CSParameters) -> Result, CaesiumError> -{ +pub fn compress_to_memory( + mut in_file: Vec, + parameters: &CSParameters, +) -> Result, CaesiumError> { if parameters.width > 0 || parameters.height > 0 { if parameters.keep_metadata { let metadata = extract_metadata(in_file.clone()); @@ -55,14 +67,17 @@ pub fn compress_to_memory(mut in_file: Vec, parameters: &CSParameters) -> Re } else { lossy(in_file, parameters) } - }).unwrap_or_else(|_| Err(CaesiumError { message: format!("Internal JPEG error: {}", JPEG_ERROR), code: 20104 })) + }) + .unwrap_or_else(|_| { + Err(CaesiumError { + message: format!("Internal JPEG error: {}", JPEG_ERROR), + code: 20104, + }) + }) } } -unsafe fn lossless( - in_file: Vec, - parameters: &CSParameters, -) -> Result, CaesiumError> { +unsafe fn lossless(in_file: Vec, parameters: &CSParameters) -> Result, CaesiumError> { let mut src_info: jpeg_decompress_struct = mem::zeroed(); let mut src_err = mem::zeroed(); @@ -110,10 +125,7 @@ unsafe fn lossless( jpeg_finish_decompress(&mut src_info); jpeg_destroy_decompress(&mut src_info); - let slice = std::slice::from_raw_parts( - buf, - buf_size as usize, - ); + let slice = std::slice::from_raw_parts(buf, buf_size as usize); let result = slice.to_vec(); @@ -214,10 +226,7 @@ unsafe fn lossy(in_file: Vec, parameters: &CSParameters) -> Result, jpeg_finish_compress(&mut dst_info); jpeg_destroy_compress(&mut dst_info); - let slice = std::slice::from_raw_parts( - buf, - buf_size as usize, - ); + let slice = std::slice::from_raw_parts(buf, buf_size as usize); let result = slice.to_vec(); @@ -265,7 +274,10 @@ fn save_metadata( } } -unsafe fn write_metadata(src_info: &mut jpeg_decompress_struct, dst_info: &mut jpeg_compress_struct) { +unsafe fn write_metadata( + src_info: &mut jpeg_decompress_struct, + dst_info: &mut jpeg_compress_struct, +) { let mut marker = src_info.marker_list; while !marker.is_null() { @@ -279,8 +291,10 @@ unsafe fn write_metadata(src_info: &mut jpeg_decompress_struct, dst_info: &mut j } } -unsafe fn set_chroma_subsampling(subsampling: ChromaSubsampling, dst_info: &mut jpeg_compress_struct) -{ +unsafe fn set_chroma_subsampling( + subsampling: ChromaSubsampling, + dst_info: &mut jpeg_compress_struct, +) { (*dst_info.comp_info.add(1)).h_samp_factor = 1; (*dst_info.comp_info.add(1)).v_samp_factor = 1; (*dst_info.comp_info.add(2)).h_samp_factor = 1; @@ -311,4 +325,4 @@ unsafe extern "C" fn error_handler(cinfo: &mut jpeg_common_struct) { panic!("Internal JPEG error: {}", JPEG_ERROR); } -unsafe extern "C" fn error_message_handler(_cinfo: &mut jpeg_common_struct) {} \ No newline at end of file +unsafe extern "C" fn error_message_handler(_cinfo: &mut jpeg_common_struct) {} diff --git a/src/lib.rs b/src/lib.rs index 88fe6a6..f0dbe04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,30 +1,14 @@ extern crate alloc; +use crate::jpeg::ChromaSubsampling; +use crate::utils::{get_filetype_from_memory, get_filetype_from_path, SupportedFileTypes}; use alloc::ffi::CString; -use std::{cmp, fs}; use std::ffi::CStr; use std::fs::File; use std::io::Write; use std::os::raw::c_char; -use crate::jpeg::ChromaSubsampling; - -use crate::utils::{get_filetype_from_memory, get_filetype_from_path, SupportedFileTypes}; - -use std::fmt; - -type Result = std::result::Result; - -#[derive(Debug, Clone)] -pub struct CaesiumError { - pub message: String, - pub code: u32, -} - -impl fmt::Display for CaesiumError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{} [{}]", self.message, self.code) - } -} +use std::{cmp, fs}; +use utils::CaesiumError; #[cfg(feature = "gif")] mod gif; @@ -144,7 +128,7 @@ pub unsafe extern "C" fn c_compress_to_size( output_path: *const c_char, params: CCSParameters, max_output_size: usize, - return_smallest: bool + return_smallest: bool, ) -> CCSResult { let mut parameters = c_set_parameters(params); @@ -153,11 +137,11 @@ pub unsafe extern "C" fn c_compress_to_size( CStr::from_ptr(output_path).to_str().unwrap().to_string(), &mut parameters, max_output_size, - return_smallest + return_smallest, )) } -fn c_return_result(result: Result<()>) -> CCSResult { +fn c_return_result(result: utils::Result<()>) -> CCSResult { let mut error_message = CString::new("").unwrap(); match result { @@ -201,7 +185,7 @@ fn c_set_parameters(params: CCSParameters) -> CSParameters { 422 => ChromaSubsampling::CS422, 420 => ChromaSubsampling::CS420, 411 => ChromaSubsampling::CS411, - _ => ChromaSubsampling::Auto + _ => ChromaSubsampling::Auto, }; parameters @@ -211,7 +195,7 @@ pub fn compress( input_path: String, output_path: String, parameters: &CSParameters, -) -> Result<()> { +) -> utils::Result<()> { validate_parameters(parameters)?; let file_type = get_filetype_from_path(&input_path); @@ -232,10 +216,12 @@ pub fn compress( SupportedFileTypes::Gif => { gif::compress(input_path, output_path, parameters)?; } - _ => return Err(CaesiumError { - message: "Unknown file type".into(), - code: 10000, - }), + _ => { + return Err(CaesiumError { + message: "Unknown file type".into(), + code: 10000, + }) + } } Ok(()) @@ -244,25 +230,21 @@ pub fn compress( pub fn compress_in_memory( in_file: Vec, parameters: &mut CSParameters, -) -> Result> { +) -> utils::Result> { let file_type = get_filetype_from_memory(in_file.as_slice()); let compressed_file = match file_type { #[cfg(feature = "jpg")] - SupportedFileTypes::Jpeg => { - jpeg::compress_to_memory(in_file, parameters)? - } + SupportedFileTypes::Jpeg => jpeg::compress_to_memory(in_file, parameters)?, #[cfg(feature = "png")] - SupportedFileTypes::Png => { - png::compress_to_memory(in_file, parameters)? - } + SupportedFileTypes::Png => png::compress_to_memory(in_file, parameters)?, #[cfg(feature = "webp")] - SupportedFileTypes::WebP => { - webp::compress_to_memory(in_file, parameters)? + SupportedFileTypes::WebP => webp::compress_to_memory(in_file, parameters)?, + _ => { + return Err(CaesiumError { + message: "Format not supported for compression to size".into(), + code: 10200, + }) } - _ => return Err(CaesiumError { - message: "Format not supported for compression to size".into(), - code: 10200, - }), }; Ok(compressed_file) @@ -272,8 +254,8 @@ pub fn compress_to_size_in_memory( in_file: Vec, parameters: &mut CSParameters, max_output_size: usize, - return_smallest: bool -) -> Result> { + return_smallest: bool, +) -> utils::Result> { let file_type = get_filetype_from_memory(&in_file); let tolerance_percentage = 2; @@ -308,15 +290,19 @@ pub fn compress_to_size_in_memory( parameters.webp.quality = quality; webp::compress_to_memory(in_file.clone(), parameters)? //TODO clone } - _ => return Err(CaesiumError { - message: "Format not supported for compression to size".into(), - code: 10200, - }), + _ => { + return Err(CaesiumError { + message: "Format not supported for compression to size".into(), + code: 10200, + }) + } }; let compressed_file_size = compressed_file.len(); - if compressed_file_size <= max_output_size && max_output_size - compressed_file_size < tolerance { + if compressed_file_size <= max_output_size + && max_output_size - compressed_file_size < tolerance + { break compressed_file; } @@ -332,8 +318,11 @@ pub fn compress_to_size_in_memory( return if return_smallest { Ok(compressed_file) } else { - Err(CaesiumError { message: "Cannot compress to desired quality".into(), code: 10202 }) - } + Err(CaesiumError { + message: "Cannot compress to desired quality".into(), + code: 10202, + }) + }; } break compressed_file; @@ -350,41 +339,70 @@ pub fn compress_to_size( output_path: String, parameters: &mut CSParameters, max_output_size: usize, - return_smallest: bool -) -> Result<()> -{ - let in_file = fs::read(input_path.clone()).map_err(|e| CaesiumError { message: e.to_string(), code: 10201 })?; + return_smallest: bool, +) -> utils::Result<()> { + let in_file = fs::read(input_path.clone()).map_err(|e| CaesiumError { + message: e.to_string(), + code: 10201, + })?; let original_size = in_file.len(); if original_size <= max_output_size { - fs::copy(input_path, output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 10202 })?; + fs::copy(input_path, output_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 10202, + })?; return Ok(()); } - let compressed_file = compress_to_size_in_memory(in_file, parameters, max_output_size, return_smallest)?; - let mut out_file = File::create(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 10203 })?; - out_file.write_all(&compressed_file).map_err(|e| CaesiumError { message: e.to_string(), code: 10204 })?; + let compressed_file = + compress_to_size_in_memory(in_file, parameters, max_output_size, return_smallest)?; + let mut out_file = File::create(output_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 10203, + })?; + out_file + .write_all(&compressed_file) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 10204, + })?; Ok(()) } -fn validate_parameters(parameters: &CSParameters) -> Result<()> { +fn validate_parameters(parameters: &CSParameters) -> utils::Result<()> { if parameters.jpeg.quality == 0 || parameters.jpeg.quality > 100 { - return Err(CaesiumError { message: "Invalid JPEG quality value".into(), code: 10001 }); + return Err(CaesiumError { + message: "Invalid JPEG quality value".into(), + code: 10001, + }); } if parameters.png.quality > 100 { - return Err(CaesiumError { message: "Invalid PNG quality value".into(), code: 10002 }); + return Err(CaesiumError { + message: "Invalid PNG quality value".into(), + code: 10002, + }); } if parameters.gif.quality > 100 { - return Err(CaesiumError { message: "Invalid GIF quality value".into(), code: 10003 }); + return Err(CaesiumError { + message: "Invalid GIF quality value".into(), + code: 10003, + }); } if parameters.webp.quality > 100 { - return Err(CaesiumError { message: "Invalid WebP quality value".into(), code: 10004 }); + return Err(CaesiumError { + message: "Invalid WebP quality value".into(), + code: 10004, + }); } if parameters.optimize && parameters.output_size > 0 { - return Err(CaesiumError { message: "Cannot compress to desired size with lossless optimization".into(), code: 10005 }); + return Err(CaesiumError { + message: "Cannot compress to desired size with lossless optimization".into(), + code: 10005, + }); } Ok(()) diff --git a/src/png.rs b/src/png.rs index 0a5101f..1affb29 100644 --- a/src/png.rs +++ b/src/png.rs @@ -1,4 +1,4 @@ -use std::{fs}; +use std::fs; use std::fs::File; use std::io::Write; use std::num::NonZeroU8; @@ -6,29 +6,48 @@ use std::num::NonZeroU8; use image::ImageOutputFormat; use oxipng::Deflaters::{Libdeflater, Zopfli}; -use crate::{CaesiumError, CSParameters}; use crate::resize::resize; +use crate::utils::CaesiumError; +use crate::CSParameters; pub fn compress( input_path: String, output_path: String, parameters: &CSParameters, ) -> Result<(), CaesiumError> { - let mut in_file = fs::read(input_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20200 })?; + let mut in_file = fs::read(input_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20200, + })?; if parameters.width > 0 || parameters.height > 0 { - in_file = resize(in_file, parameters.width, parameters.height, ImageOutputFormat::Png)?; + in_file = resize( + in_file, + parameters.width, + parameters.height, + ImageOutputFormat::Png, + )?; } let optimized_png = compress_to_memory(in_file, parameters)?; - let mut output_file_buffer = File::create(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20202 })?; - output_file_buffer.write_all(optimized_png.as_slice()).map_err(|e| CaesiumError { message: e.to_string(), code: 20203 })?; + let mut output_file_buffer = File::create(output_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20202, + })?; + output_file_buffer + .write_all(optimized_png.as_slice()) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20203, + })?; Ok(()) } -pub fn compress_to_memory(in_file: Vec, parameters: &CSParameters) -> Result, CaesiumError> -{ +pub fn compress_to_memory( + in_file: Vec, + parameters: &CSParameters, +) -> Result, CaesiumError> { let optimized_png: Vec = if parameters.optimize { lossless(in_file, parameters)? } else { @@ -39,25 +58,55 @@ pub fn compress_to_memory(in_file: Vec, parameters: &CSParameters) -> Result } fn lossy(in_file: Vec, parameters: &CSParameters) -> Result, CaesiumError> { - let rgba_bitmap = lodepng::decode32(in_file).map_err(|e| CaesiumError { message: e.to_string(), code: 20204 })?; + let rgba_bitmap = lodepng::decode32(in_file).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20204, + })?; let mut liq = imagequant::new(); - liq.set_quality(0, parameters.png.quality as u8).map_err(|e| CaesiumError { message: e.to_string(), code: 20205 })?; + liq.set_quality(0, parameters.png.quality as u8) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20205, + })?; - let mut liq_image = liq.new_image( - rgba_bitmap.buffer.as_slice(), - rgba_bitmap.width, - rgba_bitmap.height, - 0.0, - ).map_err(|e| CaesiumError { message: e.to_string(), code: 20206 })?; + let mut liq_image = liq + .new_image( + rgba_bitmap.buffer.as_slice(), + rgba_bitmap.width, + rgba_bitmap.height, + 0.0, + ) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20206, + })?; - let mut quantization = liq.quantize(&mut liq_image).map_err(|e| CaesiumError { message: e.to_string(), code: 20207 })?; + let mut quantization = liq.quantize(&mut liq_image).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20207, + })?; - let (palette, pixels) = quantization.remapped(&mut liq_image).map_err(|e| CaesiumError { message: e.to_string(), code: 20208 })?; + let (palette, pixels) = quantization + .remapped(&mut liq_image) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20208, + })?; let mut encoder = lodepng::Encoder::new(); - encoder.set_palette(palette.as_slice()).map_err(|e| CaesiumError { message: e.to_string(), code: 20212 })?; - let png_vec = encoder.encode(pixels.as_slice(), rgba_bitmap.width, rgba_bitmap.height).map_err(|e| CaesiumError { message: e.to_string(), code: 20209 })?; + encoder + .set_palette(palette.as_slice()) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20212, + })?; + let png_vec = encoder + .encode(pixels.as_slice(), rgba_bitmap.width, rgba_bitmap.height) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20209, + })?; Ok(png_vec) } @@ -77,7 +126,13 @@ fn lossless(in_file: Vec, parameters: &CSParameters) -> Result, Caes oxipng_options.deflate = Libdeflater { compression: 6 }; } - let optimized_png = oxipng::optimize_from_memory(in_file.as_slice(), &oxipng_options).map_err(|e| CaesiumError { message: e.to_string(), code: 20210 })?; + let optimized_png = + oxipng::optimize_from_memory(in_file.as_slice(), &oxipng_options).map_err(|e| { + CaesiumError { + message: e.to_string(), + code: 20210, + } + })?; Ok(optimized_png) } diff --git a/src/resize.rs b/src/resize.rs index 668f069..755e6ca 100644 --- a/src/resize.rs +++ b/src/resize.rs @@ -1,9 +1,9 @@ use std::io::Cursor; -use image::DynamicImage; +use crate::utils::CaesiumError; use image::imageops::FilterType; use image::io::Reader as ImageReader; -use crate::CaesiumError; +use image::DynamicImage; pub fn resize( image_buffer: Vec, @@ -13,24 +13,31 @@ pub fn resize( ) -> Result, CaesiumError> { let mut image = ImageReader::new(Cursor::new(image_buffer)) .with_guessed_format() - .map_err(|e| CaesiumError { message: e.to_string(), code: 10300 })? + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 10300, + })? .decode() - .map_err(|e| CaesiumError { message: e.to_string(), code: 10301 })?; + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 10301, + })?; let dimensions = compute_dimensions(image.width(), image.height(), width, height); image = image.resize_exact(dimensions.0, dimensions.1, FilterType::Lanczos3); let mut resized_file: Vec = vec![]; - image.write_to(&mut Cursor::new(&mut resized_file), format).map_err(|e| CaesiumError { message: e.to_string(), code: 10302 })?; + image + .write_to(&mut Cursor::new(&mut resized_file), format) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 10302, + })?; Ok(resized_file) } -pub fn resize_image( - image: DynamicImage, - width: u32, - height: u32, -) -> DynamicImage { +pub fn resize_image(image: DynamicImage, width: u32, height: u32) -> DynamicImage { let dimensions = compute_dimensions(image.width(), image.height(), width, height); image.resize_exact(dimensions.0, dimensions.1, FilterType::Lanczos3) } diff --git a/src/utils.rs b/src/utils.rs index a219f87..800a556 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,4 @@ +use core::fmt; use infer::Type; pub enum SupportedFileTypes { @@ -12,7 +13,7 @@ pub fn get_filetype_from_path(file_path: &str) -> SupportedFileTypes { match infer::get_from_path(file_path) { Ok(v) => match v { None => SupportedFileTypes::Unkn, - Some(ft) => match_supported_filetypes(ft) + Some(ft) => match_supported_filetypes(ft), }, Err(_) => SupportedFileTypes::Unkn, } @@ -21,7 +22,7 @@ pub fn get_filetype_from_path(file_path: &str) -> SupportedFileTypes { pub fn get_filetype_from_memory(buf: &[u8]) -> SupportedFileTypes { match infer::get(buf) { None => SupportedFileTypes::Unkn, - Some(ft) => match_supported_filetypes(ft) + Some(ft) => match_supported_filetypes(ft), } } @@ -35,3 +36,16 @@ fn match_supported_filetypes(ft: Type) -> SupportedFileTypes { } } +pub type Result = std::result::Result; + +#[derive(Debug, Clone)] +pub struct CaesiumError { + pub message: String, + pub code: u32, +} + +impl fmt::Display for CaesiumError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} [{}]", self.message, self.code) + } +} diff --git a/src/webp.rs b/src/webp.rs index b90b58f..fee04e8 100644 --- a/src/webp.rs +++ b/src/webp.rs @@ -2,34 +2,55 @@ use std::fs::File; use std::io::{Read, Write}; use std::ops::Deref; -use crate::{CaesiumError, CSParameters}; use crate::resize::resize_image; +use crate::utils::CaesiumError; +use crate::CSParameters; pub fn compress( input_path: String, output_path: String, parameters: &CSParameters, ) -> Result<(), CaesiumError> { - let mut input_file = File::open(input_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20300 })?; + let mut input_file = File::open(input_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20300, + })?; let mut input_data = Vec::new(); - input_file.read_to_end(&mut input_data).map_err(|e| CaesiumError { message: e.to_string(), code: 20301 })?; + input_file + .read_to_end(&mut input_data) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20301, + })?; - let mut output_file = File::create(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 20302 })?; + let mut output_file = File::create(output_path).map_err(|e| CaesiumError { + message: e.to_string(), + code: 20302, + })?; let compressed_image = compress_to_memory(input_data, parameters)?; - output_file.write_all(&compressed_image).map_err(|e| CaesiumError { message: e.to_string(), code: 20303 })?; + output_file + .write_all(&compressed_image) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 20303, + })?; Ok(()) } -pub fn compress_to_memory(in_file: Vec, parameters: &CSParameters) -> Result, CaesiumError> -{ +pub fn compress_to_memory( + in_file: Vec, + parameters: &CSParameters, +) -> Result, CaesiumError> { let decoder = webp::Decoder::new(&in_file); let input_webp = match decoder.decode() { Some(img) => img, - None => return Err(CaesiumError { - message: "Error decoding WebP image".to_string(), - code: 20304, - }) + None => { + return Err(CaesiumError { + message: "Error decoding WebP image".to_string(), + code: 20304, + }) + } }; let mut input_image = input_webp.to_image(); let must_resize = parameters.width > 0 || parameters.height > 0; @@ -39,10 +60,12 @@ pub fn compress_to_memory(in_file: Vec, parameters: &CSParameters) -> Result let encoder = match webp::Encoder::from_image(&input_image) { Ok(encoder) => encoder, - Err(e) => return Err(CaesiumError { - message: e.to_string(), - code: 20305, - }) + Err(e) => { + return Err(CaesiumError { + message: e.to_string(), + code: 20305, + }) + } }; let encoded_image = if parameters.optimize { diff --git a/tests/cleanup.rs b/tests/cleanup.rs index bb1feec..ac5e4bb 100644 --- a/tests/cleanup.rs +++ b/tests/cleanup.rs @@ -4,4 +4,4 @@ pub fn remove_compressed_test_file(file: &str) { if fs::metadata(file).is_ok() { fs::remove_file(file).unwrap(); } -} \ No newline at end of file +} diff --git a/tests/compress_to_size.rs b/tests/compress_to_size.rs index af4b5b0..1f64d12 100644 --- a/tests/compress_to_size.rs +++ b/tests/compress_to_size.rs @@ -1,6 +1,6 @@ +use crate::cleanup::remove_compressed_test_file; use std::fs::File; use std::sync::Once; -use crate::cleanup::remove_compressed_test_file; mod cleanup; @@ -22,8 +22,9 @@ fn compress_to_1_byte() { String::from(output), &mut pars, 1, - false - ).expect_err("Cannot compress to desired quality"); + false, + ) + .expect_err("Cannot compress to desired quality"); remove_compressed_test_file(output) } @@ -37,8 +38,9 @@ fn compress_to_1_byte_and_return() { String::from(output), &mut pars, 1, - true - ).unwrap(); + true, + ) + .unwrap(); assert!(std::path::Path::new(output).exists()); assert!(File::open(output).unwrap().metadata().unwrap().len() > 1); @@ -58,8 +60,9 @@ fn compress_to_10_mb() { String::from(output), &mut pars, max_output_size, - false - ).unwrap(); + false, + ) + .unwrap(); assert_eq!(80, pars.jpeg.quality); assert!(std::path::Path::new(output).exists()); @@ -83,8 +86,9 @@ fn compress_to_range() { String::from(output), &mut pars, max_output_size, - false - ).unwrap(); + false, + ) + .unwrap(); assert!(std::path::Path::new(output).exists()); assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); diff --git a/tests/gif.rs b/tests/gif.rs index 5f6c125..c2fc147 100644 --- a/tests/gif.rs +++ b/tests/gif.rs @@ -1,14 +1,12 @@ -use std::sync::Once; use crate::cleanup::remove_compressed_test_file; +use std::sync::Once; mod cleanup; static INIT: Once = Once::new(); pub fn initialize(file: &str) { - INIT.call_once(|| { - remove_compressed_test_file(file) - }); + INIT.call_once(|| remove_compressed_test_file(file)); } // #[test] diff --git a/tests/jpeg.rs b/tests/jpeg.rs index 98fb688..0a02e91 100644 --- a/tests/jpeg.rs +++ b/tests/jpeg.rs @@ -1,6 +1,6 @@ +use crate::cleanup::remove_compressed_test_file; use dssim::Val; use std::sync::Once; -use crate::cleanup::remove_compressed_test_file; mod cleanup; @@ -106,7 +106,8 @@ fn compress_corrupted_lossy() { String::from("tests/samples/corrupted.jpg"), String::from(output), &pars, - ).is_err()) + ) + .is_err()) } #[test] @@ -142,7 +143,8 @@ fn compress_corrupted_lossless() { String::from("tests/samples/corrupted.jpg"), String::from(output), &pars, - ).is_err()); + ) + .is_err()); } #[test] diff --git a/tests/metadata.rs b/tests/metadata.rs index 9f68954..5d9f89f 100644 --- a/tests/metadata.rs +++ b/tests/metadata.rs @@ -86,10 +86,7 @@ fn extract_exif(path: &Path) -> HashMap { let exif = exif_reader.read_from_container(&mut bufreader).unwrap(); let mut exif_map = HashMap::new(); for f in exif.fields() { - exif_map.insert( - format!("{}", f.tag), - f.display_value().to_string(), - ); + exif_map.insert(format!("{}", f.tag), f.display_value().to_string()); } exif_map diff --git a/tests/png.rs b/tests/png.rs index db5101e..648ec57 100644 --- a/tests/png.rs +++ b/tests/png.rs @@ -1,5 +1,5 @@ -use std::sync::Once; use crate::cleanup::remove_compressed_test_file; +use std::sync::Once; mod cleanup; diff --git a/tests/webp.rs b/tests/webp.rs index 1d668c9..dd0e98a 100644 --- a/tests/webp.rs +++ b/tests/webp.rs @@ -23,7 +23,7 @@ fn compress_20() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -43,7 +43,7 @@ fn compress_50() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -63,7 +63,7 @@ fn compress_80() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -83,7 +83,7 @@ fn compress_100() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -103,7 +103,7 @@ fn optimize() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -125,7 +125,7 @@ fn downscale_compress_80() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(), @@ -148,7 +148,7 @@ fn downscale_optimize() { String::from(output), ¶ms, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); assert_eq!( infer::get_from_path(output).unwrap().unwrap().mime_type(),