diff --git a/src/convert.rs b/src/convert.rs index 1e44057..92db831 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -1,7 +1,7 @@ use std::io::Cursor; use bytes::Bytes; -use image::ImageFormat; +use image::{ColorType, DynamicImage, ImageFormat}; use image::io::Reader as ImageReader; use img_parts::{DynImage, ImageEXIF, ImageICC}; @@ -22,7 +22,7 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter } let i = in_file.as_slice(); - let original_image = ImageReader::new(Cursor::new(i)).with_guessed_format() + let mut original_image = ImageReader::new(Cursor::new(i)).with_guessed_format() .map_err(|e| CaesiumError { message: e.to_string(), code: 10402, @@ -32,6 +32,15 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter code: 10403, })?; + if format == SupportedFileTypes::Jpeg { + original_image = match original_image.color() { + ColorType::Rgba8 => DynamicImage::from(original_image.to_rgb8()), + ColorType::Rgba16 => DynamicImage::from(original_image.to_rgb16()), + ColorType::Rgba32F => DynamicImage::from(original_image.to_rgb32f()), + _ => original_image, + }; + } + let mut output_image: Vec = Vec::new(); original_image.write_to(&mut Cursor::new(&mut output_image), output_format) .map_err(|e| CaesiumError { diff --git a/src/lib.rs b/src/lib.rs index 4372225..00f608f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -175,7 +175,7 @@ pub fn compress_in_memory( SupportedFileTypes::Tiff => tiff::compress_in_memory(in_file, parameters)?, _ => { return Err(CaesiumError { - message: "Format not supported for compression to size".into(), + message: "Format not supported for compression in memory".into(), code: 10200, }); } diff --git a/tests/convert.rs b/tests/convert.rs new file mode 100644 index 0000000..f1a5599 --- /dev/null +++ b/tests/convert.rs @@ -0,0 +1,257 @@ +use std::collections::HashMap; +use std::fs; +use std::path::Path; +use std::sync::Once; + +use caesium::SupportedFileTypes; + +use crate::cleanup::remove_compressed_test_file; + +mod cleanup; + +static INIT: Once = Once::new(); + +pub fn initialize(file: &str) { + INIT.call_once(|| { + remove_compressed_test_file(file); + }); +} + +#[test] +fn convert_jpg_to_png() { + let output = "tests/samples/output/jpg.to.png"; + initialize(output); + let mut params = caesium::initialize_parameters(); + params.keep_metadata = true; + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::Png).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/png" + ); + assert!(metadata_is_equal( + Path::new("tests/samples/uncompressed_드림캐쳐.jpg"), + Path::new(output) + )); + remove_compressed_test_file(output) +} + +#[test] +fn convert_jpg_to_webp() { + let output = "tests/samples/output/jpg.to.webp"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/webp" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_jpg_to_tiff() { + let output = "tests/samples/output/jpg.to.tiff"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/tiff" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_png_to_jpg() { + let output = "tests/samples/output/png.to.jpg"; + initialize(output); + let mut params = caesium::initialize_parameters(); + params.keep_metadata = true; + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/jpeg" + ); + // assert!(metadata_is_equal( + // Path::new("tests/samples/uncompressed_드림캐쳐.png"), + // Path::new(output) + // )); + remove_compressed_test_file(output) +} + +#[test] +fn convert_png_to_webp() { + let output = "tests/samples/output/png.to.webp"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/webp" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_png_to_tiff() { + let output = "tests/samples/output/png.to.tiff"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/tiff" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_webp_to_jpg() { + let output = "tests/samples/output/webp.to.jpg"; + initialize(output); + let mut params = caesium::initialize_parameters(); + params.keep_metadata = true; + caesium::convert(String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/jpeg" + ); + // assert!(metadata_is_equal( + // Path::new("tests/samples/uncompressed_家.webp"), + // Path::new(output) + // )); + remove_compressed_test_file(output) +} + +#[test] +fn convert_webp_to_png() { + let output = "tests/samples/output/webp.to.png"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Png).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/png" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_webp_to_tiff() { + let output = "tests/samples/output/webp.to.tiff"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/tiff" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_tiff_to_jpg() { + let output = "tests/samples/output/tiff.to.jpg"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/jpeg" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_tiff_to_png() { + let output = "tests/samples/output/tiff.to.png"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::Png).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/png" + ); + remove_compressed_test_file(output) +} + +#[test] +fn convert_tiff_to_webp() { + let output = "tests/samples/output/tiff.to.webp"; + initialize(output); + let params = caesium::initialize_parameters(); + caesium::convert(String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP).expect("Image converted successfully"); + assert!(std::path::Path::new(output).exists()); + assert_eq!( + infer::get_from_path(output).unwrap().unwrap().mime_type(), + "image/webp" + ); + remove_compressed_test_file(output) +} + +fn extract_exif(path: &Path) -> HashMap { + let file = fs::File::open(path).unwrap(); + let mut bufreader = std::io::BufReader::new(&file); + let exif_reader = exif::Reader::new(); + 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 +} + +fn metadata_is_equal(input: &Path, output: &Path) -> bool { + let original_exif_map = extract_exif(input); + let compressed_exif_map = extract_exif(output); + + original_exif_map.eq(&compressed_exif_map) +} diff --git a/tests/metadata.rs b/tests/metadata.rs index a87f154..3216366 100644 --- a/tests/metadata.rs +++ b/tests/metadata.rs @@ -78,6 +78,27 @@ fn jpeg_resize_optimize_with_metadata() { )); remove_compressed_test_file(output) } +// +// #[test] +// fn webp_compress_80_with_metadata() { +// let output = "tests/samples/output/compressed_80_metadata.webp"; +// initialize(output); +// let mut pars = caesium::initialize_parameters(); +// pars.webp.quality = 80; +// pars.keep_metadata = true; +// caesium::compress( +// String::from("tests/samples/uncompressed_家.webp"), +// String::from(output), +// &pars, +// ) +// .unwrap(); +// assert!(Path::new(output).exists()); +// assert!(metadata_is_equal( +// Path::new("tests/samples/uncompressed_家.webp"), +// Path::new(output) +// )); +// remove_compressed_test_file(output) +// } fn extract_exif(path: &Path) -> HashMap { let file = fs::File::open(path).unwrap(); diff --git a/tests/samples/output/.gitignore b/tests/samples/output/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/tests/samples/output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/tests/samples/output/.gitkeep b/tests/samples/output/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/samples/uncompressed_metadata.webp b/tests/samples/uncompressed_metadata.webp deleted file mode 100644 index 5dd9209..0000000 Binary files a/tests/samples/uncompressed_metadata.webp and /dev/null differ diff --git a/tests/samples/uncompressed_家.webp b/tests/samples/uncompressed_家.webp index 5d3ea02..fbdd2d8 100644 Binary files a/tests/samples/uncompressed_家.webp and b/tests/samples/uncompressed_家.webp differ