HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_BloscDecompressionFilter.h
Go to the documentation of this file.
1 /*
2  * UT_BloscDecompressionFilter.h
3  *
4  * Created on: May 1, 2014
5  * Author: cspeller
6  */
7 
8 #ifndef UT_BLOSCDECOMPRESSIONFILTER_H_
9 #define UT_BLOSCDECOMPRESSIONFILTER_H_
10 
11 // Use UT_IStreamBuf blosc filter
12 #if 0
13 
14 #include <SYS/SYS_BoostStreams.h>
15 #include <cstdio>
16 #include <blosc.h>
17 
18 
19 ///
20 /// The blosc decompression filter is an implementation of boost multicharacter input filter
21 /// It can be used in boost input streams to read data compressed with blosc
22 ///
23 class UT_BloscDecompressionFilter : public bios::multichar_input_filter
24 {
25  /// Buffer for storing read blocks
26  char* myInputBuffer;
27  size_t myInputBufferSize;
28 
29  /// Buffer for result from blosc
30  char* myOutputBuffer;
31  size_t myOutputBufferSize;
32  size_t myOutputBufferFlushPosition;
33  size_t myOutputBufferUsedSize;
34 
35 public:
36  UT_BloscDecompressionFilter();
37  virtual ~UT_BloscDecompressionFilter();
38 
39  template<typename Source>
40  std::streamsize read(Source& src, char* destinationBuffer,
41  std::streamsize destinationSize);
42 
43  template<typename Source>
44  void close(Source&) {}
45 };
46 
47 inline UT_BloscDecompressionFilter::UT_BloscDecompressionFilter() :
48  myInputBuffer(NULL), myInputBufferSize(0), myOutputBuffer(NULL),
49  myOutputBufferSize(0), myOutputBufferFlushPosition(0), myOutputBufferUsedSize(0)
50 {
51 }
52 
53 inline UT_BloscDecompressionFilter::~UT_BloscDecompressionFilter()
54 {
55  if (myInputBuffer)
56  {
57  delete myInputBuffer;
58  }
59  if (myOutputBuffer)
60  {
61  delete myOutputBuffer;
62  }
63 }
64 
65 template<typename Source>
66 inline std::streamsize UT_BloscDecompressionFilter::read(Source& src,
67  char* destinationBuffer, std::streamsize destinationSize)
68 {
69  // Allocate input buffer if not allocated yet
70  // This is done because BOOST copies us around a bit before
71  // using the filter.
72  if (!myInputBuffer)
73  {
74  myInputBuffer = new char[BLOSC_MIN_HEADER_LENGTH];
75  myInputBufferSize = BLOSC_MIN_HEADER_LENGTH;
76  }
77 
78  // If there is nothing to flush
79  if (myOutputBufferUsedSize == myOutputBufferFlushPosition)
80  {
81  // Reset flush position
82  myOutputBufferFlushPosition = 0;
83  myOutputBufferUsedSize = 0;
84 
85  // Read the blosc header
86  if (bios::read(src, myInputBuffer, BLOSC_MIN_HEADER_LENGTH) == -1)
87  {
88  return -1;
89  }
90 
91  // Retrieve metadata about the current blosc block
92  size_t uncompressedSize;
93  size_t compressedSize;
94  size_t blockSize;
95  blosc_cbuffer_sizes(myInputBuffer, &uncompressedSize, &compressedSize,
96  &blockSize);
97 
98  // Make sure buffer is big enough to hold all we are going to read
99  if (myInputBufferSize < BLOSC_MIN_HEADER_LENGTH + compressedSize)
100  {
101  char* oldBuffer = myInputBuffer;
102  myInputBuffer = new char[blockSize + BLOSC_MAX_OVERHEAD];
103  memcpy(myInputBuffer, oldBuffer, BLOSC_MIN_HEADER_LENGTH);
104  delete oldBuffer;
105  myInputBufferSize = blockSize + BLOSC_MAX_OVERHEAD;
106  }
107 
108  // Make sure output buffer is big enough for all possible output data
109  if (myOutputBufferSize < uncompressedSize)
110  {
111  if (myOutputBuffer)
112  {
113  delete myOutputBuffer;
114  }
115  myOutputBuffer = new char[uncompressedSize];
116  myOutputBufferSize = uncompressedSize;
117  }
118 
119  // Read compressed chunk into input buffer
120  bios::read(src, myInputBuffer + BLOSC_MIN_HEADER_LENGTH,
121  compressedSize - BLOSC_MIN_HEADER_LENGTH);
122 
123  // Uncompress chunk into destination buffer
124  int finalBlocksize = blosc_decompress(myInputBuffer, myOutputBuffer,
125  myOutputBufferSize);
126 
127  // Error check
128  if (finalBlocksize <= 0)
129  {
130  std::cerr << "Unable to decompress block." << std::endl;
131  std::cerr << "Compressed Size: " << compressedSize << std::endl;
132  std::cerr << "Uncompressed Size: " << uncompressedSize << std::endl;
133  std::cerr << "Block Size: " << blockSize << std::endl;
134  std::cerr << "Error Code: " << finalBlocksize << std::endl;
135  return -1;
136  }
137 
138  // Add block size to ammount in output buffer
139  myOutputBufferUsedSize += finalBlocksize;
140  }
141  // Flush output if available
142  size_t ammountToFlush = std::min((size_t) (destinationSize),
143  myOutputBufferUsedSize - myOutputBufferFlushPosition);
144  memcpy(destinationBuffer, myOutputBuffer + myOutputBufferFlushPosition,
145  ammountToFlush);
146  myOutputBufferFlushPosition += ammountToFlush;
147  // Return how many bytes we wrote to destination
148  return ammountToFlush;
149 }
150 
151 #endif
152 
153 #endif /* UT_BLOSCDECOMPRESSIONFILTER_H_ */
#define BLOSC_MIN_HEADER_LENGTH
Definition: blosc.h:34
BLOSC_EXPORT void blosc_cbuffer_sizes(const void *cbuffer, size_t *nbytes, size_t *cbytes, size_t *blocksize)
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
void close() override
void read(T &in, bool &v)
Definition: ImfXdr.h:502
BLOSC_EXPORT int blosc_decompress(const void *src, void *dest, size_t destsize)
#define BLOSC_MAX_OVERHEAD
Definition: blosc.h:39
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_14 uint8_t blockSize(VULKAN_HPP_NAMESPACE::Format format)
GLenum src
Definition: glcorearb.h:1793