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