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 // Constructors -------------------------------------------------------------- 00088 00090 DenseFieldIO() 00091 : FieldIO() 00092 { } 00093 00095 virtual ~DenseFieldIO() 00096 { /* Empty */ } 00097 00098 00099 static FieldIO::Ptr create() 00100 { return Ptr(new DenseFieldIO); } 00101 00102 // From FieldIO -------------------------------------------------------------- 00103 00107 virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, 00108 const std::string &layerPath, 00109 DataTypeEnum typeEnum); 00110 00114 virtual bool write(hid_t layerGroup, FieldBase::Ptr field); 00115 00117 virtual std::string className() const 00118 { return std::string("DenseField"); } 00119 00120 private: 00121 00122 // Internal methods ---------------------------------------------------------- 00123 00125 template <class Data_T> 00126 bool writeInternal(hid_t layerGroup, 00127 typename DenseField<Data_T>::Ptr field); 00128 00130 template <class Data_T> 00131 bool writeData(hid_t dataSet, typename DenseField<Data_T>::Ptr field, 00132 Data_T dummy); 00133 00135 template <class Data_T> 00136 typename DenseField<Data_T>::Ptr readData(hid_t dataSet, const Box3i &extents, 00137 const Box3i &dataW); 00138 00139 // Strings ------------------------------------------------------------------- 00140 00141 static const int k_versionNumber; 00142 static const std::string k_versionAttrName; 00143 static const std::string k_extentsStr; 00144 static const std::string k_dataWindowStr; 00145 static const std::string k_componentsStr; 00146 static const std::string k_dataStr; 00147 00148 }; 00149 00150 //----------------------------------------------------------------------------// 00151 // Templated methods 00152 //----------------------------------------------------------------------------// 00153 00155 template <class Data_T> 00156 bool DenseFieldIO::writeInternal(hid_t layerGroup, 00157 typename DenseField<Data_T>::Ptr field) 00158 { 00159 using namespace Exc; 00160 using namespace Hdf5Util; 00161 00162 const V3i& memSize = field->internalMemSize(); 00163 int size[3]; 00164 size[0] = memSize.x; 00165 size[1] = memSize.y; 00166 size[2] = memSize.z; 00167 00168 int components = FieldTraits<Data_T>::dataDims(); 00169 00170 hsize_t totalSize[1]; 00171 totalSize[0] = size[0] * size[1] * size[2] * components; 00172 00173 // Make sure chunk size isn't too big. 00174 hsize_t preferredChunkSize = 4096 * 16; 00175 const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2); 00176 00177 Box3i ext(field->extents()), dw(field->dataWindow()); 00178 00179 // Add extents attribute --- 00180 00181 int extents[6] = 00182 { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z }; 00183 00184 if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) { 00185 throw WriteAttributeException("Couldn't write attribute " + k_extentsStr); 00186 } 00187 00188 // Add data window attribute --- 00189 00190 int dataWindow[6] = 00191 { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z }; 00192 00193 if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) { 00194 throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr); 00195 } 00196 00197 // Add components attribute --- 00198 00199 if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) { 00200 throw WriteAttributeException("Couldn't write attribute " + k_componentsStr); 00201 } 00202 00203 // Add data to file --- 00204 00205 H5ScopedScreate dataSpace(H5S_SIMPLE); 00206 00207 if (dataSpace.id() < 0) { 00208 throw CreateDataSpaceException("Couldn't create data space in " 00209 "DenseFieldIO::writeInternal"); 00210 } 00211 00212 // Create a "simple" data structure --- 00213 00214 H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL); 00215 00216 // Set up gzip property list 00217 bool gzipAvailable = checkHdf5Gzip(); 00218 hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE); 00219 if (gzipAvailable) { 00220 herr_t status = H5Pset_deflate(dcpl, 9); 00221 if (status < 0) { 00222 return false; 00223 } 00224 status = H5Pset_chunk(dcpl, 1, &chunkSize); 00225 if (status < 0) { 00226 return false; 00227 } 00228 } 00229 00230 H5ScopedDcreate dataSet(layerGroup, k_dataStr, 00231 DataTypeTraits<Data_T>::h5type(), 00232 dataSpace.id(), 00233 H5P_DEFAULT, dcpl, H5P_DEFAULT); 00234 00235 if (dataSet.id() < 0) { 00236 throw CreateDataSetException("Couldn't create data set in " 00237 "DenseFieldIO::writeInternal"); 00238 } 00239 00240 // Call out to the templated function, it will figure out how to get 00241 // the data into the file in the appropriate fashion. 00242 if (!writeData<Data_T>(dataSet.id(), field, Data_T(0.0f))) { 00243 throw WriteLayerException("Error writing layer"); 00244 } 00245 00246 return true; 00247 } 00248 00249 //----------------------------------------------------------------------------// 00250 00251 template <class Data_T> 00252 bool DenseFieldIO::writeData(hid_t dataSet, 00253 typename DenseField<Data_T>::Ptr field, 00254 Data_T dummy) 00255 { 00256 using namespace Hdf5Util; 00257 00258 hid_t err = H5Dwrite(dataSet, 00259 DataTypeTraits<Data_T>::h5type(), 00260 H5S_ALL, H5S_ALL, 00261 H5P_DEFAULT, &(*field->begin())); 00262 00263 if (err < 0) { 00264 throw Exc::WriteLayerException("Error writing layer in " 00265 "DenseFieldIO::writeData"); 00266 } 00267 00268 return true; 00269 } 00270 00271 //----------------------------------------------------------------------------// 00272 00273 template <class Data_T> 00274 typename DenseField<Data_T>::Ptr 00275 DenseFieldIO::readData(hid_t dataSet, const Box3i &extents, const Box3i &dataW) 00276 { 00277 typename DenseField<Data_T>::Ptr field(new DenseField<Data_T>); 00278 field->setSize(extents, dataW); 00279 00280 if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 00281 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin())) < 0) 00282 { 00283 std::string typeName = "DenseField<" + 00284 DataTypeTraits<Data_T>::name() + ">"; 00285 throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data"); 00286 } 00287 00288 return field; 00289 } 00290 00291 //----------------------------------------------------------------------------// 00292 00293 FIELD3D_NAMESPACE_HEADER_CLOSE 00294 00295 //----------------------------------------------------------------------------// 00296 00297 #endif // Include guard