OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimH5ImageDataset.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description: OSSIM HDF5 Image DataSet.
10 //
11 //----------------------------------------------------------------------------
12 // $Id
13 
14 #include "ossimH5ImageDataset.h"
15 #include "ossimH5Util.h"
16 #include <ossim/base/ossimCommon.h>
17 #include <ossim/base/ossimEndian.h>
18 #include <ossim/base/ossimIpt.h>
19 #include <ossim/base/ossimIrect.h>
20 #include <ossim/base/ossimNotify.h>
22 
23 //---
24 // This includes everything! Note the H5 includes are order dependent; hence,
25 // the mongo include.
26 //---
27 #include <hdf5.h>
28 #include <H5Cpp.h>
29 
30 #include <iostream>
31 using namespace std;
32 
34  :
35  m_dataset(0),
36  m_datasetName(),
37  m_scalar(OSSIM_SCALAR_UNKNOWN),
38  m_bands(1),
39  m_lines(0),
40  m_samples(0),
41  m_validRect(),
42  m_endian(0)
43 {
44 }
45 
47  :
48  m_dataset( ( (obj.m_dataset)?new H5::DataSet(*(obj.m_dataset)):0 ) ),
49  m_datasetName(obj.m_datasetName),
50  m_scalar(obj.m_scalar),
51  m_bands(obj.m_bands),
52  m_lines(obj.m_lines),
53  m_samples(obj.m_samples),
54  m_validRect(obj.m_validRect),
55  m_endian( obj.m_endian ? new ossimEndian() : 0 )
56 {
57  if ( obj.m_dataset )
58  {
59  m_dataset = new H5::DataSet( *(obj.m_dataset) );
60  }
61 }
62 
64 {
65  close();
66 }
67 
69 {
70  if ( this != &rhs )
71  {
72  if ( m_dataset )
73  {
74  delete m_dataset;
75  }
76  if ( rhs.m_dataset )
77  {
78  m_dataset = new H5::DataSet( *(rhs.m_dataset) );
79  }
80  else
81  {
82  m_dataset = 0;
83  }
85  m_scalar = rhs.m_scalar;
86  m_bands = rhs.m_bands;
87  m_lines = rhs.m_lines;
88  m_samples = rhs.m_samples;
90  m_endian = ( rhs.m_endian ? new ossimEndian() : 0 );
91  }
92  return *this;
93 }
94 
95 bool ossimH5ImageDataset::initialize( const H5::DataSet& dataset,
96  const std::string& datasetName )
97 {
98  bool result = false;
99 
100  // Clear old stuff.
101  close();
102 
103  m_dataset = new H5::DataSet( dataset );
104  m_datasetName = datasetName;
105 
107  {
108  // Get the extents:
109  std::vector<ossim_uint32> extents;
110  ossim_hdf5::getExtents( m_dataset, extents );
111  if ( extents.size() >= 2 )
112  {
113  m_samples = extents[1];
114  m_lines = extents[0];
115  if ( extents.size() >= 3 )
116  {
117  m_bands = extents[2];
118  }
119  else
120  {
121  m_bands = 1;
122  }
123 
124  // Scalar type:
126 
128  {
129  result = true;
130 
131  // Byte swapping logic:
132  if ( ( ossim::scalarSizeInBytes( m_scalar ) > 1 ) &&
134  {
135  m_endian = new ossimEndian();
136  }
137  }
138  }
139  }
140 
141  if ( !result )
142  {
143  // One dimensional dataset:
144  close();
145  }
146 
147  return result;
148 
149 } // End: ossimH5ImageDataset::initialize
150 
152 {
153  if ( m_dataset )
154  {
155  m_dataset->close();
156  delete m_dataset;
157  m_dataset = 0;
158  }
159  if ( m_endian )
160  {
161  delete m_endian;
162  m_endian = 0;
163  }
164 }
165 
166 const H5::DataSet* ossimH5ImageDataset::getDataset() const
167 {
168  return m_dataset;
169 }
170 
172 {
173  return m_dataset;
174 }
175 
176 const std::string& ossimH5ImageDataset::getName() const
177 {
178  return m_datasetName;
179 }
180 
182 {
183  return m_scalar;
184 }
185 
187 {
188  return m_bands;
189 }
190 
192 {
193  return m_validRect.height();
194 }
195 
197 {
198  return m_validRect.width();
199 }
200 
202 {
203  return (m_endian ? true: false);
204 }
205 
207 {
208  return m_validRect.ul();
209 }
210 
212 {
213  return m_validRect;
214 }
215 
216 void ossimH5ImageDataset::getTileBuf(void* buffer, const ossimIrect& rect, ossim_uint32 band)
217 {
218  static const char MODULE[] = "ossimH5ImageDataset::getTileBuf";
219 
220  if ( m_dataset )
221  {
222  try
223  {
224  // Shift rectangle by the sub image offse (if any) from the m_validRect.
225  ossimIrect irect = rect + m_validRect.ul();
226 
227  //--
228  // Turn off the auto-printing when failure occurs so that we can
229  // handle the errors appropriately
230  //---
231  // H5::Exception::dontPrint();
232 
233  // NOTE: rank == array dimensions in hdf5 documentation lingo.
234 
235  // Get dataspace of the dataset.
236  H5::DataSpace imageDataSpace = m_dataset->getSpace();
237 
238  // Number of dimensions of the input dataspace.:
239  const ossim_int32 IN_DIM_COUNT = imageDataSpace.getSimpleExtentNdims();
240 
241  // Native type:
242  H5::DataType dataType = m_dataset->getDataType();
243 
244  std::vector<hsize_t> inputCount(IN_DIM_COUNT);
245  std::vector<hsize_t> inputOffset(IN_DIM_COUNT);
246 
247  if ( IN_DIM_COUNT == 2 )
248  {
249  inputOffset[0] = irect.ul().y;
250  inputOffset[1] = irect.ul().x;
251 
252  inputCount[0] = irect.height();
253  inputCount[1] = irect.width();
254  }
255  else
256  {
257  inputOffset[0] = band;
258  inputOffset[1] = irect.ul().y;
259  inputOffset[2] = irect.ul().x;
260 
261  inputCount[0] = 1;
262  inputCount[1] = irect.height();
263  inputCount[2] = irect.width();
264  }
265 
266  // Define hyperslab in the dataset; implicitly giving strike strike and block NULL.
267  imageDataSpace.selectHyperslab( H5S_SELECT_SET,
268  &inputCount.front(),
269  &inputOffset.front() );
270 
271  // Output dataspace dimensions.
272  const ossim_int32 OUT_DIM_COUNT = 3;
273  std::vector<hsize_t> outputCount(OUT_DIM_COUNT);
274  outputCount[0] = 1; // single band
275  outputCount[1] = irect.height(); // lines
276  outputCount[2] = irect.width(); // samples
277 
278  // Output dataspace offset.
279  std::vector<hsize_t> outputOffset(OUT_DIM_COUNT);
280  outputOffset[0] = 0;
281  outputOffset[1] = 0;
282  outputOffset[2] = 0;
283 
284  // Output dataspace.
285  H5::DataSpace bufferDataSpace( OUT_DIM_COUNT, &outputCount.front());
286  bufferDataSpace.selectHyperslab( H5S_SELECT_SET,
287  &outputCount.front(),
288  &outputOffset.front() );
289 
290  // Read data from file into the buffer.
291  m_dataset->read( buffer, dataType, bufferDataSpace, imageDataSpace );
292 
293  if ( m_endian )
294  {
295  // If the m_endian pointer is initialized(not zero) swap the bytes.
296  m_endian->swap( m_scalar, buffer, irect.area() );
297  }
298 
299  // Cleanup:
300  bufferDataSpace.close();
301  dataType.close();
302  imageDataSpace.close();
303 
304  // memSpace.close();
305  // dataType.close();
306  // dataSpace.close();
307  }
308  catch( const H5::FileIException& error )
309  {
311  << MODULE << " caught H5::FileIException!" << std::endl;
312  error.printError();
313  }
314 
315  // catch failure caused by the DataSet operations
316  catch( const H5::DataSetIException& error )
317  {
319  << MODULE << " caught H5::DataSetIException!" << std::endl;
320  error.printError();
321  }
322 
323  // catch failure caused by the DataSpace operations
324  catch( const H5::DataSpaceIException& error )
325  {
327  << MODULE << " caught H5::DataSpaceIException!" << std::endl;
328  error.printError();
329  }
330 
331  // catch failure caused by the DataSpace operations
332  catch( const H5::DataTypeIException& error )
333  {
335  << MODULE << " caught H5::DataTypeIException!" << std::endl;
336  error.printError();
337  }
338  catch( ... )
339  {
341  << MODULE << " caught unknown exception !" << std::endl;
342  }
343 
344  } // Matches: if ( m_dataset )
345 
346 } // End: ossimH5ImageDataset::getTileBuf
347 
348 
350 {
351  out << "ossimH5ImageDataset: "
352  << "\nH5::DataSet::id: " << (m_dataset?m_dataset->getId():0)
353  << "\nname: " << m_datasetName
354  << "\nscalar: " << ossimScalarTypeLut::instance()->getEntryString( m_scalar )
355  << "\nbands: " << m_bands
356  << "\nlines: " << m_lines
357  << "\nsamples: " << m_samples
358  << "\nvalid rect: " << m_validRect
359  << "\nswap_flage: " << (m_endian?"true":"false")
360  << std::endl;
361  return out;
362 }
363 
365 {
366  return obj.print( out );
367 }
368 
ossimScalarType m_scalar
void close()
Calls H5::DataSet::close then deletes data set.
const ossimH5ImageDataset & operator=(const ossimH5ImageDataset &rhs)
ossimH5ImageDataset()
default constructor
virtual ossimString getEntryString(ossim_int32 entry_number) const
ossim_uint32 height() const
Definition: ossimIrect.h:487
ossimScalarType getScalarType(const H5::DataSet *dataset)
void getTileBuf(void *buffer, const ossimIrect &rect, ossim_uint32 band)
Method to grab a tile(rectangle) from image.
const ossimIpt & ul() const
Definition: ossimIrect.h:274
OSSIM_DLL ossimByteOrder byteOrder()
Definition: ossimCommon.cpp:54
ossim_uint32 getNumberOfLines() const
const H5::DataSet * getDataset() const
Get const pointer to dataset.
static ossimScalarTypeLut * instance()
Returns the static instance of an ossimScalarTypeLut object.
std::ostream & operator<<(std::ostream &out, const ossimH5ImageDataset &obj)
ossim_uint32 getNumberOfBands() const
std::ostream & print(std::ostream &out) const
print method.
unsigned int ossim_uint32
OSSIM_DLL ossim_uint32 scalarSizeInBytes(ossimScalarType scalarType)
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimByteOrder getByteOrder(const H5::AbstractDs *dataset)
ossimScalarType
ossimScalarType getScalarType() const
bool getValidBoundingRect(H5::DataSet &dataset, const std::string &name, ossimIrect &rect)
Gets the valid bounding rect of the dataset excluding nulls on front and back.
ossim_int32 y
Definition: ossimIpt.h:142
ossim_uint32 getNumberOfSamples() const
void getExtents(const H5::DataSet *dataset, std::vector< ossim_uint32 > &extents)
const ossimIpt & getSubImageOffset() const
ossim_uint32 area() const
Definition: ossimIrect.h:396
~ossimH5ImageDataset()
destructor
const ossimIrect & getValidImageRect() const
ossim_int32 x
Definition: ossimIpt.h:141
Class encapsulates a HDF5 Data set that can be loaded as an image.
bool initialize(const H5::DataSet &dataset, const std::string &datasetName)
Opens datasetName and initializes all data members on success.
const std::string & getName() const
void swap(ossim_sint8 &)
Definition: ossimEndian.h:26
ossimIrect m_validRect
Zero based image rect:
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32