util: tweak float readers

This commit is contained in:
bnnm 2021-09-11 13:10:04 +02:00
parent dfa3779ad4
commit 227ea3db5e
2 changed files with 53 additions and 34 deletions

View File

@ -231,41 +231,22 @@ static inline uint64_t read_u64be(off_t offset, STREAMFILE* sf) { return (uint64
static inline int64_t read_s64le(off_t offset, STREAMFILE* sf) { return read_64bitLE(offset, sf); } static inline int64_t read_s64le(off_t offset, STREAMFILE* sf) { return read_64bitLE(offset, sf); }
static inline uint64_t read_u64le(off_t offset, STREAMFILE* sf) { return (uint64_t)read_64bitLE(offset, sf); } static inline uint64_t read_u64le(off_t offset, STREAMFILE* sf) { return (uint64_t)read_64bitLE(offset, sf); }
/* The recommended int-to-float type punning in C is through union, but pointer casting static inline float read_f32be(off_t offset, STREAMFILE* sf) {
* works too (though less portable due to aliasing rules?). For C++ memcpy seems uint8_t buf[4];
* recommended. Both work in GCC and VS2015+ (not sure about older, ifdef as needed). */
static inline float read_f32be(off_t offset, STREAMFILE* sf) { if (read_streamfile(buf, offset, sizeof(buf), sf) != sizeof(buf))
union { return -1;
uint32_t u32; return get_f32be(buf);
float f32;
} temp;
temp.u32 = read_u32be(offset, sf);
return temp.f32;
} }
static inline float read_f32le(off_t offset, STREAMFILE* sf) { static inline float read_f32le(off_t offset, STREAMFILE* sf) {
union { uint8_t buf[4];
uint32_t u32;
float f32; if (read_streamfile(buf, offset, sizeof(buf), sf) != sizeof(buf))
} temp; return -1;
temp.u32 = read_u32le(offset, sf); return get_f32le(buf);
return temp.f32;
} }
#if 0
static inline float read_f32be_p(off_t offset, STREAMFILE* sf) {
uint32_t sample_int = read_u32be(offset, sf);
float* sample_float = (float*)&sample_int;
return *sample_float;
}
static inline float read_f32be_m(off_t offset, STREAMFILE* sf) {
uint32_t sample_int = read_u32be(offset, sf);
float sample_float;
memcpy(&sample_float, &sample_int, sizeof(uint32_t));
return sample_float;
}
#endif
#if 0 #if 0
// on GCC, this reader will be correctly optimized out (as long as it's static/inline), would be same as declaring: // on GCC, this reader will be correctly optimized out (as long as it's static/inline), would be same as declaring:
// uintXX_t (*read_uXX)(off_t,uint8_t*) = be ? get_uXXbe : get_uXXle; // uintXX_t (*read_uXX)(off_t,uint8_t*) = be ? get_uXXbe : get_uXXle;
// only for the functions actually used in code, and inlined if possible (like big_endian param being a constant). // only for the functions actually used in code, and inlined if possible (like big_endian param being a constant).

View File

@ -51,14 +51,52 @@ static inline uint64_t get_u64le(const uint8_t* p) { return (uint64_t)get_64bitL
static inline int64_t get_s64be(const uint8_t* p) { return ( int64_t)get_64bitBE(p); } static inline int64_t get_s64be(const uint8_t* p) { return ( int64_t)get_64bitBE(p); }
static inline uint64_t get_u64be(const uint8_t* p) { return (uint64_t)get_64bitBE(p); } static inline uint64_t get_u64be(const uint8_t* p) { return (uint64_t)get_64bitBE(p); }
/* The recommended int-to-float type punning in C is through union, but pointer casting
* works too (though less portable due to aliasing rules?). For C++ memcpy seems
* recommended. Both work in GCC and VS2015+ (not sure about older, ifdef as needed). */
static inline float get_f32be(const uint8_t* p) {
union {
uint32_t u32;
float f32;
} temp;
temp.u32 = get_u32be(p);
return temp.f32;
}
static inline float get_f32le(const uint8_t* p) {
union {
uint32_t u32;
float f32;
} temp;
temp.u32 = get_u32le(p);
return temp.f32;
}
static inline float get_d64le(const uint8_t* p) {
union {
uint64_t u64;
double d64;
} temp;
temp.u64 = get_u64le(p);
return temp.d64;
}
#if 0
static inline float get_f32be_cast(const uint8_t* p) {
uint32_t sample_int = get_u32be(p);
float* sample_float = (float*)&sample_int;
return *sample_float;
}
static inline float get_f32be_mcpy(const uint8_t* p) {
uint32_t sample_int = get_u32be(p);
float sample_float;
memcpy(&sample_float, &sample_int, sizeof(uint32_t));
return sample_float;
}
#endif
void put_8bit(uint8_t* buf, int8_t i); void put_8bit(uint8_t* buf, int8_t i);
void put_16bitLE(uint8_t* buf, int16_t i); void put_16bitLE(uint8_t* buf, int16_t i);
void put_32bitLE(uint8_t* buf, int32_t i); void put_32bitLE(uint8_t* buf, int32_t i);
void put_16bitBE(uint8_t* buf, int16_t i); void put_16bitBE(uint8_t* buf, int16_t i);
void put_32bitBE(uint8_t* buf, int32_t i); void put_32bitBE(uint8_t* buf, int32_t i);
/* alias of the above */ //TODO: improve /* alias of the above */ //TODO: improve