Fix tiff compression to size
This commit is contained in:
parent
ea8b3f95a9
commit
0d99042cbf
|
@ -0,0 +1,21 @@
|
|||
name: Clippy check
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
|
||||
env:
|
||||
RUSTFLAGS: "-Dwarnings"
|
||||
|
||||
jobs:
|
||||
clippy_check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run Clippy
|
||||
run: cargo clippy --all-targets --all-features
|
|
@ -0,0 +1,27 @@
|
|||
name: Code formatting
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
|
||||
jobs:
|
||||
fmt_check:
|
||||
name: Fmt
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
|
||||
- name: Check code formatting
|
||||
run: cargo fmt -- --check
|
|
@ -37,7 +37,7 @@ oxipng = { version = "9.0", default-features = false, features = ["filetime", "z
|
|||
libc = "0.2"
|
||||
gifsicle = { version = "1.95", optional = true }
|
||||
webp = { version = "0.3.0", optional = true }
|
||||
infer = "0.16.0"
|
||||
infer = "0.19.0"
|
||||
image = { version = "0.25.1", default-features = false }
|
||||
img-parts = "0.3.3"
|
||||
bytes = "1.7"
|
||||
|
|
|
@ -13,12 +13,7 @@ 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);
|
||||
|
|
|
@ -79,15 +79,14 @@ pub fn convert_in_memory(
|
|||
code: 10404,
|
||||
})?;
|
||||
|
||||
let compressed_converted_image =
|
||||
compress_in_memory(output_image, parameters).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10405,
|
||||
})?;
|
||||
let compressed_converted_image = compress_in_memory(output_image, parameters).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10405,
|
||||
})?;
|
||||
|
||||
if parameters.keep_metadata {
|
||||
let dyn_image = DynImage::from_bytes(Bytes::from(compressed_converted_image.clone()))
|
||||
.map_err(|e| CaesiumError {
|
||||
let dyn_image =
|
||||
DynImage::from_bytes(Bytes::from(compressed_converted_image.clone())).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10408,
|
||||
})?;
|
||||
|
|
12
src/gif.rs
12
src/gif.rs
|
@ -4,11 +4,7 @@ use std::os::raw::{c_int, c_void};
|
|||
use crate::error::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
if parameters.width > 0 || parameters.height > 0 {
|
||||
return Err(CaesiumError {
|
||||
message: "GIF resizing is not supported".to_string(),
|
||||
|
@ -58,11 +54,7 @@ fn lossless(input_path: String, output_path: String) -> Result<(), CaesiumError>
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lossy(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn lossy(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
unsafe {
|
||||
let input_file = libc::fopen(
|
||||
CString::new(input_path)
|
||||
|
|
|
@ -3,9 +3,7 @@ use std::os::raw::c_char;
|
|||
|
||||
use crate::parameters::ChromaSubsampling;
|
||||
use crate::parameters::TiffCompression::{Deflate, Lzw, Packbits, Uncompressed};
|
||||
use crate::{
|
||||
compress, compress_to_size, convert, error, CSParameters, SupportedFileTypes, TiffDeflateLevel,
|
||||
};
|
||||
use crate::{compress, compress_to_size, convert, error, CSParameters, SupportedFileTypes, TiffDeflateLevel};
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSParameters {
|
||||
|
|
49
src/jpeg.rs
49
src/jpeg.rs
|
@ -18,11 +18,7 @@ use crate::CSParameters;
|
|||
|
||||
static JPEG_ERROR: AtomicI32 = AtomicI32::new(0);
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
let in_file = fs::read(input_path).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20100,
|
||||
|
@ -40,10 +36,7 @@ pub fn compress(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compress_in_memory(
|
||||
mut in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
pub fn compress_in_memory(mut in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||
if parameters.width > 0 || parameters.height > 0 {
|
||||
if parameters.keep_metadata {
|
||||
let metadata = extract_metadata(in_file.clone());
|
||||
|
@ -200,11 +193,7 @@ unsafe fn lossy(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>,
|
|||
let row_stride = dst_info.image_width as usize * dst_info.input_components as usize;
|
||||
dst_info.dct_method = J_DCT_METHOD::JDCT_ISLOW;
|
||||
dst_info.optimize_coding = i32::from(true);
|
||||
jpeg_set_quality(
|
||||
&mut dst_info,
|
||||
parameters.jpeg.quality as i32,
|
||||
false as boolean,
|
||||
);
|
||||
jpeg_set_quality(&mut dst_info, parameters.jpeg.quality as i32, false as boolean);
|
||||
|
||||
if !parameters.jpeg.progressive {
|
||||
dst_info.scan_info = null();
|
||||
|
@ -244,17 +233,12 @@ fn extract_metadata(image: Vec<u8>) -> (Option<img_parts::Bytes>, Option<img_par
|
|||
}
|
||||
|
||||
//TODO if image is resized, change "PixelXDimension" and "PixelYDimension"
|
||||
fn save_metadata(
|
||||
image_buffer: Vec<u8>,
|
||||
iccp: Option<img_parts::Bytes>,
|
||||
exif: Option<img_parts::Bytes>,
|
||||
) -> Vec<u8> {
|
||||
fn save_metadata(image_buffer: Vec<u8>, iccp: Option<img_parts::Bytes>, exif: Option<img_parts::Bytes>) -> Vec<u8> {
|
||||
if iccp.is_some() || exif.is_some() {
|
||||
let mut dyn_image =
|
||||
match PartsJpeg::from_bytes(img_parts::Bytes::from(image_buffer.clone())) {
|
||||
Ok(d) => d,
|
||||
Err(_) => return image_buffer,
|
||||
};
|
||||
let mut dyn_image = match PartsJpeg::from_bytes(img_parts::Bytes::from(image_buffer.clone())) {
|
||||
Ok(d) => d,
|
||||
Err(_) => return image_buffer,
|
||||
};
|
||||
|
||||
dyn_image.set_icc_profile(iccp);
|
||||
dyn_image.set_exif(exif);
|
||||
|
@ -269,27 +253,16 @@ fn save_metadata(
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn write_metadata(
|
||||
src_info: &mut jpeg_decompress_struct,
|
||||
dst_info: &mut jpeg_compress_struct,
|
||||
) {
|
||||
unsafe fn write_metadata(src_info: &mut jpeg_decompress_struct, dst_info: &mut jpeg_compress_struct) {
|
||||
let mut marker = src_info.marker_list;
|
||||
|
||||
while !marker.is_null() {
|
||||
jpeg_write_marker(
|
||||
dst_info,
|
||||
(*marker).marker as i32,
|
||||
(*marker).data,
|
||||
(*marker).data_length,
|
||||
);
|
||||
jpeg_write_marker(dst_info, (*marker).marker as i32, (*marker).data, (*marker).data_length);
|
||||
marker = (*marker).next;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn set_chroma_subsampling(
|
||||
subsampling: ChromaSubsampling,
|
||||
dst_info: &mut jpeg_compress_struct,
|
||||
) {
|
||||
unsafe fn set_chroma_subsampling(subsampling: ChromaSubsampling, dst_info: &mut jpeg_compress_struct) {
|
||||
(*dst_info.comp_info.add(1)).h_samp_factor = 1;
|
||||
(*dst_info.comp_info.add(1)).v_samp_factor = 1;
|
||||
(*dst_info.comp_info.add(2)).h_samp_factor = 1;
|
||||
|
|
44
src/lib.rs
44
src/lib.rs
|
@ -37,11 +37,7 @@ mod webp;
|
|||
/// # Returns
|
||||
///
|
||||
/// * `Result<(), CaesiumError>` - Returns `Ok(())` if compression is successful, otherwise returns a `CaesiumError`.
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> error::Result<()> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> error::Result<()> {
|
||||
validate_parameters(parameters)?;
|
||||
let file_type = get_filetype_from_path(&input_path);
|
||||
|
||||
|
@ -151,7 +147,7 @@ pub fn compress_to_size_in_memory(
|
|||
smallest_result = result;
|
||||
}
|
||||
}
|
||||
return if return_smallest {
|
||||
return if return_smallest || smallest_result.len() <= max_output_size {
|
||||
Ok(smallest_result)
|
||||
} else {
|
||||
Err(CaesiumError {
|
||||
|
@ -194,9 +190,7 @@ pub fn compress_to_size_in_memory(
|
|||
|
||||
let compressed_file_size = compressed_file.len();
|
||||
|
||||
if compressed_file_size <= max_output_size
|
||||
&& max_output_size - compressed_file_size < tolerance
|
||||
{
|
||||
if compressed_file_size <= max_output_size && max_output_size - compressed_file_size < tolerance {
|
||||
break compressed_file;
|
||||
}
|
||||
|
||||
|
@ -264,18 +258,15 @@ pub fn compress_to_size(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let compressed_file =
|
||||
compress_to_size_in_memory(in_file, parameters, max_output_size, return_smallest)?;
|
||||
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 {
|
||||
message: e.to_string(),
|
||||
code: 10203,
|
||||
})?;
|
||||
out_file
|
||||
.write_all(&compressed_file)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10204,
|
||||
})?;
|
||||
out_file.write_all(&compressed_file).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10204,
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -311,23 +302,20 @@ pub fn convert(
|
|||
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(())
|
||||
}
|
||||
|
|
53
src/png.rs
53
src/png.rs
|
@ -10,23 +10,14 @@ use crate::error::CaesiumError;
|
|||
use crate::resize::resize;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
let mut in_file = fs::read(input_path).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20200,
|
||||
})?;
|
||||
|
||||
if parameters.width > 0 || parameters.height > 0 {
|
||||
in_file = resize(
|
||||
in_file,
|
||||
parameters.width,
|
||||
parameters.height,
|
||||
ImageFormat::Png,
|
||||
)?;
|
||||
in_file = resize(in_file, parameters.width, parameters.height, ImageFormat::Png)?;
|
||||
}
|
||||
|
||||
let optimized_png = compress_in_memory(in_file, parameters)?;
|
||||
|
@ -44,17 +35,9 @@ pub fn compress(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compress_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
pub fn compress_in_memory(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||
let input = if parameters.width > 0 || parameters.height > 0 {
|
||||
resize(
|
||||
in_file,
|
||||
parameters.width,
|
||||
parameters.height,
|
||||
ImageFormat::Png,
|
||||
)?
|
||||
resize(in_file, parameters.width, parameters.height, ImageFormat::Png)?
|
||||
} else {
|
||||
in_file
|
||||
};
|
||||
|
@ -98,20 +81,16 @@ fn lossy(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, Caesium
|
|||
code: 20207,
|
||||
})?;
|
||||
|
||||
let (palette, pixels) = quantization
|
||||
.remapped(&mut liq_image)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20208,
|
||||
})?;
|
||||
let (palette, pixels) = quantization.remapped(&mut liq_image).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20208,
|
||||
})?;
|
||||
|
||||
let mut encoder = lodepng::Encoder::new();
|
||||
encoder
|
||||
.set_palette(palette.as_slice())
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20212,
|
||||
})?;
|
||||
encoder.set_palette(palette.as_slice()).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20212,
|
||||
})?;
|
||||
let png_vec = encoder
|
||||
.encode(pixels.as_slice(), rgba_bitmap.width, rgba_bitmap.height)
|
||||
.map_err(|e| CaesiumError {
|
||||
|
@ -142,11 +121,9 @@ fn lossless(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, Caes
|
|||
}
|
||||
|
||||
let optimized_png =
|
||||
oxipng::optimize_from_memory(in_file.as_slice(), &oxipng_options).map_err(|e| {
|
||||
CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20210,
|
||||
}
|
||||
oxipng::optimize_from_memory(in_file.as_slice(), &oxipng_options).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20210,
|
||||
})?;
|
||||
|
||||
Ok(optimized_png)
|
||||
|
|
|
@ -18,7 +18,7 @@ pub fn resize(
|
|||
let orientation = get_jpeg_orientation(buffer_slice);
|
||||
(desired_width, desired_height) = match orientation {
|
||||
5..=8 => (height, width),
|
||||
_ => (width, height)
|
||||
_ => (width, height),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,7 @@ 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![];
|
||||
|
@ -106,10 +105,7 @@ fn downscale_on_width() {
|
|||
let original_width = 800;
|
||||
let original_height = 600;
|
||||
|
||||
assert_eq!(
|
||||
compute_dimensions(original_width, original_height, 750, 0),
|
||||
(750, 563)
|
||||
)
|
||||
assert_eq!(compute_dimensions(original_width, original_height, 750, 0), (750, 563))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -117,8 +113,5 @@ fn downscale_on_height() {
|
|||
let original_width = 800;
|
||||
let original_height = 600;
|
||||
|
||||
assert_eq!(
|
||||
compute_dimensions(original_width, original_height, 0, 478),
|
||||
(637, 478)
|
||||
)
|
||||
assert_eq!(compute_dimensions(original_width, original_height, 0, 478), (637, 478))
|
||||
}
|
||||
|
|
69
src/tiff.rs
69
src/tiff.rs
|
@ -12,23 +12,17 @@ use crate::parameters::TiffCompression;
|
|||
use crate::resize::resize_image;
|
||||
use crate::{CSParameters, TiffDeflateLevel};
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
let mut input_file = File::open(input_path).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20500,
|
||||
})?;
|
||||
|
||||
let mut input_data = Vec::new();
|
||||
input_file
|
||||
.read_to_end(&mut input_data)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20501,
|
||||
})?;
|
||||
input_file.read_to_end(&mut input_data).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20501,
|
||||
})?;
|
||||
|
||||
let compressed_image = compress_in_memory(input_data, parameters)?;
|
||||
|
||||
|
@ -37,30 +31,23 @@ pub fn compress(
|
|||
code: 20502,
|
||||
})?;
|
||||
|
||||
output_file
|
||||
.write_all(&compressed_image)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20503,
|
||||
})?;
|
||||
output_file.write_all(&compressed_image).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20503,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compress_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
let decoding_result =
|
||||
match panic::catch_unwind(|| image::load_from_memory_with_format(in_file.as_slice(), Tiff))
|
||||
{
|
||||
Ok(i) => i,
|
||||
Err(_) => {
|
||||
return Err(CaesiumError {
|
||||
message: "Failed to decode TIFF image".to_string(),
|
||||
code: 20504,
|
||||
});
|
||||
}
|
||||
};
|
||||
pub fn compress_in_memory(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||
let decoding_result = match panic::catch_unwind(|| image::load_from_memory_with_format(in_file.as_slice(), Tiff)) {
|
||||
Ok(i) => i,
|
||||
Err(_) => {
|
||||
return Err(CaesiumError {
|
||||
message: "Failed to decode TIFF image".to_string(),
|
||||
code: 20504,
|
||||
});
|
||||
}
|
||||
};
|
||||
let mut image = match decoding_result {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
|
@ -106,18 +93,12 @@ pub fn compress_in_memory(
|
|||
},
|
||||
|
||||
TiffCompression::Lzw => match color_type {
|
||||
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Lzw>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Lzw,
|
||||
image.as_bytes(),
|
||||
),
|
||||
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Lzw>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Lzw,
|
||||
image.as_bytes(),
|
||||
),
|
||||
image::ColorType::Rgb8 => {
|
||||
encoder.write_image_with_compression::<RGB8, Lzw>(image.width(), image.height(), Lzw, image.as_bytes())
|
||||
}
|
||||
image::ColorType::Rgba8 => {
|
||||
encoder.write_image_with_compression::<RGBA8, Lzw>(image.width(), image.height(), Lzw, image.as_bytes())
|
||||
}
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: format!("Unsupported TIFF color type ({:?})", color_type).to_string(),
|
||||
|
|
55
src/webp.rs
55
src/webp.rs
|
@ -12,23 +12,17 @@ use crate::error::CaesiumError;
|
|||
use crate::resize::resize_image;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<(), CaesiumError> {
|
||||
pub fn compress(input_path: String, output_path: String, parameters: &CSParameters) -> Result<(), CaesiumError> {
|
||||
let mut input_file = File::open(input_path).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20300,
|
||||
})?;
|
||||
|
||||
let mut input_data = Vec::new();
|
||||
input_file
|
||||
.read_to_end(&mut input_data)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20301,
|
||||
})?;
|
||||
input_file.read_to_end(&mut input_data).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20301,
|
||||
})?;
|
||||
|
||||
let compressed_image = compress_in_memory(input_data, parameters)?;
|
||||
|
||||
|
@ -37,19 +31,14 @@ pub fn compress(
|
|||
code: 20302,
|
||||
})?;
|
||||
|
||||
output_file
|
||||
.write_all(&compressed_image)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20303,
|
||||
})?;
|
||||
output_file.write_all(&compressed_image).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20303,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compress_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
pub fn compress_in_memory(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>, CaesiumError> {
|
||||
let mut iccp: Option<Bytes> = None;
|
||||
let mut exif: Option<Bytes> = None;
|
||||
|
||||
|
@ -59,9 +48,7 @@ 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;
|
||||
|
@ -120,12 +107,10 @@ 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,
|
||||
},
|
||||
)?,
|
||||
AnimFrame::from_image(images_data.get(i).unwrap(), last_ms).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20310,
|
||||
})?,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -206,14 +191,12 @@ fn to_rgba(value: u32) -> [u8; 4] {
|
|||
|
||||
fn to_dynamic_image(frame: AnimFrame) -> DynamicImage {
|
||||
if frame.get_layout().is_alpha() {
|
||||
let image =
|
||||
ImageBuffer::from_raw(frame.width(), frame.height(), frame.get_image().to_owned())
|
||||
.expect("ImageBuffer couldn't be created");
|
||||
let image = ImageBuffer::from_raw(frame.width(), frame.height(), frame.get_image().to_owned())
|
||||
.expect("ImageBuffer couldn't be created");
|
||||
DynamicImage::ImageRgba8(image)
|
||||
} else {
|
||||
let image =
|
||||
ImageBuffer::from_raw(frame.width(), frame.height(), frame.get_image().to_owned())
|
||||
.expect("ImageBuffer couldn't be created");
|
||||
let image = ImageBuffer::from_raw(frame.width(), frame.height(), frame.get_image().to_owned())
|
||||
.expect("ImageBuffer couldn't be created");
|
||||
DynamicImage::ImageRgb8(image)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ fn rgb8_downscale() {
|
|||
|
||||
#[test]
|
||||
fn rgb8_downscale_to_size() {
|
||||
let max_output_size = 10_000;
|
||||
let max_output_size = 100_000;
|
||||
let output = "tests/samples/output/downscale_rgb8_to_size.tif";
|
||||
initialize(output);
|
||||
let mut params = CSParameters::new();
|
||||
|
@ -138,7 +138,7 @@ fn rgb8_downscale_to_size() {
|
|||
String::from(output),
|
||||
&mut params,
|
||||
max_output_size,
|
||||
false,
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(std::path::Path::new(output).exists());
|
||||
|
|
Loading…
Reference in New Issue