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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
use crate::crunch::crn_decomp::CrnHeader;
// Supported compressed pixel formats.
// Basically all the standard DX9 formats, with some swizzled DXT5 formats
// (most of them supported by ATI's Compressonator), along with some ATI/X360 GPU specific formats.
#[derive(PartialEq, PartialOrd)]
#[repr(u32)]
pub enum CrnFormat {
Invalid = 4294967295, // u32 -1,
Dxt1 = 0,
// cCRNFmtFirstValid = crn_format::cCRNFmtDXT1 as isize, // Rust doesn't allow same value enums, and as far as I see this is not used in the lib.
// cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
Dxt3,
CCrnfmtDxt5,
// Various DXT5 derivatives
Dxt5CcxY, // Luma-chroma
Dxt5XGxR, // Swizzled 2-component
Dxt5XGbr, // Swizzled 3-component
Dxt5Agbr, // Swizzled 4-component
// ATI 3DC and X360 DXN
DxnXy,
DxnYx,
// DXT5 alpha blocks only
Dxt5a,
Etc1,
Etc2,
Etc2a,
Etc1s,
Etc2as,
Total,
}
#[repr(C)]
pub struct CrnTextureInfo {
pub struct_size: u32,
pub width: u32,
pub height: u32,
pub levels: u32,
pub faces: u32,
pub bytes_per_block: u32,
pub userdata0: u32,
pub userdata1: u32,
pub format: CrnFormat,
}
impl CrnTextureInfo {
pub const fn default() -> Self {
Self {
struct_size: core::mem::size_of::<CrnTextureInfo>() as u32,
width: 0,
height: 0,
levels: 0,
faces: 0,
bytes_per_block: 0,
userdata0: 0,
userdata1: 0,
format: CrnFormat::Invalid, // Init as invalid?
}
}
pub fn crnd_get_texture_info(&mut self, p_data: &[u8], data_size: u32) -> bool {
if data_size < CrnHeader::MIN_SIZE {
return false;
}
if self.struct_size != core::mem::size_of::<CrnTextureInfo>() as u32 {
return false;
}
let mut p_header: CrnHeader = CrnHeader::default();
let res: bool = p_header.crnd_get_header(p_data, data_size);
if !res {
return res;
}
self.width = p_header.width.cast_to_uint();
self.height = p_header.height.cast_to_uint();
self.levels = p_header.levels.cast_to_uint();
self.faces = p_header.faces.cast_to_uint();
self.format = match p_header.format.cast_to_uint() {
// -1 => crn_format::cCRNFmtInvalid,
0 => CrnFormat::Dxt1,
// 0 => crn_formatcCRNFmtFirstValid,
// cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
1 => CrnFormat::Dxt3,
2 => CrnFormat::CCrnfmtDxt5,
// Various DXT5 derivatives
3 => CrnFormat::Dxt5CcxY, // Luma-chroma
4 => CrnFormat::Dxt5XGxR, // Swizzled 2-component
5 => CrnFormat::Dxt5XGbr, // Swizzled 3-component
6 => CrnFormat::Dxt5Agbr, // Swizzled 4-component
// ATI 3DC and X360 DXN
7 => CrnFormat::DxnXy,
8 => CrnFormat::DxnYx,
// DXT5 alpha blocks only
9 => CrnFormat::Dxt5a,
10 => CrnFormat::Etc1,
11 => CrnFormat::Etc2,
12 => CrnFormat::Etc2a,
13 => CrnFormat::Etc1s,
14 => CrnFormat::Etc2as,
15 => CrnFormat::Total,
_ => CrnFormat::Invalid,
};
if self.format == CrnFormat::Invalid {
return false;
}
if (p_header.format.cast_to_uint() == CrnFormat::Dxt1 as u32)
|| (p_header.format.cast_to_uint() == CrnFormat::Dxt5a as u32)
|| (p_header.format.cast_to_uint() == CrnFormat::Etc1 as u32)
|| (p_header.format.cast_to_uint() == CrnFormat::Etc2 as u32)
|| (p_header.format.cast_to_uint() == CrnFormat::Etc1s as u32)
{
self.bytes_per_block = 8;
} else {
self.bytes_per_block = 16;
}
self.userdata0 = p_header.userdata0.cast_to_uint();
self.userdata1 = p_header.userdata1.cast_to_uint();
true
}
}