31 #ifndef OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
32 #define OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
34 #include <openvdb/Types.h>
35 #include <openvdb/math/Math.h>
36 #include <boost/scoped_array.hpp>
101 enum { isReal =
false };
141 is.read(reinterpret_cast<char*>(data),
sizeof(T) * count);
148 readData<std::string>(std::istream& is, std::string* data,
Index count,
bool )
150 for (
Index i = 0; i < count; ++i) {
156 std::string buffer(len+1,
' ');
157 is.read(&buffer[0], len+1 );
158 data[i].assign(buffer, 0, len);
170 static inline void read(std::istream& is, T* data,
Index count,
bool compressed) {
171 readData(is, data, count, compressed);
178 static inline void read(std::istream& is, T* data,
Index count,
bool compressed) {
179 if (count < 1)
return;
180 std::vector<HalfT> halfData(count);
181 readData<HalfT>(is,
reinterpret_cast<HalfT*
>(&halfData[0]), count, compressed);
183 std::copy(halfData.begin(), halfData.end(), data);
200 zipToStream(os, reinterpret_cast<const char*>(data),
sizeof(T) * count);
202 os.write(reinterpret_cast<const char*>(data),
sizeof(T) * count);
210 writeData<std::string>(std::ostream& os,
const std::string* data,
Index count,
bool )
212 for (
Index i = 0; i < count; ++i) {
213 const size_t len = data[i].size();
215 os.write(data[i].c_str(), len+1);
228 static inline void write(std::ostream& os,
const T* data,
Index count,
bool compress) {
236 static inline void write(std::ostream& os,
const T* data,
Index count,
bool compress) {
237 if (count < 1)
return;
239 std::vector<HalfT> halfData(count);
240 std::copy(data, data + count, halfData.begin());
241 writeData<HalfT>(os,
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compress);
247 struct HalfWriter<true, double> {
248 typedef RealToHalf<double>::HalfT HalfT;
249 static inline void write(std::ostream& os,
const double* data,
Index count,
bool compress) {
250 if (count < 1)
return;
252 std::vector<HalfT> halfData(count);
253 for (
Index i = 0; i < count; ++i) halfData[i] =
float(data[i]);
254 writeData<HalfT>(os,
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compress);
275 template<
typename ValueT,
typename MaskT>
278 const MaskT& valueMask,
bool fromHalf)
290 is.read(reinterpret_cast<char*>(&metadata), 1);
293 ValueT background = zeroVal<ValueT>();
295 background = *
static_cast<const ValueT*
>(bgPtr);
297 ValueT inactiveVal1 = background;
298 ValueT inactiveVal0 =
306 is.read(reinterpret_cast<char*>(&inactiveVal0),
sizeof(ValueT));
309 is.read(reinterpret_cast<char*>(&inactiveVal1),
sizeof(ValueT));
320 selectionMask.load(is);
323 ValueT* tempBuf = destBuf;
324 boost::scoped_array<ValueT> scopedTempBuf;
326 Index tempCount = destCount;
330 tempCount = valueMask.countOn();
331 if (tempCount != destCount) {
334 scopedTempBuf.reset(
new ValueT[tempCount]);
335 tempBuf = scopedTempBuf.get();
343 readData<ValueT>(is, tempBuf, tempCount, zipped);
349 if (maskCompressed && tempCount != destCount) {
353 for (
Index destIdx = 0, tempIdx = 0; destIdx < MaskT::SIZE; ++destIdx) {
354 if (valueMask.isOn(destIdx)) {
356 destBuf[destIdx] = tempBuf[tempIdx];
360 destBuf[destIdx] = (selectionMask.isOn(destIdx) ? inactiveVal1 : inactiveVal0);
379 template<
typename ValueT,
typename MaskT>
382 const MaskT& valueMask,
const MaskT& childMask,
bool toHalf)
386 static inline bool eq(
const ValueT& a,
const ValueT& b) {
397 Index tempCount = srcCount;
398 ValueT* tempBuf = srcBuf;
399 boost::scoped_array<ValueT> scopedTempBuf;
404 os.write(reinterpret_cast<const char*>(&metadata), 1);
412 const ValueT zero = zeroVal<ValueT>();
413 ValueT background = zero;
415 background = *
static_cast<const ValueT*
>(bgPtr);
419 ValueT inactiveVal[2] = { background, background };
420 int numUniqueInactiveVals = 0;
421 for (
typename MaskT::OffIterator it = valueMask.beginOff();
422 numUniqueInactiveVals < 3 && it; ++it)
427 if (childMask.isOn(idx))
continue;
429 const ValueT& val = srcBuf[idx];
430 const bool unique = !(
431 (numUniqueInactiveVals > 0 && Local::eq(val, inactiveVal[0])) ||
432 (numUniqueInactiveVals > 1 && Local::eq(val, inactiveVal[1]))
435 if (numUniqueInactiveVals < 2) inactiveVal[numUniqueInactiveVals] = val;
436 ++numUniqueInactiveVals;
442 if (numUniqueInactiveVals == 1) {
443 if (!Local::eq(inactiveVal[0], background)) {
450 }
else if (numUniqueInactiveVals == 2) {
452 if (!Local::eq(inactiveVal[0], background) && !Local::eq(inactiveVal[1], background)) {
457 }
else if (Local::eq(inactiveVal[1], background)) {
469 }
else if (Local::eq(inactiveVal[0], background)) {
475 std::swap(inactiveVal[0], inactiveVal[1]);
480 std::swap(inactiveVal[0], inactiveVal[1]);
484 }
else if (numUniqueInactiveVals > 2) {
488 os.write(reinterpret_cast<const char*>(&metadata), 1);
496 os.write(reinterpret_cast<const char*>(&inactiveVal[0]),
sizeof(ValueT));
499 os.write(reinterpret_cast<const char*>(&inactiveVal[1]),
sizeof(ValueT));
504 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueT));
508 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueT));
520 scopedTempBuf.reset(
new ValueT[srcCount]);
521 tempBuf = scopedTempBuf.get();
529 for (
typename MaskT::OnIterator it = valueMask.beginOn(); it; ++it, ++tempCount) {
530 tempBuf[tempCount] = srcBuf[it.pos()];
537 for (
Index srcIdx = 0; srcIdx < srcCount; ++srcIdx) {
538 if (valueMask.isOn(srcIdx)) {
539 tempBuf[tempCount] = srcBuf[srcIdx];
542 if (Local::eq(srcBuf[srcIdx], inactiveVal[1])) {
543 selectionMask.setOn(srcIdx);
547 assert(tempCount == valueMask.countOn());
550 selectionMask.save(os);
567 #endif // OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
Definition: Compression.h:90
Vec2< double > Vec2d
Definition: Vec2.h:521
OPENVDB_API void unzipFromStream(std::istream &, char *data, size_t numBytes)
half HalfT
Definition: Compression.h:105
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:381
void readData(std::istream &is, T *data, Index count, bool compressed)
Read data from a stream.
Definition: Compression.h:136
static void read(std::istream &is, T *data, Index count, bool compressed)
Definition: Compression.h:178
T HalfT
Definition: Compression.h:102
Definition: Compression.h:89
Index32 Index
Definition: Types.h:57
Definition: Compression.h:88
RealToHalf< T >::HalfT HalfT
Definition: Compression.h:235
Definition: Compression.h:87
OPENVDB_API std::string compressionToString(uint32_t flags)
Return a string describing the given compression flags.
void writeData(std::ostream &os, const T *data, Index count, bool compress)
Definition: Compression.h:197
OPENVDB_API void zipToStream(std::ostream &, const char *data, size_t numBytes)
half HalfT
Definition: Compression.h:104
RealToHalf and its specializations define a mapping from floating-point data types to analogous half ...
Definition: Compression.h:100
Definition: Compression.h:84
static void write(std::ostream &os, const T *data, Index count, bool compress)
Definition: Compression.h:236
Definition: version.h:106
#define OPENVDB_VERSION_NAME
Definition: version.h:45
Definition: Compression.h:85
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:351
Definition: Compression.h:166
static void write(std::ostream &os, const T *data, Index count, bool compress)
Definition: Compression.h:228
Definition: Compression.h:71
Definition: Compression.h:70
uint32_t Index32
Definition: Types.h:55
OPENVDB_IMPORT uint32_t getFormatVersion(std::istream &)
Return the file format version number associated with the given input stream.
Definition: Compression.h:69
Vec2< float > Vec2s
Definition: Vec2.h:520
Vec3< double > Vec3d
Definition: Vec3.h:625
Vec3< float > Vec3s
Definition: Vec3.h:624
OPENVDB_IMPORT const void * getGridBackgroundValuePtr(std::ios_base &)
Return a pointer to the background value of the grid currently being read from or written to the give...
RealToHalf< T >::HalfT HalfT
Definition: Compression.h:177
static void read(std::istream &is, T *data, Index count, bool compressed)
Definition: Compression.h:170
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:107
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
Definition: Compression.h:224
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:115
OPENVDB_IMPORT uint32_t getDataCompression(std::ios_base &)
Return a bitwise OR of compression option flags (COMPRESS_ZIP, COMPRESS_ACTIVE_MASK, etc.) specifying whether and how input data is compressed or output data should be compressed.
Definition: Compression.h:86
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:277