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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use image::GenericImageView;
use image::ImageFormat;
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DecodedImageColorSpace {
Srgb,
Linear,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DecodedImageMips {
None,
Runtime(u32),
Precomputed(u32),
}
impl DecodedImageMips {
pub fn mip_level_count(&self) -> u32 {
match self {
DecodedImageMips::None => 1,
DecodedImageMips::Runtime(mip_count) => *mip_count,
DecodedImageMips::Precomputed(mip_count) => *mip_count,
}
}
}
#[derive(Clone)]
pub struct DecodedImage {
pub width: u32,
pub height: u32,
pub color_space: DecodedImageColorSpace,
pub mips: DecodedImageMips,
pub data: Vec<u8>,
}
impl DecodedImage {
pub fn new_1x1(
r: u8,
g: u8,
b: u8,
a: u8,
color_space: DecodedImageColorSpace,
) -> DecodedImage {
DecodedImage {
width: 1,
height: 1,
color_space,
mips: DecodedImageMips::None,
data: vec![r, g, b, a],
}
}
pub fn new_from_buffer(
buf: &[u8],
format: ImageFormat,
) -> DecodedImage {
let image_data = image::load_from_memory_with_format(buf, format).unwrap();
let dimensions = image_data.dimensions();
let image_data = image_data.to_rgba8().into_raw();
let decoded_image_mip_info =
DecodedImage::default_mip_settings_for_image_size(dimensions.0, dimensions.1);
DecodedImage {
width: dimensions.0,
height: dimensions.1,
mips: decoded_image_mip_info,
data: image_data,
color_space: DecodedImageColorSpace::Srgb,
}
}
pub fn default_mip_settings_for_image_size(
width: u32,
height: u32,
) -> DecodedImageMips {
let max_dimension = std::cmp::max(width, height);
let mip_level_count = (max_dimension as f32).log2().floor() as u32 + 1;
DecodedImageMips::Runtime(mip_level_count)
}
}