TIFF draft
This commit is contained in:
parent
09eb085bf3
commit
4c958aac64
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "libcaesium"
|
||||
version = "0.14.1"
|
||||
version = "0.15.0"
|
||||
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
||||
edition = "2021"
|
||||
categories = ["multimedia::images"]
|
||||
|
@ -21,11 +21,12 @@ repository = "https://github.com/Lymphatus/libcaesium"
|
|||
license = "Apache-2.0"
|
||||
|
||||
[features]
|
||||
default = ["jpg", "png", "webp", "gif", "parallel"]
|
||||
default = ["jpg", "png", "webp", "gif", "tiff", "parallel"]
|
||||
jpg = ["dep:mozjpeg-sys", "image/jpeg"]
|
||||
png = ["dep:oxipng", "dep:lodepng", "dep:imagequant", "image/png"]
|
||||
webp = ["dep:webp", "image/webp"]
|
||||
gif = ["dep:gifsicle", "image/gif"]
|
||||
tiff = ["dep:tiff", "image/tiff"]
|
||||
parallel = ["oxipng?/parallel", "imagequant?/threads", "dssim/threads"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -39,7 +40,8 @@ image = { version = "0.24.8", default-features = false }
|
|||
img-parts = "0.3"
|
||||
bytes = "1.5"
|
||||
lodepng = { version = "3.10", optional = true }
|
||||
imagequant = {version = "4.3", optional = true, default-features = false}
|
||||
imagequant = { version = "4.3", optional = true, default-features = false }
|
||||
tiff = { version = "0.9", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
dssim = { version = "3.3", default-features = false, features = ["no-macos-vimage"] }
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
use core::fmt;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, CaesiumError>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CaesiumError {
|
||||
pub message: String,
|
||||
pub code: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for CaesiumError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} [{}]", self.message, self.code)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use std::ffi::CString;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
||||
use crate::utils::CaesiumError;
|
||||
use crate::error::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
use crate::jpeg::ChromaSubsampling;
|
||||
use crate::{compress, compress_to_size, error, initialize_parameters, CSParameters};
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSParameters {
|
||||
pub keep_metadata: bool,
|
||||
pub jpeg_quality: u32,
|
||||
pub jpeg_chroma_subsampling: u32,
|
||||
pub png_quality: u32,
|
||||
pub png_force_zopfli: bool,
|
||||
pub gif_quality: u32,
|
||||
pub webp_quality: u32,
|
||||
pub optimize: bool,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSResult {
|
||||
pub success: bool,
|
||||
pub code: u32,
|
||||
pub error_message: *const c_char,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe extern "C" fn c_compress(
|
||||
input_path: *const c_char,
|
||||
output_path: *const c_char,
|
||||
params: CCSParameters,
|
||||
) -> CCSResult {
|
||||
let parameters = c_set_parameters(params);
|
||||
|
||||
c_return_result(compress(
|
||||
CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
CStr::from_ptr(output_path).to_str().unwrap().to_string(),
|
||||
¶meters,
|
||||
))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe extern "C" fn c_compress_to_size(
|
||||
input_path: *const c_char,
|
||||
output_path: *const c_char,
|
||||
params: CCSParameters,
|
||||
max_output_size: usize,
|
||||
return_smallest: bool,
|
||||
) -> CCSResult {
|
||||
let mut parameters = c_set_parameters(params);
|
||||
|
||||
c_return_result(compress_to_size(
|
||||
CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
CStr::from_ptr(output_path).to_str().unwrap().to_string(),
|
||||
&mut parameters,
|
||||
max_output_size,
|
||||
return_smallest,
|
||||
))
|
||||
}
|
||||
|
||||
fn c_return_result(result: error::Result<()>) -> CCSResult {
|
||||
let mut error_message = CString::new("").unwrap();
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let em_pointer = error_message.as_ptr();
|
||||
std::mem::forget(error_message);
|
||||
CCSResult {
|
||||
success: true,
|
||||
code: 0,
|
||||
error_message: em_pointer,
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error_message = CString::new(e.to_string()).unwrap();
|
||||
let em_pointer = error_message.as_ptr();
|
||||
std::mem::forget(error_message);
|
||||
CCSResult {
|
||||
success: false,
|
||||
code: e.code,
|
||||
error_message: em_pointer,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn c_set_parameters(params: CCSParameters) -> CSParameters {
|
||||
let mut parameters = initialize_parameters();
|
||||
|
||||
parameters.jpeg.quality = params.jpeg_quality;
|
||||
parameters.png.quality = params.png_quality;
|
||||
parameters.optimize = params.optimize;
|
||||
parameters.keep_metadata = params.keep_metadata;
|
||||
parameters.png.force_zopfli = params.png_force_zopfli;
|
||||
parameters.gif.quality = params.gif_quality;
|
||||
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,
|
||||
420 => ChromaSubsampling::CS420,
|
||||
411 => ChromaSubsampling::CS411,
|
||||
_ => ChromaSubsampling::Auto,
|
||||
};
|
||||
|
||||
parameters
|
||||
}
|
|
@ -10,8 +10,8 @@ use img_parts::{ImageEXIF, ImageICC};
|
|||
use libc::free;
|
||||
use mozjpeg_sys::*;
|
||||
|
||||
use crate::error::CaesiumError;
|
||||
use crate::resize::resize;
|
||||
use crate::utils::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
|
||||
static mut JPEG_ERROR: c_int = 0;
|
||||
|
|
157
src/lib.rs
157
src/lib.rs
|
@ -1,47 +1,30 @@
|
|||
extern crate alloc;
|
||||
|
||||
use crate::jpeg::ChromaSubsampling;
|
||||
use crate::tiff::TiffCompression;
|
||||
use crate::tiff::TiffCompression::Deflate;
|
||||
use crate::utils::{get_filetype_from_memory, get_filetype_from_path, SupportedFileTypes};
|
||||
use alloc::ffi::CString;
|
||||
use std::ffi::CStr;
|
||||
use ::tiff::encoder::compression::DeflateLevel;
|
||||
use error::CaesiumError;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::os::raw::c_char;
|
||||
use std::{cmp, fs};
|
||||
use utils::CaesiumError;
|
||||
|
||||
mod error;
|
||||
#[cfg(feature = "gif")]
|
||||
mod gif;
|
||||
mod interface;
|
||||
#[cfg(feature = "jpg")]
|
||||
pub mod jpeg;
|
||||
#[cfg(feature = "png")]
|
||||
mod png;
|
||||
mod resize;
|
||||
#[cfg(feature = "tiff")]
|
||||
mod tiff;
|
||||
mod utils;
|
||||
#[cfg(feature = "webp")]
|
||||
mod webp;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSParameters {
|
||||
pub keep_metadata: bool,
|
||||
pub jpeg_quality: u32,
|
||||
pub jpeg_chroma_subsampling: u32,
|
||||
pub png_quality: u32,
|
||||
pub png_force_zopfli: bool,
|
||||
pub gif_quality: u32,
|
||||
pub webp_quality: u32,
|
||||
pub optimize: bool,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSResult {
|
||||
pub success: bool,
|
||||
pub code: u32,
|
||||
pub error_message: *const c_char,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct JpegParameters {
|
||||
pub quality: u32,
|
||||
|
@ -64,12 +47,19 @@ pub struct WebPParameters {
|
|||
pub quality: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct TiffParameters {
|
||||
pub algorithm: TiffCompression,
|
||||
pub deflate_level: DeflateLevel,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct CSParameters {
|
||||
pub jpeg: JpegParameters,
|
||||
pub png: PngParameters,
|
||||
pub gif: GifParameters,
|
||||
pub webp: WebPParameters,
|
||||
pub tiff: TiffParameters,
|
||||
pub keep_metadata: bool,
|
||||
pub optimize: bool,
|
||||
pub width: u32,
|
||||
|
@ -82,21 +72,23 @@ pub fn initialize_parameters() -> CSParameters {
|
|||
quality: 80,
|
||||
chroma_subsampling: ChromaSubsampling::Auto,
|
||||
};
|
||||
|
||||
let png = PngParameters {
|
||||
quality: 80,
|
||||
force_zopfli: false,
|
||||
};
|
||||
|
||||
let gif = GifParameters { quality: 80 };
|
||||
|
||||
let webp = WebPParameters { quality: 80 };
|
||||
let tiff = TiffParameters {
|
||||
algorithm: Deflate,
|
||||
deflate_level: DeflateLevel::Balanced,
|
||||
};
|
||||
|
||||
CSParameters {
|
||||
jpeg,
|
||||
png,
|
||||
gif,
|
||||
webp,
|
||||
tiff,
|
||||
keep_metadata: false,
|
||||
optimize: false,
|
||||
width: 0,
|
||||
|
@ -105,97 +97,11 @@ pub fn initialize_parameters() -> CSParameters {
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe extern "C" fn c_compress(
|
||||
input_path: *const c_char,
|
||||
output_path: *const c_char,
|
||||
params: CCSParameters,
|
||||
) -> CCSResult {
|
||||
let parameters = c_set_parameters(params);
|
||||
|
||||
c_return_result(compress(
|
||||
CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
CStr::from_ptr(output_path).to_str().unwrap().to_string(),
|
||||
¶meters,
|
||||
))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe extern "C" fn c_compress_to_size(
|
||||
input_path: *const c_char,
|
||||
output_path: *const c_char,
|
||||
params: CCSParameters,
|
||||
max_output_size: usize,
|
||||
return_smallest: bool,
|
||||
) -> CCSResult {
|
||||
let mut parameters = c_set_parameters(params);
|
||||
|
||||
c_return_result(compress_to_size(
|
||||
CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
CStr::from_ptr(output_path).to_str().unwrap().to_string(),
|
||||
&mut parameters,
|
||||
max_output_size,
|
||||
return_smallest,
|
||||
))
|
||||
}
|
||||
|
||||
fn c_return_result(result: utils::Result<()>) -> CCSResult {
|
||||
let mut error_message = CString::new("").unwrap();
|
||||
|
||||
match result {
|
||||
Ok(_) => {
|
||||
let em_pointer = error_message.as_ptr();
|
||||
std::mem::forget(error_message);
|
||||
CCSResult {
|
||||
success: true,
|
||||
code: 0,
|
||||
error_message: em_pointer,
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
error_message = CString::new(e.to_string()).unwrap();
|
||||
let em_pointer = error_message.as_ptr();
|
||||
std::mem::forget(error_message);
|
||||
CCSResult {
|
||||
success: false,
|
||||
code: e.code,
|
||||
error_message: em_pointer,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn c_set_parameters(params: CCSParameters) -> CSParameters {
|
||||
let mut parameters = initialize_parameters();
|
||||
|
||||
parameters.jpeg.quality = params.jpeg_quality;
|
||||
parameters.png.quality = params.png_quality;
|
||||
parameters.optimize = params.optimize;
|
||||
parameters.keep_metadata = params.keep_metadata;
|
||||
parameters.png.force_zopfli = params.png_force_zopfli;
|
||||
parameters.gif.quality = params.gif_quality;
|
||||
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,
|
||||
420 => ChromaSubsampling::CS420,
|
||||
411 => ChromaSubsampling::CS411,
|
||||
_ => ChromaSubsampling::Auto,
|
||||
};
|
||||
|
||||
parameters
|
||||
}
|
||||
|
||||
pub fn compress(
|
||||
input_path: String,
|
||||
output_path: String,
|
||||
parameters: &CSParameters,
|
||||
) -> utils::Result<()> {
|
||||
) -> error::Result<()> {
|
||||
validate_parameters(parameters)?;
|
||||
let file_type = get_filetype_from_path(&input_path);
|
||||
|
||||
|
@ -216,11 +122,15 @@ pub fn compress(
|
|||
SupportedFileTypes::Gif => {
|
||||
gif::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
#[cfg(feature = "tiff")]
|
||||
SupportedFileTypes::Tiff => {
|
||||
tiff::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: "Unknown file type".into(),
|
||||
code: 10000,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +140,7 @@ pub fn compress(
|
|||
pub fn compress_in_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &mut CSParameters,
|
||||
) -> utils::Result<Vec<u8>> {
|
||||
) -> error::Result<Vec<u8>> {
|
||||
let file_type = get_filetype_from_memory(in_file.as_slice());
|
||||
let compressed_file = match file_type {
|
||||
#[cfg(feature = "jpg")]
|
||||
|
@ -239,11 +149,13 @@ pub fn compress_in_memory(
|
|||
SupportedFileTypes::Png => png::compress_to_memory(in_file, parameters)?,
|
||||
#[cfg(feature = "webp")]
|
||||
SupportedFileTypes::WebP => webp::compress_to_memory(in_file, parameters)?,
|
||||
#[cfg(feature = "tiff")]
|
||||
SupportedFileTypes::Tiff => tiff::compress_to_memory(in_file, parameters)?,
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: "Format not supported for compression to size".into(),
|
||||
code: 10200,
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -255,7 +167,7 @@ pub fn compress_to_size_in_memory(
|
|||
parameters: &mut CSParameters,
|
||||
max_output_size: usize,
|
||||
return_smallest: bool,
|
||||
) -> utils::Result<Vec<u8>> {
|
||||
) -> error::Result<Vec<u8>> {
|
||||
let file_type = get_filetype_from_memory(&in_file);
|
||||
|
||||
let tolerance_percentage = 2;
|
||||
|
@ -290,11 +202,12 @@ pub fn compress_to_size_in_memory(
|
|||
parameters.webp.quality = quality;
|
||||
webp::compress_to_memory(in_file.clone(), parameters)? //TODO clone
|
||||
}
|
||||
//TODO Tiff
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: "Format not supported for compression to size".into(),
|
||||
code: 10200,
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -340,7 +253,7 @@ pub fn compress_to_size(
|
|||
parameters: &mut CSParameters,
|
||||
max_output_size: usize,
|
||||
return_smallest: bool,
|
||||
) -> utils::Result<()> {
|
||||
) -> error::Result<()> {
|
||||
let in_file = fs::read(input_path.clone()).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 10201,
|
||||
|
@ -369,7 +282,7 @@ pub fn compress_to_size(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_parameters(parameters: &CSParameters) -> utils::Result<()> {
|
||||
fn validate_parameters(parameters: &CSParameters) -> error::Result<()> {
|
||||
if parameters.jpeg.quality == 0 || parameters.jpeg.quality > 100 {
|
||||
return Err(CaesiumError {
|
||||
message: "Invalid JPEG quality value".into(),
|
||||
|
|
|
@ -6,8 +6,8 @@ use std::num::NonZeroU8;
|
|||
use image::ImageOutputFormat;
|
||||
use oxipng::Deflaters::{Libdeflater, Zopfli};
|
||||
|
||||
use crate::error::CaesiumError;
|
||||
use crate::resize::resize;
|
||||
use crate::utils::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::io::Cursor;
|
||||
|
||||
use crate::utils::CaesiumError;
|
||||
use crate::error::CaesiumError;
|
||||
use image::imageops::FilterType;
|
||||
use image::io::Reader as ImageReader;
|
||||
use image::DynamicImage;
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
use crate::error::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
use image::ImageFormat::Tiff;
|
||||
use std::fs::File;
|
||||
use std::io::{Cursor, Read, Write};
|
||||
use tiff::encoder::colortype::{RGB8, RGBA8};
|
||||
use tiff::encoder::compression::{Deflate, Lzw, Packbits, Uncompressed};
|
||||
use tiff::encoder::TiffEncoder;
|
||||
use crate::resize::resize_image;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum TiffCompression {
|
||||
Lzw,
|
||||
Deflate,
|
||||
Packbits,
|
||||
Uncompressed,
|
||||
}
|
||||
|
||||
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,
|
||||
})?;
|
||||
|
||||
let mut output_file = File::create(output_path).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20502,
|
||||
})?;
|
||||
let compressed_image = compress_to_memory(input_data, parameters)?;
|
||||
output_file
|
||||
.write_all(&compressed_image)
|
||||
.map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20503,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compress_to_memory(
|
||||
in_file: Vec<u8>,
|
||||
parameters: &CSParameters,
|
||||
) -> Result<Vec<u8>, CaesiumError> {
|
||||
let mut image = image::load_from_memory_with_format(in_file.as_slice(), Tiff).map_err(|e| {
|
||||
CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20504,
|
||||
}
|
||||
})?;
|
||||
|
||||
if parameters.width > 0 || parameters.height > 0 {
|
||||
image = resize_image(image, parameters.width, parameters.height);
|
||||
}
|
||||
|
||||
let color_type = image.color();
|
||||
let output_buff = vec![];
|
||||
let mut output_stream = Cursor::new(output_buff);
|
||||
let mut encoder = TiffEncoder::new(&mut output_stream).map_err(|e| CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20505,
|
||||
})?;
|
||||
let compression_result = match parameters.tiff.algorithm {
|
||||
TiffCompression::Deflate => match color_type {
|
||||
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Deflate>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Deflate::with_level(parameters.tiff.deflate_level),
|
||||
image.as_bytes(),
|
||||
),
|
||||
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Deflate>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Deflate::with_level(parameters.tiff.deflate_level),
|
||||
image.as_bytes(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: format!("Unsupported TIFF color type ({:?})", color_type).to_string(),
|
||||
code: 20506,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
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(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: format!("Unsupported TIFF color type ({:?})", color_type).to_string(),
|
||||
code: 20506,
|
||||
});
|
||||
}
|
||||
},
|
||||
TiffCompression::Packbits => match color_type {
|
||||
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Packbits>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Packbits,
|
||||
image.as_bytes(),
|
||||
),
|
||||
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Packbits>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Packbits,
|
||||
image.as_bytes(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: format!("Unsupported TIFF color type ({:?})", color_type).to_string(),
|
||||
code: 20506,
|
||||
});
|
||||
}
|
||||
},
|
||||
TiffCompression::Uncompressed => match color_type {
|
||||
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Uncompressed>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Uncompressed,
|
||||
image.as_bytes(),
|
||||
),
|
||||
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Uncompressed>(
|
||||
image.width(),
|
||||
image.height(),
|
||||
Uncompressed,
|
||||
image.as_bytes(),
|
||||
),
|
||||
_ => {
|
||||
return Err(CaesiumError {
|
||||
message: format!("Unsupported TIFF color type ({:?})", color_type).to_string(),
|
||||
code: 20506,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
match compression_result {
|
||||
Ok(_) => Ok(output_stream.get_ref().to_vec()),
|
||||
Err(e) => Err(CaesiumError {
|
||||
message: e.to_string(),
|
||||
code: 20507,
|
||||
}),
|
||||
}
|
||||
}
|
17
src/utils.rs
17
src/utils.rs
|
@ -1,4 +1,3 @@
|
|||
use core::fmt;
|
||||
use infer::Type;
|
||||
|
||||
pub enum SupportedFileTypes {
|
||||
|
@ -6,6 +5,7 @@ pub enum SupportedFileTypes {
|
|||
Png,
|
||||
Gif,
|
||||
WebP,
|
||||
Tiff,
|
||||
Unkn,
|
||||
}
|
||||
|
||||
|
@ -32,20 +32,7 @@ fn match_supported_filetypes(ft: Type) -> SupportedFileTypes {
|
|||
"image/png" => SupportedFileTypes::Png,
|
||||
"image/gif" => SupportedFileTypes::Gif,
|
||||
"image/webp" => SupportedFileTypes::WebP,
|
||||
"image/tiff" => SupportedFileTypes::Tiff,
|
||||
_ => SupportedFileTypes::Unkn,
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, CaesiumError>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CaesiumError {
|
||||
pub message: String,
|
||||
pub code: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for CaesiumError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{} [{}]", self.message, self.code)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::fs::File;
|
|||
use std::io::{Read, Write};
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::error::CaesiumError;
|
||||
use crate::resize::resize_image;
|
||||
use crate::utils::CaesiumError;
|
||||
use crate::CSParameters;
|
||||
|
||||
pub fn compress(
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue