Field3D
SparseFieldIO.cpp
Go to the documentation of this file.
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 //----------------------------------------------------------------------------//