diff --git a/Cargo.toml b/Cargo.toml index 2f1bf5d..2abedd6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libcaesium" -version = "0.11.0" +version = "0.11.1" authors = ["Matteo Paonessa "] edition = "2021" categories = ["multimedia::images"] diff --git a/src/jpeg.rs b/src/jpeg.rs index 87949ea..78950a9 100644 --- a/src/jpeg.rs +++ b/src/jpeg.rs @@ -11,6 +11,8 @@ use libc::free; use crate::resize::resize; use crate::CSParameters; +static mut JPEG_ERROR: c_int = 0; + pub fn compress( input_path: String, output_path: String, @@ -58,7 +60,10 @@ unsafe fn lossless( let mut dst_err = mem::zeroed(); src_info.common.err = jpeg_std_error(&mut src_err); + (*src_info.common.err).error_exit = Option::Some(error_handler); + dst_info.common.err = jpeg_std_error(&mut dst_err); + (*dst_info.common.err).error_exit = Option::Some(error_handler); jpeg_create_decompress(&mut src_info); jpeg_create_compress(&mut dst_info); @@ -72,7 +77,13 @@ unsafe fn lossless( } } - jpeg_read_header(&mut src_info, i32::from(true)); + jpeg_read_header(&mut src_info, true as boolean); + + if JPEG_ERROR == 11 { + jpeg_destroy_decompress(&mut src_info); + jpeg_create_compress(&mut dst_info); + return Err(io::Error::new(io::ErrorKind::Other, format!("Decompress internal error: {}", JPEG_ERROR))); + } let src_coef_arrays = jpeg_read_coefficients(&mut src_info); jpeg_copy_critical_parameters(&src_info, &mut dst_info); let dst_coef_arrays = src_coef_arrays; @@ -121,7 +132,9 @@ unsafe fn lossy(in_file: Vec, parameters: &CSParameters) -> Result, let mut dst_err = mem::zeroed(); src_info.common.err = jpeg_std_error(&mut src_err); + (*src_info.common.err).error_exit = Option::Some(error_handler); dst_info.common.err = jpeg_std_error(&mut dst_err); + (*dst_info.common.err).error_exit = Option::Some(error_handler); jpeg_create_decompress(&mut src_info); jpeg_create_compress(&mut dst_info); @@ -137,6 +150,12 @@ unsafe fn lossy(in_file: Vec, parameters: &CSParameters) -> Result, jpeg_read_header(&mut src_info, true as boolean); + if JPEG_ERROR == 11 { + jpeg_destroy_decompress(&mut src_info); + jpeg_create_compress(&mut dst_info); + return Err(io::Error::new(io::ErrorKind::Other, format!("Decompress internal error: {}", JPEG_ERROR))); + } + let width = src_info.image_width; let height = src_info.image_height; let color_space = src_info.jpeg_color_space; @@ -257,3 +276,7 @@ fn save_metadata( image_buffer } } + +unsafe extern "C" fn error_handler(cinfo: &mut jpeg_common_struct) { + JPEG_ERROR = (*cinfo.err).msg_code; +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index def54d2..1f94ec4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,16 @@ -use caesium::{compress_to_size, initialize_parameters}; +use caesium::{compress, initialize_parameters}; use std::env; +use std::process::ExitCode; -fn main() { +fn main() -> ExitCode { let args: Vec = env::args().collect(); let input = args[1].clone(); let output = args[2].clone(); - let mut parameters = initialize_parameters(); - compress_to_size(input, output, &mut parameters, args[3].clone().parse().unwrap()).unwrap(); + let parameters = initialize_parameters(); + match compress(input, output, ¶meters) { + Ok(_) => ExitCode::SUCCESS, + Err(_) => ExitCode::FAILURE, + } } diff --git a/tests/jpeg.rs b/tests/jpeg.rs index c483c93..98fb688 100644 --- a/tests/jpeg.rs +++ b/tests/jpeg.rs @@ -96,6 +96,19 @@ fn compress_10() { remove_compressed_test_file(output) } +#[test] +fn compress_corrupted_lossy() { + let output = "tests/samples/output/corrupted_lossy.jpg"; + initialize(output); + let mut pars = caesium::initialize_parameters(); + pars.jpeg.quality = 50; + assert!(caesium::compress( + String::from("tests/samples/corrupted.jpg"), + String::from(output), + &pars, + ).is_err()) +} + #[test] fn optimize_jpeg() { let output = "tests/samples/output/compressed_optimized_드림캐쳐.jpg"; @@ -119,6 +132,19 @@ fn optimize_jpeg() { remove_compressed_test_file(output) } +#[test] +fn compress_corrupted_lossless() { + let output = "tests/samples/output/corrupted_lossless.jpg"; + initialize(output); + let mut pars = caesium::initialize_parameters(); + pars.optimize = true; + assert!(caesium::compress( + String::from("tests/samples/corrupted.jpg"), + String::from(output), + &pars, + ).is_err()); +} + #[test] fn downscale_exact() { let output = "tests/samples/output/downscale_800_600.jpg"; diff --git a/tests/samples/corrupted.jpg b/tests/samples/corrupted.jpg new file mode 100644 index 0000000..d85d5d9 Binary files /dev/null and b/tests/samples/corrupted.jpg differ