Changed return type of C interface
This commit is contained in:
parent
5c6da6f755
commit
af3556d19d
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownSettings">
|
||||
<option name="areInjectionsEnabled" value="false" />
|
||||
</component>
|
||||
</project>
|
10
Cargo.toml
10
Cargo.toml
|
@ -1,8 +1,8 @@
|
|||
[package]
|
||||
name = "libcaesium"
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
categories = ["multimedia::images"]
|
||||
keywords = [
|
||||
"compression",
|
||||
|
@ -24,17 +24,17 @@ license = "Apache-2.0"
|
|||
[dependencies]
|
||||
mozjpeg-sys = "1.0.1"
|
||||
oxipng = "5.0.1"
|
||||
libc = "0.2.76"
|
||||
libc = "0.2.119"
|
||||
gifsicle = "1.92.5"
|
||||
webp = "0.2.1"
|
||||
infer = "0.6.0"
|
||||
infer = "0.7.0"
|
||||
image = { version = "0.24", default-features = false, features = ["jpeg", "png", "webp", "gif"] }
|
||||
img-parts = "0.2.3"
|
||||
bytes = "1.1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
dssim = "3.2.0"
|
||||
kamadak-exif = "0.5.0"
|
||||
kamadak-exif = "0.5.4"
|
||||
|
||||
[lib]
|
||||
name = "caesium"
|
||||
|
|
21
README.md
21
README.md
|
@ -17,7 +17,7 @@ pub fn compress(
|
|||
- `output_path` - output file path (full filename)
|
||||
- `parameters` - options struct, containing compression parameters (see below)
|
||||
|
||||
The output folder where the file is compressed **must** exist.
|
||||
NOTE: The output folder where the file is compressed **must** exist.
|
||||
### Compression options
|
||||
Libcaesium supports a few compression parameters for each file it supports.
|
||||
They are defined into a top level struct containing each supported file parameters, as follows:
|
||||
|
@ -57,7 +57,7 @@ pub struct Parameters {
|
|||
```
|
||||
- `oxipng`: oxipng options. Should be left as default unless you want to do something advanced. Refer to [oxipng](https://github.com/shssoichiro/oxipng) for documentation.
|
||||
- `level`: level of optimization, from 1 to 7. Increasing the level will result in a smaller file, at the cost of computation time. If the optimization flag is `true`, the level is set to `6`. Default: `3`.
|
||||
- `force_zopfli`: if `optimization` is `true` and this option is also `true`, will use zopfli algorithm for compression, resulting in a smaller image but it may take minutes to finish the process. Default `false`.
|
||||
- `force_zopfli`: if `optimization` is `true` and this option is also `true`, will use zopfli algorithm for compression, resulting in a smaller image, but it may take minutes to finish the process. Default `false`.
|
||||
|
||||
#### gif
|
||||
GIF support is experimental, has many know issues and does not support optimization. Expect bugs (especially on Windows).
|
||||
|
@ -69,7 +69,7 @@ pub struct Parameters {
|
|||
- `quality`: in a range from 0 to 100, the quality of the resulting image. If the optimization flag is `true`, the level is set to `100`. Default: `80`.
|
||||
|
||||
#### webp
|
||||
WebP compression is tricky. The format is already well optimized and using the `optimize` flag will probably result in a bigger image.
|
||||
WebP's compression is tricky. The format is already well optimized and using the `optimize` flag will probably result in a bigger image.
|
||||
```Rust
|
||||
pub struct Parameters {
|
||||
pub quality: u32,
|
||||
|
@ -84,14 +84,23 @@ pub extern fn c_compress(
|
|||
input_path: *const c_char,
|
||||
output_path: *const c_char,
|
||||
params: CCSParameters
|
||||
) -> bool
|
||||
) -> CCSResult
|
||||
```
|
||||
#### Parameters
|
||||
- `input_path` - input file path (full filename)
|
||||
- `output_path` - output file path (full filename)
|
||||
- `parameters` - options struct, containing compression parameters (see below)
|
||||
#### Return
|
||||
`true` if all goes well, `false` otherwise.
|
||||
A `CCSResult` struct
|
||||
```Rust
|
||||
#[repr(C)]
|
||||
pub struct CCSResult {
|
||||
pub success: bool,
|
||||
pub error_message: *const c_char,
|
||||
}
|
||||
```
|
||||
If `success` is `true` the compression process ended successfully and `error_message` will be empty.
|
||||
On failure, the `error_message` will be filled with a string containing a brief explanation of the error.
|
||||
|
||||
### Compression options
|
||||
The C options struct is slightly different from the Rust one:
|
||||
|
@ -131,4 +140,4 @@ Libcaesium also supports optimization, by setting the _quality_ to 0. This perfo
|
|||
but with a smaller size (10-12% usually).
|
||||
PNG is lossless, so libcaesium will always perform optimization rather than compression.
|
||||
GIF optimization is possible, but currently not supported.
|
||||
WebP optimization is also possible, but it will probably result in a bigger output file as it's well suited to losslessly convert from PNG or JPEG.s
|
||||
WebP's optimization is also possible, but it will probably result in a bigger output file as it's well suited to losslessly convert from PNG or JPEG.s
|
||||
|
|
10
src/jpeg.rs
10
src/jpeg.rs
|
@ -16,6 +16,7 @@ pub fn compress(input_path: String, output_path: String, parameters: CSParameter
|
|||
{
|
||||
let mut in_file = fs::read(input_path)?;
|
||||
|
||||
|
||||
if parameters.width > 0 || parameters.height > 0 {
|
||||
if parameters.keep_metadata {
|
||||
let metadata = extract_metadata(in_file.clone());
|
||||
|
@ -27,12 +28,11 @@ pub fn compress(input_path: String, output_path: String, parameters: CSParameter
|
|||
}
|
||||
|
||||
unsafe {
|
||||
let compression_buffer: (*mut u8, u64);
|
||||
if parameters.optimize {
|
||||
compression_buffer = lossless(in_file, parameters)?;
|
||||
let compression_buffer: (*mut u8, u64) = if parameters.optimize {
|
||||
lossless(in_file, parameters)?
|
||||
} else {
|
||||
compression_buffer = lossy(in_file, parameters)?;
|
||||
}
|
||||
lossy(in_file, parameters)?
|
||||
};
|
||||
let mut output_file_buffer = File::create(output_path)?;
|
||||
output_file_buffer.write_all(std::slice::from_raw_parts(compression_buffer.0, compression_buffer.1 as usize))?;
|
||||
}
|
||||
|
|
70
src/lib.rs
70
src/lib.rs
|
@ -7,7 +7,7 @@ mod resize;
|
|||
|
||||
use std::error::Error;
|
||||
use crate::utils::get_filetype;
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -23,6 +23,12 @@ pub struct CCSParameters {
|
|||
pub height: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CCSResult {
|
||||
pub success: bool,
|
||||
pub error_message: *const c_char,
|
||||
}
|
||||
|
||||
pub struct CSParameters {
|
||||
pub jpeg: jpeg::Parameters,
|
||||
pub png: png::Parameters,
|
||||
|
@ -68,8 +74,9 @@ pub fn initialize_parameters() -> CSParameters
|
|||
|
||||
#[no_mangle]
|
||||
#[allow(clippy::missing_safety_doc)]
|
||||
pub unsafe extern fn c_compress(input_path: *const c_char, output_path: *const c_char, params: CCSParameters) -> bool {
|
||||
pub unsafe extern fn c_compress(input_path: *const c_char, output_path: *const c_char, params: CCSParameters) -> CCSResult {
|
||||
let mut parameters = initialize_parameters();
|
||||
|
||||
parameters.jpeg.quality = params.jpeg_quality;
|
||||
parameters.png.level = params.png_level;
|
||||
parameters.optimize = params.optimize;
|
||||
|
@ -80,10 +87,29 @@ pub unsafe extern fn c_compress(input_path: *const c_char, output_path: *const c
|
|||
parameters.width = params.width;
|
||||
parameters.height = params.height;
|
||||
|
||||
let x = compress(CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
let mut error_message = CString::new("").unwrap();
|
||||
|
||||
match compress(CStr::from_ptr(input_path).to_str().unwrap().to_string(),
|
||||
CStr::from_ptr(output_path).to_str().unwrap().to_string(),
|
||||
parameters).is_ok();
|
||||
x
|
||||
parameters) {
|
||||
Ok(_) => {
|
||||
let em_pointer = error_message.as_ptr();
|
||||
std::mem::forget(error_message);
|
||||
CCSResult {
|
||||
success: true,
|
||||
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,
|
||||
error_message: em_pointer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compress(input_path: String, output_path: String, parameters: CSParameters) -> Result<(), Box<dyn Error>> {
|
||||
|
@ -92,43 +118,21 @@ pub fn compress(input_path: String, output_path: String, parameters: CSParameter
|
|||
|
||||
match file_type {
|
||||
utils::SupportedFileTypes::Jpeg => {
|
||||
return match jpeg::compress(input_path, output_path, parameters) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!("JPEG compression error: {}", e.to_string());
|
||||
Err(e.into())
|
||||
}
|
||||
};
|
||||
jpeg::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
utils::SupportedFileTypes::Png => {
|
||||
return match png::compress(input_path, output_path, parameters) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!("PNG compression error: {}", e.to_string());
|
||||
Err(e.into())
|
||||
}
|
||||
};
|
||||
png::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
utils::SupportedFileTypes::Gif => {
|
||||
return match gif::compress(input_path, output_path, parameters) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!("GIF compression error: {}", e.to_string());
|
||||
Err(e.into())
|
||||
}
|
||||
};
|
||||
gif::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
utils::SupportedFileTypes::WebP => {
|
||||
return match webp::compress(input_path, output_path, parameters) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
eprintln!("WebP compression error: {}", e.to_string());
|
||||
Err(e.into())
|
||||
}
|
||||
};
|
||||
webp::compress(input_path, output_path, parameters)?;
|
||||
}
|
||||
_ => return Err("Unknown file type".into())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_parameters(parameters: &CSParameters) -> Result<(), Box<dyn Error>> {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
use caesium;
|
||||
|
||||
#[test]
|
||||
fn unknown_file_type() {
|
||||
let output = "tests/samples/output/should_not_be_there";
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
use caesium;
|
||||
use std::sync::Once;
|
||||
use std::fs;
|
||||
|
||||
|
|
Loading…
Reference in New Issue