OpenVDB  5.2.0
StreamCompression.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 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 
45 
46 #ifndef OPENVDB_TOOLS_STREAM_COMPRESSION_HAS_BEEN_INCLUDED
47 #define OPENVDB_TOOLS_STREAM_COMPRESSION_HAS_BEEN_INCLUDED
48 
49 #include <openvdb/io/io.h>
50 #include <tbb/spin_mutex.h>
51 #include <memory>
52 #include <string>
53 
54 
55 class TestStreamCompression;
56 
57 namespace openvdb {
59 namespace OPENVDB_VERSION_NAME {
60 namespace compression {
61 
62 
63 // This is the minimum number of bytes below which Blosc compression is not used to
64 // avoid unecessary computation, as Blosc offers minimal compression until this limit
65 static const int BLOSC_MINIMUM_BYTES = 48;
66 
67 // This is the minimum number of bytes below which the array is padded with zeros up
68 // to this number of bytes to allow Blosc to perform compression with small arrays
69 static const int BLOSC_PAD_BYTES = 128;
70 
71 
74 
78 OPENVDB_API size_t bloscUncompressedSize(const char* buffer);
79 
87 OPENVDB_API void bloscCompress(char* compressedBuffer, size_t& compressedBytes,
88  const size_t bufferBytes, const char* uncompressedBuffer, const size_t uncompressedBytes);
89 
98 OPENVDB_API std::unique_ptr<char[]> bloscCompress(const char* buffer,
99  const size_t uncompressedBytes, size_t& compressedBytes, const bool resize = true);
100 
105 OPENVDB_API size_t bloscCompressedSize(const char* buffer, const size_t uncompressedBytes);
106 
114 OPENVDB_API void bloscDecompress(char* uncompressedBuffer, const size_t expectedBytes,
115  const size_t bufferBytes, const char* compressedBuffer);
116 
124 OPENVDB_API std::unique_ptr<char[]> bloscDecompress(const char* buffer,
125  const size_t expectedBytes, const bool resize = true);
126 
127 
129 
130 
131 // 1MB = 1048576 Bytes
132 static const int PageSize = 1024 * 1024;
133 
134 
139 {
140 private:
141  struct Info
142  {
143  io::MappedFile::Ptr mappedFile;
145  std::streamoff filepos;
146  long compressedBytes;
147  long uncompressedBytes;
148  }; // Info
149 
150 public:
151  using Ptr = std::shared_ptr<Page>;
152 
153  Page() = default;
154 
156  void load() const;
157 
160  long uncompressedBytes() const;
161 
164  const char* buffer(const int index) const;
165 
167  void readHeader(std::istream&);
168 
171  void readBuffers(std::istream&, bool delayed);
172 
174  bool isOutOfCore() const;
175 
176 private:
178  void copy(const std::unique_ptr<char[]>& temp, int pageSize);
179 
181  void decompress(const std::unique_ptr<char[]>& temp);
182 
184  void doLoad() const;
185 
186  std::unique_ptr<Info> mInfo = std::unique_ptr<Info>(new Info);
187  std::unique_ptr<char[]> mData;
188  tbb::spin_mutex mMutex;
189 }; // class Page
190 
191 
195 {
196 public:
197  using Ptr = std::shared_ptr<PageHandle>;
198 
203  PageHandle(const Page::Ptr& page, const int index, const int size);
204 
206  Page& page();
207 
210  std::unique_ptr<char[]> read();
211 
212 protected:
213  friend class ::TestStreamCompression;
214 
215 private:
216  Page::Ptr mPage;
217  int mIndex = -1;
218  int mSize = 0;
219 }; // class PageHandle
220 
221 
226 {
227 public:
228  using Ptr = std::shared_ptr<PagedInputStream>;
229 
230  PagedInputStream() = default;
231 
232  explicit PagedInputStream(std::istream& is);
233 
235  void setSizeOnly(bool sizeOnly) { mSizeOnly = sizeOnly; }
236  bool sizeOnly() const { return mSizeOnly; }
237 
238  // @brief Set and get the input stream
239  std::istream& getInputStream() { assert(mIs); return *mIs; }
240  void setInputStream(std::istream& is) { mIs = &is; }
241 
243  PageHandle::Ptr createHandle(std::streamsize n);
244 
248  void read(PageHandle::Ptr& pageHandle, std::streamsize n, bool delayed = true);
249 
250 private:
251  int mByteIndex = 0;
252  int mUncompressedBytes = 0;
253  std::istream* mIs = nullptr;
254  Page::Ptr mPage;
255  bool mSizeOnly = false;
256 }; // class PagedInputStream
257 
258 
263 {
264 public:
265  using Ptr = std::shared_ptr<PagedOutputStream>;
266 
268 
269  explicit PagedOutputStream(std::ostream& os);
270 
272  void setSizeOnly(bool sizeOnly) { mSizeOnly = sizeOnly; }
273  bool sizeOnly() const { return mSizeOnly; }
274 
276  std::ostream& getOutputStream() { assert(mOs); return *mOs; }
277  void setOutputStream(std::ostream& os) { mOs = &os; }
278 
280  PagedOutputStream& write(const char* str, std::streamsize n);
281 
283  void flush();
284 
285 private:
288  void compressAndWrite(const char* buffer, size_t size);
289 
291  void resize(size_t size);
292 
293  std::unique_ptr<char[]> mData = std::unique_ptr<char[]>(new char[PageSize]);
294  std::unique_ptr<char[]> mCompressedData = nullptr;
295  size_t mCapacity = PageSize;
296  int mBytes = 0;
297  std::ostream* mOs = nullptr;
298  bool mSizeOnly = false;
299 }; // class PagedOutputStream
300 
301 
302 } // namespace compression
303 } // namespace OPENVDB_VERSION_NAME
304 } // namespace openvdb
305 
306 #endif // OPENVDB_TOOLS_STREAM_COMPRESSION_HAS_BEEN_INCLUDED
307 
308 // Copyright (c) 2012-2018 DreamWorks Animation LLC
309 // All rights reserved. This software is distributed under the
310 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
bool sizeOnly() const
Definition: StreamCompression.h:236
#define OPENVDB_API
Helper macros for defining library symbol visibility.
Definition: Platform.h:194
std::shared_ptr< Page > Ptr
Definition: StreamCompression.h:151
static const int BLOSC_MINIMUM_BYTES
Definition: StreamCompression.h:65
A Paging wrapper to std::istream that is responsible for reading from a given input stream and creati...
Definition: StreamCompression.h:225
std::shared_ptr< PagedInputStream > Ptr
Definition: StreamCompression.h:228
OPENVDB_API size_t bloscCompressedSize(const char *buffer, const size_t uncompressedBytes)
Convenience wrapper to retrieve the compressed size of buffer when compressed.
static const int BLOSC_PAD_BYTES
Definition: StreamCompression.h:69
OPENVDB_API bool bloscCanCompress()
Returns true if compression is available.
std::shared_ptr< T > SharedPtr
Definition: Types.h:139
std::shared_ptr< PageHandle > Ptr
Definition: StreamCompression.h:197
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only writing size data.
Definition: StreamCompression.h:272
std::shared_ptr< PagedOutputStream > Ptr
Definition: StreamCompression.h:265
void setOutputStream(std::ostream &os)
Definition: StreamCompression.h:277
A PageHandle holds a shared ptr to a Page and a specific stream pointer to a point within the decompr...
Definition: StreamCompression.h:194
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
static const int PageSize
Definition: StreamCompression.h:132
Stores a variable-size, compressed, delayed-load Page of data that is loaded into memory when accesse...
Definition: StreamCompression.h:138
bool sizeOnly() const
Definition: StreamCompression.h:273
Definition: Exceptions.h:40
std::istream & getInputStream()
Definition: StreamCompression.h:239
std::ostream & getOutputStream()
Set and get the output stream.
Definition: StreamCompression.h:276
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void setSizeOnly(bool sizeOnly)
Size-only mode tags the stream as only reading size data.
Definition: StreamCompression.h:235
SharedPtr< MappedFile > Ptr
Definition: io.h:152
A Paging wrapper to std::ostream that is responsible for writing from a given output stream at interv...
Definition: StreamCompression.h:262
OPENVDB_API size_t bloscUncompressedSize(const char *buffer)
Retrieves the uncompressed size of buffer when uncompressed.
void setInputStream(std::istream &is)
Definition: StreamCompression.h:240
OPENVDB_API std::unique_ptr< char[]> bloscCompress(const char *buffer, const size_t uncompressedBytes, size_t &compressedBytes, const bool resize=true)
Compress and return the heap-allocated compressed buffer.
OPENVDB_API std::unique_ptr< char[]> bloscDecompress(const char *buffer, const size_t expectedBytes, const bool resize=true)
Decompress and return the the heap-allocated uncompressed buffer.