Expand description
§fovea-derive
fovea-derive contains the procedural macros that turn pixel structs into fovea pixel types with explicit layout and semantics.
Most users should depend on fovea, not on this crate directly. The core crate re-exports the derives so custom pixel definitions can stay in normal fovea code.
[dependencies]
fovea = "0.1.1"Depend on fovea-derive directly only if you are working on fovea internals or explicitly need the macro crate.
§Derives
| Derive | What it promises |
|---|---|
PlainPixel | The type has a stable byte layout suitable for byte-level access. |
HomogeneousPixel | Every channel has the same channel type and can be viewed as a channel array. |
ZeroablePixel | The type has an all-zero pixel value for allocation and initialization. |
LinearPixel | The type supports channel-wise linear arithmetic with an explicit accumulator. |
WhiteChannel | A homogeneous pixel can report its white/max channel value. |
The derives are intentionally strict. If the macro rejects a type, it is usually protecting a layout or semantic invariant that unsafe byte paths and transform bounds rely on.
§Custom pixel example
use fovea::{HomogeneousPixel, PlainPixel, ZeroablePixel};
use std::num::Saturating;
#[derive(Clone, Copy, PlainPixel, HomogeneousPixel, ZeroablePixel)]
#[repr(C)]
pub struct BayerRg8 {
pub value: Saturating<u8>,
}Use #[repr(C)] for multi-field pixels and #[repr(transparent)] for one-field wrapper pixels. Avoid implicit layout. Pixel layout is part of the API contract.
§Linear pixels need an accumulator
Interpolation and blending often need more precision than the storage pixel. LinearPixel makes that accumulator explicit.
use fovea::{HomogeneousPixel, LinearPixel, PlainPixel, ZeroablePixel};
use std::num::Saturating;
#[derive(Clone, Copy, PlainPixel, HomogeneousPixel, ZeroablePixel, LinearPixel)]
#[repr(C)]
#[linear(accumulator = RgbF32)]
pub struct Rgb8 {
pub r: Saturating<u8>,
pub g: Saturating<u8>,
pub b: Saturating<u8>,
}
#[derive(Clone, Copy, PlainPixel, HomogeneousPixel, ZeroablePixel, LinearPixel)]
#[repr(C)]
#[linear(accumulator = Self)]
pub struct RgbF32 {
pub r: f32,
pub g: f32,
pub b: f32,
}Do not derive LinearPixel just because arithmetic is possible. Derive it only when blending or interpolation is meaningful for the pixel semantics. Gamma-encoded sRGB pixel types intentionally do not implement LinearSpace.
§What this crate is not
fovea-derive does not define the pixel model. The model lives in fovea::pixel; this crate only automates correct implementations. Read the fovea crate docs first unless you are debugging macro behavior.
§Crate ecosystem
| Crate | Purpose |
|---|---|
fovea | Core crate and normal home of the derive re-exports. |
fovea-derive | Procedural macro implementation crate. |
fovea-examples | Repo-only examples, including custom-pixel patterns. |
§License
Licensed under the MIT License.
Derive Macros§
- Homogeneous
Pixel - Derive macro for
HomogeneousPixeltrait. - Linear
Pixel - Derive macro for
LinearPixeltrait. - Plain
Pixel - Derive macro for
PlainPixeltrait. - White
Channel - Derive macro for
WhiteChanneltrait. - Zeroable
Pixel - Derive macro for
ZeroablePixeltrait.