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 #include <boost/intrusive_ptr.hpp> 00045 00046 #include "SparseFieldIO.h" 00047 #include "Types.h" 00048 00049 //----------------------------------------------------------------------------// 00050 00051 using namespace boost; 00052 using namespace std; 00053 00054 //----------------------------------------------------------------------------// 00055 00056 FIELD3D_NAMESPACE_OPEN 00057 00058 //----------------------------------------------------------------------------// 00059 // Field3D namespaces 00060 //----------------------------------------------------------------------------// 00061 00062 using namespace Exc; 00063 using namespace Hdf5Util; 00064 00065 //----------------------------------------------------------------------------// 00066 // Static members 00067 //----------------------------------------------------------------------------// 00068 00069 const int SparseFieldIO::k_versionNumber(1); 00070 const std::string SparseFieldIO::k_versionAttrName("version"); 00071 const std::string SparseFieldIO::k_extentsStr("extents"); 00072 const std::string SparseFieldIO::k_dataWindowStr("data_window"); 00073 const std::string SparseFieldIO::k_componentsStr("components"); 00074 const std::string SparseFieldIO::k_dataStr("data"); 00075 const std::string SparseFieldIO::k_blockOrderStr("block_order"); 00076 const std::string SparseFieldIO::k_numBlocksStr("num_blocks"); 00077 const std::string SparseFieldIO::k_blockResStr("block_res"); 00078 const std::string SparseFieldIO::k_bitsPerComponentStr("bits_per_component"); 00079 const std::string SparseFieldIO::k_numOccupiedBlocksStr("num_occupied_blocks"); 00080 00081 //----------------------------------------------------------------------------// 00082 00083 FieldBase::Ptr 00084 SparseFieldIO::read(hid_t layerGroup, const std::string &filename, 00085 const std::string &layerPath, 00086 DataTypeEnum typeEnum) 00087 { 00088 Box3i extents, dataW; 00089 int components; 00090 int blockOrder; 00091 int numBlocks; 00092 V3i blockRes; 00093 00094 if (layerGroup == -1) { 00095 Msg::print(Msg::SevWarning, "Bad layerGroup."); 00096 return FieldBase::Ptr(); 00097 } 00098 00099 int version; 00100 if (!readAttribute(layerGroup, k_versionAttrName, 1, version)) 00101 throw MissingAttributeException("Couldn't find attribute: " + 00102 k_versionAttrName); 00103 00104 if (version != k_versionNumber) 00105 throw UnsupportedVersionException("SparseField version not supported: " + 00106 lexical_cast<std::string>(version)); 00107 00108 if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x)) 00109 throw MissingAttributeException("Couldn't find attribute: " + 00110 k_extentsStr); 00111 00112 if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x)) 00113 throw MissingAttributeException("Couldn't find attribute: " + 00114 k_dataWindowStr); 00115 00116 if (!readAttribute(layerGroup, k_componentsStr, 1, components)) 00117 throw MissingAttributeException("Couldn't find attribute: " + 00118 k_componentsStr); 00119 00120 // Read block order 00121 if (!readAttribute(layerGroup, k_blockOrderStr, 1, blockOrder)) 00122 throw MissingAttributeException("Couldn't find attribute: " + 00123 k_blockOrderStr); 00124 00125 // Read number of blocks total 00126 if (!readAttribute(layerGroup, k_numBlocksStr, 1, numBlocks)) 00127 throw MissingAttributeException("Couldn't find attribute: " + 00128 k_numBlocksStr); 00129 00130 // Read block resolution in each dimension 00131 if (!readAttribute(layerGroup, k_blockResStr, 3, blockRes.x)) 00132 throw MissingAttributeException("Couldn't find attribute: " + 00133 k_blockResStr); 00134 00135 // ... Check that it matches the # reported by summing the active blocks 00136 00137 int numCalculatedBlocks = blockRes.x * blockRes.y * blockRes.z; 00138 if (numCalculatedBlocks != numBlocks) 00139 throw FileIntegrityException("Incorrect block count in SparseFieldIO::read"); 00140 00141 // Call the appropriate read function based on the data type --- 00142 00143 FieldBase::Ptr result; 00144 00145 int occupiedBlocks; 00146 if (!readAttribute(layerGroup, k_numOccupiedBlocksStr, 1, occupiedBlocks)) 00147 throw MissingAttributeException("Couldn't find attribute: " + 00148 k_numOccupiedBlocksStr); 00149 00150 // Check the data type --- 00151 00152 int bits; 00153 if (!readAttribute(layerGroup, k_bitsPerComponentStr, 1, bits)) 00154 throw MissingAttributeException("Couldn't find attribute: " + 00155 k_bitsPerComponentStr); 00156 00157 bool isHalf = false; 00158 bool isFloat = false; 00159 bool isDouble = false; 00160 00161 switch (bits) { 00162 case 16: 00163 isHalf = true; 00164 break; 00165 case 64: 00166 isDouble = true; 00167 break; 00168 case 32: 00169 default: 00170 isFloat = true; 00171 } 00172 00173 // Finally, read the data --- 00174 00175 if (components == 1) { 00176 if (isHalf && typeEnum == DataTypeHalf) { 00177 SparseField<half>::Ptr field(new SparseField<half>); 00178 field->setSize(extents, dataW); 00179 field->setBlockOrder(blockOrder); 00180 readData<half>(layerGroup, numBlocks, filename, layerPath, field); 00181 result = field; 00182 } else if (isFloat && typeEnum == DataTypeFloat) { 00183 SparseField<float>::Ptr field(new SparseField<float>); 00184 field->setSize(extents, dataW); 00185 field->setBlockOrder(blockOrder); 00186 readData<float>(layerGroup, numBlocks, filename, layerPath, field); 00187 result = field; 00188 } else if (isDouble && typeEnum == DataTypeDouble) { 00189 SparseField<double>::Ptr field(new SparseField<double>); 00190 field->setSize(extents, dataW); 00191 field->setBlockOrder(blockOrder); 00192 readData<double>(layerGroup, numBlocks, filename, layerPath, field); 00193 result = field; 00194 } 00195 } else if (components == 3) { 00196 if (isHalf && typeEnum == DataTypeVecHalf) { 00197 SparseField<V3h>::Ptr field(new SparseField<V3h>); 00198 field->setSize(extents, dataW); 00199 field->setBlockOrder(blockOrder); 00200 readData<V3h>(layerGroup, numBlocks, filename, layerPath, field); 00201 result = field; 00202 } else if (isFloat && typeEnum == DataTypeVecFloat) { 00203 SparseField<V3f>::Ptr field(new SparseField<V3f>); 00204 field->setSize(extents, dataW); 00205 field->setBlockOrder(blockOrder); 00206 readData<V3f>(layerGroup, numBlocks, filename, layerPath, field); 00207 result = field; 00208 } else if (isDouble && typeEnum == DataTypeVecDouble) { 00209 SparseField<V3d>::Ptr field(new SparseField<V3d>); 00210 field->setSize(extents, dataW); 00211 field->setBlockOrder(blockOrder); 00212 readData<V3d>(layerGroup, numBlocks, filename, layerPath, field); 00213 result = field; 00214 } 00215 } 00216 00217 return result; 00218 } 00219 00220 //----------------------------------------------------------------------------// 00221 00222 bool 00223 SparseFieldIO::write(hid_t layerGroup, FieldBase::Ptr field) 00224 { 00225 if (layerGroup == -1) { 00226 Msg::print(Msg::SevWarning, "Bad layerGroup."); 00227 return false; 00228 } 00229 00230 // Add version attribute 00231 if (!writeAttribute(layerGroup, k_versionAttrName, 00232 1, k_versionNumber)) { 00233 Msg::print(Msg::SevWarning, "Error adding version attribute."); 00234 return false; 00235 } 00236 00237 SparseField<half>::Ptr halfField = 00238 field_dynamic_cast<SparseField<half> >(field); 00239 SparseField<float>::Ptr floatField = 00240 field_dynamic_cast<SparseField<float> >(field); 00241 SparseField<double>::Ptr doubleField = 00242 field_dynamic_cast<SparseField<double> >(field); 00243 SparseField<V3h>::Ptr vecHalfField = 00244 field_dynamic_cast<SparseField<V3h> >(field); 00245 SparseField<V3f>::Ptr vecFloatField = 00246 field_dynamic_cast<SparseField<V3f> >(field); 00247 SparseField<V3d>::Ptr vecDoubleField = 00248 field_dynamic_cast<SparseField<V3d> >(field); 00249 00250 bool success = true; 00251 if (halfField) { 00252 success = writeInternal<half>(layerGroup, halfField); 00253 } else if (floatField) { 00254 success = writeInternal<float>(layerGroup, floatField); 00255 } else if (doubleField) { 00256 success = writeInternal<double>(layerGroup, doubleField); 00257 } else if (vecHalfField) { 00258 success = writeInternal<V3h>(layerGroup, vecHalfField); 00259 } else if (vecFloatField) { 00260 success = writeInternal<V3f>(layerGroup, vecFloatField); 00261 } else if (vecDoubleField) { 00262 success = writeInternal<V3d>(layerGroup, vecDoubleField); 00263 } else { 00264 throw WriteLayerException("SparseFieldIO::write does not support the given " 00265 "SparseField template parameter"); 00266 } 00267 00268 return success; 00269 } 00270 00271 //----------------------------------------------------------------------------// 00272 00273 FIELD3D_NAMESPACE_SOURCE_CLOSE 00274 00275 //----------------------------------------------------------------------------//