1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Core engine for `otf-pixels`: the op graph, tiles, codec traits, and the
//! M1 reference evaluator.
//!
//! Most users want the [`otf-pixels`] facade instead — this crate is the
//! substrate it and the op/codec crates are built on. Depend on it directly
//! when implementing a codec or an op.
//!
//! [`otf-pixels`]: https://docs.rs/otf-pixels
//!
//! # The model
//!
//! An [`Image`] is a handle onto a node of an immutable lazy DAG. Chaining ops
//! builds graph structure and computes descriptors; it reads no pixels. Pixels
//! move only when a terminal pulls them, at which point demand propagates
//! *backwards* through [`Op::input_regions`] and pixels flow *forwards* through
//! [`Op::compute`] (ADR-0001).
//!
//! ```
//! use otf_pixels_core::{Format, Image, ImageDescriptor, PixelFormat, TileBuf, evaluate};
//! use otf_pixels_core::{BufferSource, Producer, Region};
//! use std::sync::Arc;
//!
//! # fn main() -> Result<(), otf_pixels_core::PixelsError> {
//! let descriptor = ImageDescriptor::new(2, 2, PixelFormat::Gray8)?;
//! let pixels = TileBuf::from_vec(descriptor.region(), PixelFormat::Gray8, vec![1, 2, 3, 4])?;
//! let source = BufferSource::new(descriptor, Arc::new(pixels))?;
//!
//! // Construction and chaining do no pixel work.
//! let image = Image::from_producer(Arc::new(source), Format::Raw);
//! assert_eq!(image.metadata()?.width, 2);
//!
//! // A terminal pulls.
//! assert_eq!(evaluate(&image)?.bytes(), &[1, 2, 3, 4]);
//! # Ok(())
//! # }
//! ```
//!
//! # Errors never panic
//!
//! Every fallible path returns [`PixelsError`]. Malformed input is a value, not
//! a panic — this crate forbids `unsafe` and denies `unwrap`/`expect`/`panic!`
//! outside tests, because a hostile image must not be able to take down a
//! process embedding the engine (ARCHITECTURE §Failure model).
//!
//! # Concurrency
//!
//! The core is synchronous (ADR-0005). [`Image`] is `Send + Sync` and cheap to
//! clone, so an async host integrates by running pipelines on its own worker
//! threads and meeting the engine at the [`Source`]/[`Sink`] boundary.
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Orientation;
pub use ;
pub use ;
pub use ThreadPool;
pub use ;
pub use ;
pub use ;
pub use ;