A fast, correct and safe jpeg decoder in pure Rust.
The library provides a simple-to-use API for jpeg decoding and an ability to add options to influence decoding.
// Import the library
use zune_jpeg::JpegDecoder;
use std::fs::read;
fn main()->Result<(),DecoderErrors> {
// load some jpeg data
let data = read("cat.jpg").unwrap();
// create a decoder
let mut decoder = JpegDecoder::new(&data);
// decode the file
let pixels = decoder.decode()?;
}
The decoder supports more manipulations via DecoderOptions
,
see additional documentation in the library.
The implementation aims to have the following goals achieved, in order of importance
- Safety - Do not segfault on errors or invalid input. Panics are okay, but
should be fixed when reported.
unsafe
is only used for SIMD intrinsics, and can be turned off entirely both at compile time and at runtime. - Speed - Get the data as quickly as possible, which means
- Platform intrinsics code where justifiable
- Carefully written platform independent code that allows the compiler to vectorize it.
- Regression tests.
- Watch the memory usage of the program
- Usability - Provide utility functions like different color conversions functions.
- Bit identical results with libjpeg/libjpeg-turbo will never be an aim of this library. Jpeg is a lossy format with very few parts specified by the standard (i.e it doesn't give a reference upsampling and color conversion algorithm)
- A Pretty fast 8*8 integer IDCT.
- Fast Huffman Decoding
- Fast color convert functions.
- Support for extended colorspaces like GrayScale and RGBA
- Single-threaded decoding.
- Support for four component JPEGs, and esoteric color schemes like CYMK
- Support for
no_std
- BGR/BGRA decoding support.
feature | on | Capabilities |
---|---|---|
x86 |
yes | Enables x86 specific instructions, specifically avx and sse for accelerated decoding. |
std |
yes | Enable linking to the std crate |
Note that the x86
features are automatically disabled on platforms that aren't x86 during compile
time hence there is no need to disable them explicitly if you are targeting such a platform.
The crate can be used in a no_std
environment with the alloc
feature.
But one is required to link to a working allocator for whatever environment the decoder will be running on
The decoder heavily relies on platform specific intrinsics, namely AVX2 and SSE to gain speed-ups in decoding,
but they perform poorly in debug builds. To get reasonable performance even
when compiling your program in debug mode, add this to your Cargo.toml
:
# `zune-jpeg` package will be always built with optimizations
[profile.dev.package.zune-jpeg]
opt-level = 3
The library tries to be at fast as libjpeg-turbo while being as safe as possible. Platform specific intrinsics help get speed up intensive operations ensuring we can almost match libjpeg-turbo speeds but speeds are always +- 10 ms of this library.
For more up-to-date benchmarks, see the online repo with benchmarks here