#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_rgb_row(packed: &[u8], rgb_out: &mut [u8], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(rgb_out.len() >= width * 3, "rgb_out too short");
for x in 0..width {
let y = packed[x * 2];
let i = x * 3;
rgb_out[i] = y;
rgb_out[i + 1] = y;
rgb_out[i + 2] = y;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_rgba_row(packed: &[u8], rgba_out: &mut [u8], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(rgba_out.len() >= width * 4, "rgba_out too short");
for x in 0..width {
let y = packed[x * 2];
let a = packed[x * 2 + 1];
let i = x * 4;
rgba_out[i] = y;
rgba_out[i + 1] = y;
rgba_out[i + 2] = y;
rgba_out[i + 3] = a;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_rgb_u16_row(packed: &[u8], rgb_u16_out: &mut [u16], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(rgb_u16_out.len() >= width * 3, "rgb_u16_out too short");
for x in 0..width {
let y = packed[x * 2] as u16;
let i = x * 3;
rgb_u16_out[i] = y;
rgb_u16_out[i + 1] = y;
rgb_u16_out[i + 2] = y;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_rgba_u16_row(packed: &[u8], rgba_u16_out: &mut [u16], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(rgba_u16_out.len() >= width * 4, "rgba_u16_out too short");
for x in 0..width {
let y = packed[x * 2] as u16;
let a = packed[x * 2 + 1] as u16;
let i = x * 4;
rgba_u16_out[i] = y;
rgba_u16_out[i + 1] = y;
rgba_u16_out[i + 2] = y;
rgba_u16_out[i + 3] = a;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_luma_row(packed: &[u8], luma_out: &mut [u8], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(luma_out.len() >= width, "luma_out too short");
for x in 0..width {
luma_out[x] = packed[x * 2];
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_luma_u16_row(packed: &[u8], luma_u16_out: &mut [u16], width: usize) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(luma_u16_out.len() >= width, "luma_u16_out too short");
for x in 0..width {
luma_u16_out[x] = packed[x * 2] as u16;
}
}
#[cfg_attr(not(tarpaulin), inline(always))]
pub(crate) fn ya8_to_hsv_row(
packed: &[u8],
h_out: &mut [u8],
s_out: &mut [u8],
v_out: &mut [u8],
width: usize,
) {
debug_assert!(packed.len() >= width * 2, "packed too short");
debug_assert!(h_out.len() >= width, "h_out too short");
debug_assert!(s_out.len() >= width, "s_out too short");
debug_assert!(v_out.len() >= width, "v_out too short");
for x in 0..width {
h_out[x] = 0;
s_out[x] = 0;
v_out[x] = packed[x * 2];
}
}
#[cfg(all(test, feature = "std"))]
mod tests {
use super::*;
fn packed_ya(pairs: &[(u8, u8)]) -> std::vec::Vec<u8> {
pairs.iter().flat_map(|&(y, a)| [y, a]).collect()
}
#[test]
fn ya8_to_rgb_broadcasts_y_drops_alpha() {
let p = packed_ya(&[(100, 200)]);
let mut out = [0u8; 3];
ya8_to_rgb_row(&p, &mut out, 1);
assert_eq!(out, [100, 100, 100]);
}
#[test]
fn ya8_to_rgb_zero_pixel() {
let p = packed_ya(&[(0, 0)]);
let mut out = [0xFFu8; 3];
ya8_to_rgb_row(&p, &mut out, 1);
assert_eq!(out, [0, 0, 0]);
}
#[test]
fn ya8_to_rgb_max_pixel() {
let p = packed_ya(&[(255, 0)]);
let mut out = [0u8; 3];
ya8_to_rgb_row(&p, &mut out, 1);
assert_eq!(out, [255, 255, 255]);
}
#[test]
fn ya8_to_rgba_broadcasts_y_passes_alpha() {
let p = packed_ya(&[(100, 200)]);
let mut out = [0u8; 4];
ya8_to_rgba_row(&p, &mut out, 1);
assert_eq!(out, [100, 100, 100, 200]);
}
#[test]
fn ya8_to_rgba_two_pixels() {
let p = packed_ya(&[(50, 150), (200, 255)]);
let mut out = [0u8; 8];
ya8_to_rgba_row(&p, &mut out, 2);
assert_eq!(&out[0..4], &[50, 50, 50, 150]);
assert_eq!(&out[4..8], &[200, 200, 200, 255]);
}
#[test]
fn ya8_to_rgb_u16_zero_extends() {
let p = packed_ya(&[(100, 0)]);
let mut out = [0u16; 3];
ya8_to_rgb_u16_row(&p, &mut out, 1);
assert_eq!(out, [100, 100, 100]);
}
#[test]
fn ya8_to_rgb_u16_max_y() {
let p = packed_ya(&[(255, 0)]);
let mut out = [0u16; 3];
ya8_to_rgb_u16_row(&p, &mut out, 1);
assert_eq!(out, [255, 255, 255]);
}
#[test]
fn ya8_to_rgba_u16_passes_alpha_zero_extended() {
let p = packed_ya(&[(100, 200)]);
let mut out = [0u16; 4];
ya8_to_rgba_u16_row(&p, &mut out, 1);
assert_eq!(out, [100, 100, 100, 200]);
}
#[test]
fn ya8_to_luma_extracts_y_bytes() {
let p = packed_ya(&[(100, 200), (50, 25)]);
let mut out = [0u8; 2];
ya8_to_luma_row(&p, &mut out, 2);
assert_eq!(out, [100, 50]);
}
#[test]
fn ya8_to_luma_u16_zero_extends_y() {
let p = packed_ya(&[(128, 0)]);
let mut out = [0u16; 1];
ya8_to_luma_u16_row(&p, &mut out, 1);
assert_eq!(out[0], 128);
}
#[test]
fn ya8_to_hsv_h0_s0_v_y_drops_alpha() {
let p = packed_ya(&[(100, 200)]);
let mut h = [0xFFu8; 1];
let mut s = [0xFFu8; 1];
let mut v = [0u8; 1];
ya8_to_hsv_row(&p, &mut h, &mut s, &mut v, 1);
assert_eq!(h[0], 0);
assert_eq!(s[0], 0);
assert_eq!(v[0], 100);
}
#[test]
fn ya8_to_hsv_zero_luma() {
let p = packed_ya(&[(0, 255)]);
let mut h = [0u8; 1];
let mut s = [0u8; 1];
let mut v = [0xFFu8; 1];
ya8_to_hsv_row(&p, &mut h, &mut s, &mut v, 1);
assert_eq!(v[0], 0);
}
#[test]
fn ya8_to_hsv_max_luma() {
let p = packed_ya(&[(255, 0)]);
let mut h = [0u8; 1];
let mut s = [0u8; 1];
let mut v = [0u8; 1];
ya8_to_hsv_row(&p, &mut h, &mut s, &mut v, 1);
assert_eq!(v[0], 255);
}
}