use super::etc1s::Etc1sTranscoder;
use super::etc1s_bc1::convert_etc1s_to_dxt1;
use super::etc1s_bc4::convert_etc1s_to_dxt5a;
use alloc::vec::Vec;
const BC4_OPAQUE_BLOCK: [u8; 8] = [255, 255, 0, 0, 0, 0, 0, 0];
impl Etc1sTranscoder {
pub fn transcode_slice_bc3_opaque(
&self,
rgb_slice: &[u8],
num_blocks_x: u32,
num_blocks_y: u32,
video: Option<&mut Vec<u32>>,
out: &mut [u8],
) -> Option<()> {
let rgb = self.decode_slice_indices(rgb_slice, num_blocks_x, num_blocks_y, video)?;
if out.len() != rgb.len() * 16 {
return None;
}
out.fill(0);
for (b, &(rei, rsi)) in rgb.iter().enumerate() {
out[b * 16..b * 16 + 8].copy_from_slice(&BC4_OPAQUE_BLOCK);
let color = convert_etc1s_to_dxt1(
&self.endpoints[rei as usize],
&self.selectors[rsi as usize],
false,
);
out[b * 16 + 8..b * 16 + 16].copy_from_slice(&color);
}
Some(())
}
pub fn transcode_image_bc3_rgba(
&self,
rgb_slice: &[u8],
alpha_slice: &[u8],
num_blocks_x: u32,
num_blocks_y: u32,
video: Option<(&mut Vec<u32>, &mut Vec<u32>)>,
out: &mut [u8],
) -> Option<()> {
let (vc, va) = match video {
Some((c, a)) => (Some(c), Some(a)),
None => (None, None),
};
let rgb = self.decode_slice_indices(rgb_slice, num_blocks_x, num_blocks_y, vc)?;
let alpha = self.decode_slice_indices(alpha_slice, num_blocks_x, num_blocks_y, va)?;
if out.len() != rgb.len() * 16 {
return None;
}
out.fill(0);
for (b, (&(rei, rsi), &(aei, asi))) in rgb.iter().zip(alpha.iter()).enumerate() {
let a = convert_etc1s_to_dxt5a(
&self.endpoints[aei as usize],
&self.selectors[asi as usize],
);
out[b * 16..b * 16 + 8].copy_from_slice(&a);
let color = convert_etc1s_to_dxt1(
&self.endpoints[rei as usize],
&self.selectors[rsi as usize],
false,
);
out[b * 16 + 8..b * 16 + 16].copy_from_slice(&color);
}
Some(())
}
pub fn transcode_slice_bc5_opaque(
&self,
rgb_slice: &[u8],
num_blocks_x: u32,
num_blocks_y: u32,
video: Option<&mut Vec<u32>>,
out: &mut [u8],
) -> Option<()> {
let rgb = self.decode_slice_indices(rgb_slice, num_blocks_x, num_blocks_y, video)?;
if out.len() != rgb.len() * 16 {
return None;
}
out.fill(0);
for (b, &(rei, rsi)) in rgb.iter().enumerate() {
let r = convert_etc1s_to_dxt5a(
&self.endpoints[rei as usize],
&self.selectors[rsi as usize],
);
out[b * 16..b * 16 + 8].copy_from_slice(&r);
out[b * 16 + 8..b * 16 + 16].copy_from_slice(&BC4_OPAQUE_BLOCK);
}
Some(())
}
pub fn transcode_image_bc5_rg(
&self,
rgb_slice: &[u8],
alpha_slice: &[u8],
num_blocks_x: u32,
num_blocks_y: u32,
video: Option<(&mut Vec<u32>, &mut Vec<u32>)>,
out: &mut [u8],
) -> Option<()> {
let (vc, va) = match video {
Some((c, a)) => (Some(c), Some(a)),
None => (None, None),
};
let rgb = self.decode_slice_indices(rgb_slice, num_blocks_x, num_blocks_y, vc)?;
let alpha = self.decode_slice_indices(alpha_slice, num_blocks_x, num_blocks_y, va)?;
if out.len() != rgb.len() * 16 {
return None;
}
out.fill(0);
for (b, (&(rei, rsi), &(aei, asi))) in rgb.iter().zip(alpha.iter()).enumerate() {
let r = convert_etc1s_to_dxt5a(
&self.endpoints[rei as usize],
&self.selectors[rsi as usize],
);
out[b * 16..b * 16 + 8].copy_from_slice(&r);
let g = convert_etc1s_to_dxt5a(
&self.endpoints[aei as usize],
&self.selectors[asi as usize],
);
out[b * 16 + 8..b * 16 + 16].copy_from_slice(&g);
}
Some(())
}
}