Field3D
DenseFieldIO.cpp
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------//
00002 
00003 /*
00004  * Copyright (c) 2009 Sony Pictures Imageworks Inc
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the
00017  * distribution.  Neither the name of Sony Pictures Imageworks nor the
00018  * names of its contributors may be used to endorse or promote
00019  * products derived from this software without specific prior written
00020  * permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00031  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033  * OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 //----------------------------------------------------------------------------//
00037 
00042 //----------------------------------------------------------------------------//
00043 
00044 #include "DenseFieldIO.h"
00045 
00046 //----------------------------------------------------------------------------//
00047 
00048 using namespace boost;
00049 using namespace std;
00050 
00051 //----------------------------------------------------------------------------//
00052 
00053 FIELD3D_NAMESPACE_OPEN
00054 
00055 //----------------------------------------------------------------------------//
00056 // Field3D namespaces
00057 //----------------------------------------------------------------------------//
00058 
00059 using namespace Exc;
00060 using namespace Hdf5Util;
00061 
00062 //----------------------------------------------------------------------------//
00063 // Static members
00064 //----------------------------------------------------------------------------//
00065 
00066 const int         DenseFieldIO::k_versionNumber(1);
00067 const std::string DenseFieldIO::k_versionAttrName("version");
00068 const std::string DenseFieldIO::k_extentsStr("extents");
00069 const std::string DenseFieldIO::k_dataWindowStr("data_window");
00070 const std::string DenseFieldIO::k_componentsStr("components");
00071 const std::string DenseFieldIO::k_dataStr("data");
00072 
00073 //----------------------------------------------------------------------------//
00074 
00075 FieldBase::Ptr
00076 DenseFieldIO::read(hid_t layerGroup, const std::string &/*filename*/, 
00077                    const std::string &/*layerPath*/,
00078                    DataTypeEnum typeEnum)
00079 {
00080   Box3i extents, dataW;
00081   int components;
00082   hsize_t dims[1];
00083   
00084   if (layerGroup == -1)
00085     throw BadHdf5IdException("Bad layer group in DenseFieldIO::read");
00086 
00087   int version;
00088   if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
00089     throw MissingAttributeException("Couldn't find attribute " + 
00090                                     k_versionAttrName);
00091 
00092   if (version != k_versionNumber)
00093     throw UnsupportedVersionException("DenseField version not supported: " + 
00094                                       lexical_cast<std::string>(version));
00095 
00096   if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x)) 
00097     throw MissingAttributeException("Couldn't find attribute " + 
00098                                     k_extentsStr);
00099 
00100   if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x)) 
00101     throw MissingAttributeException("Couldn't find attribute " + 
00102                                     k_dataWindowStr);
00103   
00104   if (!readAttribute(layerGroup, k_componentsStr, 1, components)) 
00105     throw MissingAttributeException("Couldn't find attribute " + 
00106                                     k_componentsStr);
00107 
00108   H5ScopedDopen dataSet(layerGroup, k_dataStr, H5P_DEFAULT);
00109 
00110   if (dataSet.id() < 0) 
00111     throw OpenDataSetException("Couldn't open data set: " + k_dataStr);
00112 
00113   H5ScopedDget_space dataSpace(dataSet.id());
00114   H5ScopedDget_type dataType(dataSet.id());
00115   H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL);
00116 
00117   if (dataSpace.id() < 0) 
00118     throw GetDataSpaceException("Couldn't get data space");
00119 
00120   if (dataType.id() < 0)
00121     throw GetDataTypeException("Couldn't get data type");
00122 
00123   // Double-check that the sizes match ---
00124 
00125   V3i size(dataW.size() + V3i(1));
00126   int calculatedTotal = size.x * size.y * size.z;
00127   int reportedSize = dims[0] / components;
00128 
00129   if (calculatedTotal != reportedSize) 
00130     throw FileIntegrityException("Data size doesn't match number of voxels");
00131 
00132   // Build a DenseField to store everything in
00133   FieldBase::Ptr result;
00134 
00135   // Read the data ---
00136 
00137   bool isHalf, isFloat, isDouble;
00138   isHalf = H5Tequal(dataType, H5T_NATIVE_SHORT);
00139   isFloat = H5Tequal(dataType, H5T_NATIVE_FLOAT);
00140   isDouble = H5Tequal(dataType, H5T_NATIVE_DOUBLE);
00141 
00142   if (isHalf && components == 1 && typeEnum == DataTypeHalf)
00143     result = readData<half>(dataSet.id(), extents, dataW);
00144   if (isFloat && components == 1 && typeEnum == DataTypeFloat)
00145     result = readData<float>(dataSet.id(), extents, dataW);
00146   if (isDouble && components == 1 && typeEnum == DataTypeDouble)
00147     result = readData<double>(dataSet.id(), extents, dataW);
00148   if (isHalf && components == 3 && typeEnum == DataTypeVecHalf)
00149     result = readData<V3h>(dataSet.id(), extents, dataW);
00150   if (isFloat && components == 3 && typeEnum == DataTypeVecFloat)
00151     result = readData<V3f>(dataSet.id(), extents, dataW);
00152   if (isDouble && components == 3 && typeEnum == DataTypeVecDouble)
00153     result = readData<V3d>(dataSet.id(), extents, dataW);
00154 
00155   return result;
00156 }
00157 
00158 //----------------------------------------------------------------------------//
00159 
00160 bool
00161 DenseFieldIO::write(hid_t layerGroup, FieldBase::Ptr field)
00162 {
00163   if (layerGroup == -1)
00164     throw BadHdf5IdException("Bad layer group in DenseFieldIO::write");
00165 
00166   // Add version attribute
00167   if (!writeAttribute(layerGroup, k_versionAttrName, 
00168                     1, k_versionNumber))
00169     throw WriteAttributeException("Couldn't write attribute " + 
00170                                   k_versionAttrName);
00171 
00172   DenseField<half>::Ptr halfField = 
00173     field_dynamic_cast<DenseField<half> >(field);
00174   DenseField<float>::Ptr floatField = 
00175     field_dynamic_cast<DenseField<float> >(field);
00176   DenseField<double>::Ptr doubleField = 
00177     field_dynamic_cast<DenseField<double> >(field);
00178   DenseField<V3h>::Ptr vecHalfField = 
00179     field_dynamic_cast<DenseField<V3h> >(field);
00180   DenseField<V3f>::Ptr vecFloatField = 
00181     field_dynamic_cast<DenseField<V3f> >(field);
00182   DenseField<V3d>::Ptr vecDoubleField = 
00183     field_dynamic_cast<DenseField<V3d> >(field);
00184 
00185   bool success = true;
00186 
00187   if (floatField) {
00188     success = writeInternal<float>(layerGroup, floatField);
00189   }
00190   else if (halfField) {
00191     success = writeInternal<half>(layerGroup, halfField);
00192   }
00193   else if (doubleField) {
00194     success = writeInternal<double>(layerGroup, doubleField);
00195   }
00196   else if (vecFloatField) {
00197     success = writeInternal<V3f>(layerGroup, vecFloatField);
00198   }
00199   else if (vecHalfField) {
00200     success = writeInternal<V3h>(layerGroup, vecHalfField);
00201   }
00202   else if (vecDoubleField) {
00203     success = writeInternal<V3d>(layerGroup, vecDoubleField);
00204   }
00205   else {
00206     throw WriteLayerException("DenseFieldIO does not support the given "
00207                               "DenseField template parameter");
00208   }
00209 
00210   return success;
00211 }
00212 
00213 //----------------------------------------------------------------------------//
00214 
00215 FIELD3D_NAMESPACE_SOURCE_CLOSE
00216 
00217 //----------------------------------------------------------------------------//