Fix resize on PNG to size compression
This commit is contained in:
parent
d49ebd9a79
commit
ea8b3f95a9
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "libcaesium"
|
||||
version = "0.17.2"
|
||||
version = "0.17.3"
|
||||
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
||||
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"] }
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use caesium::parameters::CSParameters;
|
||||
use caesium::compress;
|
||||
use caesium::parameters::CSParameters;
|
||||
use std::env;
|
||||
use std::process::ExitCode;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use caesium::parameters::CSParameters;
|
||||
use caesium::compress;
|
||||
use caesium::parameters::CSParameters;
|
||||
use std::env;
|
||||
use std::process::ExitCode;
|
||||
|
||||
|
|
|
@ -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<u8>, format: SupportedFileTypes, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||
pub fn convert_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
format: SupportedFileTypes,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
let mut iccp = None;
|
||||
let mut exif = None;
|
||||
|
||||
|
@ -23,11 +27,13 @@ pub fn convert_in_memory(in_file: Vec<u8>, 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<u8>, 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<u8>, format: SupportedFileTypes, parameter
|
|||
}
|
||||
|
||||
let mut output_image: Vec<u8> = 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<u8>, 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, CaesiumEr
|
|||
SupportedFileTypes::Gif => 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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
16
src/jpeg.rs
16
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) {}
|
||||
unsafe extern "C-unwind" fn error_message_handler(_cinfo: &mut jpeg_common_struct) {}
|
||||
|
|
62
src/lib.rs
62
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<Vec<u8>, CaesiumError>` - Returns a vector of bytes representing the compressed image if successful, otherwise returns a `CaesiumError`.
|
||||
pub fn compress_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> error::Result<Vec<u8>> {
|
||||
pub fn compress_in_memory(in_file: Vec<u8>, parameters: &CSParameters) -> error::Result<Vec<u8>> {
|
||||
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<Vec<u8>, 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<u8>,
|
||||
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<Vec<u8>, CaesiumError>` - Returns a vector of bytes representing the converted image if successful, otherwise returns a `CaesiumError`.
|
||||
pub fn convert_in_memory(in_file: Vec<u8>, parameters: &CSParameters, format: SupportedFileTypes) -> Result<Vec<u8>, CaesiumError> {
|
||||
pub fn convert_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
format: SupportedFileTypes,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
convert::convert_in_memory(in_file, format, parameters)
|
||||
}
|
||||
|
||||
|
@ -393,4 +399,4 @@ pub enum SupportedFileTypes {
|
|||
WebP,
|
||||
Tiff,
|
||||
Unkn,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
19
src/png.rs
19
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<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
let optimized_png: Vec<u8> = 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)
|
||||
|
|
|
@ -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<u8> = vec![];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
31
src/webp.rs
31
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<u8> = 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
196
tests/convert.rs
196
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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";
|
||||
|
|
86
tests/png.rs
86
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)
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
max_width = 120
|
138
tests/tiff.rs
138
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());
|
||||
}
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue