Skip to content

Commit 68905dc

Browse files
committed
vtfpp: maintain byte order of underlying buffers
1 parent 7bc1038 commit 68905dc

3 files changed

Lines changed: 69 additions & 29 deletions

File tree

include/vtfpp/ImageConversion.h

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,52 @@
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

1418
namespace 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+
1654
namespace ImagePixel {
1755

1856
#define VTFPP_CHECK_SIZE(format) \
@@ -157,18 +195,18 @@ struct UVWQ8888 {
157195

158196
struct 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

166204
struct 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

174212
struct UVLX8888 {
@@ -181,34 +219,34 @@ struct UVLX8888 {
181219

182220
struct R32F {
183221
static constexpr auto FORMAT = ImageFormat::R32F;
184-
float r;
222+
LERep<float> r;
185223
}; VTFPP_CHECK_SIZE(R32F);
186224

187225
struct 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

194232
struct 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

202240
struct 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

208246
struct 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

214252
struct RGBX8888 {

src/vtfpp/ImageConversion.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,10 @@ namespace {
730730
#endif
731731
imageDataSpan.begin(), imageDataSpan.end(), newDataSpan.begin(), [](ImagePixel::RGBA32323232F pixel) -> ImagePixel::RGBA8888 {
732732
return {
733-
static_cast<uint8_t>(std::clamp(pixel.r, 0.f, 1.f) * ((1 << 8) - 1)),
734-
static_cast<uint8_t>(std::clamp(pixel.g, 0.f, 1.f) * ((1 << 8) - 1)),
735-
static_cast<uint8_t>(std::clamp(pixel.b, 0.f, 1.f) * ((1 << 8) - 1)),
736-
static_cast<uint8_t>(std::clamp(pixel.a, 0.f, 1.f) * ((1 << 8) - 1)),
733+
static_cast<uint8_t>(std::clamp<float>(pixel.r, 0.f, 1.f) * ((1 << 8) - 1)),
734+
static_cast<uint8_t>(std::clamp<float>(pixel.g, 0.f, 1.f) * ((1 << 8) - 1)),
735+
static_cast<uint8_t>(std::clamp<float>(pixel.b, 0.f, 1.f) * ((1 << 8) - 1)),
736+
static_cast<uint8_t>(std::clamp<float>(pixel.a, 0.f, 1.f) * ((1 << 8) - 1)),
737737
};
738738
});
739739

@@ -808,10 +808,10 @@ namespace {
808808
#endif
809809
imageDataSpan.begin(), imageDataSpan.end(), newDataSpan.begin(), [](ImagePixel::RGBA32323232F pixel) -> ImagePixel::RGBA16161616 {
810810
return {
811-
static_cast<uint16_t>(std::clamp(pixel.r, 0.f, 1.f) * ((1 << 16) - 1)),
812-
static_cast<uint16_t>(std::clamp(pixel.g, 0.f, 1.f) * ((1 << 16) - 1)),
813-
static_cast<uint16_t>(std::clamp(pixel.b, 0.f, 1.f) * ((1 << 16) - 1)),
814-
static_cast<uint16_t>(std::clamp(pixel.a, 0.f, 1.f) * ((1 << 16) - 1)),
811+
static_cast<uint16_t>(std::clamp<float>(pixel.r, 0.f, 1.f) * ((1 << 16) - 1)),
812+
static_cast<uint16_t>(std::clamp<float>(pixel.g, 0.f, 1.f) * ((1 << 16) - 1)),
813+
static_cast<uint16_t>(std::clamp<float>(pixel.b, 0.f, 1.f) * ((1 << 16) - 1)),
814+
static_cast<uint16_t>(std::clamp<float>(pixel.a, 0.f, 1.f) * ((1 << 16) - 1)),
815815
};
816816
});
817817

src/vtfpp/VTF.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,7 +1681,9 @@ std::vector<std::byte> VTF::bake() const {
16811681
.write(this->frameCount)
16821682
.write(this->startFrame)
16831683
.write<uint32_t>(0) // padding
1684-
.write(this->reflectivity)
1684+
.write(this->reflectivity[0])
1685+
.write(this->reflectivity[1])
1686+
.write(this->reflectivity[2])
16851687
.write<uint32_t>(0) // padding
16861688
.write(this->bumpMapScale)
16871689
.write(bakeFormat)

0 commit comments

Comments
 (0)