1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use more_asserts::assert_ge;
use crate::bindings::kernel;
use crate::RgbaSurface;
#[inline(always)]
pub fn calc_output_size(width: u32, height: u32) -> usize {
let block_count = crate::cal_block_count(width, height, 4, 4) as usize;
block_count * 8
}
pub fn compress_blocks(surface: &RgbaSurface) -> Vec<u8> {
let output_size = calc_output_size(surface.width, surface.height);
let mut output = vec![0u8; output_size];
compress_blocks_into(surface, &mut output);
output
}
pub fn compress_blocks_into(surface: &RgbaSurface, blocks: &mut [u8]) {
assert_ge!(
blocks.len(),
calc_output_size(surface.width, surface.height)
);
let mut r_data = vec![0_u8; (surface.width * surface.height) as usize];
let pitch = (surface.width * 32 + 7) / 8;
let mut offset = 0_u32;
for y in 0..surface.height {
for x in 0..surface.width {
r_data[offset as usize] = surface.data[(x * 4 + y * pitch) as usize];
offset += 1;
}
}
let mut surface = kernel::rgba_surface {
width: surface.width as i32,
height: surface.height as i32,
stride: (surface.stride / 4) as i32,
ptr: (&r_data).as_ptr() as *mut u8,
};
unsafe {
kernel::CompressBlocksBC4_ispc(&mut surface, blocks.as_mut_ptr());
}
}