Skip to main content

TransferCurve

Trait TransferCurve 

Source
pub trait TransferCurve:
    Send
    + Sync
    + 'static {
    type Luts: Send + Sync;

    // Required methods
    fn to_linear(&self, encoded: f32) -> f32;
    fn from_linear(&self, linear: f32) -> f32;
    fn build_luts(&self) -> Self::Luts;
    fn u8_to_linear_f32(
        &self,
        src: &[u8],
        dst: &mut [f32],
        luts: &Self::Luts,
        channels: usize,
        has_alpha: bool,
        premul: bool,
    );
    fn linear_f32_to_u8(
        &self,
        src: &[f32],
        dst: &mut [u8],
        luts: &Self::Luts,
        channels: usize,
        has_alpha: bool,
        unpremul: bool,
    );
    fn u16_to_linear_f32(
        &self,
        src: &[u16],
        dst: &mut [f32],
        luts: &Self::Luts,
        channels: usize,
        has_alpha: bool,
        premul: bool,
    );
    fn linear_f32_to_u16(
        &self,
        src: &[f32],
        dst: &mut [u16],
        luts: &Self::Luts,
        channels: usize,
        has_alpha: bool,
        unpremul: bool,
    );
    fn u8_to_linear_i12(&self, src: &[u8], dst: &mut [i16], luts: &Self::Luts);
    fn linear_i12_to_u8(&self, src: &[i16], dst: &mut [u8], luts: &Self::Luts);
    fn f32_to_linear_inplace(
        &self,
        row: &mut [f32],
        channels: usize,
        has_alpha: bool,
        premul: bool,
    );
    fn linear_to_f32_inplace(
        &self,
        row: &mut [f32],
        channels: usize,
        has_alpha: bool,
        unpremul: bool,
    );

    // Provided method
    fn is_identity(&self) -> bool { ... }
}
Expand description

Transfer function for encoding/decoding pixel values to/from linear light.

Provides batch scanline methods for converting between encoded element types and the working-space type used during filtering. The channels parameter and premul/unpremul flags handle arbitrary layouts — RGB (3ch, no alpha), RGBA (4ch, alpha last), CMYK (4ch, no alpha), Gray (1ch), etc.

§Implementing a custom TF

Implement to_linear and from_linear for the scalar curve. The batch methods have default implementations that call these in a loop, but optimized implementations should override the batch methods with LUT-based or SIMD-based versions.

Required Associated Types§

Source

type Luts: Send + Sync

Cached state (LUTs, etc.). Built once by build_luts(), passed to batch methods.

Standard TFs use &'static RuntimeLuts (permanently cached via OnceLock). Custom TFs can use owned RuntimeLuts or ().

Required Methods§

Source

fn to_linear(&self, encoded: f32) -> f32

Encode a linear-light value to this TF’s encoded space. Both input and output are in [0, 1] for SDR TFs.

Source

fn from_linear(&self, linear: f32) -> f32

Decode a value from this TF’s encoded space to linear light.

Source

fn build_luts(&self) -> Self::Luts

Build or retrieve cached LUTs.

Source

fn u8_to_linear_f32( &self, src: &[u8], dst: &mut [f32], luts: &Self::Luts, channels: usize, has_alpha: bool, premul: bool, )

Convert a row of u8 encoded pixels to premultiplied linear f32.

Fuses linearize + premultiply. If premul is false, only linearizes. channels is the number of components per pixel (1, 3, or 4). Alpha (if present) is assumed to be the last channel and is NOT linearized — it’s scaled linearly (v/255).

Source

fn linear_f32_to_u8( &self, src: &[f32], dst: &mut [u8], luts: &Self::Luts, channels: usize, has_alpha: bool, unpremul: bool, )

Convert a row of premultiplied linear f32 to u8 encoded pixels.

Fuses unpremultiply + delinearize + quantize. Clamps to [0, 255].

Source

fn u16_to_linear_f32( &self, src: &[u16], dst: &mut [f32], luts: &Self::Luts, channels: usize, has_alpha: bool, premul: bool, )

Convert a row of u16 encoded pixels to premultiplied linear f32.

Values span full 0-65535 range. Alpha (if present, last channel) is scaled linearly (v/65535). Non-alpha channels go through the TF.

Source

fn linear_f32_to_u16( &self, src: &[f32], dst: &mut [u16], luts: &Self::Luts, channels: usize, has_alpha: bool, unpremul: bool, )

Convert premultiplied linear f32 to u16 encoded pixels.

Source

fn u8_to_linear_i12(&self, src: &[u8], dst: &mut [i16], luts: &Self::Luts)

Convert a row of u8 encoded pixels to linear i12 (0-4095). All channels converted; no premul/unpremul (I16Work doesn’t support premul).

Source

fn linear_i12_to_u8(&self, src: &[i16], dst: &mut [u8], luts: &Self::Luts)

Convert a row of linear i12 to u8 encoded pixels.

Source

fn f32_to_linear_inplace( &self, row: &mut [f32], channels: usize, has_alpha: bool, premul: bool, )

Convert f32 encoded values to premultiplied linear f32 in-place.

Source

fn linear_to_f32_inplace( &self, row: &mut [f32], channels: usize, has_alpha: bool, unpremul: bool, )

Convert premultiplied linear f32 to f32 encoded in-place. Does NOT clamp — output can have values outside [0, 1] for wide gamut.

Provided Methods§

Source

fn is_identity(&self) -> bool

Whether this TF is the identity (no conversion needed).

Implementors§