tbc/
bc3.rs

1//! BC3 (DXT5) Encoder.
2
3use crate::{
4    bc4::{encode_block_bc4, GreyScaleBlock8},
5    color::{min_max_luminance, ColorRgba8},
6    utils::{encode_color_table_bc1_bc3, encode_image, encode_image_conv_u8, fetch_block},
7};
8
9struct MinMax<T: ColorRgba8> {
10    min: T,
11    min_565: u16,
12    max: T,
13    max_565: u16,
14}
15
16fn min_max_colors<T: ColorRgba8>(block: &[T]) -> MinMax<T> {
17    let (min, max) = min_max_luminance(block);
18
19    let min_565 = min.to_565();
20    let max_565 = max.to_565();
21
22    if max_565 > min_565 {
23        MinMax {
24            min,
25            min_565,
26            max,
27            max_565,
28        }
29    } else {
30        MinMax {
31            min_565: max_565,
32            max_565: min_565,
33            min: max,
34            max: min,
35        }
36    }
37}
38
39#[derive(Debug, Copy, Clone, Eq, PartialEq)]
40#[repr(C)]
41pub struct Block16 {
42    pub alpha_block: GreyScaleBlock8,
43    pub max: u16,
44    pub min: u16,
45    pub color_table: u32,
46}
47
48pub fn encode_block_bc3<T: ColorRgba8>(block: [T; 16]) -> Block16 {
49    let alpha_block = encode_block_bc4(&block, &|p| p.alpha());
50
51    let MinMax {
52        min,
53        min_565,
54        max,
55        max_565,
56    } = min_max_colors(&block);
57
58    let color2 = max.mix_2_1_over_3_saturate(&min);
59    let color3 = max.mix_1_2_over_3_saturate(&min);
60
61    Block16 {
62        alpha_block,
63        max: max_565,
64        min: min_565,
65        color_table: encode_color_table_bc1_bc3(&block, [max, min, color2, color3]),
66    }
67}
68
69fn fetch_and_encode<T: ColorRgba8>(pixels: &[T], x: usize, y: usize, width: usize) -> Block16 {
70    encode_block_bc3(fetch_block(pixels, x, y, width))
71}
72
73pub fn encode_image_bc3<T>(pixels: &[T], width: usize, height: usize) -> Vec<Block16>
74where
75    T: ColorRgba8,
76{
77    encode_image(pixels, width, height, fetch_and_encode)
78}
79
80pub fn encode_image_bc3_conv_u8<T>(pixels: &[T], width: usize, height: usize) -> Vec<u8>
81where
82    T: ColorRgba8,
83{
84    encode_image_conv_u8(pixels, width, height, fetch_and_encode)
85}