55#include < cstddef>
66#include < span>
77#include < vector>
8+ #include < type_traits>
89
910#include < BufferStream.h>
1011#include < sourcepp/Templates.h>
12+ #include < sourcepp/Math.h>
13+
14+ using sourcepp::math::Arithmetic;
1115
1216#include " ImageFormats.h"
1317
1418namespace vtfpp {
1519
20+ template <Arithmetic A>
21+ class LERep : public std ::array<std::byte, sizeof (A)> {
22+ using uint_according = typename std::conditional<sizeof (A) == 8 ,
23+ uint64_t ,
24+ typename std::conditional<sizeof (A) == 4 ,
25+ uint32_t ,
26+ typename std::conditional<sizeof (A) == 2 ,
27+ uint16_t ,
28+ uint8_t >::type>::type>::type;
29+ public:
30+ constexpr operator A () {
31+ uint_according ret = 0 ;
32+ for (size_t offs = 0 ; auto &b : *this ) {
33+ ret |= (static_cast <uint_according>(b) << offs) & (uint_according (0xFFu ) << offs);
34+ offs += 8 ;
35+ }
36+ return *reinterpret_cast <A *>(&ret);
37+ }
38+ constexpr LERep &operator =(const A &v) {
39+ auto in = *reinterpret_cast <const uint_according *>(&v);
40+ for (size_t offs = 0 ; auto &b : *this ) {
41+ b = static_cast <std::byte>((in >> offs) & uint_according (0xFFu ));
42+ offs += 8 ;
43+ }
44+ return *this ;
45+ }
46+ template <Arithmetic B> requires (std::convertible_to<B, A> || std::is_same_v<A, half>)
47+ constexpr LERep(const B &u) { *this = static_cast <A>(u); }
48+ template <Arithmetic B> requires std::convertible_to<B, A>
49+ constexpr LERep (const LERep<B> &u) { *this = static_cast <A>(u); }
50+ template <Arithmetic B> requires std::convertible_to<A, B>
51+ constexpr operator B () const { return static_cast <B>(static_cast <A>(*this )); }
52+ };
53+
1654namespace ImagePixel {
1755
1856#define VTFPP_CHECK_SIZE (format ) \
@@ -157,18 +195,18 @@ struct UVWQ8888 {
157195
158196struct RGBA16161616F {
159197 static constexpr auto FORMAT = ImageFormat::RGBA16161616F ;
160- half r;
161- half g;
162- half b;
163- half a;
198+ LERep< half> r;
199+ LERep< half> g;
200+ LERep< half> b;
201+ LERep< half> a;
164202}; VTFPP_CHECK_SIZE (RGBA16161616F );
165203
166204struct RGBA16161616 {
167205 static constexpr auto FORMAT = ImageFormat::RGBA16161616 ;
168- uint16_t r;
169- uint16_t g;
170- uint16_t b;
171- uint16_t a;
206+ LERep< uint16_t > r;
207+ LERep< uint16_t > g;
208+ LERep< uint16_t > b;
209+ LERep< uint16_t > a;
172210}; VTFPP_CHECK_SIZE (RGBA16161616 );
173211
174212struct UVLX8888 {
@@ -181,34 +219,34 @@ struct UVLX8888 {
181219
182220struct R32F {
183221 static constexpr auto FORMAT = ImageFormat::R32F ;
184- float r;
222+ LERep< float > r;
185223}; VTFPP_CHECK_SIZE (R32F );
186224
187225struct RGB323232F {
188226 static constexpr auto FORMAT = ImageFormat::R32F ;
189- float r;
190- float g;
191- float b;
227+ LERep< float > r;
228+ LERep< float > g;
229+ LERep< float > b;
192230}; VTFPP_CHECK_SIZE (RGB323232F );
193231
194232struct RGBA32323232F {
195233 static constexpr auto FORMAT = ImageFormat::RGBA32323232F ;
196- float r;
197- float g;
198- float b;
199- float a;
234+ LERep< float > r;
235+ LERep< float > g;
236+ LERep< float > b;
237+ LERep< float > a;
200238}; VTFPP_CHECK_SIZE (RGBA32323232F );
201239
202240struct RG1616F {
203241 static constexpr auto FORMAT = ImageFormat::RG1616F ;
204- half r;
205- half g;
242+ LERep< half> r;
243+ LERep< half> g;
206244}; VTFPP_CHECK_SIZE (RG1616F );
207245
208246struct RG3232F {
209247 static constexpr auto FORMAT = ImageFormat::RG3232F ;
210- float r;
211- float g;
248+ LERep< float > r;
249+ LERep< float > g;
212250}; VTFPP_CHECK_SIZE (RG3232F );
213251
214252struct RGBX8888 {
0 commit comments