From ea8b3f95a9c0149507122bf6cc30951ca417e4c6 Mon Sep 17 00:00:00 2001 From: Matteo Paonessa Date: Fri, 21 Feb 2025 13:35:34 +0100 Subject: [PATCH] Fix resize on PNG to size compression --- Cargo.toml | 7 +- examples/basic.rs | 2 +- examples/convert.rs | 9 +- examples/lossless.rs | 2 +- src/convert.rs | 39 ++++---- src/gif.rs | 2 +- src/interface.rs | 12 ++- src/jpeg.rs | 16 ++-- src/lib.rs | 62 ++++++------ src/parameters.rs | 26 ++--- src/png.rs | 19 +++- src/resize.rs | 3 +- src/tiff.rs | 2 +- src/utils.rs | 7 +- src/webp.rs | 31 +++--- tests/compress_to_size.rs | 27 +++++- tests/convert.rs | 196 +++++++++++++++++++------------------- tests/jpeg.rs | 38 +++++--- tests/metadata.rs | 6 +- tests/png.rs | 86 +++++++++-------- tests/rustfmt.toml | 1 + tests/tiff.rs | 138 +++++++++------------------ tests/webp.rs | 61 ++++-------- 23 files changed, 407 insertions(+), 385 deletions(-) create mode 100644 tests/rustfmt.toml diff --git a/Cargo.toml b/Cargo.toml index abfe230..6f47a58 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libcaesium" -version = "0.17.2" +version = "0.17.3" authors = ["Matteo Paonessa "] edition = "2021" categories = ["multimedia::images"] @@ -43,9 +43,12 @@ img-parts = "0.3.3" bytes = "1.7" lodepng = { version = "3.10", optional = true } imagequant = { version = "4.3", optional = true, default-features = false } -tiff = { version = "0.9" } +tiff = "0.9" kamadak-exif = "0.6" +[target.wasm32-unknown-emscripten.dependencies] +libwebp-sys = "=0.9.5" + [dev-dependencies] dssim = { version = "3.3", default-features = false, features = ["no-macos-vimage"] } diff --git a/examples/basic.rs b/examples/basic.rs index d56b156..ee22853 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,5 +1,5 @@ -use caesium::parameters::CSParameters; use caesium::compress; +use caesium::parameters::CSParameters; use std::env; use std::process::ExitCode; diff --git a/examples/convert.rs b/examples/convert.rs index da59238..5cd074c 100644 --- a/examples/convert.rs +++ b/examples/convert.rs @@ -1,5 +1,5 @@ -use caesium::parameters::CSParameters; use caesium::convert; +use caesium::parameters::CSParameters; use std::env; use std::process::ExitCode; @@ -13,7 +13,12 @@ fn main() -> ExitCode { parameters.keep_metadata = true; parameters.webp.quality = 60; - match convert(input, output, ¶meters, caesium::SupportedFileTypes::WebP) { + match convert( + input, + output, + ¶meters, + caesium::SupportedFileTypes::WebP, + ) { Ok(_) => ExitCode::SUCCESS, Err(e) => { eprintln!("{}", e); diff --git a/examples/lossless.rs b/examples/lossless.rs index 7059a1b..a8f7f55 100644 --- a/examples/lossless.rs +++ b/examples/lossless.rs @@ -1,5 +1,5 @@ -use caesium::parameters::CSParameters; use caesium::compress; +use caesium::parameters::CSParameters; use std::env; use std::process::ExitCode; diff --git a/src/convert.rs b/src/convert.rs index 918163e..60eca6f 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -4,11 +4,15 @@ use bytes::Bytes; use image::{ColorType, DynamicImage, ImageFormat, ImageReader}; use img_parts::{DynImage, ImageEXIF, ImageICC}; -use crate::{compress_in_memory, CSParameters, SupportedFileTypes}; use crate::error::CaesiumError; use crate::utils::{get_filetype_from_memory, get_jpeg_orientation}; +use crate::{compress_in_memory, CSParameters, SupportedFileTypes}; -pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameters: &CSParameters) -> Result, CaesiumError> { +pub fn convert_in_memory( + in_file: Vec, + format: SupportedFileTypes, + parameters: &CSParameters, +) -> Result, CaesiumError> { let mut iccp = None; let mut exif = None; @@ -23,11 +27,13 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter } let i = in_file.as_slice(); - let mut 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, - })?.decode() + })? + .decode() .map_err(|e| CaesiumError { message: e.to_string(), code: 10403, @@ -44,7 +50,7 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter 6 => original_image.rotate90(), 7 => original_image.fliph().rotate90(), 8 => original_image.rotate270(), - _ => original_image + _ => original_image, } } @@ -66,14 +72,15 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter } let mut output_image: Vec = Vec::new(); - original_image.write_to(&mut Cursor::new(&mut output_image), output_format) + original_image + .write_to(&mut Cursor::new(&mut output_image), output_format) .map_err(|e| CaesiumError { message: e.to_string(), code: 10404, })?; - let compressed_converted_image = compress_in_memory(output_image, parameters) - .map_err(|e| CaesiumError { + let compressed_converted_image = + compress_in_memory(output_image, parameters).map_err(|e| CaesiumError { message: e.to_string(), code: 10405, })?; @@ -103,9 +110,7 @@ pub fn convert_in_memory(in_file: Vec, format: SupportedFileTypes, parameter Ok(output_image_with_metadata) } - None => { - Ok(compressed_converted_image) - } + None => Ok(compressed_converted_image), } } else { Ok(compressed_converted_image) @@ -119,11 +124,13 @@ fn map_image_format(format: SupportedFileTypes) -> Result ImageFormat::Gif, SupportedFileTypes::WebP => ImageFormat::WebP, SupportedFileTypes::Tiff => ImageFormat::Tiff, - _ => return Err(CaesiumError { - message: "Output format is unknown".into(), - code: 10400, - }) + _ => { + return Err(CaesiumError { + message: "Output format is unknown".into(), + code: 10400, + }) + } }; Ok(image_format) -} \ No newline at end of file +} diff --git a/src/gif.rs b/src/gif.rs index e8eebea..f452404 100644 --- a/src/gif.rs +++ b/src/gif.rs @@ -1,8 +1,8 @@ use std::ffi::CString; use std::os::raw::{c_int, c_void}; -use crate::CSParameters; use crate::error::CaesiumError; +use crate::CSParameters; pub fn compress( input_path: String, diff --git a/src/interface.rs b/src/interface.rs index 22b99cd..5e16d4a 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -1,9 +1,11 @@ use std::ffi::{CStr, CString}; use std::os::raw::c_char; -use crate::{compress, compress_to_size, convert, CSParameters, error, SupportedFileTypes, TiffDeflateLevel}; use crate::parameters::ChromaSubsampling; use crate::parameters::TiffCompression::{Deflate, Lzw, Packbits, Uncompressed}; +use crate::{ + compress, compress_to_size, convert, error, CSParameters, SupportedFileTypes, TiffDeflateLevel, +}; #[repr(C)] pub struct CCSParameters { @@ -80,7 +82,7 @@ pub unsafe extern "C" fn c_convert( CStr::from_ptr(input_path).to_str().unwrap().to_string(), CStr::from_ptr(output_path).to_str().unwrap().to_string(), ¶meters, - format + format, )) } @@ -124,7 +126,7 @@ fn c_set_parameters(params: CCSParameters) -> CSParameters { parameters.webp.quality = params.webp_quality; parameters.width = params.width; parameters.height = params.height; - + parameters.jpeg.chroma_subsampling = match params.jpeg_chroma_subsampling { 444 => ChromaSubsampling::CS444, 422 => ChromaSubsampling::CS422, @@ -137,13 +139,13 @@ fn c_set_parameters(params: CCSParameters) -> CSParameters { 1 => Lzw, 2 => Deflate, 3 => Packbits, - _ => Uncompressed + _ => Uncompressed, }; parameters.tiff.deflate_level = match params.tiff_deflate_level { 1 => TiffDeflateLevel::Fast, 6 => TiffDeflateLevel::Balanced, - _ => TiffDeflateLevel::Best + _ => TiffDeflateLevel::Best, }; parameters diff --git a/src/jpeg.rs b/src/jpeg.rs index 6de5a29..ade76e7 100644 --- a/src/jpeg.rs +++ b/src/jpeg.rs @@ -1,20 +1,20 @@ -use std::{fs, ptr}; +use image::ImageFormat::Jpeg; +use img_parts::jpeg::Jpeg as PartsJpeg; +use img_parts::{ImageEXIF, ImageICC}; +use libc::free; +use mozjpeg_sys::*; use std::fs::File; use std::io::Write; use std::mem; use std::panic::catch_unwind; use std::ptr::null; use std::sync::atomic::{AtomicI32, Ordering}; -use image::ImageFormat::Jpeg; -use img_parts::{ImageEXIF, ImageICC}; -use img_parts::jpeg::Jpeg as PartsJpeg; -use libc::free; -use mozjpeg_sys::*; +use std::{fs, ptr}; -use crate::{CSParameters}; use crate::error::CaesiumError; use crate::parameters::ChromaSubsampling; use crate::resize::resize; +use crate::CSParameters; static JPEG_ERROR: AtomicI32 = AtomicI32::new(0); @@ -320,4 +320,4 @@ unsafe extern "C-unwind" fn error_handler(cinfo: &mut jpeg_common_struct) { panic!("Internal JPEG error: {}", JPEG_ERROR.load(Ordering::SeqCst)); } -unsafe extern "C-unwind" fn error_message_handler(_cinfo: &mut jpeg_common_struct) {} \ No newline at end of file +unsafe extern "C-unwind" fn error_message_handler(_cinfo: &mut jpeg_common_struct) {} diff --git a/src/lib.rs b/src/lib.rs index 19d8eaf..6892a4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,17 +4,19 @@ use std::fs; use std::fs::File; use std::io::Write; -use error::CaesiumError; -use crate::parameters::{CSParameters, TiffDeflateLevel}; use crate::parameters::TiffCompression::{Deflate, Lzw, Packbits}; +use crate::parameters::{CSParameters, TiffDeflateLevel}; use crate::utils::{get_filetype_from_memory, get_filetype_from_path}; +use error::CaesiumError; +mod convert; pub mod error; #[cfg(feature = "gif")] mod gif; mod interface; #[cfg(feature = "jpg")] mod jpeg; +pub mod parameters; #[cfg(feature = "png")] mod png; mod resize; @@ -23,8 +25,6 @@ mod tiff; mod utils; #[cfg(feature = "webp")] mod webp; -mod convert; -pub mod parameters; /// Compresses an image file from the input path and writes the compressed image to the output path. /// @@ -87,10 +87,7 @@ pub fn compress( /// # Returns /// /// * `Result, CaesiumError>` - Returns a vector of bytes representing the compressed image if successful, otherwise returns a `CaesiumError`. -pub fn compress_in_memory( - in_file: Vec, - parameters: &CSParameters, -) -> error::Result> { +pub fn compress_in_memory(in_file: Vec, parameters: &CSParameters) -> error::Result> { let file_type = get_filetype_from_memory(in_file.as_slice()); let compressed_file = match file_type { #[cfg(feature = "jpg")] @@ -124,7 +121,6 @@ pub fn compress_in_memory( /// # Returns /// /// * `Result, CaesiumError>` - Returns a vector of bytes representing the compressed image if successful, otherwise returns a `CaesiumError`. - pub fn compress_to_size_in_memory( in_file: Vec, parameters: &mut CSParameters, @@ -136,7 +132,7 @@ pub fn compress_to_size_in_memory( let tolerance_percentage = 2; let tolerance = max_output_size * tolerance_percentage / 100; let mut quality = 80; - let mut last_less = 1; + let mut last_less = 0; let mut last_high = 101; let max_tries: u32 = 10; let mut tries: u32 = 0; @@ -144,10 +140,7 @@ pub fn compress_to_size_in_memory( let compressed_file = match file_type { #[cfg(feature = "tiff")] SupportedFileTypes::Tiff => { - let algorithms = [ - Lzw, - Packbits - ]; + let algorithms = [Lzw, Packbits]; parameters.tiff.deflate_level = TiffDeflateLevel::Best; parameters.tiff.algorithm = Deflate; let mut smallest_result = tiff::compress_in_memory(in_file.clone(), parameters)?; //TODO clone @@ -261,13 +254,16 @@ pub fn compress_to_size( code: 10201, })?; let original_size = in_file.len(); - if original_size <= max_output_size { + + // If we resize, we should always go for at least a round of compression + if !(parameters.width > 0 || parameters.height > 0) && original_size <= max_output_size { 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 { @@ -296,9 +292,12 @@ pub fn compress_to_size( /// # Returns /// /// * `Result<(), CaesiumError>` - Returns `Ok(())` if conversion is successful, otherwise returns a `CaesiumError`. - -pub fn convert(input_path: String, output_path: String, parameters: &CSParameters, format: SupportedFileTypes) -> error::Result<()> { - +pub fn convert( + input_path: String, + output_path: String, + parameters: &CSParameters, + format: SupportedFileTypes, +) -> error::Result<()> { let file_type = get_filetype_from_path(&input_path); if file_type == format { @@ -312,20 +311,23 @@ pub fn convert(input_path: String, output_path: String, parameters: &CSParameter message: e.to_string(), code: 10410, })?; - let output_buffer = convert_in_memory(in_file, parameters, format).map_err(|e| CaesiumError { - message: e.to_string(), - code: 10411, - })?; + let output_buffer = + convert_in_memory(in_file, parameters, format).map_err(|e| CaesiumError { + message: e.to_string(), + code: 10411, + })?; let mut out_file = File::create(output_path).map_err(|e| CaesiumError { message: e.to_string(), code: 10412, })?; - out_file.write_all(&output_buffer).map_err(|e| CaesiumError { - message: e.to_string(), - code: 10413, - })?; + out_file + .write_all(&output_buffer) + .map_err(|e| CaesiumError { + message: e.to_string(), + code: 10413, + })?; Ok(()) } @@ -341,7 +343,11 @@ pub fn convert(input_path: String, output_path: String, parameters: &CSParameter /// # Returns /// /// * `Result, CaesiumError>` - Returns a vector of bytes representing the converted image if successful, otherwise returns a `CaesiumError`. -pub fn convert_in_memory(in_file: Vec, parameters: &CSParameters, format: SupportedFileTypes) -> Result, CaesiumError> { +pub fn convert_in_memory( + in_file: Vec, + parameters: &CSParameters, + format: SupportedFileTypes, +) -> Result, CaesiumError> { convert::convert_in_memory(in_file, format, parameters) } @@ -393,4 +399,4 @@ pub enum SupportedFileTypes { WebP, Tiff, Unkn, -} \ No newline at end of file +} diff --git a/src/parameters.rs b/src/parameters.rs index 7589741..341d25c 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -1,7 +1,7 @@ use crate::parameters::TiffCompression::Deflate; /// Enum representing different chroma subsampling options for JPEG compression. -/// +/// /// - `CS444`: 4:4:4 chroma subsampling /// - `CS422`: 4:2:2 chroma subsampling /// - `CS420`: 4:2:0 chroma subsampling @@ -17,7 +17,7 @@ pub enum ChromaSubsampling { } /// Enum representing different compression algorithms for TIFF images. -/// +/// /// - `Uncompressed`: No compression /// - `Lzw`: LZW compression /// - `Deflate`: Deflate compression @@ -31,7 +31,7 @@ pub enum TiffCompression { } /// Enum representing different deflate levels for TIFF compression. -/// +/// /// - `Fast`: Fast compression /// - `Balanced`: Balanced compression /// - `Best`: Best compression @@ -43,7 +43,7 @@ pub enum TiffDeflateLevel { } /// Struct representing parameters for JPEG compression. -/// +/// /// Fields: /// - `quality`: Quality of the JPEG image (0-100) /// - `chroma_subsampling`: Chroma subsampling option @@ -56,7 +56,7 @@ pub struct JpegParameters { } /// Struct representing parameters for PNG compression. -/// +/// /// Fields: /// - `quality`: Quality of the PNG image (0-100) /// - `force_zopfli`: Whether to force the use of Zopfli compression (can be very slow) @@ -69,7 +69,7 @@ pub struct PngParameters { } /// Struct representing parameters for GIF compression. -/// +/// /// Fields: /// - `quality`: Quality of the GIF image (0-100) #[derive(Copy, Clone)] @@ -78,7 +78,7 @@ pub struct GifParameters { } /// Struct representing parameters for WebP compression. -/// +/// /// Fields: /// - `quality`: Quality of the WebP image (0-100) #[derive(Copy, Clone)] @@ -87,7 +87,7 @@ pub struct WebPParameters { } /// Struct representing parameters for TIFF compression. -/// +/// /// Fields: /// - `algorithm`: Compression algorithm for TIFF /// - `deflate_level`: Deflate level for TIFF compression @@ -98,7 +98,7 @@ pub struct TiffParameters { } /// Struct representing overall compression parameters. -/// +/// /// Fields: /// - `jpeg`: JPEG compression parameters /// - `png`: PNG compression parameters @@ -119,7 +119,7 @@ pub struct CSParameters { pub keep_metadata: bool, pub optimize: bool, pub width: u32, - pub height: u32 + pub height: u32, } impl Default for CSParameters { fn default() -> Self { @@ -137,7 +137,7 @@ fn initialize_parameters() -> CSParameters { let jpeg = JpegParameters { quality: 80, chroma_subsampling: ChromaSubsampling::Auto, - progressive: true + progressive: true, }; let png = PngParameters { quality: 80, @@ -160,6 +160,6 @@ fn initialize_parameters() -> CSParameters { keep_metadata: false, optimize: false, width: 0, - height: 0 + height: 0, } -} \ No newline at end of file +} diff --git a/src/png.rs b/src/png.rs index fa1f0b8..2f94418 100644 --- a/src/png.rs +++ b/src/png.rs @@ -6,9 +6,9 @@ use std::num::NonZeroU8; use image::ImageFormat; use oxipng::Deflaters::Zopfli; -use crate::CSParameters; use crate::error::CaesiumError; use crate::resize::resize; +use crate::CSParameters; pub fn compress( input_path: String, @@ -48,10 +48,21 @@ pub fn compress_in_memory( in_file: Vec, parameters: &CSParameters, ) -> Result, CaesiumError> { - let optimized_png: Vec = if parameters.optimize { - lossless(in_file, parameters)? + let input = if parameters.width > 0 || parameters.height > 0 { + resize( + in_file, + parameters.width, + parameters.height, + ImageFormat::Png, + )? } else { - lossy(in_file, parameters)? + in_file + }; + + let optimized_png = if parameters.optimize { + lossless(input, parameters)? + } else { + lossy(input, parameters)? }; Ok(optimized_png) diff --git a/src/resize.rs b/src/resize.rs index 083b2f1..5815df1 100644 --- a/src/resize.rs +++ b/src/resize.rs @@ -34,7 +34,8 @@ pub fn resize( code: 10301, })?; - let dimensions = compute_dimensions(image.width(), image.height(), desired_width, desired_height); + let dimensions = + compute_dimensions(image.width(), image.height(), desired_width, desired_height); image = image.resize_exact(dimensions.0, dimensions.1, FilterType::Lanczos3); let mut resized_file: Vec = vec![]; diff --git a/src/tiff.rs b/src/tiff.rs index c3fe0fb..0d3e8a1 100644 --- a/src/tiff.rs +++ b/src/tiff.rs @@ -7,10 +7,10 @@ use tiff::encoder::colortype::{RGB8, RGBA8}; use tiff::encoder::compression::{Deflate, DeflateLevel, Lzw, Packbits, Uncompressed}; use tiff::encoder::TiffEncoder; -use crate::{CSParameters, TiffDeflateLevel}; use crate::error::CaesiumError; use crate::parameters::TiffCompression; use crate::resize::resize_image; +use crate::{CSParameters, TiffDeflateLevel}; pub fn compress( input_path: String, diff --git a/src/utils.rs b/src/utils.rs index c590b37..76b84fd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ -use std::io::Cursor; -use infer::Type; use crate::SupportedFileTypes; +use infer::Type; +use std::io::Cursor; pub fn get_filetype_from_path(file_path: &str) -> SupportedFileTypes { match infer::get_from_path(file_path) { @@ -25,7 +25,7 @@ pub fn get_jpeg_orientation(data: &[u8]) -> u32 { let exif_data = match reader.read_from_container(&mut cursor) { Ok(v) => v, - Err(_) => return 1 + Err(_) => return 1, }; let exif_field = match exif_data.get_field(exif::Tag::Orientation, exif::In::PRIMARY) { @@ -36,7 +36,6 @@ pub fn get_jpeg_orientation(data: &[u8]) -> u32 { exif_field.value.get_uint(0).unwrap_or(1) } - fn match_supported_filetypes(ft: Type) -> SupportedFileTypes { match ft.mime_type() { "image/jpeg" => SupportedFileTypes::Jpeg, diff --git a/src/webp.rs b/src/webp.rs index 28c85b1..8158e98 100644 --- a/src/webp.rs +++ b/src/webp.rs @@ -4,13 +4,13 @@ use std::ops::Deref; use bytes::Bytes; use image::{DynamicImage, ImageBuffer}; -use img_parts::{DynImage, ImageEXIF, ImageICC}; use img_parts::webp::WebP as PartsWebp; +use img_parts::{DynImage, ImageEXIF, ImageICC}; use webp::{AnimDecoder, AnimEncoder, AnimFrame, WebPConfig}; -use crate::CSParameters; use crate::error::CaesiumError; use crate::resize::resize_image; +use crate::CSParameters; pub fn compress( input_path: String, @@ -59,7 +59,9 @@ pub fn compress_in_memory( message: e.to_string(), code: 20306, })? - .map_or((None, None), |dyn_img| (dyn_img.icc_profile(), dyn_img.exif())); + .map_or((None, None), |dyn_img| { + (dyn_img.icc_profile(), dyn_img.exif()) + }); } let must_resize = parameters.width > 0 || parameters.height > 0; @@ -84,7 +86,6 @@ pub fn compress_in_memory( config.lossless = if parameters.optimize { 1 } else { 0 }; config.alpha_compression = if parameters.optimize { 0 } else { 1 }; config.quality = parameters.webp.quality as f32; - let mut images_data = vec![]; let mut width = 0; @@ -118,11 +119,14 @@ pub fn compress_in_memory( if must_resize { if images_data.get(i).is_some() { - encoder.add_frame(AnimFrame::from_image(images_data.get(i).unwrap(), last_ms) - .map_err(|e| CaesiumError { - message: e.to_string(), - code: 20310, - })?); + encoder.add_frame( + AnimFrame::from_image(images_data.get(i).unwrap(), last_ms).map_err( + |e| CaesiumError { + message: e.to_string(), + code: 20310, + }, + )?, + ); } } else { encoder.add_frame(f); @@ -138,7 +142,7 @@ pub fn compress_in_memory( code: 20311, }); } - Some(f) => f + Some(f) => f, }; let mut input_image = (&first_frame).into(); if must_resize { @@ -173,11 +177,12 @@ pub fn compress_in_memory( let mut image_with_metadata: Vec = vec![]; let mut dyn_img = match PartsWebp::from_bytes(encoded_image.clone().into()) { Ok(d) => d, - Err(_) => return Ok(encoded_image) + Err(_) => return Ok(encoded_image), }; dyn_img.set_icc_profile(iccp); dyn_img.set_exif(exif); - dyn_img.encoder() + dyn_img + .encoder() .write_to(&mut image_with_metadata) .map_err(|e| CaesiumError { message: e.to_string(), @@ -211,4 +216,4 @@ fn to_dynamic_image(frame: AnimFrame) -> DynamicImage { .expect("ImageBuffer couldn't be created"); DynamicImage::ImageRgb8(image) } -} \ No newline at end of file +} diff --git a/tests/compress_to_size.rs b/tests/compress_to_size.rs index 8557834..dee9881 100644 --- a/tests/compress_to_size.rs +++ b/tests/compress_to_size.rs @@ -1,7 +1,7 @@ use crate::cleanup::remove_compressed_test_file; +use caesium::parameters::CSParameters; use std::fs::File; use std::sync::Once; -use caesium::parameters::CSParameters; mod cleanup; @@ -99,3 +99,28 @@ fn compress_to_range() { remove_compressed_test_file(output); } } + +#[test] +fn compress_to_higher_size_and_resize() { + let output = "tests/samples/output/compressed_10mb.jpg"; + let max_output_size = 100_000_000; + initialize(output); + let mut pars = CSParameters::new(); + pars.width = 800; + pars.height = 600; + caesium::compress_to_size( + String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + &mut pars, + max_output_size, + false, + ) + .unwrap(); + + assert!(std::path::Path::new(output).exists()); + assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); + let kind = infer::get_from_path(output).unwrap().unwrap(); + assert_eq!(kind.mime_type(), "image/jpeg"); + assert_eq!(image::image_dimensions(output).unwrap(), (800, 600)); + remove_compressed_test_file(output) +} diff --git a/tests/convert.rs b/tests/convert.rs index ef2d1e5..803b847 100644 --- a/tests/convert.rs +++ b/tests/convert.rs @@ -1,9 +1,9 @@ +use caesium::parameters::CSParameters; +use caesium::SupportedFileTypes; use std::collections::HashMap; use std::fs; use std::path::Path; use std::sync::Once; -use caesium::parameters::CSParameters; -use caesium::SupportedFileTypes; use crate::cleanup::remove_compressed_test_file; @@ -23,15 +23,15 @@ fn convert_jpg_to_png() { initialize(output); let mut params = CSParameters::new(); params.keep_metadata = true; - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), - String::from(output), - ¶ms, - SupportedFileTypes::Png).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::Png, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + 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) @@ -44,15 +44,15 @@ fn convert_jpg_to_webp() { let output = "tests/samples/output/jpg.to.webp"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), - String::from(output), - ¶ms, - SupportedFileTypes::WebP).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -61,15 +61,15 @@ fn convert_jpg_to_tiff() { let output = "tests/samples/output/jpg.to.tiff"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.jpg"), - String::from(output), - ¶ms, - SupportedFileTypes::Tiff).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.jpg"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -79,15 +79,15 @@ fn convert_png_to_jpg() { initialize(output); let mut params = CSParameters::new(); params.keep_metadata = true; - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), - String::from(output), - ¶ms, - SupportedFileTypes::Jpeg).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/jpeg" - ); + 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) @@ -100,15 +100,15 @@ fn convert_png_to_webp() { let output = "tests/samples/output/png.to.webp"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), - String::from(output), - ¶ms, - SupportedFileTypes::WebP).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -117,15 +117,15 @@ fn convert_png_to_tiff() { let output = "tests/samples/output/png.to.tiff"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_드림캐쳐.png"), - String::from(output), - ¶ms, - SupportedFileTypes::Tiff).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -135,15 +135,15 @@ fn convert_webp_to_jpg() { initialize(output); let mut params = CSParameters::new(); params.keep_metadata = true; - caesium::convert(String::from("tests/samples/uncompressed_家.webp"), - String::from(output), - ¶ms, - SupportedFileTypes::Jpeg).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/jpeg" - ); + 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) @@ -156,15 +156,15 @@ fn convert_webp_to_png() { let output = "tests/samples/output/webp.to.png"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_家.webp"), - String::from(output), - ¶ms, - SupportedFileTypes::Png).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Png, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); remove_compressed_test_file(output) } @@ -173,15 +173,15 @@ fn convert_webp_to_tiff() { let output = "tests/samples/output/webp.to.tiff"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/uncompressed_家.webp"), - String::from(output), - ¶ms, - SupportedFileTypes::Tiff).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/uncompressed_家.webp"), + String::from(output), + ¶ms, + SupportedFileTypes::Tiff, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -190,15 +190,15 @@ fn convert_tiff_to_jpg() { let output = "tests/samples/output/tiff.to.jpg"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - SupportedFileTypes::Jpeg).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::Jpeg, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/jpeg" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/jpeg"); remove_compressed_test_file(output) } @@ -207,15 +207,15 @@ fn convert_tiff_to_png() { let output = "tests/samples/output/tiff.to.png"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - SupportedFileTypes::Png).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::Png, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); remove_compressed_test_file(output) } @@ -224,15 +224,15 @@ fn convert_tiff_to_webp() { let output = "tests/samples/output/tiff.to.webp"; initialize(output); let params = CSParameters::new(); - caesium::convert(String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - SupportedFileTypes::WebP).expect("Image converted successfully"); + caesium::convert( + String::from("tests/samples/rgba8.tif"), + String::from(output), + ¶ms, + SupportedFileTypes::WebP, + ) + .expect("Image converted successfully"); assert!(Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } diff --git a/tests/jpeg.rs b/tests/jpeg.rs index 9a47e17..f027362 100644 --- a/tests/jpeg.rs +++ b/tests/jpeg.rs @@ -1,7 +1,7 @@ use crate::cleanup::remove_compressed_test_file; -use dssim::Val; -use std::sync::Once; use caesium::parameters::CSParameters; +use dssim::Val; +use std::{fs::File, sync::Once}; mod cleanup; @@ -103,12 +103,7 @@ fn compress_corrupted_lossy() { initialize(output); let mut pars = CSParameters::new(); pars.jpeg.quality = 50; - assert!(caesium::compress( - String::from("tests/samples/corrupted.jpg"), - String::from(output), - &pars, - ) - .is_err()) + assert!(caesium::compress(String::from("tests/samples/corrupted.jpg"), String::from(output), &pars,).is_err()) } #[test] @@ -140,12 +135,31 @@ fn compress_corrupted_lossless() { initialize(output); let mut pars = CSParameters::new(); pars.optimize = true; - assert!(caesium::compress( - String::from("tests/samples/corrupted.jpg"), + assert!(caesium::compress(String::from("tests/samples/corrupted.jpg"), String::from(output), &pars,).is_err()); +} + +#[test] +fn downscale_to_size() { + let max_output_size = 2_000_000; + let output = "tests/samples/output/downscale_800_600_to_size.jpg"; + initialize(output); + let mut pars = CSParameters::new(); + pars.width = 800; + pars.height = 600; + caesium::compress_to_size( + String::from("tests/samples/uncompressed_드림캐쳐.jpg"), String::from(output), - &pars, + &mut pars, + max_output_size, + false, ) - .is_err()); + .unwrap(); + assert!(std::path::Path::new(output).exists()); + let kind = infer::get_from_path(output).unwrap().unwrap(); + assert_eq!(kind.mime_type(), "image/jpeg"); + assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); + assert_eq!(image::image_dimensions(output).unwrap(), (800, 600)); + remove_compressed_test_file(output) } #[test] diff --git a/tests/metadata.rs b/tests/metadata.rs index 2460132..bb3a56a 100644 --- a/tests/metadata.rs +++ b/tests/metadata.rs @@ -1,9 +1,9 @@ +use crate::cleanup::remove_compressed_test_file; +use caesium::parameters::CSParameters; use std::collections::HashMap; use std::fs; use std::path::Path; use std::sync::Once; -use caesium::parameters::CSParameters; -use crate::cleanup::remove_compressed_test_file; mod cleanup; static INIT: Once = Once::new(); @@ -78,7 +78,7 @@ 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"; diff --git a/tests/png.rs b/tests/png.rs index 07aea74..5ac0932 100644 --- a/tests/png.rs +++ b/tests/png.rs @@ -1,6 +1,6 @@ use crate::cleanup::remove_compressed_test_file; -use std::sync::Once; use caesium::parameters::CSParameters; +use std::{fs::File, sync::Once}; mod cleanup; @@ -23,10 +23,7 @@ fn standard_compress_png() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); assert_eq!(image::image_dimensions(output).unwrap(), (380, 287)); remove_compressed_test_file(output) } @@ -44,31 +41,29 @@ fn standard_compress_png_with_optimize_flag() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); assert_eq!(image::image_dimensions(output).unwrap(), (380, 287)); remove_compressed_test_file(output) } -// #[test] -// fn zopfli_compress_png() { -// let output = "tests/samples/output/optimized.png"; -// initialize(output); -// let mut params = CSParameters::new(); -// params.png.level = 3; -// params.optimize = true; -// params.png.force_zopfli = true; -// caesium::compress(String::from("tests/samples/uncompressed_드림캐쳐.png"), -// String::from(output), -// params) -// .unwrap(); -// assert!(std::path::Path::new(output).exists()); -// assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); -// assert_eq!(image::image_dimensions(output).unwrap(), (380, 287)); -// remove_compressed_test_file(output) -// } +#[test] +fn zopfli_compress_png() { + let output = "tests/samples/output/optimized.png"; + initialize(output); + let mut params = CSParameters::new(); + params.optimize = true; + params.png.force_zopfli = true; + caesium::compress( + String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + ¶ms, + ) + .unwrap(); + assert!(std::path::Path::new(output).exists()); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); + assert_eq!(image::image_dimensions(output).unwrap(), (380, 287)); + remove_compressed_test_file(output) +} #[test] fn downscale_standard_compress_png() { @@ -84,10 +79,7 @@ fn downscale_standard_compress_png() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); assert_eq!(image::image_dimensions(output).unwrap(), (150, 150)); remove_compressed_test_file(output) } @@ -107,10 +99,7 @@ fn downscale_standard_compress_png_with_optimize_flag() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); assert_eq!(image::image_dimensions(output).unwrap(), (150, 150)); remove_compressed_test_file(output) } @@ -132,10 +121,31 @@ fn downscale_zopfli_compress_png() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/png" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/png"); + assert_eq!(image::image_dimensions(output).unwrap(), (150, 150)); + remove_compressed_test_file(output) +} + +#[test] +fn downscale_to_size() { + let max_output_size = 20_000; + let output = "tests/samples/output/downscale_to_size.png"; + initialize(output); + let mut pars = CSParameters::new(); + pars.width = 150; + pars.height = 150; + caesium::compress_to_size( + String::from("tests/samples/uncompressed_드림캐쳐.png"), + String::from(output), + &mut pars, + max_output_size, + false, + ) + .unwrap(); + assert!(std::path::Path::new(output).exists()); + let kind = infer::get_from_path(output).unwrap().unwrap(); + assert_eq!(kind.mime_type(), "image/png"); + assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); assert_eq!(image::image_dimensions(output).unwrap(), (150, 150)); remove_compressed_test_file(output) } diff --git a/tests/rustfmt.toml b/tests/rustfmt.toml new file mode 100644 index 0000000..866c756 --- /dev/null +++ b/tests/rustfmt.toml @@ -0,0 +1 @@ +max_width = 120 \ No newline at end of file diff --git a/tests/tiff.rs b/tests/tiff.rs index 3ed9498..d314c7e 100644 --- a/tests/tiff.rs +++ b/tests/tiff.rs @@ -1,6 +1,6 @@ -use std::sync::Once; -use caesium::parameters::{CSParameters, TiffCompression, TiffDeflateLevel}; use crate::cleanup::remove_compressed_test_file; +use caesium::parameters::{CSParameters, TiffCompression, TiffDeflateLevel}; +use std::{fs::File, sync::Once}; mod cleanup; static INIT: Once = Once::new(); @@ -17,17 +17,9 @@ fn rgb8_uncompressed() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Uncompressed; - caesium::compress( - String::from("tests/samples/rgb8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgb8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -37,17 +29,9 @@ fn rgba8_uncompressed() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Uncompressed; - caesium::compress( - String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgba8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -58,17 +42,9 @@ fn rgb8_deflate() { let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Deflate; params.tiff.deflate_level = TiffDeflateLevel::Balanced; - caesium::compress( - String::from("tests/samples/rgb8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgb8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -79,17 +55,9 @@ fn rgba8_deflate() { let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Deflate; params.tiff.deflate_level = TiffDeflateLevel::Balanced; - caesium::compress( - String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgba8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -99,17 +67,9 @@ fn rgb8_lzw() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Lzw; - caesium::compress( - String::from("tests/samples/rgb8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgb8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -119,17 +79,9 @@ fn rgba8_lzw() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Lzw; - caesium::compress( - String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgba8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -139,17 +91,9 @@ fn rgb8_packbits() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Packbits; - caesium::compress( - String::from("tests/samples/rgb8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgb8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -159,17 +103,9 @@ fn rgba8_packbits() { initialize(output); let mut params = CSParameters::new(); params.tiff.algorithm = TiffCompression::Packbits; - caesium::compress( - String::from("tests/samples/rgba8.tif"), - String::from(output), - ¶ms, - ) - .unwrap(); + caesium::compress(String::from("tests/samples/rgba8.tif"), String::from(output), ¶ms).unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); remove_compressed_test_file(output) } @@ -181,17 +117,33 @@ fn rgb8_downscale() { params.tiff.algorithm = TiffCompression::Lzw; params.width = 50; params.height = 20; - caesium::compress( + caesium::compress(String::from("tests/samples/rgb8.tif"), String::from(output), ¶ms).unwrap(); + assert!(std::path::Path::new(output).exists()); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); + assert_eq!(image::image_dimensions(output).unwrap(), (50, 20)); + remove_compressed_test_file(output) +} + +#[test] +fn rgb8_downscale_to_size() { + let max_output_size = 10_000; + let output = "tests/samples/output/downscale_rgb8_to_size.tif"; + initialize(output); + let mut params = CSParameters::new(); + params.tiff.algorithm = TiffCompression::Lzw; + params.width = 50; + params.height = 20; + caesium::compress_to_size( String::from("tests/samples/rgb8.tif"), String::from(output), - ¶ms, + &mut params, + max_output_size, + false, ) - .unwrap(); + .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/tiff" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/tiff"); + assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); assert_eq!(image::image_dimensions(output).unwrap(), (50, 20)); remove_compressed_test_file(output) } @@ -206,7 +158,8 @@ fn unsupported() { String::from("tests/samples/unsupported.tif"), String::from(output), ¶ms, - ).is_err()); + ) + .is_err()); } #[test] @@ -219,5 +172,6 @@ fn prevent_panic() { String::from("tests/samples/unsupported.tif"), String::from(output), ¶ms, - ).is_err()); -} \ No newline at end of file + ) + .is_err()); +} diff --git a/tests/webp.rs b/tests/webp.rs index b95d8a0..62dc5ae 100644 --- a/tests/webp.rs +++ b/tests/webp.rs @@ -1,6 +1,6 @@ -use std::sync::Once; -use caesium::parameters::CSParameters; use crate::cleanup::remove_compressed_test_file; +use caesium::parameters::CSParameters; +use std::{fs::File, sync::Once}; mod cleanup; @@ -25,10 +25,7 @@ fn compress_20() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -45,10 +42,7 @@ fn compress_50() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -65,10 +59,7 @@ fn compress_80() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -85,10 +76,7 @@ fn compress_100() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } @@ -105,32 +93,29 @@ fn optimize() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) } #[test] -fn downscale_compress_80() { - let output = "tests/samples/output/downscale_compressed_80.webp"; +fn downscale_to_size() { + let max_output_size = 100_000; + let output = "tests/samples/output/downscale_to_size.webp"; initialize(output); let mut params = CSParameters::new(); - params.webp.quality = 80; params.width = 150; params.height = 100; - caesium::compress( + caesium::compress_to_size( String::from("tests/samples/uncompressed_家.webp"), String::from(output), - ¶ms, + &mut params, + max_output_size, + false, ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); + assert!(File::open(output).unwrap().metadata().unwrap().len() < max_output_size as u64); assert_eq!(image::image_dimensions(output).unwrap(), (150, 100)); remove_compressed_test_file(output) } @@ -150,10 +135,7 @@ fn downscale_optimize() { ) .unwrap(); assert!(std::path::Path::new(output).exists()); - assert_eq!( - infer::get_from_path(output).unwrap().unwrap().mime_type(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); assert_eq!(image::image_dimensions(output).unwrap(), (150, 100)); remove_compressed_test_file(output) } @@ -169,11 +151,8 @@ fn compress_animated_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(), - "image/webp" - ); + assert_eq!(infer::get_from_path(output).unwrap().unwrap().mime_type(), "image/webp"); remove_compressed_test_file(output) -} \ No newline at end of file +}