ispc_texcomp/
etc1.rs

1use more_asserts::assert_ge;
2
3use crate::bindings::kernel;
4use crate::RgbaSurface;
5
6#[derive(Debug, Copy, Clone)]
7pub struct EncodeSettings {
8    pub fast_skip_threshold: u32,
9}
10
11#[inline(always)]
12pub fn calc_output_size(width: u32, height: u32) -> usize {
13    // ETC1 uses a fixed block size of 8 bytes (64 bits) and a fixed tile size of 4x4 texels.
14    let block_count = crate::cal_block_count(width, height, 4, 4);
15    block_count as usize * 8
16}
17
18pub fn compress_blocks(settings: EncodeSettings, surface: &RgbaSurface) -> Vec<u8> {
19    let output_size = calc_output_size(surface.width, surface.height);
20    let mut output = vec![0u8; output_size];
21    compress_blocks_into(settings, surface, &mut output);
22    output
23}
24
25pub fn compress_blocks_into(settings: EncodeSettings, surface: &RgbaSurface, blocks: &mut [u8]) {
26    assert_ge!(
27        blocks.len(),
28        calc_output_size(surface.width, surface.height)
29    );
30    let mut surface = kernel::rgba_surface {
31        width: surface.width as i32,
32        height: surface.height as i32,
33        stride: surface.stride as i32,
34        ptr: surface.data.as_ptr() as *mut u8,
35    };
36    let mut settings = kernel::etc_enc_settings {
37        fastSkipTreshold: settings.fast_skip_threshold as i32,
38    };
39
40    unsafe {
41        kernel::CompressBlocksETC1_ispc(&mut surface, blocks.as_mut_ptr(), &mut settings);
42    }
43}
44
45#[inline(always)]
46pub fn slow_settings() -> EncodeSettings {
47    EncodeSettings {
48        fast_skip_threshold: 6,
49    }
50}