Field3D
MIPFieldIO.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 "MIPFieldIO.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 member initialization
64 //----------------------------------------------------------------------------//
65 
66 const int MIPFieldIO::k_versionNumber (1);
67 const std::string MIPFieldIO::k_versionAttrName ("version");
68 const std::string MIPFieldIO::k_extentsStr ("extents");
69 const std::string MIPFieldIO::k_extentsMinStr ("extents_min");
70 const std::string MIPFieldIO::k_extentsMaxStr ("extents_max");
71 const std::string MIPFieldIO::k_dataWindowStr ("data_window");
72 const std::string MIPFieldIO::k_dataWindowMinStr ("data_window_min");
73 const std::string MIPFieldIO::k_dataWindowMaxStr ("data_window_max");
74 const std::string MIPFieldIO::k_componentsStr ("components");
75 const std::string MIPFieldIO::k_bitsPerComponentStr("bits_per_component");
76 const std::string MIPFieldIO::k_mipGroupStr ("mip_levels");
77 const std::string MIPFieldIO::k_levelGroupStr ("level");
78 const std::string MIPFieldIO::k_levelsStr ("levels");
79 const std::string MIPFieldIO::k_baseTypeStr ("base_type");
80 const std::string MIPFieldIO::k_dummyDataStr ("dummy_data");
81 
82 //----------------------------------------------------------------------------//
83 // MIPFieldIO
84 //----------------------------------------------------------------------------//
85 
87 MIPFieldIO::read(hid_t layerGroup, const std::string &filename,
88  const std::string &layerPath,
89  DataTypeEnum typeEnum)
90 {
91  Box3i extents, dataW;
92  int components;
93 
94  if (layerGroup == -1)
95  throw BadHdf5IdException("Bad layer group in MIPFieldIO::read");
96 
97  int version;
98  if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
99  throw MissingAttributeException("Couldn't find attribute " +
100  k_versionAttrName);
101 
102  if (version != k_versionNumber)
103  throw UnsupportedVersionException("MIPField version not supported: " +
104  lexical_cast<std::string>(version));
105 
106  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
107  throw MissingAttributeException("Couldn't find attribute " +
108  k_componentsStr);
109 
110  // Check data type ---
111 
112  int bits;
113  if (!readAttribute(layerGroup, k_bitsPerComponentStr, 1, bits))
114  throw MissingAttributeException("Couldn't find attribute: " +
115  k_bitsPerComponentStr);
116 
117  std::string baseType;
118  if (!readAttribute(layerGroup, k_baseTypeStr, baseType)) {
119  throw MissingAttributeException("Couldn't find attribute: " +
120  k_baseTypeStr);
121  }
122 
123  bool isHalf = false;
124  bool isFloat = false;
125  bool isDouble = false;
126 
127  switch (bits) {
128  case 16:
129  isHalf = true;
130  break;
131  case 64:
132  isDouble = true;
133  break;
134  case 32:
135  default:
136  isFloat = true;
137  }
138 
139  bool isSparse = false;
140  bool isDense = false;
141 
142  if (baseType == "SparseField") {
143  isSparse = true;
144  } else if (baseType == "DenseField") {
145  isDense = true;
146  }
147 
148  // Read the data ---
149 
150  FieldBase::Ptr result;
151 
152  if (isDense && isHalf && components == 1 && typeEnum == DataTypeHalf)
153  result = readInternal<DenseField, half>(layerGroup, filename,
154  layerPath, typeEnum);
155  if (isDense && isFloat && components == 1 && typeEnum == DataTypeFloat)
156  result = readInternal<DenseField, float>(layerGroup, filename,
157  layerPath, typeEnum);
158  if (isDense && isDouble && components == 1 && typeEnum == DataTypeDouble)
159  result = readInternal<DenseField, double>(layerGroup, filename,
160  layerPath, typeEnum);
161  if (isDense && isHalf && components == 3 && typeEnum == DataTypeVecHalf)
162  result = readInternal<DenseField, V3h>(layerGroup, filename,
163  layerPath, typeEnum);
164  if (isDense && isFloat && components == 3 && typeEnum == DataTypeVecFloat)
165  result = readInternal<DenseField, V3f>(layerGroup, filename,
166  layerPath, typeEnum);
167  if (isDense && isDouble && components == 3 && typeEnum == DataTypeVecDouble)
168  result = readInternal<DenseField, V3d>(layerGroup, filename,
169  layerPath, typeEnum);
170  if (isSparse && isHalf && components == 1 && typeEnum == DataTypeHalf)
171  result = readInternal<SparseField, half>(layerGroup, filename,
172  layerPath, typeEnum);
173  if (isSparse && isFloat && components == 1 && typeEnum == DataTypeFloat)
174  result = readInternal<SparseField, float>(layerGroup, filename,
175  layerPath, typeEnum);
176  if (isSparse && isDouble && components == 1 && typeEnum == DataTypeDouble)
177  result = readInternal<SparseField, double>(layerGroup, filename,
178  layerPath, typeEnum);
179  if (isSparse && isHalf && components == 3 && typeEnum == DataTypeVecHalf)
180  result = readInternal<SparseField, V3h>(layerGroup, filename,
181  layerPath, typeEnum);
182  if (isSparse && isFloat && components == 3 && typeEnum == DataTypeVecFloat)
183  result = readInternal<SparseField, V3f>(layerGroup, filename,
184  layerPath, typeEnum);
185  if (isSparse && isDouble && components == 3 && typeEnum == DataTypeVecDouble)
186  result = readInternal<SparseField, V3d>(layerGroup, filename,
187  layerPath, typeEnum);
188 
189  return result;
190 }
191 
192 //----------------------------------------------------------------------------//
193 
195 MIPFieldIO::read(const OgIGroup &layerGroup, const std::string &filename,
196  const std::string &layerPath, OgDataType typeEnum)
197 {
198  Box3i extents, dataW;
199 
200  if (!layerGroup.isValid()) {
201  Msg::print(Msg::SevWarning, "Bad layerGroup group in "
202  "MIPFieldIO::read(ogawa).");
203  return FieldBase::Ptr();
204  }
205 
206  // Check version ---
207 
208  OgIAttribute<int> versionAttr =
209  layerGroup.findAttribute<int>(k_versionAttrName);
210  if (!versionAttr.isValid()) {
211  throw MissingAttributeException("Couldn't find attribute: " +
212  k_versionAttrName);
213  }
214  const int version = versionAttr.value();
215 
216  if (version != k_versionNumber) {
217  throw UnsupportedVersionException("MIPField version not supported: " +
218  lexical_cast<std::string>(version));
219  }
220 
221  // Get num components ---
222 
223  OgIAttribute<uint8_t> numComponentsAttr =
224  layerGroup.findAttribute<uint8_t>(k_componentsStr);
225  if (!numComponentsAttr.isValid()) {
226  throw MissingAttributeException("Couldn't find attribute " +
227  k_componentsStr);
228  }
229 
230  // Get base type ---
231 
232  OgIAttribute<std::string> baseTypeAttr =
233  layerGroup.findAttribute<std::string>(k_baseTypeStr);
234  if (!baseTypeAttr.isValid()) {
235  throw MissingAttributeException("Couldn't find attribute " +
236  k_baseTypeStr);
237  }
238 
239  bool isSparse = false;
240  bool isDense = false;
241 
242  if (baseTypeAttr.value() == "SparseField") {
243  isSparse = true;
244  } else if (baseTypeAttr.value() == "DenseField") {
245  isDense = true;
246  }
247 
248  // Get the deta type ---
249 
250  OgDataType typeOnDisk = layerGroup.datasetType(k_dummyDataStr);
251 
252  FieldBase::Ptr result;
253 
254  if (typeEnum == typeOnDisk) {
255  if (isDense) {
256  if (typeEnum == F3DFloat16) {
257  result = readInternal<DenseField, float16_t>(layerGroup, filename,
258  layerPath, typeEnum);
259  } else if (typeEnum == F3DFloat32) {
260  result = readInternal<DenseField, float32_t>(layerGroup, filename,
261  layerPath, typeEnum);
262  } else if (typeEnum == F3DFloat64) {
263  result = readInternal<DenseField, float64_t>(layerGroup, filename,
264  layerPath, typeEnum);
265  } else if (typeEnum == F3DVec16) {
266  result = readInternal<DenseField, vec16_t>(layerGroup, filename,
267  layerPath, typeEnum);
268  } else if (typeEnum == F3DVec32) {
269  result = readInternal<DenseField, vec32_t>(layerGroup, filename,
270  layerPath, typeEnum);
271  } else if (typeEnum == F3DVec64) {
272  result = readInternal<DenseField, vec64_t>(layerGroup, filename,
273  layerPath, typeEnum);
274  }
275  } else if (isSparse) {
276  if (typeEnum == F3DFloat16) {
277  result = readInternal<SparseField, float16_t>(layerGroup, filename,
278  layerPath, typeEnum);
279  } else if (typeEnum == F3DFloat32) {
280  result = readInternal<SparseField, float32_t>(layerGroup, filename,
281  layerPath, typeEnum);
282  } else if (typeEnum == F3DFloat64) {
283  result = readInternal<SparseField, float64_t>(layerGroup, filename,
284  layerPath, typeEnum);
285  } else if (typeEnum == F3DVec16) {
286  result = readInternal<SparseField, vec16_t>(layerGroup, filename,
287  layerPath, typeEnum);
288  } else if (typeEnum == F3DVec32) {
289  result = readInternal<SparseField, vec32_t>(layerGroup, filename,
290  layerPath, typeEnum);
291  } else if (typeEnum == F3DVec64) {
292  result = readInternal<SparseField, vec64_t>(layerGroup, filename,
293  layerPath, typeEnum);
294  }
295  }
296  }
297 
298  return result;
299 }
300 
301 //----------------------------------------------------------------------------//
302 
303 bool
304 MIPFieldIO::write(hid_t layerGroup, FieldBase::Ptr field)
305 {
306  if (layerGroup == -1) {
307  throw BadHdf5IdException("Bad layer group in MIPFieldIO::write");
308  }
309 
310  // Add version attribute
311  if (!writeAttribute(layerGroup, k_versionAttrName,
312  1, k_versionNumber)) {
313  throw WriteAttributeException("Couldn't write attribute " +
314  k_versionAttrName);
315  }
316 
317  MIPField<DenseField<half> >::Ptr halfDenseField =
319  MIPField<DenseField<float> >::Ptr floatDenseField =
321  MIPField<DenseField<double> >::Ptr doubleDenseField =
323  MIPField<DenseField<V3h> >::Ptr vecHalfDenseField =
325  MIPField<DenseField<V3f> >::Ptr vecFloatDenseField =
327  MIPField<DenseField<V3d> >::Ptr vecDoubleDenseField =
329  MIPField<SparseField<half> >::Ptr halfSparseField =
331  MIPField<SparseField<float> >::Ptr floatSparseField =
333  MIPField<SparseField<double> >::Ptr doubleSparseField =
335  MIPField<SparseField<V3h> >::Ptr vecHalfSparseField =
337  MIPField<SparseField<V3f> >::Ptr vecFloatSparseField =
339  MIPField<SparseField<V3d> >::Ptr vecDoubleSparseField =
341 
342  bool success = true;
343 
344  if (floatDenseField) {
345  success = writeInternal<DenseField, float>(layerGroup, floatDenseField);
346  }
347  else if (halfDenseField) {
348  success = writeInternal<DenseField, half>(layerGroup, halfDenseField);
349  }
350  else if (doubleDenseField) {
351  success = writeInternal<DenseField, double>(layerGroup, doubleDenseField);
352  }
353  else if (vecFloatDenseField) {
354  success = writeInternal<DenseField, V3f>(layerGroup, vecFloatDenseField);
355  }
356  else if (vecHalfDenseField) {
357  success = writeInternal<DenseField, V3h>(layerGroup, vecHalfDenseField);
358  }
359  else if (vecDoubleDenseField) {
360  success = writeInternal<DenseField, V3d>(layerGroup, vecDoubleDenseField);
361  }
362  else if (floatSparseField) {
363  success = writeInternal<SparseField, float>(layerGroup, floatSparseField);
364  }
365  else if (halfSparseField) {
366  success = writeInternal<SparseField, half>(layerGroup, halfSparseField);
367  }
368  else if (doubleSparseField) {
369  success = writeInternal<SparseField, double>(layerGroup, doubleSparseField);
370  }
371  else if (vecFloatSparseField) {
372  success = writeInternal<SparseField, V3f>(layerGroup, vecFloatSparseField);
373  }
374  else if (vecHalfSparseField) {
375  success = writeInternal<SparseField, V3h>(layerGroup, vecHalfSparseField);
376  }
377  else if (vecDoubleSparseField) {
378  success = writeInternal<SparseField, V3d>(layerGroup, vecDoubleSparseField);
379  }
380  else {
381  throw WriteLayerException("MIPFieldIO does not support the given "
382  "MIPField template parameter");
383  }
384 
385  return success;
386 }
387 
388 //----------------------------------------------------------------------------//
389 
390 bool
391 MIPFieldIO::write(OgOGroup &layerGroup, FieldBase::Ptr field)
392 {
393  // Add version attribute
394  OgOAttribute<int> version(layerGroup, k_versionAttrName, k_versionNumber);
395 
396  MIPField<DenseField<half> >::Ptr halfDenseField =
398  MIPField<DenseField<float> >::Ptr floatDenseField =
400  MIPField<DenseField<double> >::Ptr doubleDenseField =
402  MIPField<DenseField<V3h> >::Ptr vecHalfDenseField =
404  MIPField<DenseField<V3f> >::Ptr vecFloatDenseField =
406  MIPField<DenseField<V3d> >::Ptr vecDoubleDenseField =
408  MIPField<SparseField<half> >::Ptr halfSparseField =
410  MIPField<SparseField<float> >::Ptr floatSparseField =
412  MIPField<SparseField<double> >::Ptr doubleSparseField =
414  MIPField<SparseField<V3h> >::Ptr vecHalfSparseField =
416  MIPField<SparseField<V3f> >::Ptr vecFloatSparseField =
418  MIPField<SparseField<V3d> >::Ptr vecDoubleSparseField =
420 
421  bool success = true;
422 
423  if (floatDenseField) {
424  success = writeInternal<DenseField, float>(layerGroup, floatDenseField);
425  }
426  else if (halfDenseField) {
427  success = writeInternal<DenseField, half>(layerGroup, halfDenseField);
428  }
429  else if (doubleDenseField) {
430  success = writeInternal<DenseField, double>(layerGroup, doubleDenseField);
431  }
432  else if (vecFloatDenseField) {
433  success = writeInternal<DenseField, V3f>(layerGroup, vecFloatDenseField);
434  }
435  else if (vecHalfDenseField) {
436  success = writeInternal<DenseField, V3h>(layerGroup, vecHalfDenseField);
437  }
438  else if (vecDoubleDenseField) {
439  success = writeInternal<DenseField, V3d>(layerGroup, vecDoubleDenseField);
440  }
441  else if (floatSparseField) {
442  success = writeInternal<SparseField, float>(layerGroup, floatSparseField);
443  }
444  else if (halfSparseField) {
445  success = writeInternal<SparseField, half>(layerGroup, halfSparseField);
446  }
447  else if (doubleSparseField) {
448  success = writeInternal<SparseField, double>(layerGroup, doubleSparseField);
449  }
450  else if (vecFloatSparseField) {
451  success = writeInternal<SparseField, V3f>(layerGroup, vecFloatSparseField);
452  }
453  else if (vecHalfSparseField) {
454  success = writeInternal<SparseField, V3h>(layerGroup, vecHalfSparseField);
455  }
456  else if (vecDoubleSparseField) {
457  success = writeInternal<SparseField, V3d>(layerGroup, vecDoubleSparseField);
458  }
459  else {
460  throw WriteLayerException("MIPFieldIO does not support the given "
461  "MIPField template parameter");
462  }
463 
464  return true;
465 }
466 
467 //----------------------------------------------------------------------------//
468 
470 
471 //----------------------------------------------------------------------------//
F3DVec64
Definition: Traits.h:148
F3DFloat64
Definition: Traits.h:143
F3DFloat32
Definition: Traits.h:142
Hdf5Util::writeAttribute
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
F3DFloat16
Definition: Traits.h:141
F3DVec32
Definition: Traits.h:147
Msg::SevWarning
Definition: Log.h:68
OgIAttribute
Definition: OgawaFwd.h:62
DataTypeFloat
Definition: Traits.h:112
DataTypeEnum
DataTypeEnum
Definition: Traits.h:108
OgOAttribute
Definition: OgawaFwd.h:64
FieldBase::Ptr
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
F3DVec16
Definition: Traits.h:146
DataTypeVecHalf
Definition: Traits.h:114
DataTypeHalf
Definition: Traits.h:109
field_dynamic_cast
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
DataTypeVecDouble
Definition: Traits.h:116
FIELD3D_NAMESPACE_SOURCE_CLOSE
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
DataTypeVecFloat
Definition: Traits.h:115
Exc
Namespace for Exception objects.
Definition: Exception.h:57
DataTypeDouble
Definition: Traits.h:113
Hdf5Util::readAttribute
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
Hdf5Util
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
MIPField
This subclass stores a MIP representation of a Field_T field.
Definition: MIPField.h:109
FIELD3D_NAMESPACE_OPEN
Definition: FieldMapping.cpp:74
Box3i
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Msg::print
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity.
Definition: Log.cpp:70
OgDataType
OgDataType
Enumerates the various uses for Ogawa-level groups.
Definition: Traits.h:125