1//! Fast encoder/decoder for [QOI image format](https://qoiformat.org/), implemented in pure and safe Rust.
2//!
3//! - One of the [fastest](#benchmarks) QOI encoders/decoders out there.
4//! - Compliant with the [latest](https://qoiformat.org/qoi-specification.pdf) QOI format specification.
5//! - Zero unsafe code.
6//! - Supports decoding from / encoding to `std::io` streams directly.
7//! - `no_std` support.
8//! - Roundtrip-tested vs the reference C implementation; fuzz-tested.
9//!
10//! ### Examples
11//!
12//! ```rust
13//! use qoi::{encode_to_vec, decode_to_vec};
14//!
15//! let encoded = encode_to_vec(&pixels, width, height)?;
16//! let (header, decoded) = decode_to_vec(&encoded)?;
17//!
18//! assert_eq!(header.width, width);
19//! assert_eq!(header.height, height);
20//! assert_eq!(decoded, pixels);
21//! ```
22//!
23//! ### Benchmarks
24//!
25//! ```
26//! decode:Mp/s encode:Mp/s decode:MB/s encode:MB/s
27//! qoi.h 282.9 225.3 978.3 778.9
28//! qoi-rust 427.4 290.0 1477.7 1002.9
29//! ```
30//!
31//! - Reference C implementation:
32//! [phoboslab/qoi@00e34217](https://github.com/phoboslab/qoi/commit/00e34217).
33//! - Benchmark timings were collected on an Apple M1 laptop.
34//! - 2846 images from the suite provided upstream
35//! ([tarball](https://phoboslab.org/files/qoibench/qoi_benchmark_suite.tar)):
36//! all pngs except two with broken checksums.
37//! - 1.32 GPixels in total with 4.46 GB of raw pixel data.
38//!
39//! Benchmarks have also been run for all of the other Rust implementations
40//! of QOI for comparison purposes and, at the time of writing this document,
41//! this library proved to be the fastest one by a noticeable margin.
42//!
43//! ### Rust version
44//!
45//! The minimum supported Rust version is 1.51.0 (any changes to this would be
46//! considered to be a breaking change).
47//!
48//! ### `no_std`
49//!
50//! This crate supports `no_std` mode. By default, std is enabled via the `std`
51//! feature. You can deactivate the `default-features` to target core instead.
52//! In that case anything related to `std::io`, `std::error::Error` and heap
53//! allocations is disabled. There is an additional `alloc` feature that can
54//! be activated to bring back the support for heap allocations.
55
56#![forbid(unsafe_code)]
57#![warn(clippy::all, clippy::pedantic, clippy::nursery, clippy::cargo)]
58#![allow(
59 clippy::inline_always,
60 clippy::similar_names,
61 clippy::missing_errors_doc,
62 clippy::must_use_candidate,
63 clippy::module_name_repetitions,
64 clippy::cargo_common_metadata,
65 clippy::doc_markdown,
66 clippy::return_self_not_must_use,
67)]
68#![cfg_attr(not(any(feature = "std", test)), no_std)]
69#[cfg(all(feature = "alloc", not(any(feature = "std", test))))]
70extern crate alloc;
71#[cfg(any(feature = "std", test))]
72extern crate std as alloc;
73
74mod decode;
75mod encode;
76mod error;
77mod header;
78mod pixel;
79mod types;
80mod utils;
81
82#[doc(hidden)]
83pub mod consts;
84
85#[cfg(any(feature = "alloc", feature = "std"))]
86pub use crate::decode::decode_to_vec;
87pub use crate::decode::{decode_header, decode_to_buf, Decoder};
88
89#[cfg(any(feature = "alloc", feature = "std"))]
90pub use crate::encode::encode_to_vec;
91pub use crate::encode::{encode_max_len, encode_to_buf, Encoder};
92
93pub use crate::error::{Error, Result};
94pub use crate::header::Header;
95pub use crate::types::{Channels, ColorSpace};
96