You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ZettaScript 8099e065f3
wip
3 months ago
.github/workflows Bump MSRV to 1.60, set edition to 2021 5 months ago
assets Add assets for tests and reference checks 1 year ago
bench Rename qoi-fast -> qoi (qoi-rust) + update repo 1 year ago
doc Add qoi format specification pdf to the repo 1 year ago
ext (Update the upstream qoi submodule) 1 year ago
fuzz Rename qoi-fast -> qoi (qoi-rust) + update repo 1 year ago
libqoi Add `libqoi` helper crate that wraps qoi.h 1 year ago
src wip 3 months ago
tests Make `Bytes` pub 5 months ago
.gitignore (Add fuzz coverage to .gitignore) 1 year ago
.gitmodules Add reference implementation as a submodule 1 year ago
Cargo.toml Version bump to v0.4.1 5 months ago
LICENSE-APACHE Add license files 1 year ago
LICENSE-MIT Add license files 1 year ago
README.md wip 3 months ago
rustfmt.toml Initial working version (but lots of temp stuff) 1 year ago

README.md

qoi

Build Latest Version Documentation Apache 2.0 MIT unsafe forbidden

Fast encoder/decoder for QOI image format, implemented in pure and safe Rust.

  • One of the fastest QOI encoders/decoders out there.
  • Compliant with the latest QOI format specification.
  • Zero unsafe code.
  • Supports decoding from / encoding to std::io streams directly.
  • no_std support.
  • Roundtrip-tested vs the reference C implementation; fuzz-tested.

Note about this fork

This fork implements a slight improvement to the original specs, which leaves unused the QOI_OP_RGBA chunk flag with RGB.

Here, we use this flag for the new QOI_OP_RUN2 chunk. It's like the QOI_OP_RUN chunk, but followed by two bytes representing run (BE). (only for RGB, as the flag is already used for RGBA)

The decoder remains fully compatible with the original one (except when using QOI_OP_RGBA in a RGB image). The encoder is fully compatible for RGBA, not for RGB (except using the reference feature).

Why this? Because it enables significant improvements for compressing images with large uniform areas (such as screen captures), or for encoding a diff-filtered video stream where successive frames often have identical regions. (see syeve for the video encoding)

Examples

use qoi::{encode_to_vec, decode_to_vec};

let encoded = encode_to_vec(&pixels, width, height)?;
let (header, decoded) = decode_to_vec(&encoded)?;

assert_eq!(header.width, width);
assert_eq!(header.height, height);
assert_eq!(decoded, pixels);

Benchmarks

             decode:Mp/s  encode:Mp/s  decode:MB/s  encode:MB/s
qoi.h              282.9        225.3        978.3        778.9
qoi-rust           427.4        290.0       1477.7       1002.9
  • Reference C implementation: phoboslab/qoi@00e34217.
  • Benchmark timings were collected on an Apple M1 laptop.
  • 2846 images from the suite provided upstream (tarball): all pngs except two with broken checksums.
  • 1.32 GPixels in total with 4.46 GB of raw pixel data.

Benchmarks have also been run for all of the other Rust implementations of QOI for comparison purposes and, at the time of writing this document, this library proved to be the fastest one by a noticeable margin.

Rust version

The minimum required Rust version for the latest crate version is 1.61.0.

no_std

This crate supports no_std mode. By default, std is enabled via the std feature. You can deactivate the default-features to target core instead. In that case anything related to std::io, std::error::Error and heap allocations is disabled. There is an additional alloc feature that can be activated to bring back the support for heap allocations.

License

This project is dual-licensed under MIT and Apache 2.0.