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_MACFieldIO_H_ 00045 #define _INCLUDED_Field3D_MACFieldIO_H_ 00046 00047 //----------------------------------------------------------------------------// 00048 00049 #include <string> 00050 00051 #include <boost/intrusive_ptr.hpp> 00052 00053 #include <hdf5.h> 00054 00055 #include "Exception.h" 00056 #include "Field3DFile.h" 00057 #include "FieldIO.h" 00058 #include "Hdf5Util.h" 00059 #include "MACField.h" 00060 00061 //----------------------------------------------------------------------------// 00062 00063 #include "ns.h" 00064 00065 FIELD3D_NAMESPACE_OPEN 00066 00067 //----------------------------------------------------------------------------// 00068 // MACFieldIO 00069 //----------------------------------------------------------------------------// 00070 00076 //----------------------------------------------------------------------------// 00077 00078 class MACFieldIO : public FieldIO 00079 { 00080 00081 public: 00082 00083 // Typedefs ------------------------------------------------------------------ 00084 00085 typedef boost::intrusive_ptr<MACFieldIO> Ptr; 00086 00087 // RTTI replacement ---------------------------------------------------------- 00088 00089 typedef MACFieldIO class_type; 00090 DEFINE_FIELD_RTTI_CONCRETE_CLASS; 00091 00092 static const char *classType() 00093 { 00094 return "MACFieldIO"; 00095 } 00096 00097 // Constructors -------------------------------------------------------------- 00098 00100 MACFieldIO() 00101 : FieldIO() 00102 { } 00103 00105 virtual ~MACFieldIO() 00106 { /* Empty */ } 00107 00108 static FieldIO::Ptr create() 00109 { return Ptr(new MACFieldIO); } 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 00122 virtual bool write(hid_t layerGroup, FieldBase::Ptr field); 00123 00125 virtual std::string className() const 00126 { return "MACField"; } 00127 00128 private: 00129 00130 // Internal methods ---------------------------------------------------------- 00131 00133 template <class Data_T> 00134 bool writeInternal(hid_t layerGroup, typename MACField<Data_T>::Ptr field); 00135 00137 template <class Data_T> 00138 bool writeData(hid_t layerGroup, typename MACField<Data_T>::Ptr field, 00139 MACComponent comp); 00140 00142 template <class Data_T> 00143 bool readData(hid_t location, typename MACField<Data_T>::Ptr result); 00144 00145 // Strings ------------------------------------------------------------------- 00146 00147 static const int k_versionNumber; 00148 static const std::string k_versionAttrName; 00149 static const std::string k_extentsStr; 00150 static const std::string k_dataWindowStr; 00151 static const std::string k_componentsStr; 00152 static const std::string k_bitsPerComponentStr; 00153 static const std::string k_uDataStr; 00154 static const std::string k_vDataStr; 00155 static const std::string k_wDataStr; 00156 00157 // Typedefs ------------------------------------------------------------------ 00158 00160 typedef FieldIO base; 00161 }; 00162 00163 //----------------------------------------------------------------------------// 00164 // Template methods 00165 //----------------------------------------------------------------------------// 00166 00168 template <class Data_T> 00169 bool MACFieldIO::writeInternal(hid_t layerGroup, 00170 typename MACField<Data_T>::Ptr field) 00171 { 00172 using namespace Exc; 00173 using namespace Hdf5Util; 00174 00175 int components = FieldTraits<Data_T>::dataDims(); 00176 V3i compSize = field->getComponentSize(); 00177 int size[3]; 00178 size[0] = compSize.x; 00179 size[1] = compSize.y; 00180 size[2] = compSize.z; 00181 00182 Box3i ext(field->extents()), dw(field->dataWindow()); 00183 00184 // Add extents attribute --- 00185 00186 int extents[6] = 00187 { ext.min.x, ext.min.y, ext.min.z, ext.max.x, ext.max.y, ext.max.z }; 00188 00189 if (!writeAttribute(layerGroup, k_extentsStr, 6, extents[0])) 00190 throw WriteAttributeException("Couldn't write attribute " + k_extentsStr); 00191 00192 // Add data window attribute --- 00193 00194 int dataWindow[6] = 00195 { dw.min.x, dw.min.y, dw.min.z, dw.max.x, dw.max.y, dw.max.z }; 00196 00197 if (!writeAttribute(layerGroup, k_dataWindowStr, 6, dataWindow[0])) 00198 throw WriteAttributeException("Couldn't write attribute " + k_dataWindowStr); 00199 00200 // Add components attribute --- 00201 00202 if (!writeAttribute(layerGroup, k_componentsStr, 1, components)) 00203 throw WriteAttributeException("Couldn't write attribute " + k_componentsStr); 00204 00205 // Add the bits per component attribute --- 00206 00207 int bits = DataTypeTraits<Data_T>::h5bits(); 00208 if (!writeAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) { 00209 throw WriteAttributeException("Couldn't write attribute " + k_bitsPerComponentStr); 00210 return false; 00211 } 00212 00213 // Add data to file --- 00214 if (!writeData<Data_T>(layerGroup, field, MACCompU)) { 00215 throw WriteMACFieldDataException("Error writing u_data"); 00216 return false; 00217 } 00218 if (!writeData<Data_T>(layerGroup, field, MACCompV)) { 00219 throw WriteMACFieldDataException("Error writing v_data"); 00220 return false; 00221 } 00222 if (!writeData<Data_T>(layerGroup, field, MACCompW)) { 00223 throw WriteMACFieldDataException("Error writing w_data"); 00224 return false; 00225 } 00226 00227 return true; 00228 } 00229 00230 //----------------------------------------------------------------------------// 00231 00232 template <class Data_T> 00233 bool MACFieldIO::writeData(hid_t layerGroup, 00234 typename MACField<Data_T>::Ptr field, 00235 MACComponent comp) 00236 { 00237 using namespace Exc; 00238 using namespace Hdf5Util; 00239 00240 const V3i &compSize = field->getComponentSize(); 00241 00242 hsize_t totalSize[1]; 00243 std::string compStr; 00244 00245 switch (comp) { 00246 case MACCompU: 00247 totalSize[0] = compSize.x; 00248 compStr = k_uDataStr; 00249 break; 00250 case MACCompV: 00251 totalSize[0] = compSize.y; 00252 compStr = k_vDataStr; 00253 break; 00254 case MACCompW: 00255 totalSize[0] = compSize.z; 00256 compStr = k_wDataStr; 00257 break; 00258 default: 00259 break; 00260 } 00261 00262 // Make sure chunk size isn't too big. 00263 hsize_t preferredChunkSize = 4096 * 16; 00264 const hsize_t chunkSize = std::min(preferredChunkSize, totalSize[0] / 2); 00265 00266 H5ScopedScreate dataSpace(H5S_SIMPLE); 00267 00268 if (dataSpace.id() < 0) 00269 throw CreateDataSpaceException("Couldn't create data space in " 00270 "MACFieldIO::writeData"); 00271 00272 // Create a "simple" data structure --- 00273 00274 H5Sset_extent_simple(dataSpace.id(), 1, totalSize, NULL); 00275 00276 // Set up gzip property list 00277 bool gzipAvailable = checkHdf5Gzip(); 00278 hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE); 00279 if (gzipAvailable) { 00280 herr_t status = H5Pset_deflate(dcpl, 9); 00281 if (status < 0) { 00282 return false; 00283 } 00284 status = H5Pset_chunk(dcpl, 1, &chunkSize); 00285 if (status < 0) { 00286 return false; 00287 } 00288 } 00289 00290 H5ScopedDcreate dataSet(layerGroup, compStr, 00291 DataTypeTraits<Data_T>::h5type(), 00292 dataSpace.id(), 00293 H5P_DEFAULT, dcpl, H5P_DEFAULT); 00294 00295 if (dataSet.id() < 0) 00296 throw CreateDataSetException("Couldn't create data set in " 00297 "MACFieldIO::writeData"); 00298 00299 hid_t err = H5Dwrite(dataSet, 00300 DataTypeTraits<Data_T>::h5type(), 00301 H5S_ALL, H5S_ALL, 00302 H5P_DEFAULT, &(*field->cbegin_comp(comp))); 00303 if (err < 0) 00304 throw Exc::WriteLayerException("Error writing layer in " 00305 "MACFieldIO::writeData"); 00306 00307 00308 return true; 00309 } 00310 00311 //----------------------------------------------------------------------------// 00312 00313 template <class Data_T> 00314 bool MACFieldIO::readData(hid_t layerGroup, 00315 typename MACField<Data_T>::Ptr field) 00316 { 00317 using namespace std; 00318 using namespace Exc; 00319 using namespace Hdf5Util; 00320 00321 hsize_t dims[1]; 00322 00323 // read u_data 00324 { 00325 00326 H5ScopedDopen dataSet(layerGroup, k_uDataStr, H5P_DEFAULT); 00327 if (dataSet.id() < 0) 00328 throw OpenDataSetException("Couldn't open data set: " + k_uDataStr); 00329 00330 H5ScopedDget_space dataSpace(dataSet.id()); 00331 H5ScopedDget_type dataType(dataSet.id()); 00332 H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL); 00333 00334 if (dataSpace.id() < 0) 00335 throw GetDataSpaceException("Couldn't get data space"); 00336 00337 if (dataType.id() < 0) 00338 throw GetDataTypeException("Couldn't get data type"); 00339 00340 if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 00341 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompU))) < 0) 00342 { 00343 std::string typeName = "MACField<" + 00344 DataTypeTraits<Data_T>::name() + ">"; 00345 throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data"); 00346 } 00347 00348 } 00349 00350 // read v_data 00351 { 00352 00353 H5ScopedDopen dataSet(layerGroup, k_vDataStr, H5P_DEFAULT); 00354 if (dataSet.id() < 0) 00355 throw OpenDataSetException("Couldn't open data set: " + k_vDataStr); 00356 00357 H5ScopedDget_space dataSpace(dataSet.id()); 00358 H5ScopedDget_type dataType(dataSet.id()); 00359 H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL); 00360 00361 if (dataSpace.id() < 0) 00362 throw GetDataSpaceException("Couldn't get data space"); 00363 00364 if (dataType.id() < 0) 00365 throw GetDataTypeException("Couldn't get data type"); 00366 00367 00368 if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 00369 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompV))) < 0) 00370 { 00371 std::string typeName = "MACField<" + 00372 DataTypeTraits<Data_T>::name() + ">"; 00373 throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data"); 00374 } 00375 00376 } 00377 00378 // read w_data 00379 { 00380 00381 H5ScopedDopen dataSet(layerGroup, k_wDataStr, H5P_DEFAULT); 00382 if (dataSet.id() < 0) 00383 throw OpenDataSetException("Couldn't open data set: " + k_wDataStr); 00384 00385 H5ScopedDget_space dataSpace(dataSet.id()); 00386 H5ScopedDget_type dataType(dataSet.id()); 00387 H5Sget_simple_extent_dims(dataSpace.id(), dims, NULL); 00388 00389 if (dataSpace.id() < 0) 00390 throw GetDataSpaceException("Couldn't get data space"); 00391 00392 if (dataType.id() < 0) 00393 throw GetDataTypeException("Couldn't get data type"); 00394 00395 00396 if (H5Dread(dataSet, DataTypeTraits<Data_T>::h5type(), 00397 H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*field->begin_comp(MACCompW))) < 0) 00398 { 00399 std::string typeName = "MACField<" + 00400 DataTypeTraits<Data_T>::name() + ">"; 00401 throw Exc::Hdf5DataReadException("Couldn't read " + typeName + " data"); 00402 } 00403 00404 } 00405 00406 return true; 00407 } 00408 00409 //----------------------------------------------------------------------------// 00410 00411 FIELD3D_NAMESPACE_HEADER_CLOSE 00412 00413 //----------------------------------------------------------------------------// 00414 00415 #endif // Include guard