use crate::row::{
rgb_row_bytes, rgb_row_elems, rgba_row_bytes, rgba_row_elems,
scalar::pal8::{
pal8_to_rgb_row as scalar_rgb, pal8_to_rgb_u16_row as scalar_rgb_u16,
pal8_to_rgba_row as scalar_rgba, pal8_to_rgba_u16_row as scalar_rgba_u16,
},
};
pub fn pal8_to_rgb_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgb_out: &mut [u8],
_use_simd: bool,
) {
let width = indices.len();
let out_min = rgb_row_bytes(width);
assert!(indices.len() >= width, "indices too short");
assert!(rgb_out.len() >= out_min, "rgb_out too short");
#[cfg(target_arch = "aarch64")]
{
use crate::row::neon_available;
if _use_simd && neon_available() {
unsafe { crate::row::arch::neon::pal8::pal8_to_rgb_row(indices, palette, rgb_out) }
return;
}
}
scalar_rgb(indices, palette, rgb_out);
}
pub fn pal8_to_rgba_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgba_out: &mut [u8],
_use_simd: bool,
) {
let width = indices.len();
let out_min = rgba_row_bytes(width);
assert!(indices.len() >= width, "indices too short");
assert!(rgba_out.len() >= out_min, "rgba_out too short");
#[cfg(target_arch = "aarch64")]
{
use crate::row::neon_available;
if _use_simd && neon_available() {
unsafe { crate::row::arch::neon::pal8::pal8_to_rgba_row(indices, palette, rgba_out) }
return;
}
}
scalar_rgba(indices, palette, rgba_out);
}
pub fn pal8_to_rgb_u16_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgb_u16_out: &mut [u16],
_use_simd: bool,
) {
let width = indices.len();
let out_min = rgb_row_elems(width);
assert!(indices.len() >= width, "indices too short");
assert!(rgb_u16_out.len() >= out_min, "rgb_u16_out too short");
#[cfg(target_arch = "aarch64")]
{
use crate::row::neon_available;
if _use_simd && neon_available() {
unsafe { crate::row::arch::neon::pal8::pal8_to_rgb_u16_row(indices, palette, rgb_u16_out) }
return;
}
}
scalar_rgb_u16(indices, palette, rgb_u16_out);
}
pub fn pal8_to_rgba_u16_row(
indices: &[u8],
palette: &[[u8; 4]; 256],
rgba_u16_out: &mut [u16],
_use_simd: bool,
) {
let width = indices.len();
let out_min = rgba_row_elems(width);
assert!(indices.len() >= width, "indices too short");
assert!(rgba_u16_out.len() >= out_min, "rgba_u16_out too short");
#[cfg(target_arch = "aarch64")]
{
use crate::row::neon_available;
if _use_simd && neon_available() {
unsafe { crate::row::arch::neon::pal8::pal8_to_rgba_u16_row(indices, palette, rgba_u16_out) }
return;
}
}
scalar_rgba_u16(indices, palette, rgba_u16_out);
}
#[cfg(test)]
mod tests {
use super::*;
fn make_palette() -> [[u8; 4]; 256] {
let mut p = [[0u8; 4]; 256];
for (i, entry) in p.iter_mut().enumerate() {
let i = i as u32;
entry[0] = ((i.wrapping_mul(73) ^ 0xA5) & 0xFF) as u8;
entry[1] = ((i.wrapping_mul(131) ^ 0x5A) & 0xFF) as u8;
entry[2] = ((i.wrapping_mul(197) ^ 0x3C) & 0xFF) as u8;
entry[3] = ((i.wrapping_mul(251) ^ 0xF0) & 0xFF) as u8;
}
p
}
#[test]
#[should_panic(expected = "rgb_out too short")]
fn pal8_to_rgb_row_undersized_out_panics() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u8; 47];
pal8_to_rgb_row(&indices, &palette, &mut out, true);
}
#[test]
#[should_panic(expected = "rgba_out too short")]
fn pal8_to_rgba_row_undersized_out_panics() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u8; 63];
pal8_to_rgba_row(&indices, &palette, &mut out, true);
}
#[test]
#[should_panic(expected = "rgb_u16_out too short")]
fn pal8_to_rgb_u16_row_undersized_out_panics() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u16; 47];
pal8_to_rgb_u16_row(&indices, &palette, &mut out, true);
}
#[test]
#[should_panic(expected = "rgba_u16_out too short")]
fn pal8_to_rgba_u16_row_undersized_out_panics() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u16; 63];
pal8_to_rgba_u16_row(&indices, &palette, &mut out, true);
}
#[test]
fn pal8_to_rgb_row_exact_size_ok() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u8; 48];
pal8_to_rgb_row(&indices, &palette, &mut out, true);
}
#[test]
fn pal8_to_rgba_row_exact_size_ok() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u8; 64];
pal8_to_rgba_row(&indices, &palette, &mut out, true);
}
#[test]
fn pal8_to_rgb_u16_row_exact_size_ok() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u16; 48];
pal8_to_rgb_u16_row(&indices, &palette, &mut out, true);
}
#[test]
fn pal8_to_rgba_u16_row_exact_size_ok() {
let palette = make_palette();
let indices = [0u8; 16];
let mut out = [0u16; 64];
pal8_to_rgba_u16_row(&indices, &palette, &mut out, true);
}
}