Skip to main content

valo_codec/
lib.rs

1//! Image decoding for Valo: encoded bytes in, drawable [`Image`](valo::Image)s out.
2//!
3//! The engine itself never decodes (hosts upload images); this crate is the optional piece a host
4//! adds when it wants Valo to do that job. It has no codecs of its own. A host registers
5//! [`Decoder`]s — the platform's native one first where it exists, a portable software one as
6//! fallback — and an [`ImageLoader`] tries them in that order for each image.
7//!
8//! Decoders produce pixels or a texture; the loader alone turns those into images through
9//! [`ImageContext`](valo::ImageContext). That split is what lets a native codec deliver a texture
10//! it already decoded into GPU-shared memory, with no readback, while software decoders never
11//! touch the GPU.
12//!
13//! Results arrive as [`Pending`] values, which are futures. With [`ImageLoader::new`] the work
14//! runs inside the first poll, on the polling thread — the shape for a single-threaded host or
15//! the web. With `ImageLoader::with_worker` (the `worker` feature) a dedicated thread decodes and
16//! uploads, and the poll wakes when the image is ready.
17//!
18//! ```no_run
19//! # use std::sync::Arc;
20//! # async fn demo(context: &valo::Context, decoders: Vec<Box<dyn valo_codec::Decoder>>, bytes: Arc<[u8]>) -> Result<(), valo_codec::DecodeError> {
21//! use valo_codec::{DecodeOptions, ImageLoader};
22//!
23//! let loader = ImageLoader::new(context.image_context(), decoders);
24//! let options = DecodeOptions { max_size: Some([512, 512]), mipmaps: true, ..Default::default() };
25//! let image = loader.decode(bytes, options).await?;
26//! # Ok(()) }
27//! ```
28
29#![warn(missing_docs)]
30// A decoded frame carries a wgpu texture, and proving one `Send` walks a type graph deeper than
31// the default limit once a host builds wgpu with every backend.
32#![recursion_limit = "256"]
33
34mod backend;
35mod error;
36mod loader;
37mod options;
38mod pending;
39mod service;
40#[cfg(all(feature = "worker", not(target_arch = "wasm32")))]
41mod worker;
42
43pub use backend::{DecodedFrame, Decoder, FramePixels, FrameReader, OpenError, OpenRequest};
44pub use error::{Declined, DecodeError};
45pub use loader::{Codec, Frame, ImageLoader};
46pub use options::{fit_within, DecodeLimits, DecodeOptions, ImageInfo, Repetition};
47pub use pending::Pending;