| 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))))] |
| 70 | extern crate alloc; |
| 71 | #[cfg (any(feature = "std" , test))] |
| 72 | extern crate std as alloc; |
| 73 | |
| 74 | mod decode; |
| 75 | mod encode; |
| 76 | mod error; |
| 77 | mod header; |
| 78 | mod pixel; |
| 79 | mod types; |
| 80 | mod utils; |
| 81 | |
| 82 | #[doc (hidden)] |
| 83 | pub mod consts; |
| 84 | |
| 85 | #[cfg (any(feature = "alloc" , feature = "std" ))] |
| 86 | pub use crate::decode::decode_to_vec; |
| 87 | pub use crate::decode::{decode_header, decode_to_buf, Decoder}; |
| 88 | |
| 89 | #[cfg (any(feature = "alloc" , feature = "std" ))] |
| 90 | pub use crate::encode::encode_to_vec; |
| 91 | pub use crate::encode::{encode_max_len, encode_to_buf, Encoder}; |
| 92 | |
| 93 | pub use crate::error::{Error, Result}; |
| 94 | pub use crate::header::Header; |
| 95 | pub use crate::types::{Channels, ColorSpace}; |
| 96 | |