/*************************************************************************** * Copyright (C) 2005 by Nicolas PASCAL * * nicolas.pascal@icare.univ-lille1.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "hdffiledata.h" #include "Hdf_common.hpp" #include "Hdf_sds.hpp" #include "Hdf_attr.hpp" #include "tools.h" #include "mfhdf.h" HDFFileData::HDFFileData(const string & name,const string & mode/*= "r"*/,const bool open_file): FileData(name,mode),FileDataReader(name,mode) { // The basis constructor can throw a bad_file or bad_file_opening_mode exception hdf_file=NULL; metadata=NULL; if (open_file) { load_hdf_file(); load_hdf_metadata(); } } HDFFileData::~HDFFileData() { free_hdf_metadata(); free_hdf_file(); } const int32 HDFFileData::get_sds_type_code( const string & sds_name ) { // the sds corresponding to var_name Hdf_sds sds = (get_hdf_file())->get_sds(sds_name.c_str()); return sds.get_data_type(); } void HDFFileData::get_dataset_fill_value( const string & sds_name, void * fill_value ) { if (!is_hdf_file_loaded()) load_hdf_file(); get_hdf_file()->get_fill_value(sds_name.c_str(),fill_value); } HDFFileData::HDFFileData( const HDFFileData & hfd ) :FileData(hfd),FileDataReader(hfd) { if ( &hfd != NULL ) { hdf_file=hfd.hdf_file; metadata=hfd.metadata; } } HDFFileData &HDFFileData::operator= (const HDFFileData &hfd) { if (&hfd == this) return *this; // protection against self assignation if ( &hfd != NULL ) { hdf_file=hfd.hdf_file; metadata=hfd.metadata; } return *this; } void HDFFileData::free_read_write_allocations( const bool *are_limits_initialized, int *start, int *stride, int *edges ) { if ( are_limits_initialized[0]) delete[] start; if ( are_limits_initialized[1]) delete[] stride; if ( are_limits_initialized[2]) delete[] edges; }; const bool HDFFileData::check_read_write_limits(const char* sds_name, int *start, int *stride, int *edges, const int rank) { assert(start!=NULL); assert(edges!=NULL); Hdf_sds sds = hdf_file->get_sds(sds_name); for ( int i = 0 ; i (sds.get_dimension(i)-1)) { bad_index e(start[i],(sds.get_dimension(i)-1)); throw e; return false; } // test the selection length int stride_val; if ( stride!=NULL ) stride_val=stride[i]; else stride_val=1; if ( (start[i]+(edges[i]*stride_val))> sds.get_dimension(i) ) { bad_index e(start[i]+(edges[i]*stride_val),sds.get_dimension(i)-1); throw e; return false; } } return true; }; void HDFFileData::init_read_write_null_input_param(const char* sds_name, int *&start, int *&stride, int *&edges, int &rank, bool * initialized_values) { initialized_values[0] = false; initialized_values[1] = false; initialized_values[2] = false; Hdf_sds sds = hdf_file->get_sds(sds_name); // if rank is not defined, set to the sds one if (rank==-1) rank = sds.get_rank(); // if start is not defined, allocate it with a rank size, and set its values to 0 if ( start == NULL ) { start = new int[rank]; initialized_values[0] = true; for ( int i = 0;iget_sds_sizeof(sds_name); data = static_cast(malloc(data_type_size*data_size)); } hdf_file->read_sds(sds_name,data,(int32*)start,(int32*)stride,(int32*)edges); // free the ressources allocated by this method free_read_write_allocations(are_limits_initialized, start, stride, edges); if (!hdf_file_already_loaded) free_hdf_file(); return data; } void* HDFFileData::read_vdata( void* data, const char* vdata_name, const char* vdata_field, int start, int edges ) { bool hdf_file_already_loaded = is_hdf_file_loaded(); if (!hdf_file_already_loaded) load_hdf_file(); // set start to the beginig of selection if negative if (start<0) start=0; // init the selection range vector v_dim=get_vdata_dimension(vdata_name); // return {nb_record,nb_field} Hdf_vd_field vd_field=hdf_file->get_vd(vdata_name).get_field(vdata_field); int32 field_order=vd_field.get_order(); int32 field_size=vd_field.get_size(); v_dim[1]=field_order; // now {nb_record,field_order} if (edges<=0) // if negative, the whole data will be loaded edges=v_dim[0]; // test the selection range validity if (start >= v_dim[0]) { bad_index e(start,(v_dim[0]-1)); throw e; } if ( (start+edges) > v_dim[0] ) { bad_index e(start+edges,(v_dim[0]-1)); throw e; return false; } // if data is NULL, allocate it if (data==NULL) // size of one order in the field data = static_cast(malloc(field_size*edges)); // read the data hdf_file->read_vdata_field(vdata_name,vdata_field,data,(int32)start,(int32)edges); if (!hdf_file_already_loaded) free_hdf_file(); return data; } Hdf_file * HDFFileData::get_hdf_file() { if (!is_hdf_file_loaded()) load_hdf_file(); return hdf_file; } void HDFFileData::load_hdf_file() { if (!is_hdf_file_loaded()) hdf_file = new Hdf_file( get_name().c_str(), DFACC_READ); } void HDFFileData::free_hdf_file() { delete hdf_file; hdf_file=NULL; } HDFFileMetaData* HDFFileData::get_metadata() { if (!is_hdf_metadata_loaded()) load_hdf_metadata(); return metadata; } void HDFFileData::load_hdf_metadata() { bool hdf_file_loaded=is_hdf_file_loaded(); // is the hdf_file instanciated before calling this method if (!hdf_file_loaded) load_hdf_file(); metadata = new HDFFileMetaData(hdf_file); if (!hdf_file_loaded) // free hdf_file if not instanciated before calling this method free_hdf_file(); } void HDFFileData::free_hdf_metadata() { delete metadata; metadata=NULL; } const bool HDFFileData::is_hdf_file_loaded(){ return (hdf_file!=NULL); } const bool HDFFileData::is_hdf_metadata_loaded(){ return (metadata!=NULL); } vector< int > HDFFileData::get_sds_dimension( const string & sds_name ) { bool hdf_file_loaded=is_hdf_file_loaded(); // is the hdf_file instanciated before calling this method if (!hdf_file_loaded) load_hdf_file(); vector v_dim; Hdf_sds sds = hdf_file->get_sds(sds_name.c_str()); int32 rank = sds.get_rank(); int32 dim[rank]; sds.get_dimensions(dim); v_dim.reserve(rank); for (int i = 0 ; i HDFFileData::get_vdata_dimension( const string & vdata_name ) { bool hdf_file_loaded=is_hdf_file_loaded(); // is the hdf_file instanciated before calling this method if (!hdf_file_loaded) load_hdf_file(); vector v_dim(2); Hdf_vd vd = hdf_file->get_vd(vdata_name.c_str()); v_dim[0]=vd.get_nb_record(); v_dim[1]=vd.get_nb_field(); assert(v_dim.size()==2); if (!hdf_file_loaded) // free hdf_file if not instanciated before calling this method free_hdf_file(); // cast needed for some compilers return v_dim; } string HDFFileData::get_values_attr(string attr_name) { if(!this->is_hdf_metadata_loaded()) load_hdf_metadata(); HDFFileMetaData* metaData = get_metadata(); string val; metaData->get_tree_value_string(val, attr_name.c_str()); return val; } string HDFFileData::get_file_attr(string attr_name) { char cdata[4096]; hdf_file->get_attr(attr_name.c_str()).get_values(cdata); string val=string(cdata); return val; } bool HDFFileData::has_attr(string attr_name) { if(!this->is_hdf_metadata_loaded()) load_hdf_metadata(); HDFFileMetaData* metaData = get_metadata(); string val; return metaData->get_tree_value_string(val, attr_name.c_str()); } bool HDFFileData::has_file_attr(string attr_name) { Hdf_attr meta = (hdf_file->get_attr(attr_name.c_str())); return true; } string HDFFileData::get_values_attr_dataset(string sds_name,string attr_name){ Hdf_sds sds = hdf_file->get_sds(sds_name.c_str()); Hdf_attr attr = sds.get_attribute(attr_name.c_str()); int32 type = attr.get_type(); switch (type) { case DFNT_CHAR8 : { char8 *values = new char8[(attr.get_nvalues() +1) * sizeof(char8)]; attr.get_values((void*)values); values[attr.get_nvalues() * sizeof(char8)]='\0'; string ret = string(values); return ret; break; } case DFNT_UCHAR8 : { uchar8 *values = new uchar8[attr.get_nvalues() * sizeof(uchar8)]; attr.get_values((void*)values); string ret = string((char8*)values); return ret; break; } case DFNT_INT8 : { int8 *values = new int8[attr.get_nvalues() * sizeof(int8)]; attr.get_values((void*)values); string ret = ""; for(int i = 0; iget_sds(sds_name.c_str()); //Hdf_attr attr = sds.get_attribute(attr_name.c_str()); return sds.has_attr(attr_name.c_str()); }; void HDFFileData::get_fillValue(const string &sds_name, void *fillValue) { int32 id = hdf_file->get_sds(sds_name.c_str()).get_id(); SDgetfillvalue(id,(VOIDP)fillValue); }; void HDFFileData::get_scaling(const string &sds_name, float64 &scale, float64 &offset) { float64 cal_err; float64 offset_err; int32 data_type; int32 id = hdf_file->get_sds(sds_name.c_str()).get_id(); SDgetcal(id,&scale,&cal_err,&offset,&offset_err,&data_type); };