dcv-color-primitives 0.5.1

a library to perform image color model conversion
Documentation
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify,
// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#[cfg(not(tarpaulin_include))]
const fn u8_to_fix(x: i32, frac_bits: i32) -> i32 {
    x << frac_bits
}

#[cfg(not(tarpaulin_include))]
pub const fn sampler_to_depth(sampler: Sampler) -> usize {
    match sampler {
        Sampler::Bgr | Sampler::BgrOverflow => 3,
        _ => 4,
    }
}

#[cfg(not(tarpaulin_include))]
pub const fn is_full_range<const COLORIMETRY: usize>() -> bool {
    // Forward weights should be defined to mach this order
    COLORIMETRY >= 2
}

#[cfg(not(tarpaulin_include))]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
pub const fn i32x2_to_i32(x: i32, y: i32) -> i32 {
    let val = (((x & 0xFFFF) as u32) << 16) | ((y & 0xFFFF) as u32);

    // Checked: we want to reinterpret the bits
    val as i32
}

#[cfg(not(tarpaulin_include))]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
pub const fn i32_to_i16(x: i32) -> i16 {
    // Checked: we want to reinterpret the bits
    let val = (x & 0xFFFF) as u32;

    // Checked: we are extracting the lower part of a 32-bit integer
    val as i16
}

pub fn wg_index(x: usize, y: usize, w: usize, h: usize) -> usize {
    (h * y) + (x * w)
}

pub fn lower_multiple_of_pot(x: usize, p: usize) -> usize {
    x & !(p - 1)
}

pub fn out_of_bounds(size: usize, width: usize, height_minus_one: usize, stride: usize) -> bool {
    width > size
        || (height_minus_one != 0
            && ((stride > usize::max_value() / height_minus_one)
                || (stride * height_minus_one > size - width)))
}

pub fn compute_stride(stride: usize, def: usize) -> usize {
    if stride == 0 {
        def
    } else {
        stride
    }
}

pub const FIX16: i32 = 16;
pub const FIX18: i32 = 18;
pub const FIX16_HALF: i32 = 1 << (FIX16 - 1);
pub const FIX18_HALF: i32 = 1 << (FIX16 + 1);
pub const FIX6: i32 = 6;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub const SHORT_HALF: i32 = 16384;

// Coefficient table for 601
pub const XR_601: i32 = 16829;
pub const XG_601: i32 = 33039;
pub const XB_601: i32 = 6416;
pub const YR_601: i32 = -9713;
pub const YG_601: i32 = -19070;
pub const YB_601: i32 = 28784;
pub const ZR_601: i32 = 28784;
pub const ZG_601: i32 = -24102;
pub const ZB_601: i32 = -4680;

pub const XXYM_601: i32 = 19077;
pub const RCRM_601: i32 = 26149;
pub const GCRM_601: i32 = 13320;
pub const GCBM_601: i32 = 6419;
pub const BCBM_601: i32 = 33050;
pub const RN_601: i32 = 14234;
pub const GP_601: i32 = 8709;
pub const BN_601: i32 = 17685;

// Coefficient table for 709
pub const XR_709: i32 = 11966;
pub const XG_709: i32 = 40254;
pub const XB_709: i32 = 4064;
pub const YR_709: i32 = -6595;
pub const YG_709: i32 = -22188;
pub const YB_709: i32 = 28784;
pub const ZR_709: i32 = 28784;
pub const ZG_709: i32 = -26144;
pub const ZB_709: i32 = -2638;

pub const XXYM_709: i32 = 19077;
pub const RCRM_709: i32 = 29372;
pub const GCRM_709: i32 = 8731;
pub const GCBM_709: i32 = 3494;
pub const BCBM_709: i32 = 34610;
pub const RN_709: i32 = 15846;
pub const GP_709: i32 = 4952;
pub const BN_709: i32 = 18465;

// Coefficient table for 601 (full range)
pub const XR_601FR: i32 = 19595;
pub const XG_601FR: i32 = 38470;
pub const XB_601FR: i32 = 7471;
pub const YR_601FR: i32 = -11057;
pub const YG_601FR: i32 = -21709;
pub const YB_601FR: i32 = 32768;
pub const ZR_601FR: i32 = 32768;
pub const ZG_601FR: i32 = -27438;
pub const ZB_601FR: i32 = -5328;

pub const XXYM_601FR: i32 = 16384;
pub const RCRM_601FR: i32 = 22970;
pub const GCRM_601FR: i32 = 11700;
pub const GCBM_601FR: i32 = 5638;
pub const BCBM_601FR: i32 = 29032;
pub const RN_601FR: i32 = 11363;
pub const GP_601FR: i32 = 8633;
pub const BN_601FR: i32 = 14370;

// Coefficient table for 709 (full range)
pub const XR_709FR: i32 = 13933;
pub const XG_709FR: i32 = 46871;
pub const XB_709FR: i32 = 4732;
pub const YR_709FR: i32 = -7508;
pub const YG_709FR: i32 = -25258;
pub const YB_709FR: i32 = 32768;
pub const ZR_709FR: i32 = 32768;
pub const ZG_709FR: i32 = -29762;
pub const ZB_709FR: i32 = -3004;

pub const XXYM_709FR: i32 = 16384;
pub const RCRM_709FR: i32 = 25802;
pub const GCRM_709FR: i32 = 7670;
pub const GCBM_709FR: i32 = 3069;
pub const BCBM_709FR: i32 = 30402;
pub const RN_709FR: i32 = 12768;
pub const GP_709FR: i32 = 5359;
pub const BN_709FR: i32 = 15050;

// Other defines
const Y_MIN: i32 = 16;
const C_HALF: i32 = 128;
const FIX16_Y_MIN: i32 = u8_to_fix(Y_MIN, FIX16);
const FIX16_C_HALF: i32 = u8_to_fix(C_HALF, FIX16);
pub const FIX18_C_HALF: i32 = u8_to_fix(C_HALF, FIX18);
pub const Y_OFFSET: i32 = FIX16_Y_MIN + FIX16_HALF;
pub const C_OFFSET: i32 = FIX18_C_HALF + FIX18_HALF;
pub const C_OFFSET16: i32 = FIX16_C_HALF + FIX16_HALF;
pub const DEFAULT_ALPHA: u8 = 255;

#[derive(Copy, Clone)]
pub enum Sampler {
    Argb,
    Bgra,
    Bgr,
    BgrOverflow,
    Length,
}

pub enum Colorimetry {
    Bt601,
    Bt709,
    Bt601FR,
    Bt709FR,
    Length,
}