Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/include/OpenImageIO/fmath.h
Original file line number Diff line number Diff line change
Expand Up @@ -1114,18 +1114,20 @@ bit_pack(cspan<T> data, void* out, int outbits)
/// will be stored in a successive out[i].
template<typename T>
inline void
bit_unpack(int n, const unsigned char* in, int inbits, T* out)
bit_unpack(cspan<unsigned char> in, int inbits, span<T> out)
{
static_assert(std::is_same<T,uint8_t>::value ||
std::is_same<T,uint16_t>::value ||
std::is_same<T,uint32_t>::value,
"bit_unpack must be unsigned int 8/16/32");
OIIO_DASSERT(in.size() * 8 >= inbits * out.size());
OIIO_DASSERT(inbits >= 1 && inbits < 32); // surely bugs if not
// int highest = (1 << inbits) - 1;
size_t n = out.size();
int B = 0, b = 0;
// Invariant:
// So far, we have used in[0..B-1] and the high b bits of in[B].
for (int i = 0; i < n; ++i) {
for (size_t i = 0; i < n; ++i) {
long long val = 0;
int valbits = 0; // bits so far we've accumulated in val
while (valbits < inbits) {
Expand Down Expand Up @@ -1160,6 +1162,23 @@ bit_unpack(int n, const unsigned char* in, int inbits, T* out)



/// Decode n packed inbits-bits values from in[...] into normal uint8,
/// uint16, or uint32 representation of `T out[0..n-1]`. In other words,
/// each successive `inbits` of `in` (allowing spanning of byte boundaries)
/// will be stored in a successive out[i].
/// Note that this is the "unsafe" raw pointer version, and we recommend
/// instead using the span-based version.
template<typename T>
OIIO_DEPRECATED("Use span-based version")
inline void
bit_unpack(int n, const unsigned char* in, int inbits, T* out)
{
return bit_unpack(cspan<unsigned char>(in, (n * inbits + 7) / 8),
inbits, span<T>(out, n));
}



/// A DataProxy<I,E> looks like an (E &), but it really holds an (I &)
/// and does conversions (via convert_type) as it reads in and out.
/// (I and E are for INTERNAL and EXTERNAL data types, respectively).
Expand Down
2 changes: 1 addition & 1 deletion src/libutil/fmath_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ test_packbits()
" packed to 10 bits, as 16 bit values: %04x %04x %04x %04x %04x\n",
u10[0], u10[1], u10[2], u10[3], u10[4]);
uint16_t u16[8];
bit_unpack(8, (const unsigned char*)u10, 10, u16);
bit_unpack(make_cspan((const unsigned char*)u10, 10), 10, make_span(u16));
Strutil::printf(
" unpacked back to 16 bits: %04x %04x %04x %04x %04x %04x %04x %04x\n",
u16[0], u16[1], u16[2], u16[3], u16[4], u16[5], u16[6], u16[7]);
Expand Down
Loading