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_bitsPerComponentStr("bits_per_component");
72 const std::string DenseFieldIO::k_dataStr("data");
73 
74 //----------------------------------------------------------------------------//
75 
77 DenseFieldIO::read(hid_t layerGroup, const std::string &/*filename*/,
78  const std::string &/*layerPath*/,
79  DataTypeEnum typeEnum)
80 {
81  Box3i extents, dataW;
82  int components;
83  hsize_t dims[1];
84 
85  if (layerGroup == -1)
86  throw BadHdf5IdException("Bad layer group in DenseFieldIO::read");
87 
88  int version;
89  if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
90  throw MissingAttributeException("Couldn't find attribute " +
91  k_versionAttrName);
92 
93  if (version != k_versionNumber)
94  throw UnsupportedVersionException("DenseField version not supported: " +
95  lexical_cast<std::string>(version));
96 
97  if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
98  throw MissingAttributeException("Couldn't find attribute " +
99  k_extentsStr);
100 
101  if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
102  throw MissingAttributeException("Couldn't find attribute " +
103  k_dataWindowStr);
104 
105  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
106  throw MissingAttributeException("Couldn't find attribute " +
107  k_componentsStr);
108 
109  H5ScopedDopen dataSet(layerGroup, k_dataStr, H5P_DEFAULT);
110 
111  if (dataSet.id() < 0)
112  throw OpenDataSetException("Couldn't open data set: " + k_dataStr);
113 
114  H5ScopedDget_space dataSpace(dataSet.id());
115  H5ScopedDget_type dataType(dataSet.id());
116  H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
117 
118  if (dataSpace.id() < 0)
119  throw GetDataSpaceException("Couldn't get data space");
120 
121  if (dataType.id() < 0)
122  throw GetDataTypeException("Couldn't get data type");
123 
124  // Double-check that the sizes match ---
125 
126  V3i size(dataW.size() + V3i(1));
127  int calculatedTotal = size.x * size.y * size.z;
128  int reportedSize = dims[0] / components;
129 
130  if (calculatedTotal != reportedSize)
131  throw FileIntegrityException("Data size doesn't match number of voxels");
132 
133  // Build a DenseField to store everything in
134  FieldBase::Ptr result;
135 
136  // Read the data ---
137 
138  bool isHalf, isFloat, isDouble;
139  isHalf = H5Tequal(dataType, H5T_NATIVE_SHORT);
140  isFloat = H5Tequal(dataType, H5T_NATIVE_FLOAT);
141  isDouble = H5Tequal(dataType, H5T_NATIVE_DOUBLE);
142 
143  if (isHalf && components == 1 && typeEnum == DataTypeHalf)
144  result = readData<half>(dataSet.id(), extents, dataW);
145  if (isFloat && components == 1 && typeEnum == DataTypeFloat)
146  result = readData<float>(dataSet.id(), extents, dataW);
147  if (isDouble && components == 1 && typeEnum == DataTypeDouble)
148  result = readData<double>(dataSet.id(), extents, dataW);
149  if (isHalf && components == 3 && typeEnum == DataTypeVecHalf)
150  result = readData<V3h>(dataSet.id(), extents, dataW);
151  if (isFloat && components == 3 && typeEnum == DataTypeVecFloat)
152  result = readData<V3f>(dataSet.id(), extents, dataW);
153  if (isDouble && components == 3 && typeEnum == DataTypeVecDouble)
154  result = readData<V3d>(dataSet.id(), extents, dataW);
155 
156  return result;
157 }
158 
159 //----------------------------------------------------------------------------//
160 
161 bool
162 DenseFieldIO::write(hid_t layerGroup, FieldBase::Ptr field)
163 {
164  if (layerGroup == -1)
165  throw BadHdf5IdException("Bad layer group in DenseFieldIO::write");
166 
167  // Add version attribute
168  if (!writeAttribute(layerGroup, k_versionAttrName,
169  1, k_versionNumber))
170  throw WriteAttributeException("Couldn't write attribute " +
171  k_versionAttrName);
172 
173  DenseField<half>::Ptr halfField =
175  DenseField<float>::Ptr floatField =
177  DenseField<double>::Ptr doubleField =
179  DenseField<V3h>::Ptr vecHalfField =
181  DenseField<V3f>::Ptr vecFloatField =
183  DenseField<V3d>::Ptr vecDoubleField =
185 
186  bool success = true;
187 
188  if (floatField) {
189  success = writeInternal<float>(layerGroup, floatField);
190  }
191  else if (halfField) {
192  success = writeInternal<half>(layerGroup, halfField);
193  }
194  else if (doubleField) {
195  success = writeInternal<double>(layerGroup, doubleField);
196  }
197  else if (vecFloatField) {
198  success = writeInternal<V3f>(layerGroup, vecFloatField);
199  }
200  else if (vecHalfField) {
201  success = writeInternal<V3h>(layerGroup, vecHalfField);
202  }
203  else if (vecDoubleField) {
204  success = writeInternal<V3d>(layerGroup, vecDoubleField);
205  }
206  else {
207  throw WriteLayerException("DenseFieldIO does not support the given "
208  "DenseField template parameter");
209  }
210 
211  return success;
212 }
213 
214 //----------------------------------------------------------------------------//
215 
217 
218 //----------------------------------------------------------------------------//
This subclass of Field stores data in a contiguous std::vector.
Definition: DenseField.h:85
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:256
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
Scoped object - opens a dataset on creation and closes it on destruction.
Definition: Hdf5Util.h:416
static const std::string k_versionAttrName
Definition: DenseFieldIO.h:151
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
Namespace for Exception objects.
Definition: Exception.h:57
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:356
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
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_bitsPerComponentStr
Definition: DenseFieldIO.h:155
static const std::string k_dataStr
Definition: DenseFieldIO.h:156
static const std::string k_componentsStr
Definition: DenseFieldIO.h:154
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:92
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:386
hid_t id() const
Query the hid_t value.
Definition: Hdf5Util.h:100