#[inline(always)]
fn expand_u8_to_u16(v: u8) -> u16 {
let v16 = v as u16;
(v16 << 8) | v16
}
pub(crate) fn pal8_to_rgb_row(indices: &[u8], palette: &[[u8; 4]; 256], rgb_out: &mut [u8]) {
let w = indices.len();
debug_assert!(rgb_out.len() >= 3 * w);
for x in 0..w {
let [b, g, r, _a] = palette[indices[x] as usize];
rgb_out[3 * x] = r;
rgb_out[3 * x + 1] = g;
rgb_out[3 * x + 2] = b;
}
}
pub(crate) fn pal8_to_rgba_row(indices: &[u8], palette: &[[u8; 4]; 256], rgba_out: &mut [u8]) {
let w = indices.len();
debug_assert!(rgba_out.len() >= 4 * w);
for x in 0..w {
let [b, g, r, a] = palette[indices[x] as usize];
rgba_out[4 * x] = r;
rgba_out[4 * x + 1] = g;
rgba_out[4 * x + 2] = b;
rgba_out[4 * x + 3] = a;
}
}
pub(crate) fn pal8_to_rgb_u16_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgb_u16_out: &mut [u16],
) {
let w = indices.len();
debug_assert!(rgb_u16_out.len() >= 3 * w);
for x in 0..w {
let [b, g, r, _a] = palette[indices[x] as usize];
rgb_u16_out[3 * x] = expand_u8_to_u16(r);
rgb_u16_out[3 * x + 1] = expand_u8_to_u16(g);
rgb_u16_out[3 * x + 2] = expand_u8_to_u16(b);
}
}
pub(crate) fn pal8_to_rgba_u16_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgba_u16_out: &mut [u16],
) {
let w = indices.len();
debug_assert!(rgba_u16_out.len() >= 4 * w);
for x in 0..w {
let [b, g, r, a] = palette[indices[x] as usize];
rgba_u16_out[4 * x] = expand_u8_to_u16(r);
rgba_u16_out[4 * x + 1] = expand_u8_to_u16(g);
rgba_u16_out[4 * x + 2] = expand_u8_to_u16(b);
rgba_u16_out[4 * x + 3] = expand_u8_to_u16(a);
}
}
#[cfg(test)]
mod tests {
use super::*;
fn make_palette() -> [[u8; 4]; 256] {
let mut p = [[0u8; 4]; 256];
p[0] = [10, 20, 30, 40];
p[1] = [50, 100, 200, 255];
p
}
#[test]
fn rgb_row_reorders_bgra_to_rgb() {
let palette = make_palette();
let indices = [0u8, 1u8];
let mut out = [0u8; 6];
pal8_to_rgb_row(&indices, &palette, &mut out);
assert_eq!(out[0..3], [30, 20, 10]);
assert_eq!(out[3..6], [200, 100, 50]);
}
#[test]
fn rgba_row_passes_alpha() {
let palette = make_palette();
let indices = [0u8];
let mut out = [0u8; 4];
pal8_to_rgba_row(&indices, &palette, &mut out);
assert_eq!(out, [30, 20, 10, 40]); }
#[test]
fn rgb_u16_row_expands_full_range() {
let mut palette = [[0u8; 4]; 256];
palette[0] = [0, 0, 255, 255]; let indices = [0u8];
let mut out = [0u16; 3];
pal8_to_rgb_u16_row(&indices, &palette, &mut out);
assert_eq!(out[0], 0xFFFF); assert_eq!(out[1], 0x0000); assert_eq!(out[2], 0x0000); }
#[test]
fn rgba_u16_row_expands_alpha() {
let mut palette = [[0u8; 4]; 256];
palette[0] = [0, 0, 0, 128];
let indices = [0u8];
let mut out = [0u16; 4];
pal8_to_rgba_u16_row(&indices, &palette, &mut out);
assert_eq!(out[3], expand_u8_to_u16(128)); }
#[test]
fn expand_u8_to_u16_boundary_values() {
assert_eq!(expand_u8_to_u16(0), 0x0000);
assert_eq!(expand_u8_to_u16(1), 0x0101);
assert_eq!(expand_u8_to_u16(128), 0x8080);
assert_eq!(expand_u8_to_u16(255), 0xFFFF);
}
}