Baseline/progressive JPEG switch
This commit is contained in:
parent
5499d2ff9d
commit
cd5d0529b1
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "libcaesium"
|
name = "libcaesium"
|
||||||
version = "0.16.5"
|
version = "0.17.0"
|
||||||
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
authors = ["Matteo Paonessa <matteo.paonessa@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
categories = ["multimedia::images"]
|
categories = ["multimedia::images"]
|
||||||
|
@ -33,12 +33,12 @@ parallel = ["oxipng?/parallel", "imagequant?/threads", "dssim/threads"]
|
||||||
mozjpeg-sys = { version = "2.2", optional = true }
|
mozjpeg-sys = { version = "2.2", optional = true }
|
||||||
oxipng = { version = "9.0", default-features = false, features = ["filetime", "zopfli"], optional = true }
|
oxipng = { version = "9.0", default-features = false, features = ["filetime", "zopfli"], optional = true }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
gifsicle = { version = "1.94", optional = true }
|
gifsicle = { version = "1.95", optional = true }
|
||||||
webp = { version = "0.3.0", optional = true }
|
webp = { version = "0.3.0", optional = true }
|
||||||
infer = "0.16.0"
|
infer = "0.16.0"
|
||||||
image = { version = "0.25.1", default-features = false }
|
image = { version = "0.25.1", default-features = false }
|
||||||
img-parts = "0.3"
|
img-parts = "0.3"
|
||||||
bytes = "1.6"
|
bytes = "1.7"
|
||||||
lodepng = { version = "3.10", optional = true }
|
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" }
|
tiff = { version = "0.9" }
|
||||||
|
|
119
README.md
119
README.md
|
@ -1,11 +1,18 @@
|
||||||
# libcaesium [](https://github.com/Lymphatus/libcaesium/actions/workflows/rust.yml)
|
# libcaesium [](https://github.com/Lymphatus/libcaesium/actions/workflows/rust.yml)
|
||||||
|
|
||||||
Libcaesium is a simple library performing JPEG, PNG, WebP and GIF (experimental) compression/optimization written in Rust, with a C interface.\
|
Libcaesium is a simple library performing JPEG, PNG, WebP and GIF (experimental) compression/optimization written in
|
||||||
**IMPORTANT**: starting from v0.6.0 the library is written in Rust and no longer in C. There's a C interface, but it's not backward compatible with the <0.6.0.
|
Rust, with a C interface.
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> starting from v0.6.0 the library is written in Rust and no longer in C. There's a C interface, but it's not backward
|
||||||
|
> compatible with the <0.6.0.
|
||||||
|
|
||||||
## Usage in Rust
|
## Usage in Rust
|
||||||
|
|
||||||
Libcaesium exposes two functions, auto-detecting the input file type
|
Libcaesium exposes two functions, auto-detecting the input file type
|
||||||
|
|
||||||
### Based on quality values
|
### Based on quality values
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub fn compress(
|
pub fn compress(
|
||||||
input_path: String,
|
input_path: String,
|
||||||
|
@ -13,12 +20,15 @@ pub fn compress(
|
||||||
parameters: &CSParameters
|
parameters: &CSParameters
|
||||||
) -> Result<(), Box<dyn Error>>
|
) -> Result<(), Box<dyn Error>>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
- `input_path` - input file path (full filename)
|
- `input_path` - input file path (full filename)
|
||||||
- `output_path` - output file path (full filename)
|
- `output_path` - output file path (full filename)
|
||||||
- `parameters` - options struct, containing compression parameters (see below)
|
- `parameters` - options struct, containing compression parameters (see below)
|
||||||
|
|
||||||
### Based on output size
|
### Based on output size
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub fn compress_to_size(
|
pub fn compress_to_size(
|
||||||
input_path: String,
|
input_path: String,
|
||||||
|
@ -27,20 +37,26 @@ pub fn compress_to_size(
|
||||||
max_output_size: usize,
|
max_output_size: usize,
|
||||||
) -> Result<(), Box<dyn Error>>
|
) -> Result<(), Box<dyn Error>>
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
- `input_path` - input file path (full filename)
|
- `input_path` - input file path (full filename)
|
||||||
- `output_path` - output file path (full filename)
|
- `output_path` - output file path (full filename)
|
||||||
- `parameters` - options struct, containing compression parameters (see below)
|
- `parameters` - options struct, containing compression parameters (see below)
|
||||||
- `max_output_size` - the maximum output size, in bytes
|
- `max_output_size` - the maximum output size, in bytes
|
||||||
|
|
||||||
This function will attempt to compress the given file *below* the desired size. It will never exceed it. The function
|
This function will attempt to compress the given file *below* the desired size. It will never exceed it. The function
|
||||||
will start looping until the best size under the desired is achieved. The function has a 2% tolerance for the output size.
|
will start looping until the best size under the desired is achieved. The function has a 2% tolerance for the output
|
||||||
|
size.
|
||||||
All quality value set to the parameters will be ignored and overwritten during the compression.
|
All quality value set to the parameters will be ignored and overwritten during the compression.
|
||||||
|
|
||||||
NOTE: The output folder where the file is compressed **must** exist.
|
NOTE: The output folder where the file is compressed **must** exist.
|
||||||
|
|
||||||
### Compression options
|
### Compression options
|
||||||
|
|
||||||
Libcaesium supports a few compression parameters for each file it supports.
|
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:
|
They are defined into a top level struct containing each supported file parameters, as follows:
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub struct CSParameters {
|
pub struct CSParameters {
|
||||||
pub jpeg: jpeg::Parameters,
|
pub jpeg: jpeg::Parameters,
|
||||||
|
@ -54,23 +70,36 @@ pub struct CSParameters {
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Each file type has its own options, but the last two are generic:
|
Each file type has its own options, but the last two are generic:
|
||||||
|
|
||||||
- `keep_metadata`: will keep metadata information for any supported type. JPEG and PNG supported. Default `false`.
|
- `keep_metadata`: will keep metadata information for any supported type. JPEG and PNG supported. Default `false`.
|
||||||
- `optimize`: forces optimization, when available. With this option enabled the compression will be lossless. JPEG, PNG and WebP supported. Default `false`.
|
- `optimize`: forces optimization, when available. With this option enabled the compression will be lossless. JPEG, PNG
|
||||||
- `width`: Resizes the image to the given width. If this value is `0` and the height value is also `0`, no resizing will be done. If this is `0` and height is `> 0`, the image will be scaled based on height keeping the aspect ratio. Default `0`.
|
and WebP supported. Default `false`.
|
||||||
- `height`: Resizes the image to the given height. If this value is `0` and the width value is also `0`, no resizing will be done. If this is `0` and width is `> 0`, the image will be scaled based on width keeping the aspect ratio. Default `0`.
|
- `width`: Resizes the image to the given width. If this value is `0` and the height value is also `0`, no resizing will
|
||||||
|
be done. If this is `0` and height is `> 0`, the image will be scaled based on height keeping the aspect ratio.
|
||||||
|
Default `0`.
|
||||||
|
- `height`: Resizes the image to the given height. If this value is `0` and the width value is also `0`, no resizing
|
||||||
|
will be done. If this is `0` and width is `> 0`, the image will be scaled based on width keeping the aspect ratio.
|
||||||
|
Default `0`.
|
||||||
|
|
||||||
#### jpeg
|
#### jpeg
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub quality: u32,
|
pub quality: u32,
|
||||||
pub chroma_subsampling: jpeg::ChromaSubsampling
|
pub chroma_subsampling: jpeg::ChromaSubsampling,
|
||||||
|
pub progressive: bool
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- `quality`: in a range from 1 to 100, the quality of the resulting image. Default `80`.
|
|
||||||
- `chroma_subsampling`: [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling) to apply during compression. Default `Auto`.
|
- `quality`: in a range from 0 to 100, the quality of the resulting image. Default `80`.
|
||||||
|
- `chroma_subsampling`: [chroma subsampling](https://en.wikipedia.org/wiki/Chroma_subsampling) to apply during
|
||||||
|
compression. Default `Auto`.
|
||||||
|
- `progressive`: outputs a progressive image (recommended). Set to `false` for baseline. Default `true`.
|
||||||
|
|
||||||
#### png
|
#### png
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub quality: u32,
|
pub quality: u32,
|
||||||
|
@ -78,43 +107,62 @@ pub struct Parameters {
|
||||||
pub optimization_level: u32
|
pub optimization_level: u32
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `quality`: in a range from 0 to 100, the quality of the resulting image. Default `80`.
|
- `quality`: in a range from 0 to 100, the quality of the resulting image. Default `80`.
|
||||||
- `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`.
|
||||||
- `optimization_level`: if `optimization` is `true` will set the level of oxipng optimization, from 0 to 6. Default `3`.
|
- `optimization_level`: if `optimization` is `true` will set the level of oxipng optimization, from 0 to 6. Default `3`.
|
||||||
|
|
||||||
#### gif
|
#### gif
|
||||||
GIF support is experimental, has many know issues and does not support optimization. Expect bugs (especially on Windows).
|
|
||||||
|
GIF support is experimental, has many know issues and does not support optimization. Expect bugs (especially on
|
||||||
|
Windows).
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub quality: u32,
|
pub quality: u32,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- `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`.
|
|
||||||
|
- `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
|
||||||
WebP's 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
|
```Rust
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub quality: u32,
|
pub quality: u32,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- `quality`: in a range from 0 to 100, the quality of the resulting image. If the optimization flag is `true`, this option will be ignored. Default: `60`.
|
|
||||||
|
- `quality`: in a range from 0 to 100, the quality of the resulting image. If the optimization flag is `true`, this
|
||||||
|
option will be ignored. Default: `60`.
|
||||||
|
|
||||||
#### tiff
|
#### tiff
|
||||||
|
|
||||||
Supported TIFF compression is only lossless. The supported algorithms are: Lzw, Deflate, Packbits, Uncompressed.
|
Supported TIFF compression is only lossless. The supported algorithms are: Lzw, Deflate, Packbits, Uncompressed.
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub struct Parameters {
|
pub struct Parameters {
|
||||||
pub algorithm: TiffCompression,
|
pub algorithm: TiffCompression,
|
||||||
pub deflate_level: DeflateLevel,
|
pub deflate_level: TiffDeflateLevel,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `algorithm`: supported algorithms are: Lzw, Deflate, Packbits, Uncompressed.
|
||||||
- `deflate_level`: can be one of `Fast`, `Balanced`, `Best`.
|
- `deflate_level`: can be one of `Fast`, `Balanced`, `Best`.
|
||||||
|
|
||||||
_________________
|
_________________
|
||||||
|
|
||||||
## Usage in C
|
## Usage in C
|
||||||
|
|
||||||
Libcaesium exposes two C functions, auto-detecting the input file type:
|
Libcaesium exposes two C functions, auto-detecting the input file type:
|
||||||
|
|
||||||
### Based on quality values
|
### Based on quality values
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub unsafe extern "C" fn c_compress(
|
pub unsafe extern "C" fn c_compress(
|
||||||
input_path: *const c_char,
|
input_path: *const c_char,
|
||||||
|
@ -122,12 +170,17 @@ pub unsafe extern "C" fn c_compress(
|
||||||
params: CCSParameters
|
params: CCSParameters
|
||||||
) -> CCSResult
|
) -> CCSResult
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
- `input_path` - input file path (full filename)
|
- `input_path` - input file path (full filename)
|
||||||
- `output_path` - output file path (full filename)
|
- `output_path` - output file path (full filename)
|
||||||
- `parameters` - options struct, containing compression parameters (see below)
|
- `parameters` - options struct, containing compression parameters (see below)
|
||||||
|
|
||||||
#### Return
|
#### Return
|
||||||
|
|
||||||
A `CCSResult` struct
|
A `CCSResult` struct
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct CCSResult {
|
pub struct CCSResult {
|
||||||
|
@ -135,10 +188,12 @@ pub struct CCSResult {
|
||||||
pub error_message: *const c_char,
|
pub error_message: *const c_char,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If `success` is `true` the compression process ended successfully and `error_message` will be empty.
|
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.
|
On failure, the `error_message` will be filled with a string containing a brief explanation of the error.
|
||||||
|
|
||||||
### Based on output size
|
### Based on output size
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
pub unsafe extern "C" fn c_compress_to_size(
|
pub unsafe extern "C" fn c_compress_to_size(
|
||||||
input_path: *const c_char,
|
input_path: *const c_char,
|
||||||
|
@ -147,13 +202,18 @@ pub unsafe extern "C" fn c_compress_to_size(
|
||||||
max_output_size: usize,
|
max_output_size: usize,
|
||||||
) -> CCSResult
|
) -> CCSResult
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Parameters
|
#### Parameters
|
||||||
|
|
||||||
- `input_path` - input file path (full filename)
|
- `input_path` - input file path (full filename)
|
||||||
- `output_path` - output file path (full filename)
|
- `output_path` - output file path (full filename)
|
||||||
- `parameters` - options struct, containing compression parameters (see below)
|
- `parameters` - options struct, containing compression parameters (see below)
|
||||||
- `max_output_size` - the maximum output size, in bytes
|
- `max_output_size` - the maximum output size, in bytes
|
||||||
|
|
||||||
#### Return
|
#### Return
|
||||||
|
|
||||||
A `CCSResult` struct
|
A `CCSResult` struct
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct CCSResult {
|
pub struct CCSResult {
|
||||||
|
@ -161,11 +221,14 @@ pub struct CCSResult {
|
||||||
pub error_message: *const c_char,
|
pub error_message: *const c_char,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If `success` is `true` the compression process ended successfully and `error_message` will be empty.
|
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.
|
On failure, the `error_message` will be filled with a string containing a brief explanation of the error.
|
||||||
|
|
||||||
### Compression options
|
### Compression options
|
||||||
|
|
||||||
The C options struct is slightly different from the Rust one:
|
The C options struct is slightly different from the Rust one:
|
||||||
|
|
||||||
```Rust
|
```Rust
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct CCSParameters {
|
pub struct CCSParameters {
|
||||||
|
@ -184,28 +247,40 @@ pub struct CCSParameters {
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The option description is the same as the Rust counterpart.
|
The option description is the same as the Rust counterpart.
|
||||||
Valid values for `jpeg_chroma_subsampling` are [444, 422, 420, 411]. Any other value will be ignored and will be used the default option.
|
Valid values for `jpeg_chroma_subsampling` are [444, 422, 420, 411]. Any other value will be ignored and will be used
|
||||||
Valid values for `tiff_compression` are [0 (Uncompressed), 1 (Lzw), 2 (Deflate), 3 (Packbits)]. Any other value will be ignored and `0` will be used.
|
the default option.
|
||||||
Valid values for `tiff_deflate_level` are [3 (Fast), 6 (Balanced), 9 (Best)]. Any other value will be ignored and `Best` will be used.
|
Valid values for `tiff_compression` are [0 (Uncompressed), 1 (Lzw), 2 (Deflate), 3 (Packbits)]. Any other value will be
|
||||||
|
ignored and `0` will be used.
|
||||||
|
Valid values for `tiff_deflate_level` are [1 (Fast), 6 (Balanced), 9 (Best)]. Any other value will be ignored and `Best`
|
||||||
|
will be used.
|
||||||
|
|
||||||
## Download
|
## Download
|
||||||
|
|
||||||
Binaries not available. Please refer to the compilation section below.
|
Binaries not available. Please refer to the compilation section below.
|
||||||
|
|
||||||
## Compilation and Installation
|
## Compilation and Installation
|
||||||
|
|
||||||
Compilation is available for all supported platforms: Windows, macOS and Linux.
|
Compilation is available for all supported platforms: Windows, macOS and Linux.
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
Note: if you don't use the `--release` flag, the PNG optimizations can take a very long time to complete, especially using the zopfli algorithm.
|
|
||||||
|
Note: if you don't use the `--release` flag, the PNG optimizations can take a very long time to complete, especially
|
||||||
|
using the zopfli algorithm.
|
||||||
|
|
||||||
The result will be a dynamic library usable by external applications through its C interface.
|
The result will be a dynamic library usable by external applications through its C interface.
|
||||||
|
|
||||||
## Compression vs Optimization
|
## Compression vs Optimization
|
||||||
JPEG is a lossy format: that means you will always lose some information after each compression. So, compressing a file with
|
|
||||||
|
JPEG is a lossy format: that means you will always lose some information after each compression. So, compressing a file
|
||||||
|
with
|
||||||
100 quality for 10 times will result in an always different image, even though you can't really see the difference.
|
100 quality for 10 times will result in an always different image, even though you can't really see the difference.
|
||||||
Libcaesium also supports optimization, by setting the _quality_ to 0. This performs a lossless process, resulting in the same image,
|
Libcaesium also supports optimization, by setting the _quality_ to 0. This performs a lossless process, resulting in the
|
||||||
|
same image,
|
||||||
but with a smaller size (10-12% usually).
|
but with a smaller size (10-12% usually).
|
||||||
GIF optimization is possible, but currently not supported.
|
GIF optimization is possible, but currently not supported.
|
||||||
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.
|
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.
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
use tiff::encoder::compression::DeflateLevel::{Balanced, Best, Fast};
|
use crate::{ChromaSubsampling, compress, compress_to_size, convert, CSParameters, error, initialize_parameters, SupportedFileTypes, TiffDeflateLevel};
|
||||||
|
|
||||||
use crate::{ChromaSubsampling, compress, compress_to_size, convert, CSParameters, error, initialize_parameters, SupportedFileTypes};
|
|
||||||
use crate::TiffCompression::{Deflate, Lzw, Packbits, Uncompressed};
|
use crate::TiffCompression::{Deflate, Lzw, Packbits, Uncompressed};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -11,6 +9,7 @@ pub struct CCSParameters {
|
||||||
pub keep_metadata: bool,
|
pub keep_metadata: bool,
|
||||||
pub jpeg_quality: u32,
|
pub jpeg_quality: u32,
|
||||||
pub jpeg_chroma_subsampling: u32,
|
pub jpeg_chroma_subsampling: u32,
|
||||||
|
pub jpeg_progressive: bool,
|
||||||
pub png_quality: u32,
|
pub png_quality: u32,
|
||||||
pub png_optimization_level: u32,
|
pub png_optimization_level: u32,
|
||||||
pub png_force_zopfli: bool,
|
pub png_force_zopfli: bool,
|
||||||
|
@ -114,6 +113,7 @@ fn c_set_parameters(params: CCSParameters) -> CSParameters {
|
||||||
let mut parameters = initialize_parameters();
|
let mut parameters = initialize_parameters();
|
||||||
|
|
||||||
parameters.jpeg.quality = params.jpeg_quality;
|
parameters.jpeg.quality = params.jpeg_quality;
|
||||||
|
parameters.jpeg.progressive = params.jpeg_progressive;
|
||||||
parameters.png.quality = params.png_quality;
|
parameters.png.quality = params.png_quality;
|
||||||
parameters.optimize = params.optimize;
|
parameters.optimize = params.optimize;
|
||||||
parameters.keep_metadata = params.keep_metadata;
|
parameters.keep_metadata = params.keep_metadata;
|
||||||
|
@ -140,9 +140,9 @@ fn c_set_parameters(params: CCSParameters) -> CSParameters {
|
||||||
};
|
};
|
||||||
|
|
||||||
parameters.tiff.deflate_level = match params.tiff_deflate_level {
|
parameters.tiff.deflate_level = match params.tiff_deflate_level {
|
||||||
3 => Fast,
|
1 => TiffDeflateLevel::Fast,
|
||||||
6 => Balanced,
|
6 => TiffDeflateLevel::Balanced,
|
||||||
_ => Best
|
_ => TiffDeflateLevel::Best
|
||||||
};
|
};
|
||||||
|
|
||||||
parameters
|
parameters
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
|
use std::ptr::null;
|
||||||
use image::ImageFormat::Jpeg;
|
use image::ImageFormat::Jpeg;
|
||||||
use img_parts::{ImageEXIF, ImageICC};
|
use img_parts::{ImageEXIF, ImageICC};
|
||||||
use img_parts::jpeg::Jpeg as PartsJpeg;
|
use img_parts::jpeg::Jpeg as PartsJpeg;
|
||||||
|
@ -201,6 +201,10 @@ unsafe fn lossy(in_file: Vec<u8>, parameters: &CSParameters) -> Result<Vec<u8>,
|
||||||
false as boolean,
|
false as boolean,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if !parameters.jpeg.progressive {
|
||||||
|
dst_info.scan_info = null();
|
||||||
|
}
|
||||||
|
|
||||||
jpeg_start_compress(&mut dst_info, true as boolean);
|
jpeg_start_compress(&mut dst_info, true as boolean);
|
||||||
|
|
||||||
if parameters.keep_metadata {
|
if parameters.keep_metadata {
|
||||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -4,9 +4,6 @@ use std::{cmp, fs};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use ::tiff::encoder::compression::DeflateLevel;
|
|
||||||
use ::tiff::encoder::compression::DeflateLevel::Best;
|
|
||||||
|
|
||||||
use error::CaesiumError;
|
use error::CaesiumError;
|
||||||
|
|
||||||
use crate::TiffCompression::{Deflate, Lzw, Packbits};
|
use crate::TiffCompression::{Deflate, Lzw, Packbits};
|
||||||
|
@ -45,10 +42,18 @@ pub enum TiffCompression {
|
||||||
Packbits = 3,
|
Packbits = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq)]
|
||||||
|
pub enum TiffDeflateLevel {
|
||||||
|
Fast = 1,
|
||||||
|
Balanced = 6,
|
||||||
|
Best = 9,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct JpegParameters {
|
pub struct JpegParameters {
|
||||||
pub quality: u32,
|
pub quality: u32,
|
||||||
pub chroma_subsampling: ChromaSubsampling,
|
pub chroma_subsampling: ChromaSubsampling,
|
||||||
|
pub progressive: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -71,7 +76,7 @@ pub struct WebPParameters {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct TiffParameters {
|
pub struct TiffParameters {
|
||||||
pub algorithm: TiffCompression,
|
pub algorithm: TiffCompression,
|
||||||
pub deflate_level: DeflateLevel,
|
pub deflate_level: TiffDeflateLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -92,6 +97,7 @@ pub fn initialize_parameters() -> CSParameters {
|
||||||
let jpeg = JpegParameters {
|
let jpeg = JpegParameters {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
chroma_subsampling: ChromaSubsampling::Auto,
|
chroma_subsampling: ChromaSubsampling::Auto,
|
||||||
|
progressive: true
|
||||||
};
|
};
|
||||||
let png = PngParameters {
|
let png = PngParameters {
|
||||||
quality: 80,
|
quality: 80,
|
||||||
|
@ -102,7 +108,7 @@ pub fn initialize_parameters() -> CSParameters {
|
||||||
let webp = WebPParameters { quality: 80 };
|
let webp = WebPParameters { quality: 80 };
|
||||||
let tiff = TiffParameters {
|
let tiff = TiffParameters {
|
||||||
algorithm: Deflate,
|
algorithm: Deflate,
|
||||||
deflate_level: DeflateLevel::Balanced,
|
deflate_level: TiffDeflateLevel::Balanced,
|
||||||
};
|
};
|
||||||
|
|
||||||
CSParameters {
|
CSParameters {
|
||||||
|
@ -207,7 +213,7 @@ pub fn compress_to_size_in_memory(
|
||||||
Lzw,
|
Lzw,
|
||||||
Packbits
|
Packbits
|
||||||
];
|
];
|
||||||
parameters.tiff.deflate_level = Best;
|
parameters.tiff.deflate_level = TiffDeflateLevel::Best;
|
||||||
parameters.tiff.algorithm = Deflate;
|
parameters.tiff.algorithm = Deflate;
|
||||||
let mut smallest_result = tiff::compress_in_memory(in_file.clone(), parameters)?; //TODO clone
|
let mut smallest_result = tiff::compress_in_memory(in_file.clone(), parameters)?; //TODO clone
|
||||||
for tc in algorithms {
|
for tc in algorithms {
|
||||||
|
@ -367,7 +373,7 @@ pub fn convert_in_memory(in_file: Vec<u8>, parameters: &CSParameters, format: Su
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_parameters(parameters: &CSParameters) -> error::Result<()> {
|
fn validate_parameters(parameters: &CSParameters) -> error::Result<()> {
|
||||||
if parameters.jpeg.quality == 0 || parameters.jpeg.quality > 100 {
|
if parameters.jpeg.quality > 100 {
|
||||||
return Err(CaesiumError {
|
return Err(CaesiumError {
|
||||||
message: "Invalid JPEG quality value".into(),
|
message: "Invalid JPEG quality value".into(),
|
||||||
code: 10001,
|
code: 10001,
|
||||||
|
|
16
src/tiff.rs
16
src/tiff.rs
|
@ -4,10 +4,10 @@ use std::panic;
|
||||||
|
|
||||||
use image::ImageFormat::Tiff;
|
use image::ImageFormat::Tiff;
|
||||||
use tiff::encoder::colortype::{RGB8, RGBA8};
|
use tiff::encoder::colortype::{RGB8, RGBA8};
|
||||||
use tiff::encoder::compression::{Deflate, Lzw, Packbits, Uncompressed};
|
use tiff::encoder::compression::{Deflate, DeflateLevel, Lzw, Packbits, Uncompressed};
|
||||||
use tiff::encoder::TiffEncoder;
|
use tiff::encoder::TiffEncoder;
|
||||||
|
|
||||||
use crate::{CSParameters, TiffCompression};
|
use crate::{CSParameters, TiffCompression, TiffDeflateLevel};
|
||||||
use crate::error::CaesiumError;
|
use crate::error::CaesiumError;
|
||||||
use crate::resize::resize_image;
|
use crate::resize::resize_image;
|
||||||
|
|
||||||
|
@ -87,13 +87,13 @@ pub fn compress_in_memory(
|
||||||
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Deflate>(
|
image::ColorType::Rgb8 => encoder.write_image_with_compression::<RGB8, Deflate>(
|
||||||
image.width(),
|
image.width(),
|
||||||
image.height(),
|
image.height(),
|
||||||
Deflate::with_level(parameters.tiff.deflate_level),
|
Deflate::with_level(parse_deflate_level(parameters.tiff.deflate_level)),
|
||||||
image.as_bytes(),
|
image.as_bytes(),
|
||||||
),
|
),
|
||||||
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Deflate>(
|
image::ColorType::Rgba8 => encoder.write_image_with_compression::<RGBA8, Deflate>(
|
||||||
image.width(),
|
image.width(),
|
||||||
image.height(),
|
image.height(),
|
||||||
Deflate::with_level(parameters.tiff.deflate_level),
|
Deflate::with_level(parse_deflate_level(parameters.tiff.deflate_level)),
|
||||||
image.as_bytes(),
|
image.as_bytes(),
|
||||||
),
|
),
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -174,3 +174,11 @@ pub fn compress_in_memory(
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_deflate_level(level: TiffDeflateLevel) -> DeflateLevel {
|
||||||
|
match level {
|
||||||
|
TiffDeflateLevel::Fast => DeflateLevel::Fast,
|
||||||
|
TiffDeflateLevel::Best => DeflateLevel::Best,
|
||||||
|
TiffDeflateLevel::Balanced => DeflateLevel::Balanced,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use tiff::encoder::compression::DeflateLevel::Balanced;
|
|
||||||
|
|
||||||
use crate::cleanup::remove_compressed_test_file;
|
use crate::cleanup::remove_compressed_test_file;
|
||||||
mod cleanup;
|
mod cleanup;
|
||||||
|
@ -58,7 +57,7 @@ fn rgb8_deflate() {
|
||||||
initialize(output);
|
initialize(output);
|
||||||
let mut params = caesium::initialize_parameters();
|
let mut params = caesium::initialize_parameters();
|
||||||
params.tiff.algorithm = caesium::TiffCompression::Deflate;
|
params.tiff.algorithm = caesium::TiffCompression::Deflate;
|
||||||
params.tiff.deflate_level = Balanced;
|
params.tiff.deflate_level = caesium::TiffDeflateLevel::Balanced;
|
||||||
caesium::compress(
|
caesium::compress(
|
||||||
String::from("tests/samples/rgb8.tif"),
|
String::from("tests/samples/rgb8.tif"),
|
||||||
String::from(output),
|
String::from(output),
|
||||||
|
@ -79,7 +78,7 @@ fn rgba8_deflate() {
|
||||||
initialize(output);
|
initialize(output);
|
||||||
let mut params = caesium::initialize_parameters();
|
let mut params = caesium::initialize_parameters();
|
||||||
params.tiff.algorithm = caesium::TiffCompression::Deflate;
|
params.tiff.algorithm = caesium::TiffCompression::Deflate;
|
||||||
params.tiff.deflate_level = Balanced;
|
params.tiff.deflate_level = caesium::TiffDeflateLevel::Balanced;
|
||||||
caesium::compress(
|
caesium::compress(
|
||||||
String::from("tests/samples/rgba8.tif"),
|
String::from("tests/samples/rgba8.tif"),
|
||||||
String::from(output),
|
String::from(output),
|
||||||
|
|
Loading…
Reference in New Issue