4 #ifndef OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
5 #define OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
80 template <
typename ValueT,
typename MaskT>
84 static inline bool eq(
const ValueT&
a,
const ValueT&
b) {
89 const MaskT& valueMask,
const MaskT& childMask,
90 const ValueT* srcBuf,
const ValueT& background)
94 int numUniqueInactiveVals = 0;
95 for (
typename MaskT::OffIterator it = valueMask.beginOff();
96 numUniqueInactiveVals < 3 && it; ++it)
101 if (childMask.isOn(idx))
continue;
103 const ValueT&
val = srcBuf[idx];
109 if (numUniqueInactiveVals < 2)
inactiveVal[numUniqueInactiveVals] =
val;
110 ++numUniqueInactiveVals;
116 if (numUniqueInactiveVals == 1) {
124 }
else if (numUniqueInactiveVals == 2) {
158 }
else if (numUniqueInactiveVals > 2) {
251 const bool seek = data ==
nullptr;
257 if (metadata && seek && hasCompression) {
258 size_t compressedSize = metadata->getCompressedSize(metadataOffset);
259 is.seekg(compressedSize, std::ios_base::cur);
265 is.seekg(
sizeof(
T) * count, std::ios_base::cur);
267 is.read(reinterpret_cast<char*>(data),
sizeof(
T) * count);
274 readData<std::string>(std::istream& is, std::string*
data,
Index count, uint32_t ,
277 for (
Index i = 0; i < count; ++i) {
283 std::string
buffer(len+1,
' ');
284 is.read(&buffer[0], len+1);
285 if (data !=
nullptr) data[i].assign(buffer, 0, len);
297 static inline void read(std::istream& is, T* data,
Index count, uint32_t compression,
299 readData(is, data, count, compression, metadata, metadataOffset);
306 static inline void read(std::istream& is, T* data,
Index count, uint32_t compression,
308 if (count < 1)
return;
309 if (data ==
nullptr) {
311 readData<HalfT>(is,
nullptr, count, compression, metadata, metadataOffset);
313 std::vector<HalfT> halfData(count);
314 readData<HalfT>(is,
reinterpret_cast<HalfT*
>(&halfData[0]), count, compression,
315 metadata, metadataOffset);
317 std::copy(halfData.begin(), halfData.end(),
data);
330 return zipToStreamSize(reinterpret_cast<const char*>(data),
sizeof(
T) * count);
332 return sizeof(
T) * count;
340 writeDataSize<std::string>(
const std::string*
data,
Index count,
344 for (
Index i = 0; i < count; ++i) {
345 const size_t len = data[i].size();
346 size +=
sizeof(size_t) + (len+1);
367 bloscToStream(os, reinterpret_cast<const char*>(data),
sizeof(
T), count);
369 zipToStream(os, reinterpret_cast<const char*>(data),
sizeof(
T) * count);
371 os.write(reinterpret_cast<const char*>(data),
sizeof(
T) * count);
378 writeData<std::string>(std::ostream& os,
const std::string*
data,
Index count,
381 for (
Index i = 0; i < count; ++i) {
382 const size_t len = data[i].size();
384 os.write(data[i].
c_str(), len+1);
397 static inline size_t writeSize(
const T* data,
Index count, uint32_t compression) {
400 static inline void write(std::ostream& os,
const T* data,
Index count, uint32_t compression) {
408 static inline size_t writeSize(
const T* data,
Index count, uint32_t compression) {
409 if (count < 1)
return size_t(0);
411 std::vector<HalfT> halfData(count);
413 return writeDataSize<HalfT>(
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compression);
415 static inline void write(std::ostream& os,
const T* data,
Index count, uint32_t compression) {
416 if (count < 1)
return;
418 std::vector<HalfT> halfData(count);
420 writeData<HalfT>(os,
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compression);
426 struct HalfWriter<true, double> {
428 static inline size_t writeSize(
const double* data,
Index count, uint32_t compression)
430 if (count < 1)
return size_t(0);
432 std::vector<HalfT> halfData(count);
434 return writeDataSize<HalfT>(
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compression);
436 static inline void write(std::ostream& os,
const double* data, Index count,
437 uint32_t compression)
439 if (count < 1)
return;
441 std::vector<HalfT> halfData(count);
443 writeData<HalfT>(os,
reinterpret_cast<const HalfT*
>(&halfData[0]), count, compression);
464 template<
typename ValueT,
typename MaskT>
467 const MaskT& valueMask,
bool fromHalf)
476 const bool seek = (destBuf ==
nullptr);
482 uint64_t leafIndex(0);
483 if (seek && meta && meta->delayedLoadMeta()) {
486 leafIndex = meta->leaf();
494 if (seek && !maskCompressed) {
495 is.seekg(1, std::ios_base::cur);
496 }
else if (seek && delayLoadMeta) {
497 metadata = delayLoadMeta->getMask(leafIndex);
498 is.seekg(1, std::ios_base::cur);
500 is.read(reinterpret_cast<char*>(&metadata), 1);
504 ValueT background = zeroVal<ValueT>();
506 background = *
static_cast<const ValueT*
>(bgPtr);
508 ValueT inactiveVal1 = background;
509 ValueT inactiveVal0 =
518 is.seekg(
sizeof(ValueT), std::ios_base::cur);
520 is.read(reinterpret_cast<char*>(&inactiveVal0),
sizeof(ValueT));
525 is.seekg(
sizeof(ValueT), std::ios_base::cur);
527 is.read(reinterpret_cast<char*>(&inactiveVal1),
sizeof(ValueT));
540 is.seekg(selectionMask.memUsage(), std::ios_base::cur);
542 selectionMask.load(is);
546 ValueT* tempBuf = destBuf;
547 std::unique_ptr<ValueT[]> scopedTempBuf;
549 Index tempCount = destCount;
553 tempCount = valueMask.countOn();
554 if (!seek && tempCount != destCount) {
557 scopedTempBuf.reset(
new ValueT[tempCount]);
558 tempBuf = scopedTempBuf.get();
565 is, (seek ?
nullptr : tempBuf), tempCount, compression, delayLoadMeta.get(), leafIndex);
568 is, (seek ?
nullptr : tempBuf), tempCount, compression, delayLoadMeta.get(), leafIndex);
574 if (!seek && maskCompressed && tempCount != destCount) {
579 if (valueMask.isOn(destIdx)) {
581 destBuf[destIdx] = tempBuf[tempIdx];
585 destBuf[destIdx] = (selectionMask.isOn(destIdx) ? inactiveVal1 : inactiveVal0);
592 template<
typename ValueT,
typename MaskT>
595 const MaskT& valueMask, uint8_t maskMetadata,
bool toHalf, uint32_t compress)
601 Index tempCount = srcCount;
602 ValueT* tempBuf = srcBuf;
603 std::unique_ptr<NonConstValueT[]> scopedTempBuf;
609 Index64 onVoxels = valueMask.countOn();
612 scopedTempBuf.reset(
new NonConstValueT[onVoxels]);
613 NonConstValueT* localTempBuf = scopedTempBuf.get();
616 for (
typename MaskT::OnIterator it = valueMask.beginOn(); it; ++it, ++tempCount) {
617 localTempBuf[tempCount] = srcBuf[it.pos()];
620 tempBuf = scopedTempBuf.get();
627 tempBuf, tempCount, compress);
629 return writeDataSize<NonConstValueT>(tempBuf, tempCount, compress);
646 template<
typename ValueT,
typename MaskT>
649 const MaskT& valueMask,
const MaskT& childMask,
bool toHalf)
655 Index tempCount = srcCount;
656 ValueT* tempBuf =
nullptr;
657 std::unique_ptr<ValueT[]> scopedTempBuf;
662 os.write(reinterpret_cast<const char*>(&metadata), 1);
670 const ValueT zero = zeroVal<ValueT>();
671 ValueT background = zero;
673 background = *
static_cast<const ValueT*
>(bgPtr);
677 metadata = maskCompressData.
metadata;
679 os.write(reinterpret_cast<const char*>(&metadata), 1);
687 os.write(reinterpret_cast<const char*>(&maskCompressData.
inactiveVal[0]),
sizeof(ValueT));
690 os.write(reinterpret_cast<const char*>(&maskCompressData.
inactiveVal[1]),
sizeof(ValueT));
695 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueT));
699 os.write(reinterpret_cast<const char*>(&truncatedVal),
sizeof(ValueT));
711 scopedTempBuf.reset(
new ValueT[srcCount]);
712 tempBuf = scopedTempBuf.get();
720 for (
typename MaskT::OnIterator it = valueMask.beginOn(); it; ++it, ++tempCount) {
721 tempBuf[tempCount] = srcBuf[it.pos()];
728 for (
Index srcIdx = 0; srcIdx < srcCount; ++srcIdx) {
729 if (valueMask.isOn(srcIdx)) {
730 tempBuf[tempCount] = srcBuf[srcIdx];
734 selectionMask.setOn(srcIdx);
741 selectionMask.save(os);
749 bool(tempBuf) ? tempBuf : srcBuf, tempCount, compress);
751 writeData(os,
bool(tempBuf) ? tempBuf : srcBuf, tempCount, compress);
759 #endif // OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
OPENVDB_API 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...
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
void writeData(std::ostream &os, const T *data, Index count, uint32_t compression)
T negative(const T &val)
Return the unary negation of the given value.
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
OPENVDB_API void unzipFromStream(std::istream &, char *data, size_t numBytes)
OPENVDB_API std::string compressionToString(uint32_t flags)
Return a string describing the given compression flags.
OPENVDB_API 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.
GLboolean GLboolean GLboolean GLboolean a
#define OPENVDB_USE_VERSION_NAMESPACE
static HalfT convert(float val)
Tto convert(const Tfrom &source)
OPENVDB_API void bloscFromStream(std::istream &, char *data, size_t numBytes)
OPENVDB_API void checkFormatVersion(std::ios_base &)
Throws an IoError if the file format version number is not supported.
void readData(std::istream &is, T *data, Index count, uint32_t compression, DelayedLoadMetadata *metadata=nullptr, size_t metadataOffset=size_t(0))
Read data from a stream.
#define OPENVDB_ASSERT(X)
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
void writeCompressedValues(std::ostream &os, const ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
static size_t writeSize(const T *data, Index count, uint32_t compression)
OPENVDB_API size_t bloscToStreamSize(const char *data, size_t valSize, size_t numVals)
static bool eq(const ValueT &a, const ValueT &b)
size_t writeCompressedValuesSize(ValueT *srcBuf, Index srcCount, const MaskT &valueMask, uint8_t maskMetadata, bool toHalf, uint32_t compress)
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
static HalfT convert(const Vec3d &val)
static void read(std::istream &is, T *data, Index count, uint32_t compression, DelayedLoadMetadata *metadata=nullptr, size_t metadataOffset=size_t(0))
static size_t writeSize(const T *data, Index count, uint32_t compression)
typename RealToHalf< T >::HalfT HalfT
static void read(std::istream &is, T *data, Index count, uint32_t compression, DelayedLoadMetadata *metadata=nullptr, size_t metadataOffset=size_t(0))
static HalfT convert(const Vec3s &val)
GLboolean GLboolean GLboolean b
static HalfT convert(const Vec2s &val)
OPENVDB_API void bloscToStream(std::ostream &, const char *data, size_t valSize, size_t numVals)
static HalfT convert(double val)
IMATH_NAMESPACE::V2f IMATH_NAMESPACE::Box2i std::string this attribute is obsolete as of OpenEXR v3 float
static HalfT convert(const T &val)
RealToHalf and its specializations define a mapping from floating-point data types to analogous half ...
OPENVDB_API void zipToStream(std::ostream &, const char *data, size_t numBytes)
OPENVDB_API SharedPtr< StreamMetadata > getStreamMetadataPtr(std::ios_base &)
Return a shared pointer to an object that stores metadata (file format, compression scheme...
static HalfT convert(const Vec2d &val)
OIIO_UTIL_API const char * c_str(string_view str)
PUGI__FN I unique(I begin, I end)
typename RealToHalf< T >::HalfT HalfT
size_t writeDataSize(const T *data, Index count, uint32_t compression)
MaskCompress(const MaskT &valueMask, const MaskT &childMask, const ValueT *srcBuf, const ValueT &background)
static void write(std::ostream &os, const T *data, Index count, uint32_t compression)
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
static void write(std::ostream &os, const T *data, Index count, uint32_t compression)
OPENVDB_API size_t zipToStreamSize(const char *data, size_t numBytes)