tbc/
bc1.rs

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