Field3D
|
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 #ifndef _INCLUDED_Field3D_DenseFieldIO_H_ 00045 #define _INCLUDED_Field3D_DenseFieldIO_H_ 00046 00047 //----------------------------------------------------------------------------// 00048 00049 #include <string> 00050 00051 #include <boost/intrusive_ptr.hpp> 00052 00053 #include <hdf5.h> 00054 00055 #include "DenseField.h" 00056 #include "Exception.h" 00057 #include "FieldIO.h" 00058 #include "Field3DFile.h" 00059 #include "Hdf5Util.h" 00060 00061 //----------------------------------------------------------------------------// 00062 00063 #include "ns.h" 00064 00065 FIELD3D_NAMESPACE_OPEN 00066 00067 //----------------------------------------------------------------------------// 00068 // DenseFieldIO 00069 //----------------------------------------------------------------------------// 00070 00076 //----------------------------------------------------------------------------// 00077 00078 class DenseFieldIO : public FieldIO 00079 { 00080 00081 public: 00082 00083 // Typedefs ------------------------------------------------------------------ 00084 00085 typedef boost::intrusive_ptr<DenseFieldIO> Ptr; 00086 00087 // RTTI replacement ---------------------------------------------------------- 00088 00089 typedef DenseFieldIO class_type; 00090 DEFINE_FIELD_RTTI_CONCRETE_CLASS; 00091 00092 static const char* classType() 00093 { 00094 return "DenseFieldIO"; 00095 } 00096 00097 // Constructors -------------------------------------------------------------- 00098 00100 DenseFieldIO() 00101 : FieldIO() 00102 { } 00103 00105 virtual ~DenseFieldIO() 00106 { /* Empty */ } 00107 00108 static FieldIO::Ptr create() 00109 { return Ptr(new DenseFieldIO); } 00110 00111 // From FieldIO -------------------------------------------------------------- 00112 00116 virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, 00117 const std::string &layerPath, 00118 DataTypeEnum typeEnum); 00119 00123 virtual bool write(hid_t layerGroup, FieldBase::Ptr field); 00124 00126 virtual std::string className() const 00127 { return "DenseField"; } 00128 00129 private: 00130 00131 // Internal methods ---------------------------------------------------------- 00132 00134 template <class Data_T> 00135 bool writeInternal(hid_t layerGroup, 00136 typename DenseField<Data_T>::Ptr field); 00137 00139 template <class Data_T> 00140 bool writeData(hid_t dataSet, typename DenseField<Data_T>::Ptr field, 00141 Data_T dummy); 00142 00144 template <class Data_T> 00145 typename DenseField<Data_T>::Ptr readData(hid_t dataSet, const Box3i &extents, 00146 const Box3i &dataW); 00147 00148 // Strings ------------------------------------------------------------------- 00149 00150 static const int k_versionNumber; 00151 static const std::string k_versionAttrName; 00152 static const std::string k_extentsStr; 00153 static const std::string k_dataWindowStr; 00154 static const std::string k_componentsStr; 00155 static const std::string k_dataStr; 00156 00157 // Typedefs ------------------------------------------------------------------ 00158 00160 typedef FieldIO base; 00161 00162 }; 00163 00164 //----------------------------------------------------------------------------// 00165 // Templated methods 00166 //----------------------------------------------------------------------------// 00167 00169 template <class Data_T> 00170 bool DenseFieldIO::writeInternal(hid_t layerGroup, 00171 typename DenseField<Data_T>::Ptr field) 00172 { 00173 using namespace Exc; 00174 using namespace Hdf5Util; 00175 00176 const V3i& memSize = field->internalMemSize(); 00177 int size[3]; 00178 size[0] = memSize.x; 00179 size[1] = memSize.y; 00180 size[2] = memSize.z; 00181 00182 int components = FieldTraits<Data_T>::dataDims(); 00183 00184 hsize_t totalSize[1]; 00185 totalSize[0] = size[0] * size[1] * size[2] * components; 00186 00187 // Make sure chunk size isn't too big. 00188 hsize_t preferredChunkSize = 4096 * 16; 00189 const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2); 00190 00191 Box3i ext(field->extents()), dw(field->dataWindow()); 00192 00193 // Add extents attribute --- 00194 00195 int extents[6] = 00196 { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z }; 00197 00198 if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) { 00199 throw WriteAttributeException("Couldn't write attribute " + k_extentsStr); 00200 } 00201 00202 // Add data window attribute --- 00203 00204 int dataWindow[6] = 00205 { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z }; 00206 00207 if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) { 00208 throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr); 00209 } 00210 00211 // Add components attribute --- 00212 00213 if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) { 00214 throw WriteAttributeException("Couldn't write attribute " + k_componentsStr); 00215 } 00216 00217 // Add data to file --- 00218 00219 H5ScopedScreate dataSpace(H5S_SIMPLE); 00220 00221 if (dataSpace.id() < 0) { 00222 throw CreateDataSpaceException("Couldn't create data space in " 00223 "DenseFieldIO::writeInternal"); 00224 } 00225 00226 // Create a "simple" data structure --- 00227 00228 H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL); 00229 00230 // Set up gzip property list 00231 bool gzipAvailable = checkHdf5Gzip(); 00232 hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE); 00233 if (gzipAvailable) { 00234 herr_t status = H5Pset_deflate(dcpl, 9); 00235 if (status < 0) { 00236 return false; 00237 } 00238 status = H5Pset_chunk(dcpl, 1, &chunkSize); 00239 if (status < 0) { 00240 return false; 00241 } 00242 } 00243 00244 H5ScopedDcreate dataSet(layerGroup, k_dataStr, 00245 DataTypeTraits<Data_T>::h5type(), 00246 dataSpace.id(), 00247 H5P_DEFAULT, dcpl, H5P_DEFAULT); 00248 00249 if (dataSet.id() < 0) { 00250 throw CreateDataSetException("Couldn't create data set in " 00251 "DenseFieldIO::writeInternal"); 00252 } 00253 00254 // Call out to the templated function, it will figure out how to get 00255 // the data into the file in the appropriate fashion. 00256 if (!writeData<Data_T>(dataSet.id(), field, Data_T(0.0f))) { 00257 throw WriteLayerException("Error writing layer"); 00258 } 00259 00260 return true; 00261 } 00262 00263 //----------------------------------------------------------------------------// 00264 00265 template <class Data_T> 00266 bool DenseFieldIO::writeData(hid_t dataSet, 00267 typename DenseField<Data_T>::Ptr field, 00268 Data_T dummy) 00269 { 00270 using namespace Hdf5Util; 00271 00272 hid_t err = H5Dwrite(dataSet, 00273 DataTypeTraits<Data_T>::h5type(), 00274 H5S_ALL, H5S_ALL, 00275 H5P_DEFAULT, &(*field->begin())); 00276 00277 if (err < 0) { 00278 throw Exc::WriteLayerException("Error writing layer in " 00279 "DenseFieldIO::writeData"); 00280 } 00281 00282 return true; 00283 } 00284 00285 //----------------------------------------------------------------------------// 00286 00287 template <class Data_T> 00288 typename DenseField<Data_T>::Ptr 00289 DenseFieldIO::readData(hid_t dataSet, const Box3i &extents, const Box3i &dataW) 00290 { 00291 typename DenseField<Data_T>::Ptr field(new DenseField<Data_T>); 00292 field->setSize(extents, dataW); 00293 00294 if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 00295 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin())) < 0) 00296 { 00297 std::string typeName = "DenseField<" + 00298 DataTypeTraits<Data_T>::name() + ">"; 00299 throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data"); 00300 } 00301 00302 return field; 00303 } 00304 00305 //----------------------------------------------------------------------------// 00306 00307 FIELD3D_NAMESPACE_HEADER_CLOSE 00308 00309 //----------------------------------------------------------------------------// 00310 00311 #endif // Include guard