#![cfg_attr(target_arch = "x86", allow(unused_imports))]
use archmage::prelude::*;
use super::{check_copy, check_strided};
use crate::SizeError;
#[autoversion(v3, neon, wasm128)]
fn rgb565_to_rgba_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(2).zip(d.chunks_exact_mut(4)) {
let v = u16::from_le_bytes([s[0], s[1]]);
let r5 = (v >> 11) & 0x1F;
let g6 = (v >> 5) & 0x3F;
let b5 = v & 0x1F;
d[0] = (r5 << 3 | r5 >> 2) as u8;
d[1] = (g6 << 2 | g6 >> 4) as u8;
d[2] = (b5 << 3 | b5 >> 2) as u8;
d[3] = 0xFF;
}
}
#[autoversion(v3, neon, wasm128)]
fn rgb565_to_bgra_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(2).zip(d.chunks_exact_mut(4)) {
let v = u16::from_le_bytes([s[0], s[1]]);
let r5 = (v >> 11) & 0x1F;
let g6 = (v >> 5) & 0x3F;
let b5 = v & 0x1F;
d[0] = (b5 << 3 | b5 >> 2) as u8;
d[1] = (g6 << 2 | g6 >> 4) as u8;
d[2] = (r5 << 3 | r5 >> 2) as u8;
d[3] = 0xFF;
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba4444_to_rgba_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(2).zip(d.chunks_exact_mut(4)) {
let v = u16::from_le_bytes([s[0], s[1]]);
let r4 = (v >> 12) & 0xF;
let g4 = (v >> 8) & 0xF;
let b4 = (v >> 4) & 0xF;
let a4 = v & 0xF;
d[0] = (r4 << 4 | r4) as u8;
d[1] = (g4 << 4 | g4) as u8;
d[2] = (b4 << 4 | b4) as u8;
d[3] = (a4 << 4 | a4) as u8;
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba4444_to_bgra_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(2).zip(d.chunks_exact_mut(4)) {
let v = u16::from_le_bytes([s[0], s[1]]);
let r4 = (v >> 12) & 0xF;
let g4 = (v >> 8) & 0xF;
let b4 = (v >> 4) & 0xF;
let a4 = v & 0xF;
d[0] = (b4 << 4 | b4) as u8;
d[1] = (g4 << 4 | g4) as u8;
d[2] = (r4 << 4 | r4) as u8;
d[3] = (a4 << 4 | a4) as u8;
}
}
#[autoversion(v3, neon, wasm128)]
fn rgb565_to_rgba_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 2]
.chunks_exact(2)
.zip(dst[y * ds..][..w * 4].chunks_exact_mut(4))
{
let v = u16::from_le_bytes([s[0], s[1]]);
let r5 = (v >> 11) & 0x1F;
let g6 = (v >> 5) & 0x3F;
let b5 = v & 0x1F;
d[0] = (r5 << 3 | r5 >> 2) as u8;
d[1] = (g6 << 2 | g6 >> 4) as u8;
d[2] = (b5 << 3 | b5 >> 2) as u8;
d[3] = 0xFF;
}
}
}
#[autoversion(v3, neon, wasm128)]
fn rgb565_to_bgra_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 2]
.chunks_exact(2)
.zip(dst[y * ds..][..w * 4].chunks_exact_mut(4))
{
let v = u16::from_le_bytes([s[0], s[1]]);
let r5 = (v >> 11) & 0x1F;
let g6 = (v >> 5) & 0x3F;
let b5 = v & 0x1F;
d[0] = (b5 << 3 | b5 >> 2) as u8;
d[1] = (g6 << 2 | g6 >> 4) as u8;
d[2] = (r5 << 3 | r5 >> 2) as u8;
d[3] = 0xFF;
}
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba4444_to_rgba_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 2]
.chunks_exact(2)
.zip(dst[y * ds..][..w * 4].chunks_exact_mut(4))
{
let v = u16::from_le_bytes([s[0], s[1]]);
let r4 = (v >> 12) & 0xF;
let g4 = (v >> 8) & 0xF;
let b4 = (v >> 4) & 0xF;
let a4 = v & 0xF;
d[0] = (r4 << 4 | r4) as u8;
d[1] = (g4 << 4 | g4) as u8;
d[2] = (b4 << 4 | b4) as u8;
d[3] = (a4 << 4 | a4) as u8;
}
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba4444_to_bgra_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 2]
.chunks_exact(2)
.zip(dst[y * ds..][..w * 4].chunks_exact_mut(4))
{
let v = u16::from_le_bytes([s[0], s[1]]);
let r4 = (v >> 12) & 0xF;
let g4 = (v >> 8) & 0xF;
let b4 = (v >> 4) & 0xF;
let a4 = v & 0xF;
d[0] = (b4 << 4 | b4) as u8;
d[1] = (g4 << 4 | g4) as u8;
d[2] = (r4 << 4 | r4) as u8;
d[3] = (a4 << 4 | a4) as u8;
}
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba_to_rgb565_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(4).zip(d.chunks_exact_mut(2)) {
let r5 = (s[0] as u16 * 31 + 128) >> 8;
let g6 = (s[1] as u16 * 63 + 128) >> 8;
let b5 = (s[2] as u16 * 31 + 128) >> 8;
d.copy_from_slice(&((r5 << 11) | (g6 << 5) | b5).to_le_bytes());
}
}
#[autoversion(v3, neon, wasm128)]
fn bgra_to_rgb565_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(4).zip(d.chunks_exact_mut(2)) {
let r5 = (s[2] as u16 * 31 + 128) >> 8;
let g6 = (s[1] as u16 * 63 + 128) >> 8;
let b5 = (s[0] as u16 * 31 + 128) >> 8;
d.copy_from_slice(&((r5 << 11) | (g6 << 5) | b5).to_le_bytes());
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba_to_rgba4444_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(4).zip(d.chunks_exact_mut(2)) {
let r4 = (s[0] as u16 * 15 + 128) >> 8;
let g4 = (s[1] as u16 * 15 + 128) >> 8;
let b4 = (s[2] as u16 * 15 + 128) >> 8;
let a4 = (s[3] as u16 * 15 + 128) >> 8;
d.copy_from_slice(&((r4 << 12) | (g4 << 8) | (b4 << 4) | a4).to_le_bytes());
}
}
#[autoversion(v3, neon, wasm128)]
fn bgra_to_rgba4444_impl(s: &[u8], d: &mut [u8]) {
for (s, d) in s.chunks_exact(4).zip(d.chunks_exact_mut(2)) {
let r4 = (s[2] as u16 * 15 + 128) >> 8;
let g4 = (s[1] as u16 * 15 + 128) >> 8;
let b4 = (s[0] as u16 * 15 + 128) >> 8;
let a4 = (s[3] as u16 * 15 + 128) >> 8;
d.copy_from_slice(&((r4 << 12) | (g4 << 8) | (b4 << 4) | a4).to_le_bytes());
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba_to_rgb565_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 4]
.chunks_exact(4)
.zip(dst[y * ds..][..w * 2].chunks_exact_mut(2))
{
let r5 = (s[0] as u16 * 31 + 128) >> 8;
let g6 = (s[1] as u16 * 63 + 128) >> 8;
let b5 = (s[2] as u16 * 31 + 128) >> 8;
d.copy_from_slice(&((r5 << 11) | (g6 << 5) | b5).to_le_bytes());
}
}
}
#[autoversion(v3, neon, wasm128)]
fn bgra_to_rgb565_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 4]
.chunks_exact(4)
.zip(dst[y * ds..][..w * 2].chunks_exact_mut(2))
{
let r5 = (s[2] as u16 * 31 + 128) >> 8;
let g6 = (s[1] as u16 * 63 + 128) >> 8;
let b5 = (s[0] as u16 * 31 + 128) >> 8;
d.copy_from_slice(&((r5 << 11) | (g6 << 5) | b5).to_le_bytes());
}
}
}
#[autoversion(v3, neon, wasm128)]
fn rgba_to_rgba4444_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 4]
.chunks_exact(4)
.zip(dst[y * ds..][..w * 2].chunks_exact_mut(2))
{
let r4 = (s[0] as u16 * 15 + 128) >> 8;
let g4 = (s[1] as u16 * 15 + 128) >> 8;
let b4 = (s[2] as u16 * 15 + 128) >> 8;
let a4 = (s[3] as u16 * 15 + 128) >> 8;
d.copy_from_slice(&((r4 << 12) | (g4 << 8) | (b4 << 4) | a4).to_le_bytes());
}
}
}
#[autoversion(v3, neon, wasm128)]
fn bgra_to_rgba4444_strided_impl(
src: &[u8],
dst: &mut [u8],
w: usize,
h: usize,
ss: usize,
ds: usize,
) {
for y in 0..h {
for (s, d) in src[y * ss..][..w * 4]
.chunks_exact(4)
.zip(dst[y * ds..][..w * 2].chunks_exact_mut(2))
{
let r4 = (s[2] as u16 * 15 + 128) >> 8;
let g4 = (s[1] as u16 * 15 + 128) >> 8;
let b4 = (s[0] as u16 * 15 + 128) >> 8;
let a4 = (s[3] as u16 * 15 + 128) >> 8;
d.copy_from_slice(&((r4 << 12) | (g4 << 8) | (b4 << 4) | a4).to_le_bytes());
}
}
}
pub fn rgb565_to_rgba(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 2, dst.len(), 4)?;
rgb565_to_rgba_impl(src, dst);
Ok(())
}
pub fn rgb565_to_bgra(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 2, dst.len(), 4)?;
rgb565_to_bgra_impl(src, dst);
Ok(())
}
pub fn rgba4444_to_rgba(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 2, dst.len(), 4)?;
rgba4444_to_rgba_impl(src, dst);
Ok(())
}
pub fn rgba4444_to_bgra(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 2, dst.len(), 4)?;
rgba4444_to_bgra_impl(src, dst);
Ok(())
}
pub fn rgb565_to_rgba_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 2)?;
check_strided(dst.len(), width, height, dst_stride, 4)?;
rgb565_to_rgba_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn rgb565_to_bgra_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 2)?;
check_strided(dst.len(), width, height, dst_stride, 4)?;
rgb565_to_bgra_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn rgba4444_to_rgba_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 2)?;
check_strided(dst.len(), width, height, dst_stride, 4)?;
rgba4444_to_rgba_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn rgba4444_to_bgra_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 2)?;
check_strided(dst.len(), width, height, dst_stride, 4)?;
rgba4444_to_bgra_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn rgba_to_rgb565(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 4, dst.len(), 2)?;
rgba_to_rgb565_impl(src, dst);
Ok(())
}
pub fn bgra_to_rgb565(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 4, dst.len(), 2)?;
bgra_to_rgb565_impl(src, dst);
Ok(())
}
pub fn rgba_to_rgba4444(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 4, dst.len(), 2)?;
rgba_to_rgba4444_impl(src, dst);
Ok(())
}
pub fn bgra_to_rgba4444(src: &[u8], dst: &mut [u8]) -> Result<(), SizeError> {
check_copy(src.len(), 4, dst.len(), 2)?;
bgra_to_rgba4444_impl(src, dst);
Ok(())
}
pub fn rgba_to_rgb565_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 4)?;
check_strided(dst.len(), width, height, dst_stride, 2)?;
rgba_to_rgb565_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn bgra_to_rgb565_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 4)?;
check_strided(dst.len(), width, height, dst_stride, 2)?;
bgra_to_rgb565_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn rgba_to_rgba4444_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 4)?;
check_strided(dst.len(), width, height, dst_stride, 2)?;
rgba_to_rgba4444_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}
pub fn bgra_to_rgba4444_strided(
src: &[u8],
dst: &mut [u8],
width: usize,
height: usize,
src_stride: usize,
dst_stride: usize,
) -> Result<(), SizeError> {
check_strided(src.len(), width, height, src_stride, 4)?;
check_strided(dst.len(), width, height, dst_stride, 2)?;
bgra_to_rgba4444_strided_impl(src, dst, width, height, src_stride, dst_stride);
Ok(())
}