Skip to content

Commit f6904e9

Browse files
committed
Move bitcasts into mathlib
1 parent a3ed53e commit f6904e9

File tree

4 files changed

+78
-22
lines changed

4 files changed

+78
-22
lines changed

Source/astcenc_color_unquantize.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,11 @@ static ASTCENC_SIMD_INLINE vint4 uncontract_color(
5151
*
5252
* @return The shifted value.
5353
*/
54-
static ASTCENC_SIMD_INLINE int32_t safe_signed_lsh(int32_t val, int shift)
54+
static ASTCENC_SIMD_INLINE int safe_signed_lsh(int val, int shift)
5555
{
56-
// Future: Can use std:bit_cast with C++20
57-
uint32_t uval;
58-
std::memcpy(&uval, &val, sizeof(uint32_t));
56+
unsigned int uval = astc::int_as_uint(val);
5957
uval <<= shift;
60-
std::memcpy(&val, &uval, sizeof(uint32_t));
61-
return val;
58+
return astc::uint_as_int(uval);
6259
}
6360

6461
void rgba_delta_unpack(

Source/astcenc_mathlib.h

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <cassert>
2727
#include <cstdint>
2828
#include <cmath>
29+
#include <cstring>
2930

3031
#ifndef ASTCENC_POPCNT
3132
#if defined(__POPCNT__)
@@ -359,9 +360,10 @@ static inline int flt2int_rd(float v)
359360
*/
360361
static inline int float_as_int(float v)
361362
{
362-
union { int a; float b; } u;
363-
u.b = v;
364-
return u.a;
363+
// Future: Can use std:bit_cast with C++20
364+
int iv;
365+
std::memcpy(&iv, &v, sizeof(float));
366+
return iv;
365367
}
366368

367369
/**
@@ -373,9 +375,70 @@ static inline int float_as_int(float v)
373375
*/
374376
static inline float int_as_float(int v)
375377
{
376-
union { int a; float b; } u;
377-
u.a = v;
378-
return u.b;
378+
// Future: Can use std:bit_cast with C++20
379+
float fv;
380+
std::memcpy(&fv, &v, sizeof(int));
381+
return fv;
382+
}
383+
384+
/**
385+
* @brief SP float bit-interpreted as an unsigned integer.
386+
*
387+
* @param v The value to bitcast.
388+
*
389+
* @return The converted value.
390+
*/
391+
static inline unsigned int float_as_uint(float v)
392+
{
393+
// Future: Can use std:bit_cast with C++20
394+
unsigned int iv;
395+
std::memcpy(&iv, &v, sizeof(float));
396+
return iv;
397+
}
398+
399+
/**
400+
* @brief Unsigned integer bit-interpreted as an SP float.
401+
*
402+
* @param v The value to bitcast.
403+
*
404+
* @return The converted value.
405+
*/
406+
static inline float uint_as_float(unsigned int v)
407+
{
408+
// Future: Can use std:bit_cast with C++20
409+
float fv;
410+
std::memcpy(&fv, &v, sizeof(unsigned int));
411+
return fv;
412+
}
413+
414+
/**
415+
* @brief Signed int bit-interpreted as an unsigned integer.
416+
*
417+
* @param v The value to bitcast.
418+
*
419+
* @return The converted value.
420+
*/
421+
static inline unsigned int int_as_uint(int v)
422+
{
423+
// Future: Can use std:bit_cast with C++20
424+
unsigned int uv;
425+
std::memcpy(&uv, &v, sizeof(int));
426+
return uv;
427+
}
428+
429+
/**
430+
* @brief Unsigned integer bit-interpreted as a signed integer.
431+
*
432+
* @param v The value to bitcast.
433+
*
434+
* @return The converted value.
435+
*/
436+
static inline int uint_as_int(unsigned int v)
437+
{
438+
// Future: Can use std:bit_cast with C++20git p
439+
int sv;
440+
std::memcpy(&sv, &v, sizeof(unsigned int));
441+
return sv;
379442
}
380443

381444
/**

Source/astcenccli_error_metrics.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,10 @@ static float mpsnr_operator(
6868
float val,
6969
int fstop
7070
) {
71-
// Future: Can use std:bit_cast with C++20
72-
7371
// Fast implementation of pow(2.0, fstop), assuming IEEE float layout
7472
// Memcpy to uint avoids ubsan complaints shift of negative int
75-
unsigned int fstopu;
76-
std::memcpy(&fstopu, &fstop, sizeof(int));
77-
uint32_t uscale = 0x3f800000 + (fstopu << 23);
78-
79-
float scale;
80-
std::memcpy(&scale, &uscale, sizeof(float));
73+
unsigned int uscale = 0x3f800000u + (astc::int_as_uint(fstop) << 23);
74+
float scale = astc::uint_as_float(uscale);
8175

8276
val = powf(val * scale, (1.0f / 2.2f));
8377
return astc::clamp(val * 255.0f, 0.0f, 255.0f);

Source/cmake_core.cmake

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,13 @@ macro(astcenc_set_properties ASTCENC_TARGET_NAME ASTCENC_VENEER_TYPE)
199199
if(${ASTCENC_UBSAN})
200200
target_compile_options(${ASTCENC_TARGET_NAME}
201201
PRIVATE
202-
$<${is_gnu_fe}:-fsanitize=undefined>)
202+
$<${is_gnu_fe}:-fsanitize=undefined>
203+
$<${is_gnu_fe}:-fno-sanitize-recover=all>)
203204

204205
target_link_options(${ASTCENC_TARGET_NAME}
205206
PRIVATE
206-
$<${is_gnu_fe}:-fsanitize=undefined>)
207+
$<${is_gnu_fe}:-fsanitize=undefined>
208+
$<${is_gnu_fe}:-fno-sanitize-recover=all>)
207209
endif()
208210

209211
if(NOT ${ASTCENC_INVARIANCE})

0 commit comments

Comments
 (0)