Field3D
DenseFieldIO.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
42 //----------------------------------------------------------------------------//
43 
44 #include "DenseFieldIO.h"
45 
46 //----------------------------------------------------------------------------//
47 
48 using namespace boost;
49 using namespace std;
50 
51 //----------------------------------------------------------------------------//
52 
54 
55 //----------------------------------------------------------------------------//
56 // Field3D namespaces
57 //----------------------------------------------------------------------------//
58 
59 using namespace Exc;
60 using namespace Hdf5Util;
61 
62 //----------------------------------------------------------------------------//
63 // Static members
64 //----------------------------------------------------------------------------//
65 
67 const std::string DenseFieldIO::k_versionAttrName("version");
68 const std::string DenseFieldIO::k_extentsStr("extents");
69 const std::string DenseFieldIO::k_dataWindowStr("data_window");
70 const std::string DenseFieldIO::k_componentsStr("components");
71 const std::string DenseFieldIO::k_dataStr("data");
72 
73 //----------------------------------------------------------------------------//
74 
76 DenseFieldIO::read(hid_t layerGroup, const std::string &/*filename*/,
77  const std::string &/*layerPath*/,
78  DataTypeEnum typeEnum)
79 {
80  Box3i extents, dataW;
81  int components;
82  hsize_t dims[1];
83 
84  if (layerGroup == -1)
85  throw BadHdf5IdException("Bad layer group in DenseFieldIO::read");
86 
87  int version;
88  if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
89  throw MissingAttributeException("Couldn't find attribute " +
90  k_versionAttrName);
91 
92  if (version != k_versionNumber)
93  throw UnsupportedVersionException("DenseField version not supported: " +
94  lexical_cast<std::string>(version));
95 
96  if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
97  throw MissingAttributeException("Couldn't find attribute " +
98  k_extentsStr);
99 
100  if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
101  throw MissingAttributeException("Couldn't find attribute " +
102  k_dataWindowStr);
103 
104  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
105  throw MissingAttributeException("Couldn't find attribute " +
106  k_componentsStr);
107 
108  H5ScopedDopen dataSet(layerGroup, k_dataStr, H5P_DEFAULT);
109 
110  if (dataSet.id() < 0)
111  throw OpenDataSetException("Couldn't open data set: " + k_dataStr);
112 
113  H5ScopedDget_space dataSpace(dataSet.id());
114  H5ScopedDget_type dataType(dataSet.id());
115  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
116 
117  if (dataSpace.id() < 0)
118  throw GetDataSpaceException("Couldn't get data space");
119 
120  if (dataType.id() < 0)
121  throw GetDataTypeException("Couldn't get data type");
122 
123  // Double-check that the sizes match ---
124 
125  V3i size(dataW.size() + V3i(1));
126  int calculatedTotal = size.x * size.y * size.z;
127  int reportedSize = dims[0] / components;
128 
129  if (calculatedTotal != reportedSize)
130  throw FileIntegrityException("Data size doesn't match number of voxels");
131 
132  // Build a DenseField to store everything in
133  FieldBase::Ptr result;
134 
135  // Read the data ---
136 
137  bool isHalf, isFloat, isDouble;
138  isHalf = H5Tequal(dataType, H5T_NATIVE_SHORT);
139  isFloat = H5Tequal(dataType, H5T_NATIVE_FLOAT);
140  isDouble = H5Tequal(dataType, H5T_NATIVE_DOUBLE);
141 
142  if (isHalf && components == 1 && typeEnum == DataTypeHalf)
143  result = readData<half>(dataSet.id(), extents, dataW);
144  if (isFloat && components == 1 && typeEnum == DataTypeFloat)
145  result = readData<float>(dataSet.id(), extents, dataW);
146  if (isDouble && components == 1 && typeEnum == DataTypeDouble)
147  result = readData<double>(dataSet.id(), extents, dataW);
148  if (isHalf && components == 3 && typeEnum == DataTypeVecHalf)
149  result = readData<V3h>(dataSet.id(), extents, dataW);
150  if (isFloat && components == 3 && typeEnum == DataTypeVecFloat)
151  result = readData<V3f>(dataSet.id(), extents, dataW);
152  if (isDouble && components == 3 && typeEnum == DataTypeVecDouble)
153  result = readData<V3d>(dataSet.id(), extents, dataW);
154 
155  return result;
156 }
157 
158 //----------------------------------------------------------------------------//
159 
160 bool
161 DenseFieldIO::write(hid_t layerGroup, FieldBase::Ptr field)
162 {
163  if (layerGroup == -1)
164  throw BadHdf5IdException("Bad layer group in DenseFieldIO::write");
165 
166  // Add version attribute
167  if (!writeAttribute(layerGroup, k_versionAttrName,
168  1, k_versionNumber))
169  throw WriteAttributeException("Couldn't write attribute " +
170  k_versionAttrName);
171 
172  DenseField<half>::Ptr halfField =
174  DenseField<float>::Ptr floatField =
176  DenseField<double>::Ptr doubleField =
178  DenseField<V3h>::Ptr vecHalfField =
180  DenseField<V3f>::Ptr vecFloatField =
182  DenseField<V3d>::Ptr vecDoubleField =
184 
185  bool success = true;
186 
187  if (floatField) {
188  success = writeInternal<float>(layerGroup, floatField);
189  }
190  else if (halfField) {
191  success = writeInternal<half>(layerGroup, halfField);
192  }
193  else if (doubleField) {
194  success = writeInternal<double>(layerGroup, doubleField);
195  }
196  else if (vecFloatField) {
197  success = writeInternal<V3f>(layerGroup, vecFloatField);
198  }
199  else if (vecHalfField) {
200  success = writeInternal<V3h>(layerGroup, vecHalfField);
201  }
202  else if (vecDoubleField) {
203  success = writeInternal<V3d>(layerGroup, vecDoubleField);
204  }
205  else {
206  throw WriteLayerException("DenseFieldIO does not support the given "
207  "DenseField template parameter");
208  }
209 
210  return success;
211 }
212 
213 //----------------------------------------------------------------------------//
214 
216 
217 //----------------------------------------------------------------------------//
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:82
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition: RefCount.h:224
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:381
static const std::string k_versionAttrName
Definition: DenseFieldIO.h:151
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
static const std::string k_dataWindowStr
Definition: DenseFieldIO.h:153
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:325
static const int k_versionNumber
Definition: DenseFieldIO.h:150
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
static const std::string k_extentsStr
Definition: DenseFieldIO.h:152
Imath::V3i V3i
Definition: SpiMathLib.h:71
Contains the DenseFieldIO class.
static const std::string k_dataStr
Definition: DenseFieldIO.h:155
bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
static const std::string k_componentsStr
Definition: DenseFieldIO.h:154
bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, const std::string &layerPath, DataTypeEnum typeEnum)
Reads the field at the given location and tries to create a DenseField object from it...
boost::intrusive_ptr< DenseField > Ptr
Definition: DenseField.h:89
DataTypeEnum
Definition: Traits.h:66
virtual bool write(hid_t layerGroup, FieldBase::Ptr field)
Writes the given field to disk. This function calls out to writeInternal once the template type has b...
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:353
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:90
#define FIELD3D_NAMESPACE_OPEN
Definition: ns.h:56