OpenVDB  3.1.0
Compression.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2015 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 
31 #ifndef OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
32 #define OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
33 
34 #include <openvdb/Types.h>
35 #include <openvdb/math/Math.h> // for negative()
36 #include "io.h" // for getDataCompression(), etc.
37 #include <boost/scoped_array.hpp>
38 #include <algorithm>
39 #include <iostream>
40 #include <string>
41 #include <vector>
42 
43 
44 namespace openvdb {
46 namespace OPENVDB_VERSION_NAME {
47 namespace io {
48 
77 enum {
79  COMPRESS_ZIP = 0x1,
82 };
83 
85 OPENVDB_API std::string compressionToString(uint32_t flags);
86 
87 
89 
90 
93 enum {
94  /*0*/ NO_MASK_OR_INACTIVE_VALS, // no inactive vals, or all inactive vals are +background
95  /*1*/ NO_MASK_AND_MINUS_BG, // all inactive vals are -background
96  /*2*/ NO_MASK_AND_ONE_INACTIVE_VAL, // all inactive vals have the same non-background val
97  /*3*/ MASK_AND_NO_INACTIVE_VALS, // mask selects between -background and +background
98  /*4*/ MASK_AND_ONE_INACTIVE_VAL, // mask selects between backgd and one other inactive val
99  /*5*/ MASK_AND_TWO_INACTIVE_VALS, // mask selects between two non-background inactive vals
100  /*6*/ NO_MASK_AND_ALL_VALS // > 2 inactive vals, so no mask compression at all
101 };
102 
103 
105 
106 
109 template<typename T>
110 struct RealToHalf {
111  enum { isReal = false }; // unless otherwise specified, type T is not a floating-point type
112  typedef T HalfT; // type T's half float analogue is T itself
113  static HalfT convert(const T& val) { return val; }
114 };
115 template<> struct RealToHalf<float> {
116  enum { isReal = true };
117  typedef half HalfT;
118  static HalfT convert(float val) { return HalfT(val); }
119 };
120 template<> struct RealToHalf<double> {
121  enum { isReal = true };
122  typedef half HalfT;
123  // A half can only be constructed from a float, so cast the value to a float first.
124  static HalfT convert(double val) { return HalfT(float(val)); }
125 };
126 template<> struct RealToHalf<Vec2s> {
127  enum { isReal = true };
128  typedef Vec2H HalfT;
129  static HalfT convert(const Vec2s& val) { return HalfT(val); }
130 };
131 template<> struct RealToHalf<Vec2d> {
132  enum { isReal = true };
133  typedef Vec2H HalfT;
134  // A half can only be constructed from a float, so cast the vector's elements to floats first.
135  static HalfT convert(const Vec2d& val) { return HalfT(Vec2s(val)); }
136 };
137 template<> struct RealToHalf<Vec3s> {
138  enum { isReal = true };
139  typedef Vec3H HalfT;
140  static HalfT convert(const Vec3s& val) { return HalfT(val); }
141 };
142 template<> struct RealToHalf<Vec3d> {
143  enum { isReal = true };
144  typedef Vec3H HalfT;
145  // A half can only be constructed from a float, so cast the vector's elements to floats first.
146  static HalfT convert(const Vec3d& val) { return HalfT(Vec3s(val)); }
147 };
148 
149 
151 template<typename T>
152 inline T
153 truncateRealToHalf(const T& val)
154 {
155  return T(RealToHalf<T>::convert(val));
156 }
157 
158 
160 
161 
162 OPENVDB_API void zipToStream(std::ostream&, const char* data, size_t numBytes);
163 OPENVDB_API void unzipFromStream(std::istream&, char* data, size_t numBytes);
164 OPENVDB_API void bloscToStream(std::ostream&, const char* data, size_t valSize, size_t numVals);
165 OPENVDB_API void bloscFromStream(std::istream&, char* data, size_t numBytes);
166 
177 template<typename T>
178 inline void
179 readData(std::istream& is, T* data, Index count, uint32_t compression)
180 {
181  if (compression & COMPRESS_BLOSC) {
182  bloscFromStream(is, reinterpret_cast<char*>(data), sizeof(T) * count);
183  } else if (compression & COMPRESS_ZIP) {
184  unzipFromStream(is, reinterpret_cast<char*>(data), sizeof(T) * count);
185  } else {
186  is.read(reinterpret_cast<char*>(data), sizeof(T) * count);
187  }
188 }
189 
191 template<>
192 inline void
193 readData<std::string>(std::istream& is, std::string* data, Index count, uint32_t /*compression*/)
194 {
195  for (Index i = 0; i < count; ++i) {
196  size_t len = 0;
197  is >> len;
198  //data[i].resize(len);
199  //is.read(&(data[i][0]), len);
200 
201  std::string buffer(len+1, ' ');
202  is.read(&buffer[0], len+1 );
203  data[i].assign(buffer, 0, len);
204  }
205 }
206 
211 template<bool IsReal, typename T> struct HalfReader;
213 template<typename T>
214 struct HalfReader</*IsReal=*/false, T> {
215  static inline void read(std::istream& is, T* data, Index count, uint32_t compression) {
216  readData(is, data, count, compression);
217  }
218 };
220 template<typename T>
221 struct HalfReader</*IsReal=*/true, T> {
222  typedef typename RealToHalf<T>::HalfT HalfT;
223  static inline void read(std::istream& is, T* data, Index count, uint32_t compression) {
224  if (count < 1) return;
225  std::vector<HalfT> halfData(count); // temp buffer into which to read half float values
226  readData<HalfT>(is, reinterpret_cast<HalfT*>(&halfData[0]), count, compression);
227  // Copy half float values from the temporary buffer to the full float output array.
228  std::copy(halfData.begin(), halfData.end(), data);
229  }
230 };
231 
232 
243 template<typename T>
244 inline void
245 writeData(std::ostream &os, const T *data, Index count, uint32_t compression)
246 {
247  if (compression & COMPRESS_BLOSC) {
248  bloscToStream(os, reinterpret_cast<const char*>(data), sizeof(T), count);
249  } else if (compression & COMPRESS_ZIP) {
250  zipToStream(os, reinterpret_cast<const char*>(data), sizeof(T) * count);
251  } else {
252  os.write(reinterpret_cast<const char*>(data), sizeof(T) * count);
253  }
254 }
255 
257 template<>
258 inline void
259 writeData<std::string>(std::ostream& os, const std::string* data, Index count,
260  uint32_t /*compression*/)
261 {
262  for (Index i = 0; i < count; ++i) {
263  const size_t len = data[i].size();
264  os << len;
265  os.write(data[i].c_str(), len+1);
266  //os.write(&(data[i][0]), len );
267  }
268 }
269 
274 template<bool IsReal, typename T> struct HalfWriter;
276 template<typename T>
277 struct HalfWriter</*IsReal=*/false, T> {
278  static inline void write(std::ostream& os, const T* data, Index count, uint32_t compression) {
279  writeData(os, data, count, compression);
280  }
281 };
283 template<typename T>
284 struct HalfWriter</*IsReal=*/true, T> {
285  typedef typename RealToHalf<T>::HalfT HalfT;
286  static inline void write(std::ostream& os, const T* data, Index count, uint32_t compression) {
287  if (count < 1) return;
288  // Convert full float values to half float, then output the half float array.
289  std::vector<HalfT> halfData(count);
290  for (Index i = 0; i < count; ++i) halfData[i] = RealToHalf<T>::convert(data[i]);
291  writeData<HalfT>(os, reinterpret_cast<const HalfT*>(&halfData[0]), count, compression);
292  }
293 };
294 #ifdef _MSC_VER
295 template<>
297 struct HalfWriter</*IsReal=*/true, double> {
298  typedef RealToHalf<double>::HalfT HalfT;
299  static inline void write(std::ostream& os, const double* data, Index count,
300  uint32_t compression)
301  {
302  if (count < 1) return;
303  // Convert full float values to half float, then output the half float array.
304  std::vector<HalfT> halfData(count);
305  for (Index i = 0; i < count; ++i) halfData[i] = RealToHalf<double>::convert(data[i]);
306  writeData<HalfT>(os, reinterpret_cast<const HalfT*>(&halfData[0]), count, compression);
307  }
308 };
309 #endif // _MSC_VER
310 
311 
313 
314 
327 template<typename ValueT, typename MaskT>
328 inline void
329 readCompressedValues(std::istream& is, ValueT* destBuf, Index destCount,
330  const MaskT& valueMask, bool fromHalf)
331 {
332  // Get the stream's compression settings.
333  const uint32_t compression = getDataCompression(is);
334  const bool maskCompressed = compression & COMPRESS_ACTIVE_MASK;
335 
336  int8_t metadata = NO_MASK_AND_ALL_VALS;
338  // Read the flag that specifies what, if any, additional metadata
339  // (selection mask and/or inactive value(s)) is saved.
340  is.read(reinterpret_cast<char*>(&metadata), /*bytes=*/1);
341  }
342 
343  ValueT background = zeroVal<ValueT>();
344  if (const void* bgPtr = getGridBackgroundValuePtr(is)) {
345  background = *static_cast<const ValueT*>(bgPtr);
346  }
347  ValueT inactiveVal1 = background;
348  ValueT inactiveVal0 =
349  ((metadata == NO_MASK_OR_INACTIVE_VALS) ? background : math::negative(background));
350 
351  if (metadata == NO_MASK_AND_ONE_INACTIVE_VAL ||
352  metadata == MASK_AND_ONE_INACTIVE_VAL ||
353  metadata == MASK_AND_TWO_INACTIVE_VALS)
354  {
355  // Read one of at most two distinct inactive values.
356  is.read(reinterpret_cast<char*>(&inactiveVal0), sizeof(ValueT));
357  if (metadata == MASK_AND_TWO_INACTIVE_VALS) {
358  // Read the second of two distinct inactive values.
359  is.read(reinterpret_cast<char*>(&inactiveVal1), sizeof(ValueT));
360  }
361  }
362 
363  MaskT selectionMask;
364  if (metadata == MASK_AND_NO_INACTIVE_VALS ||
365  metadata == MASK_AND_ONE_INACTIVE_VAL ||
366  metadata == MASK_AND_TWO_INACTIVE_VALS)
367  {
368  // For use in mask compression (only), read the bitmask that selects
369  // between two distinct inactive values.
370  selectionMask.load(is);
371  }
372 
373  ValueT* tempBuf = destBuf;
374  boost::scoped_array<ValueT> scopedTempBuf;
375 
376  Index tempCount = destCount;
377  if (maskCompressed && metadata != NO_MASK_AND_ALL_VALS
379  {
380  tempCount = valueMask.countOn();
381  if (tempCount != destCount) {
382  // If this node has inactive voxels, allocate a temporary buffer
383  // into which to read just the active values.
384  scopedTempBuf.reset(new ValueT[tempCount]);
385  tempBuf = scopedTempBuf.get();
386  }
387  }
388 
389  // Read in the buffer.
390  if (fromHalf) {
391  HalfReader<RealToHalf<ValueT>::isReal, ValueT>::read(is, tempBuf, tempCount, compression);
392  } else {
393  readData<ValueT>(is, tempBuf, tempCount, compression);
394  }
395 
396  // If mask compression is enabled and the number of active values read into
397  // the temp buffer is smaller than the size of the destination buffer,
398  // then there are missing (inactive) values.
399  if (maskCompressed && tempCount != destCount) {
400  // Restore inactive values, using the background value and, if available,
401  // the inside/outside mask. (For fog volumes, the destination buffer is assumed
402  // to be initialized to background value zero, so inactive values can be ignored.)
403  for (Index destIdx = 0, tempIdx = 0; destIdx < MaskT::SIZE; ++destIdx) {
404  if (valueMask.isOn(destIdx)) {
405  // Copy a saved active value into this node's buffer.
406  destBuf[destIdx] = tempBuf[tempIdx];
407  ++tempIdx;
408  } else {
409  // Reconstruct an unsaved inactive value and copy it into this node's buffer.
410  destBuf[destIdx] = (selectionMask.isOn(destIdx) ? inactiveVal1 : inactiveVal0);
411  }
412  }
413  }
414 }
415 
416 
429 template<typename ValueT, typename MaskT>
430 inline void
431 writeCompressedValues(std::ostream& os, ValueT* srcBuf, Index srcCount,
432  const MaskT& valueMask, const MaskT& childMask, bool toHalf)
433 {
434  struct Local {
435  // Comparison function for values
436  static inline bool eq(const ValueT& a, const ValueT& b) {
437  return math::isExactlyEqual(a, b);
438  }
439  };
440 
441  // Get the stream's compression settings.
442  const uint32_t compress = getDataCompression(os);
443  const bool maskCompress = compress & COMPRESS_ACTIVE_MASK;
444 
445  Index tempCount = srcCount;
446  ValueT* tempBuf = srcBuf;
447  boost::scoped_array<ValueT> scopedTempBuf;
448 
449  int8_t metadata = NO_MASK_AND_ALL_VALS;
450 
451  if (!maskCompress) {
452  os.write(reinterpret_cast<const char*>(&metadata), /*bytes=*/1);
453  } else {
454  // A valid level set's inactive values are either +background (outside)
455  // or -background (inside), and a fog volume's inactive values are all zero.
456  // Rather than write out all of these values, we can store just the active values
457  // (given that the value mask specifies their positions) and, if necessary,
458  // an inside/outside bitmask.
459 
460  const ValueT zero = zeroVal<ValueT>();
461  ValueT background = zero;
462  if (const void* bgPtr = getGridBackgroundValuePtr(os)) {
463  background = *static_cast<const ValueT*>(bgPtr);
464  }
465 
467  ValueT inactiveVal[2] = { background, background };
468  int numUniqueInactiveVals = 0;
469  for (typename MaskT::OffIterator it = valueMask.beginOff();
470  numUniqueInactiveVals < 3 && it; ++it)
471  {
472  const Index32 idx = it.pos();
473 
474  // Skip inactive values that are actually child node pointers.
475  if (childMask.isOn(idx)) continue;
476 
477  const ValueT& val = srcBuf[idx];
478  const bool unique = !(
479  (numUniqueInactiveVals > 0 && Local::eq(val, inactiveVal[0])) ||
480  (numUniqueInactiveVals > 1 && Local::eq(val, inactiveVal[1]))
481  );
482  if (unique) {
483  if (numUniqueInactiveVals < 2) inactiveVal[numUniqueInactiveVals] = val;
484  ++numUniqueInactiveVals;
485  }
486  }
487 
488  metadata = NO_MASK_OR_INACTIVE_VALS;
489 
490  if (numUniqueInactiveVals == 1) {
491  if (!Local::eq(inactiveVal[0], background)) {
492  if (Local::eq(inactiveVal[0], math::negative(background))) {
493  metadata = NO_MASK_AND_MINUS_BG;
494  } else {
495  metadata = NO_MASK_AND_ONE_INACTIVE_VAL;
496  }
497  }
498  } else if (numUniqueInactiveVals == 2) {
499  metadata = NO_MASK_OR_INACTIVE_VALS;
500  if (!Local::eq(inactiveVal[0], background) && !Local::eq(inactiveVal[1], background)) {
501  // If neither inactive value is equal to the background, both values
502  // need to be saved, along with a mask that selects between them.
503  metadata = MASK_AND_TWO_INACTIVE_VALS;
504 
505  } else if (Local::eq(inactiveVal[1], background)) {
506  if (Local::eq(inactiveVal[0], math::negative(background))) {
507  // If the second inactive value is equal to the background and
508  // the first is equal to -background, neither value needs to be saved,
509  // but save a mask that selects between -background and +background.
510  metadata = MASK_AND_NO_INACTIVE_VALS;
511  } else {
512  // If the second inactive value is equal to the background, only
513  // the first value needs to be saved, along with a mask that selects
514  // between it and the background.
515  metadata = MASK_AND_ONE_INACTIVE_VAL;
516  }
517  } else if (Local::eq(inactiveVal[0], background)) {
518  if (Local::eq(inactiveVal[1], math::negative(background))) {
519  // If the first inactive value is equal to the background and
520  // the second is equal to -background, neither value needs to be saved,
521  // but save a mask that selects between -background and +background.
522  metadata = MASK_AND_NO_INACTIVE_VALS;
523  std::swap(inactiveVal[0], inactiveVal[1]);
524  } else {
525  // If the first inactive value is equal to the background, swap it
526  // with the second value and save only that value, along with a mask
527  // that selects between it and the background.
528  std::swap(inactiveVal[0], inactiveVal[1]);
529  metadata = MASK_AND_ONE_INACTIVE_VAL;
530  }
531  }
532  } else if (numUniqueInactiveVals > 2) {
533  metadata = NO_MASK_AND_ALL_VALS;
534  }
535 
536  os.write(reinterpret_cast<const char*>(&metadata), /*bytes=*/1);
537 
538  if (metadata == NO_MASK_AND_ONE_INACTIVE_VAL ||
539  metadata == MASK_AND_ONE_INACTIVE_VAL ||
540  metadata == MASK_AND_TWO_INACTIVE_VALS)
541  {
542  if (!toHalf) {
543  // Write one of at most two distinct inactive values.
544  os.write(reinterpret_cast<const char*>(&inactiveVal[0]), sizeof(ValueT));
545  if (metadata == MASK_AND_TWO_INACTIVE_VALS) {
546  // Write the second of two distinct inactive values.
547  os.write(reinterpret_cast<const char*>(&inactiveVal[1]), sizeof(ValueT));
548  }
549  } else {
550  // Write one of at most two distinct inactive values.
551  ValueT truncatedVal = static_cast<ValueT>(truncateRealToHalf(inactiveVal[0]));
552  os.write(reinterpret_cast<const char*>(&truncatedVal), sizeof(ValueT));
553  if (metadata == MASK_AND_TWO_INACTIVE_VALS) {
554  // Write the second of two distinct inactive values.
555  truncatedVal = truncateRealToHalf(inactiveVal[1]);
556  os.write(reinterpret_cast<const char*>(&truncatedVal), sizeof(ValueT));
557  }
558  }
559  }
560 
561  if (metadata == NO_MASK_AND_ALL_VALS) {
562  // If there are more than two unique inactive values, the entire input buffer
563  // needs to be saved (both active and inactive values).
566  } else {
567  // Create a new array to hold just the active values.
568  scopedTempBuf.reset(new ValueT[srcCount]);
569  tempBuf = scopedTempBuf.get();
570 
571  if (metadata == NO_MASK_OR_INACTIVE_VALS ||
572  metadata == NO_MASK_AND_MINUS_BG ||
573  metadata == NO_MASK_AND_ONE_INACTIVE_VAL)
574  {
575  // Copy active values to the contiguous array.
576  tempCount = 0;
577  for (typename MaskT::OnIterator it = valueMask.beginOn(); it; ++it, ++tempCount) {
578  tempBuf[tempCount] = srcBuf[it.pos()];
579  }
580  } else {
581  // Copy active values to a new, contiguous array and populate a bitmask
582  // that selects between two distinct inactive values.
583  MaskT selectionMask;
584  tempCount = 0;
585  for (Index srcIdx = 0; srcIdx < srcCount; ++srcIdx) {
586  if (valueMask.isOn(srcIdx)) { // active value
587  tempBuf[tempCount] = srcBuf[srcIdx];
588  ++tempCount;
589  } else { // inactive value
590  if (Local::eq(srcBuf[srcIdx], inactiveVal[1])) {
591  selectionMask.setOn(srcIdx); // inactive value 1
592  } // else inactive value 0
593  }
594  }
595  assert(tempCount == valueMask.countOn());
596 
597  // Write out the mask that selects between two inactive values.
598  selectionMask.save(os);
599  }
600  }
601  }
602 
603  // Write out the buffer.
604  if (toHalf) {
605  HalfWriter<RealToHalf<ValueT>::isReal, ValueT>::write(os, tempBuf, tempCount, compress);
606  } else {
607  writeData(os, tempBuf, tempCount, compress);
608  }
609 }
610 
611 } // namespace io
612 } // namespace OPENVDB_VERSION_NAME
613 } // namespace openvdb
614 
615 #endif // OPENVDB_IO_COMPRESSION_HAS_BEEN_INCLUDED
616 
617 // Copyright (c) 2012-2015 DreamWorks Animation LLC
618 // All rights reserved. This software is distributed under the
619 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:116
Definition: Vec2.h:48
Index32 Index
Definition: Types.h:58
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:195
static HalfT convert(const Vec3s &val)
Definition: Compression.h:140
RealToHalf< T >::HalfT HalfT
Definition: Compression.h:222
static void read(std::istream &is, T *data, Index count, uint32_t compression)
Definition: Compression.h:223
static HalfT convert(double val)
Definition: Compression.h:124
Vec3H HalfT
Definition: Compression.h:144
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
static void write(std::ostream &os, const T *data, Index count, uint32_t compression)
Definition: Compression.h:286
void writeCompressedValues(std::ostream &os, ValueT *srcBuf, Index srcCount, const MaskT &valueMask, const MaskT &childMask, bool toHalf)
Definition: Compression.h:431
uint32_t Index32
Definition: Types.h:56
Definition: Compression.h:274
OPENVDB_API void zipToStream(std::ostream &, const char *data, size_t numBytes)
static HalfT convert(const Vec2d &val)
Definition: Compression.h:135
T truncateRealToHalf(const T &val)
Return the given value truncated to 16-bit float precision.
Definition: Compression.h:153
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...
static HalfT convert(float val)
Definition: Compression.h:118
Definition: Compression.h:81
Definition: Compression.h:95
Definition: Compression.h:211
OPENVDB_API std::string compressionToString(uint32_t flags)
Return a string describing the given compression flags.
#define OPENVDB_VERSION_NAME
Definition: version.h:43
OPENVDB_API uint32_t getFormatVersion(std::ios_base &)
Return the file format version number associated with the given input stream.
Definition: Compression.h:100
void readCompressedValues(std::istream &is, ValueT *destBuf, Index destCount, const MaskT &valueMask, bool fromHalf)
Definition: Compression.h:329
Definition: Mat.h:146
RealToHalf and its specializations define a mapping from floating-point data types to analogous half ...
Definition: Compression.h:110
Definition: Exceptions.h:39
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.
Vec3H HalfT
Definition: Compression.h:139
void writeData(std::ostream &os, const T *data, Index count, uint32_t compression)
Definition: Compression.h:245
OPENVDB_API void bloscFromStream(std::istream &, char *data, size_t numBytes)
Vec2H HalfT
Definition: Compression.h:128
Vec3< double > Vec3d
Definition: Vec3.h:643
half HalfT
Definition: Compression.h:122
Definition: Compression.h:80
T HalfT
Definition: Compression.h:112
static HalfT convert(const T &val)
Definition: Compression.h:113
static HalfT convert(const Vec3d &val)
Definition: Compression.h:146
Definition: Compression.h:79
static HalfT convert(const Vec2s &val)
Definition: Compression.h:129
OPENVDB_API void bloscToStream(std::ostream &, const char *data, size_t valSize, size_t numVals)
Vec2< float > Vec2s
Definition: Vec2.h:534
static void write(std::ostream &os, const T *data, Index count, uint32_t compression)
Definition: Compression.h:278
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Vec3< float > Vec3s
Definition: Vec3.h:642
RealToHalf< T >::HalfT HalfT
Definition: Compression.h:285
half HalfT
Definition: Compression.h:117
static void read(std::istream &is, T *data, Index count, uint32_t compression)
Definition: Compression.h:215
void readData(std::istream &is, T *data, Index count, uint32_t compression)
Read data from a stream.
Definition: Compression.h:179
Vec2H HalfT
Definition: Compression.h:133
Vec2< double > Vec2d
Definition: Vec2.h:535
Definition: Compression.h:78
OPENVDB_API void unzipFromStream(std::istream &, char *data, size_t numBytes)