Progressive/baseline JPEG switch while optimizing
This commit is contained in:
parent
ba31f9d7c6
commit
c912159261
14
src/jpeg.rs
14
src/jpeg.rs
|
@ -4,6 +4,7 @@ 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;
|
||||
|
@ -15,7 +16,7 @@ use crate::error::CaesiumError;
|
|||
use crate::parameters::ChromaSubsampling;
|
||||
use crate::resize::resize;
|
||||
|
||||
static mut JPEG_ERROR: c_int = 0;
|
||||
static JPEG_ERROR: AtomicI32 = AtomicI32::new(0);
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
|
@ -63,7 +64,7 @@ pub fn compress_in_memory(
|
|||
})
|
||||
.unwrap_or_else(|_| {
|
||||
Err(CaesiumError {
|
||||
message: format!("Internal JPEG error: {}", JPEG_ERROR),
|
||||
message: format!("Internal JPEG error: {}", JPEG_ERROR.load(Ordering::SeqCst)),
|
||||
code: 20104,
|
||||
})
|
||||
})
|
||||
|
@ -107,6 +108,9 @@ unsafe fn lossless(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8
|
|||
let mut buf = ptr::null_mut();
|
||||
let mut buf_size = 0;
|
||||
jpeg_mem_dest(&mut dst_info, &mut buf, &mut buf_size);
|
||||
if !parameters.jpeg.progressive {
|
||||
dst_info.scan_info = null();
|
||||
}
|
||||
jpeg_write_coefficients(&mut dst_info, dst_coef_arrays);
|
||||
|
||||
if parameters.keep_metadata {
|
||||
|
@ -312,8 +316,8 @@ unsafe fn set_chroma_subsampling(
|
|||
}
|
||||
|
||||
unsafe extern "C-unwind" fn error_handler(cinfo: &mut jpeg_common_struct) {
|
||||
JPEG_ERROR = (*cinfo.err).msg_code;
|
||||
panic!("Internal JPEG error: {}", JPEG_ERROR);
|
||||
JPEG_ERROR.store((*cinfo.err).msg_code, Ordering::SeqCst);
|
||||
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) {}
|
|
@ -1,6 +1,6 @@
|
|||
extern crate alloc;
|
||||
|
||||
use std::{cmp, fs};
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
|
@ -14,12 +14,12 @@ pub mod error;
|
|||
mod gif;
|
||||
mod interface;
|
||||
#[cfg(feature = "jpg")]
|
||||
pub mod jpeg;
|
||||
mod jpeg;
|
||||
#[cfg(feature = "png")]
|
||||
mod png;
|
||||
mod resize;
|
||||
#[cfg(feature = "tiff")]
|
||||
pub mod tiff;
|
||||
mod tiff;
|
||||
mod utils;
|
||||
#[cfg(feature = "webp")]
|
||||
mod webp;
|
||||
|
@ -179,7 +179,7 @@ pub fn compress_to_size_in_memory(
|
|||
last_high = quality;
|
||||
}
|
||||
let last_quality = quality;
|
||||
quality = cmp::max(1, cmp::min(100, (last_high + last_less) / 2));
|
||||
quality = ((last_high + last_less) / 2).clamp(1, 100);
|
||||
if last_quality == quality {
|
||||
if quality == 1 && last_high == 1 {
|
||||
return if return_smallest {
|
||||
|
|
|
@ -66,13 +66,19 @@ pub struct CSParameters {
|
|||
pub height: u32,
|
||||
pub output_size: u32,
|
||||
}
|
||||
impl Default for CSParameters {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl CSParameters {
|
||||
pub fn new() -> CSParameters {
|
||||
initialize_parameters()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn initialize_parameters() -> CSParameters {
|
||||
fn initialize_parameters() -> CSParameters {
|
||||
let jpeg = JpegParameters {
|
||||
quality: 80,
|
||||
chroma_subsampling: ChromaSubsampling::Auto,
|
||||
|
|
10
src/webp.rs
10
src/webp.rs
|
@ -59,7 +59,7 @@ pub fn compress_in_memory(
|
|||
message: e.to_string(),
|
||||
code: 20306,
|
||||
})?
|
||||
.map_or((None, None), |dimg| (dimg.icc_profile(), dimg.exif()));
|
||||
.map_or((None, None), |dyn_img| (dyn_img.icc_profile(), dyn_img.exif()));
|
||||
}
|
||||
|
||||
let must_resize = parameters.width > 0 || parameters.height > 0;
|
||||
|
@ -171,13 +171,13 @@ pub fn compress_in_memory(
|
|||
|
||||
if iccp.is_some() || exif.is_some() {
|
||||
let mut image_with_metadata: Vec<u8> = vec![];
|
||||
let mut dimg = match PartsWebp::from_bytes(encoded_image.clone().into()) {
|
||||
let mut dyn_img = match PartsWebp::from_bytes(encoded_image.clone().into()) {
|
||||
Ok(d) => d,
|
||||
Err(_) => return Ok(encoded_image)
|
||||
};
|
||||
dimg.set_icc_profile(iccp);
|
||||
dimg.set_exif(exif);
|
||||
dimg.encoder()
|
||||
dyn_img.set_icc_profile(iccp);
|
||||
dyn_img.set_exif(exif);
|
||||
dyn_img.encoder()
|
||||
.write_to(&mut image_with_metadata)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
|
|
|
@ -27,7 +27,7 @@ fn convert_jpg_to_png() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Png).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/png"
|
||||
|
@ -48,7 +48,7 @@ fn convert_jpg_to_webp() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::WebP).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/webp"
|
||||
|
@ -65,7 +65,7 @@ fn convert_jpg_to_tiff() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Tiff).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/tiff"
|
||||
|
@ -83,7 +83,7 @@ fn convert_png_to_jpg() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Jpeg).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/jpeg"
|
||||
|
@ -104,7 +104,7 @@ fn convert_png_to_webp() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::WebP).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/webp"
|
||||
|
@ -121,7 +121,7 @@ fn convert_png_to_tiff() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Tiff).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/tiff"
|
||||
|
@ -139,7 +139,7 @@ fn convert_webp_to_jpg() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Jpeg).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/jpeg"
|
||||
|
@ -160,7 +160,7 @@ fn convert_webp_to_png() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Png).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/png"
|
||||
|
@ -177,7 +177,7 @@ fn convert_webp_to_tiff() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Tiff).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/tiff"
|
||||
|
@ -194,7 +194,7 @@ fn convert_tiff_to_jpg() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Jpeg).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/jpeg"
|
||||
|
@ -211,7 +211,7 @@ fn convert_tiff_to_png() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::Png).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/png"
|
||||
|
@ -228,7 +228,7 @@ fn convert_tiff_to_webp() {
|
|||
String::from(output),
|
||||
¶ms,
|
||||
SupportedFileTypes::WebP).expect("Image converted successfully");
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
assert!(Path::new(output).exists());
|
||||
assert_eq!(
|
||||
infer::get_from_path(output).unwrap().unwrap().mime_type(),
|
||||
"image/webp"
|
||||
|
|
Loading…
Reference in New Issue