LTP GCOV extension - code coverage report
Current view: directory - frmts/hdf5 - hdf5dataset.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 411
Code covered: 73.2 % Executed lines: 301

       1                 : /******************************************************************************
       2                 :  * $Id: hdf5dataset.cpp 19431 2010-04-17 01:12:34Z warmerdam $
       3                 :  *
       4                 :  * Project:  Hierarchical Data Format Release 5 (HDF5)
       5                 :  * Purpose:  HDF5 Datasets. Open HDF5 file, fetch metadata and list of
       6                 :  *           subdatasets.
       7                 :  *           This driver initially based on code supplied by Markus Neteler
       8                 :  * Author:  Denis Nadeau <denis.nadeau@gmail.com>
       9                 :  *
      10                 :  ******************************************************************************
      11                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      12                 :  *
      13                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      14                 :  * copy of this software and associated documentation files (the "Software"),
      15                 :  * to deal in the Software without restriction, including without limitation
      16                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      17                 :  * and/or sell copies of the Software, and to permit persons to whom the
      18                 :  * Software is furnished to do so, subject to the following conditions:
      19                 :  *
      20                 :  * The above copyright notice and this permission notice shall be included
      21                 :  * in all copies or substantial portions of the Software.
      22                 :  *
      23                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      24                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      25                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      26                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      27                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      28                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      29                 :  * DEALINGS IN THE SOFTWARE.
      30                 :  ****************************************************************************/
      31                 : 
      32                 : #define H5_USE_16_API
      33                 : 
      34                 : #include "hdf5.h"
      35                 : 
      36                 : #include "gdal_priv.h"
      37                 : #include "cpl_string.h"
      38                 : #include "hdf5dataset.h"
      39                 : 
      40                 : CPL_CVSID("$Id: hdf5dataset.cpp 19431 2010-04-17 01:12:34Z warmerdam $");
      41                 : 
      42                 : CPL_C_START
      43                 : void  GDALRegister_HDF5(void);
      44                 : CPL_C_END
      45                 : 
      46                 : 
      47                 : 
      48                 : /************************************************************************/
      49                 : /* ==================================================================== */
      50                 : /*        HDF5Dataset       */
      51                 : /* ==================================================================== */
      52                 : /************************************************************************/
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                        GDALRegister_HDF5()       */
      56                 : /************************************************************************/
      57             409 : void GDALRegister_HDF5()
      58                 :     
      59                 : {
      60                 :     GDALDriver  *poDriver;
      61             409 :     if( GDALGetDriverByName("HDF5") == NULL )
      62                 :   {
      63             392 :       poDriver = new GDALDriver();
      64             392 :       poDriver->SetDescription("HDF5");
      65                 :       poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, 
      66             392 :               "Hierarchical Data Format Release 5");
      67                 :       poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, 
      68             392 :               "frmt_hdf5.html");
      69             392 :       poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "hdf5");
      70             392 :       poDriver->pfnOpen = HDF5Dataset::Open;
      71             392 :       poDriver->pfnIdentify = HDF5Dataset::Identify;
      72             392 :       GetGDALDriverManager()->RegisterDriver(poDriver);
      73                 :   }
      74             409 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                           HDF5Dataset()                        */
      78                 : /************************************************************************/
      79              10 : HDF5Dataset::HDF5Dataset()
      80                 : {
      81              10 :     papszSubDatasets    = NULL;
      82              10 :     papszMetadata       = NULL;
      83              10 :     poH5RootGroup       = NULL;
      84              10 :     nSubDataCount       = 0;
      85              10 :     hHDF5               = -1;
      86              10 :     hDatasetID          = -1;
      87              10 :     hGroupID            = -1;
      88              10 :     bIsHDFEOS           = FALSE;
      89              10 :     nDatasetType        = -1;
      90              10 : }
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                            ~HDF5Dataset()                            */
      94                 : /************************************************************************/
      95              10 : HDF5Dataset::~HDF5Dataset()
      96                 : {
      97              10 :     CSLDestroy( papszMetadata );
      98              10 :     if( hHDF5 > 0 )
      99              10 :   H5Fclose( hHDF5 );
     100              10 :     if( hGroupID > 0 )
     101              10 :   H5Gclose( hGroupID );
     102              10 :     CSLDestroy( papszSubDatasets );
     103              10 :     if( poH5RootGroup != NULL ){
     104              10 :   DestroyH5Objects( poH5RootGroup );
     105              10 :   CPLFree( poH5RootGroup->pszName );
     106              10 :   CPLFree( poH5RootGroup->pszPath );
     107              10 :   CPLFree( poH5RootGroup->pszUnderscorePath );
     108              10 :   CPLFree( poH5RootGroup->poHchild );
     109              10 :   CPLFree( poH5RootGroup );
     110                 :     }
     111              10 : }
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                            GetDataType()                             */
     115                 : /*                                                                      */
     116                 : /*      Transform HDF5 datatype to GDAL datatype                        */
     117                 : /************************************************************************/
     118              11 : GDALDataType HDF5Dataset::GetDataType(hid_t TypeID) 
     119                 : {
     120              11 :     if( H5Tequal( H5T_NATIVE_CHAR,        TypeID ) )
     121               0 :   return GDT_Byte;
     122              11 :     else if( H5Tequal( H5T_NATIVE_UCHAR,  TypeID ) ) 
     123               4 :   return GDT_Byte;
     124               7 :     else if( H5Tequal( H5T_NATIVE_SHORT,  TypeID ) )
     125               1 :   return GDT_Int16;
     126               6 :     else if( H5Tequal( H5T_NATIVE_USHORT, TypeID ) ) 
     127               0 :   return GDT_UInt16;
     128               6 :     else if( H5Tequal( H5T_NATIVE_INT,    TypeID ) ) 
     129               6 :   return GDT_Int32;      
     130               0 :     else if( H5Tequal( H5T_NATIVE_UINT,   TypeID ) ) 
     131               0 :   return GDT_UInt32;
     132               0 :     else if( H5Tequal( H5T_NATIVE_LONG,   TypeID ) ) 
     133                 :     {
     134                 :         if( sizeof(long) == 4 )
     135                 :             return GDT_Int32;      
     136                 :         else
     137               0 :             return GDT_Unknown;
     138                 :     }
     139               0 :     else if( H5Tequal( H5T_NATIVE_ULONG,  TypeID ) ) 
     140                 :     {
     141                 :         if( sizeof(unsigned long) == 4 )
     142                 :             return GDT_UInt32;      
     143                 :         else
     144               0 :             return GDT_Unknown;
     145                 :     }
     146               0 :     else if( H5Tequal( H5T_NATIVE_FLOAT,  TypeID ) ) 
     147               0 :   return GDT_Float32;
     148               0 :     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) ) 
     149               0 :   return GDT_Float64;
     150               0 :     else if( H5Tequal( H5T_NATIVE_LLONG,  TypeID ) ) 
     151               0 :   return GDT_Unknown;
     152               0 :     else if( H5Tequal( H5T_NATIVE_ULLONG, TypeID ) ) 
     153               0 :   return GDT_Unknown;
     154               0 :     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) ) 
     155               0 :   return GDT_Unknown;
     156                 : 
     157               0 :     return GDT_Unknown;
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                          GetDataTypeName()                           */
     162                 : /*                                                                      */
     163                 : /*      Return the human readable name of data type                     */
     164                 : /************************************************************************/
     165               2 : const char *HDF5Dataset::GetDataTypeName(hid_t TypeID)
     166                 : {
     167               2 :     if( H5Tequal( H5T_NATIVE_CHAR,        TypeID ) )
     168               0 :   return "8-bit character";
     169               2 :     else if( H5Tequal( H5T_NATIVE_UCHAR,  TypeID ) ) 
     170               0 :   return "8-bit unsigned character";    
     171               2 :     else if( H5Tequal( H5T_NATIVE_SHORT,  TypeID ) )
     172               0 :   return "16-bit integer";
     173               2 :     else if( H5Tequal( H5T_NATIVE_USHORT, TypeID ) ) 
     174               0 :   return "16-bit unsigned integer";
     175               2 :     else if( H5Tequal( H5T_NATIVE_INT,    TypeID ) ) 
     176               2 :   return "32-bit integer";
     177               0 :     else if( H5Tequal( H5T_NATIVE_UINT,   TypeID ) ) 
     178               0 :   return "32-bit unsigned integer";
     179               0 :     else if( H5Tequal( H5T_NATIVE_LONG,   TypeID ) ) 
     180               0 :   return "32/64-bit integer";
     181               0 :     else if( H5Tequal( H5T_NATIVE_ULONG,  TypeID ) ) 
     182               0 :   return "32/64-bit unsigned integer";
     183               0 :     else if( H5Tequal( H5T_NATIVE_FLOAT,  TypeID ) ) 
     184               0 :   return "32-bit floating-point";
     185               0 :     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) ) 
     186               0 :   return "64-bit floating-point";
     187               0 :     else if( H5Tequal( H5T_NATIVE_LLONG,  TypeID ) ) 
     188               0 :   return "64-bit integer";
     189               0 :     else if( H5Tequal( H5T_NATIVE_ULLONG, TypeID ) ) 
     190               0 :   return "64-bit unsigned integer";
     191               0 :     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) ) 
     192               0 :         return "64-bit floating-point";
     193                 :     
     194               0 :     return "Unknown";
     195                 : }
     196                 : 
     197                 : /************************************************************************/
     198                 : /*                              Identify()                              */
     199                 : /************************************************************************/
     200                 : 
     201            9582 : int HDF5Dataset::Identify( GDALOpenInfo * poOpenInfo )
     202                 : 
     203                 : {
     204                 : /* -------------------------------------------------------------------- */
     205                 : /*      Is it an HDF5 file?                                             */
     206                 : /* -------------------------------------------------------------------- */
     207                 :     static const char achSignature[] = "\211HDF\r\n\032\n";
     208                 : 
     209            9582 :     if( poOpenInfo->pabyHeader == NULL
     210                 :         || memcmp(poOpenInfo->pabyHeader,achSignature,8) != 0 )
     211            9581 :         return FALSE;
     212                 : 
     213               1 :     return TRUE;
     214                 : }
     215                 : 
     216                 : /************************************************************************/
     217                 : /*                                Open()                                */
     218                 : /************************************************************************/
     219            1337 : GDALDataset *HDF5Dataset::Open( GDALOpenInfo * poOpenInfo )
     220                 : {
     221                 :     HDF5Dataset *poDS;
     222                 :     CPLErr      Err;
     223                 :     
     224            1337 :     if( !Identify( poOpenInfo ) )
     225            1336 :         return NULL;
     226                 : 
     227                 : /* -------------------------------------------------------------------- */
     228                 : /*      Create datasource.                                              */
     229                 : /* -------------------------------------------------------------------- */
     230               1 :     poDS = new HDF5Dataset();
     231                 : 
     232               1 :     poDS->SetDescription( poOpenInfo->pszFilename );
     233                 : 
     234                 : /* -------------------------------------------------------------------- */
     235                 : /*      Try opening the dataset.                                        */
     236                 : /* -------------------------------------------------------------------- */
     237                 :     poDS->hHDF5 = H5Fopen( poOpenInfo->pszFilename, 
     238                 :          H5F_ACC_RDONLY, 
     239               1 :          H5P_DEFAULT );
     240               1 :     if( poDS->hHDF5 < 0 )  {
     241               0 :         delete poDS;
     242               0 :     return NULL;
     243                 :     }
     244                 :     
     245               1 :     poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" ); 
     246               1 :     if( poDS->hGroupID < 0 ){
     247               0 :   poDS->bIsHDFEOS=false;
     248               0 :         delete poDS;
     249               0 :   return NULL;
     250                 :     }
     251                 :     
     252               1 :     poDS->bIsHDFEOS=true;
     253               1 :     Err = poDS->ReadGlobalAttributes( true );
     254                 : 
     255               1 :     poDS->SetMetadata( poDS->papszMetadata  );
     256                 :     
     257               1 :     if ( CSLCount( poDS->papszSubDatasets ) / 2 >= 1 )
     258               1 :         poDS->SetMetadata( poDS->papszSubDatasets, "SUBDATASETS" );
     259                 : 
     260                 :     // Make sure we don't try to do any pam stuff with this dataset.
     261               1 :     poDS->nPamFlags |= GPF_NOSAVE;
     262                 : 
     263                 : /* -------------------------------------------------------------------- */
     264                 : /*      If we have single subdataset only, open it immediately          */
     265                 : /* -------------------------------------------------------------------- */
     266               1 :     int nSubDatasets = CSLCount( poDS->papszSubDatasets ) / 2;
     267               1 :     if( nSubDatasets == 1 )
     268                 :     {
     269                 :         CPLString osDSName = CSLFetchNameValue( poDS->papszSubDatasets,
     270               0 :                                                 "SUBDATASET_1_NAME" );
     271               0 :         delete poDS;
     272               0 :         return (GDALDataset *) GDALOpen( osDSName, poOpenInfo->eAccess );
     273                 :     }
     274                 :     else
     275                 :     {
     276                 : /* -------------------------------------------------------------------- */
     277                 : /*      Confirm the requested access is supported.                      */
     278                 : /* -------------------------------------------------------------------- */
     279               1 :         if( poOpenInfo->eAccess == GA_Update )
     280                 :         {
     281               0 :             delete poDS;
     282                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     283                 :                       "The HDF5 driver does not support update access to existing"
     284               0 :                       " datasets.\n" );
     285               0 :             return NULL;
     286                 :         }
     287                 :     }
     288               1 :     return( poDS );
     289                 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                          DestroyH5Objects()                          */
     293                 : /*                                                                      */
     294                 : /*      Erase all objects                                               */
     295                 : /************************************************************************/
     296              52 : void HDF5Dataset::DestroyH5Objects( HDF5GroupObjects *poH5Object )
     297                 : {
     298                 :     int i;
     299                 : 
     300                 : 
     301                 : /* -------------------------------------------------------------------- */
     302                 : /*      Visit all objects                                               */
     303                 : /* -------------------------------------------------------------------- */
     304                 : 
     305              94 :     for( i=0; i < poH5Object->nbObjs; i++ )
     306              42 :   if( poH5Object->poHchild+i != NULL )
     307              42 :       DestroyH5Objects( poH5Object->poHchild+i );
     308                 : 
     309              52 :     if( poH5Object->poHparent ==NULL )
     310              10 :   return;
     311                 : 
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      Erase some data                                                 */
     314                 : /* -------------------------------------------------------------------- */
     315              42 :     CPLFree( poH5Object->paDims );
     316              42 :     poH5Object->paDims = NULL; 
     317                 : 
     318              42 :     CPLFree( poH5Object->pszPath );
     319              42 :     poH5Object->pszPath = NULL;
     320                 : 
     321              42 :     CPLFree( poH5Object->pszName );
     322              42 :     poH5Object->pszName = NULL;
     323                 : 
     324              42 :     CPLFree( poH5Object->pszUnderscorePath );
     325              42 :     poH5Object->pszUnderscorePath = NULL;
     326                 : /* -------------------------------------------------------------------- */
     327                 : /*      All Children are visited and can be deleted.                    */
     328                 : /* -------------------------------------------------------------------- */
     329              42 :     if( ( i==poH5Object->nbObjs ) && ( poH5Object->nbObjs!=0 ) ) {
     330              18 :   CPLFree( poH5Object->poHchild );
     331              18 :         poH5Object->poHchild = NULL;
     332                 :     }
     333                 : 
     334                 : }
     335                 : 
     336                 : /************************************************************************/
     337                 : /*                             CreatePath()                             */
     338                 : /*                                                                      */
     339                 : /*      Find Dataset path for HDopen                                    */
     340                 : /************************************************************************/
     341             125 : char* CreatePath( HDF5GroupObjects *poH5Object )
     342                 : {
     343                 :     char pszPath[8192];
     344                 :     char pszUnderscoreSpaceInName[8192];
     345                 :     char *popszPath;
     346                 :     int  i;
     347                 :     char **papszPath;
     348                 : 
     349                 : /* -------------------------------------------------------------------- */
     350                 : /*      Recurse to the root path                                        */
     351                 : /* -------------------------------------------------------------------- */
     352             125 :     pszPath[0]='\0';
     353             125 :     if( poH5Object->poHparent !=NULL ) {
     354              83 :   popszPath=CreatePath( poH5Object->poHparent );
     355              83 :   strcpy( pszPath,popszPath );
     356                 :     }
     357                 :   
     358                 : /* -------------------------------------------------------------------- */
     359                 : /*      add name to the path                                            */
     360                 : /* -------------------------------------------------------------------- */
     361             125 :     if( !EQUAL( poH5Object->pszName,"/" ) ){
     362              83 :   strcat( pszPath,"/" );
     363              83 :   strcat( pszPath,poH5Object->pszName );
     364                 :     }
     365                 : 
     366                 : /* -------------------------------------------------------------------- */
     367                 : /*      fill up path for each object                                    */
     368                 : /* -------------------------------------------------------------------- */
     369             125 :     if( poH5Object->pszPath == NULL ) {
     370                 : 
     371              52 :   if( strlen( poH5Object->pszName ) == 1 ) {
     372              10 :       strcat(pszPath, poH5Object->pszName );
     373              10 :       strcpy(pszUnderscoreSpaceInName, poH5Object->pszName);
     374                 :   }
     375                 :   else {
     376                 : /* -------------------------------------------------------------------- */
     377                 : /*      Change space for underscore                                     */
     378                 : /* -------------------------------------------------------------------- */
     379                 :       papszPath = CSLTokenizeString2( pszPath,
     380              42 :               " ", CSLT_HONOURSTRINGS );
     381                 :       
     382              42 :       strcpy(pszUnderscoreSpaceInName,papszPath[0]);
     383              50 :       for( i=1; i < CSLCount( papszPath ); i++ ) {
     384               8 :     strcat( pszUnderscoreSpaceInName, "_" );
     385               8 :     strcat( pszUnderscoreSpaceInName, papszPath[ i ] );
     386                 :       }
     387              42 :       CSLDestroy(papszPath);
     388                 : 
     389                 :   }
     390                 :   poH5Object->pszUnderscorePath  = 
     391              52 :       CPLStrdup( pszUnderscoreSpaceInName );
     392              52 :   poH5Object->pszPath  = CPLStrdup( pszPath );
     393                 :     }
     394                 : 
     395             125 :     return( poH5Object->pszPath );
     396                 : }
     397                 : 
     398                 : /************************************************************************/
     399                 : /*                      HDF5GroupCheckDuplicate()                       */
     400                 : /*                                                                      */
     401                 : /*      Returns TRUE if an ancestor has the same objno[] as passed      */
     402                 : /*      in - used to avoid looping in files with "links up" #(3218).    */
     403                 : /************************************************************************/
     404                 : 
     405                 : static int HDF5GroupCheckDuplicate( HDF5GroupObjects *poHparent,
     406              24 :                                     unsigned long *objno )
     407                 : 
     408                 : {
     409              91 :     while( poHparent != NULL )
     410                 :     {
     411              43 :         if( poHparent->objno[0] == objno[0]
     412                 :             && poHparent->objno[1] == objno[1] )
     413               0 :             return TRUE;
     414                 : 
     415              43 :         poHparent = poHparent->poHparent;
     416                 :     }
     417                 : 
     418              24 :     return FALSE;
     419                 : }
     420                 : 
     421                 : /************************************************************************/
     422                 : /*                      HDF5CreateGroupObjs()                           */
     423                 : /*                                                                      */
     424                 : /*      Create HDF5 hierarchy into a linked list                        */
     425                 : /************************************************************************/
     426                 : herr_t HDF5CreateGroupObjs(hid_t hHDF5, const char *pszObjName, 
     427              42 :          void *poHObjParent)
     428                 : {
     429                 :     herr_t  ret;      /* error return status */
     430                 :     hid_t hGroupID;   /* identifier of group */
     431                 :     hid_t hDatasetID;   /* identifier of dataset */
     432              42 :     hsize_t     nbObjs=0;   /* number of objects in a group */
     433              42 :     int         nbAttrs=0;    /* number of attributes in object */
     434                 :     int   idx;
     435                 :     int         n_dims;
     436                 :     H5G_stat_t  oStatbuf;
     437              42 :     hsize_t     *dims=NULL;
     438              42 :     hsize_t     *maxdims=NULL;
     439                 :     hid_t       datatype;
     440                 :     hid_t       dataspace;
     441                 :     hid_t       native;
     442                 :     herr_t status;
     443                 : 
     444                 :     char *CreatePath( HDF5GroupObjects *poH5Object );
     445                 : 
     446                 :     HDF5GroupObjects *poHchild;
     447                 :     HDF5GroupObjects *poHparent;
     448                 : 
     449              42 :     poHparent = ( HDF5GroupObjects * ) poHObjParent;
     450              42 :     poHchild=poHparent->poHchild;
     451                 : 
     452              42 :     if( H5Gget_objinfo( hHDF5, pszObjName, FALSE, &oStatbuf ) < 0  )
     453               0 :   return -1;
     454                 : 
     455                 :     
     456                 : /* -------------------------------------------------------------------- */
     457                 : /*      Look for next child                                             */
     458                 : /* -------------------------------------------------------------------- */
     459              61 :     for( idx=0; idx < poHparent->nbObjs; idx++ )  {
     460              61 :   if( poHchild->pszName == NULL ) break;
     461              19 :   poHchild++;
     462                 :     }
     463                 : 
     464              42 :     if( idx == poHparent->nbObjs ) 
     465               0 :   return -1;  // all children parsed
     466                 :     
     467                 : /* -------------------------------------------------------------------- */
     468                 : /*      Save child information                                          */
     469                 : /* -------------------------------------------------------------------- */
     470              42 :     poHchild->pszName  = CPLStrdup( pszObjName );
     471                 :     
     472              42 :     poHchild->nType  = oStatbuf.type;
     473              42 :     poHchild->nIndex = idx;
     474              42 :     poHchild->poHparent = poHparent;
     475              42 :     poHchild->nRank     = 0;
     476              42 :     poHchild->paDims    = 0;
     477              42 :     poHchild->HDatatype = 0;
     478              42 :     poHchild->objno[0]  = oStatbuf.objno[0];
     479              42 :     poHchild->objno[1]  = oStatbuf.objno[1];
     480              42 :     if( poHchild->pszPath == NULL ) {
     481              42 :   poHchild->pszPath  = CreatePath( poHchild );
     482                 :     }
     483              42 :     if( poHparent->pszPath == NULL ) {
     484               0 :   poHparent->pszPath = CreatePath( poHparent );
     485                 :     }
     486                 : 
     487                 : 
     488              42 :     switch ( oStatbuf.type ) 
     489                 :   {
     490                 :   case H5G_LINK:
     491               0 :       poHchild->nbAttrs = 0;
     492               0 :       poHchild->nbObjs = 0;
     493               0 :       poHchild->poHchild = NULL;
     494               0 :       poHchild->nRank      = 0;
     495               0 :       poHchild->paDims    = 0;
     496               0 :       poHchild->HDatatype = 0;
     497               0 :       break;
     498                 :       
     499                 :   case H5G_GROUP:
     500              24 :       if( ( hGroupID = H5Gopen( hHDF5, pszObjName ) ) == -1  ) {
     501                 :     printf( "Error: unable to access \"%s\" group.\n", 
     502               0 :       pszObjName );
     503               0 :     return -1;
     504                 :       }
     505              24 :       nbAttrs          = H5Aget_num_attrs( hGroupID );
     506              24 :       ret              = H5Gget_num_objs( hGroupID, &nbObjs );
     507              24 :       poHchild->nbAttrs= nbAttrs;
     508              24 :       poHchild->nbObjs = nbObjs;
     509              24 :       poHchild->nRank      = 0;
     510              24 :       poHchild->paDims    = 0;
     511              24 :       poHchild->HDatatype = 0;
     512                 :       
     513              24 :       if( nbObjs > 0 ) {
     514                 :     poHchild->poHchild =( HDF5GroupObjects * )
     515              18 :         CPLCalloc( nbObjs, sizeof( HDF5GroupObjects ) );
     516                 :     memset( poHchild->poHchild,0,
     517              18 :       sizeof( HDF5GroupObjects ) * nbObjs );
     518                 :       }
     519                 :       else 
     520               6 :     poHchild->poHchild = NULL;
     521                 : 
     522              24 :             if( !HDF5GroupCheckDuplicate( poHparent, oStatbuf.objno ) )
     523                 :                 H5Giterate( hHDF5, pszObjName, NULL, 
     524              24 :                             HDF5CreateGroupObjs,  (void*) poHchild );
     525                 :             else
     526                 :                 CPLDebug( "HDF5", "avoiding link looping on node '%s'.", 
     527               0 :                           pszObjName );
     528              24 :       H5Gclose( hGroupID );
     529              24 :       break;
     530                 :       
     531                 :   case H5G_DATASET:
     532                 :       
     533              18 :       if( ( hDatasetID = H5Dopen( hHDF5, pszObjName ) ) == -1  ) {
     534                 :     printf( "Error: unable to access \"%s\" dataset.\n", 
     535               0 :            pszObjName );
     536               0 :     return -1;
     537                 :       }
     538              18 :       nbAttrs      = H5Aget_num_attrs( hDatasetID );
     539              18 :       datatype     = H5Dget_type( hDatasetID );
     540              18 :       dataspace    = H5Dget_space( hDatasetID );
     541              18 :       n_dims       = H5Sget_simple_extent_ndims( dataspace );
     542              18 :       native       = H5Tget_native_type( datatype, H5T_DIR_ASCEND );
     543                 :       
     544              18 :       if( n_dims > 0 ) {
     545              17 :     dims     = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) );
     546              17 :     maxdims  = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) );
     547                 :       }
     548              18 :       status     = H5Sget_simple_extent_dims( dataspace, dims, maxdims );
     549              18 :       if( maxdims != NULL )
     550              17 :     CPLFree( maxdims );
     551                 :       
     552              18 :       if( n_dims > 0 ) {
     553              17 :     poHchild->nRank     = n_dims;   // rank of the array
     554              17 :     poHchild->paDims    = dims;      // dimmension of the array.
     555              17 :     poHchild->HDatatype = datatype;  // HDF5 datatype
     556                 :       }
     557                 :       else  {
     558               1 :     poHchild->nRank     = -1;
     559               1 :     poHchild->paDims    = NULL;
     560               1 :     poHchild->HDatatype = 0;
     561                 :   }
     562              18 :       poHchild->nbAttrs   = nbAttrs;
     563              18 :       poHchild->nbObjs    = 0;
     564              18 :       poHchild->poHchild  = NULL;
     565              18 :       poHchild->native    = native;
     566              18 :       ret                 = H5Dclose( hDatasetID );
     567              18 :       break;
     568                 :       
     569                 :   case H5G_TYPE:
     570               0 :       poHchild->nbAttrs = 0;
     571               0 :       poHchild->nbObjs = 0;
     572               0 :       poHchild->poHchild = NULL;
     573               0 :       poHchild->nRank      = 0;
     574               0 :       poHchild->paDims    = 0;
     575               0 :       poHchild->HDatatype = 0;
     576                 :       break;
     577                 :       
     578                 :   default:
     579                 :       break;
     580                 :   }
     581                 :     
     582              42 :     return 0;
     583                 : }
     584                 : 
     585                 : 
     586                 : /************************************************************************/
     587                 : /*                          HDF5AttrIterate()                           */
     588                 : /************************************************************************/
     589                 : 
     590                 : herr_t HDF5AttrIterate( hid_t hH5ObjID, 
     591                 :       const char *AttrName, 
     592              17 :       void *pDS )
     593                 : {
     594                 :     hid_t           hAttrID;
     595                 :     hid_t           hAttrTypeID;
     596                 :     hid_t           hAttrNativeType;
     597                 :     hid_t           hAttrSpace;
     598                 : 
     599                 :     char            szData[8192];
     600                 :     hsize_t        nSize[64];
     601                 :     unsigned int            nAttrElmts;
     602                 :     hsize_t        nAttrSize;
     603                 :     hsize_t        i;
     604              17 :     void           *buf = NULL;
     605                 :     unsigned int             nAttrDims;
     606                 : 
     607                 : 
     608                 :     HDF5Dataset    *poDS;
     609                 :     char            szTemp[8192];
     610                 :     char            szValue[8192];
     611                 : 
     612              17 :     poDS = (HDF5Dataset *) pDS;
     613                 :     sprintf( szTemp, "%s:%s", poDS->poH5CurrentObject->pszName, 
     614              17 :        AttrName );
     615                 : 
     616              17 :     hAttrID          = H5Aopen_name( hH5ObjID, AttrName );
     617              17 :     hAttrTypeID      = H5Aget_type( hAttrID );
     618              17 :     hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
     619              17 :     hAttrSpace       = H5Aget_space( hAttrID );
     620              17 :     nAttrDims        = H5Sget_simple_extent_dims( hAttrSpace, nSize, NULL );
     621                 : 
     622                 : 
     623              17 :     szValue[0] ='\0';
     624                 : 
     625              17 :     if( H5Tget_class( hAttrNativeType ) == H5T_STRING ) {
     626              13 :   nAttrSize = H5Tget_size( hAttrTypeID );
     627              13 :   H5Aread( hAttrID, hAttrNativeType, szData  );
     628              13 :   szData[nAttrSize]='\0';
     629              13 :   sprintf( szValue, "%s", szData );
     630                 : 
     631                 :     }
     632                 :     else {
     633               4 :   nAttrElmts = 1;
     634               6 :   for( i=0; i < nAttrDims; i++ ) {
     635               2 :       nAttrElmts *= nSize[i];
     636                 :   }
     637               4 :   if( nAttrElmts > 0 ){
     638                 :       buf = (void *) CPLMalloc( nAttrElmts*
     639               4 :               H5Tget_size( hAttrNativeType ));
     640               4 :       H5Aread( hAttrID, hAttrNativeType, buf );
     641                 :   }
     642               4 :   if( H5Tequal( H5T_NATIVE_CHAR, hAttrNativeType ) ){
     643               0 :       for( i=0; i < nAttrElmts; i++ ) {
     644               0 :     sprintf( szData, "%c ", ((char *) buf)[i]);
     645               0 :     strcat(szValue,szData);
     646                 :       }
     647                 :   }
     648               4 :   else if( H5Tequal( H5T_NATIVE_UCHAR,  hAttrNativeType ) ) {
     649               0 :       for( i=0; i < nAttrElmts; i++ ) {
     650               0 :     sprintf( szData, "%c", ((char *) buf)[i] );
     651               0 :     strcat(szValue,szData);
     652                 :       }
     653                 :   }
     654               4 :   else if( H5Tequal( H5T_NATIVE_SHORT,  hAttrNativeType ) ) {
     655               2 :       for( i=0; i < nAttrElmts; i++ ) {
     656               1 :     sprintf( szData, "%d ", ((short *) buf)[i] );
     657               1 :     strcat(szValue,szData);
     658                 :       }
     659                 :   }
     660               3 :   else if( H5Tequal( H5T_NATIVE_USHORT, hAttrNativeType ) ) {
     661               4 :       for( i=0; i < nAttrElmts; i++ ) {
     662               2 :     sprintf( szData, "%ud ", ((unsigned short *) buf)[i] );
     663               2 :     strcat(szValue,szData);
     664                 :       }
     665                 :   }
     666               1 :   else if( H5Tequal( H5T_NATIVE_INT,    hAttrNativeType ) ) {
     667               0 :       for( i=0; i < nAttrElmts; i++ ) {
     668               0 :     sprintf( szData, "%d ", ((int *) buf)[i] );
     669               0 :     strcat(szValue,szData);
     670                 :       }
     671                 :   }
     672               1 :   else if( H5Tequal( H5T_NATIVE_UINT,   hAttrNativeType ) ) {
     673               0 :       for( i=0; i < nAttrElmts; i++ ) {
     674               0 :     sprintf( szData, "%ud ", ((unsigned int *) buf)[i] );
     675               0 :     strcat(szValue,szData);
     676                 :       }
     677                 :   }
     678               1 :   else if( H5Tequal( H5T_NATIVE_LONG,   hAttrNativeType ) ) {
     679               0 :       for( i=0; i < nAttrElmts; i++ ) {
     680               0 :     sprintf( szData, "%ld ", ((long *)buf)[i] );
     681               0 :     strcat(szValue,szData);
     682                 :       }
     683                 :   }
     684               1 :   else if( H5Tequal( H5T_NATIVE_ULONG,  hAttrNativeType ) ) {
     685               0 :       for( i=0; i < nAttrElmts; i++ ) {
     686               0 :     sprintf( szData, "%ld ", ((unsigned long *)buf)[i] );
     687               0 :     strcat(szValue,szData);
     688                 :       }
     689                 :   }
     690               1 :   else if( H5Tequal( H5T_NATIVE_FLOAT,  hAttrNativeType ) ) {
     691               0 :       for( i=0; i < nAttrElmts; i++ ) {
     692               0 :     sprintf( szData, "%f ",  ((float *)buf)[i] );
     693               0 :     strcat(szValue,szData);
     694                 :       }
     695                 :   }
     696               1 :   else if( H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) ) {
     697               0 :       for( i=0; i < nAttrElmts; i++ ) {
     698               0 :     sprintf( szData, "%g ",  ((double *)buf)[i] );
     699               0 :     strcat(szValue,szData);
     700                 :       }
     701                 :   }
     702               4 :   CPLFree( buf );
     703                 : 
     704                 :     }
     705              17 :     H5Aclose( hAttrID );
     706                 :     //printf( "%s = %s\n",szTemp, szValue );
     707                 :     poDS->papszMetadata =
     708                 :   CSLSetNameValue( poDS->papszMetadata, szTemp,  
     709              17 :        CPLSPrintf( "%s", szValue ) );
     710                 : 
     711              17 :     return 0;
     712                 : }
     713                 : 
     714                 : /************************************************************************/
     715                 : /*                           CreateMetadata()                           */
     716                 : /************************************************************************/
     717              43 : CPLErr HDF5Dataset::CreateMetadata( HDF5GroupObjects *poH5Object, int nType)
     718                 : {
     719                 :     hid_t hGroupID;   /* identifier of group */
     720                 :     hid_t       hDatasetID;
     721                 :     int         nbAttrs;
     722                 :     herr_t      ret;
     723                 : 
     724                 :     HDF5Dataset *poDS;
     725                 : 
     726              43 :     if( !poH5Object->pszPath )
     727               0 :         return CE_None;
     728                 : 
     729              43 :     poDS = this;
     730                 : 
     731              43 :     poH5CurrentObject = poH5Object;
     732              43 :     nbAttrs = poH5Object->nbAttrs;
     733                 : 
     734              43 :     if( poH5Object->pszPath == NULL || EQUAL(poH5Object->pszPath, "" ) )
     735               0 :   return CE_None;
     736                 : 
     737              43 :     switch( nType ) {
     738                 : 
     739                 :     case H5G_GROUP:
     740                 : 
     741              34 :   hGroupID = H5Gopen( hHDF5, poH5Object->pszPath );
     742              34 :   if( nbAttrs > 0 ) { 
     743                 :       ret = H5Aiterate( hGroupID, NULL, 
     744               1 :             HDF5AttrIterate, (void *)poDS  );
     745               1 :       ret = H5Gclose( hGroupID );
     746                 :   }
     747                 : 
     748              34 :   break;
     749                 : 
     750                 :     case H5G_DATASET:
     751                 : 
     752               9 :   hDatasetID =  H5Dopen(hHDF5, poH5Object->pszPath );
     753                 : 
     754               9 :   if( nbAttrs > 0 ) { 
     755                 :       ret = H5Aiterate( hDatasetID, NULL, 
     756               3 :             HDF5AttrIterate, (void *)poDS );
     757               3 :       ret = H5Dclose( hDatasetID );
     758                 :   }
     759                 :   break;
     760                 : 
     761                 :     default:
     762                 :   break;
     763                 :     }
     764                 : 
     765              43 :     return CE_None;
     766                 : }
     767                 : 
     768                 : 
     769                 : /************************************************************************/
     770                 : /*                       HDF5FindDatasetObjectsbyPath()                 */
     771                 : /*      Find object by name                                             */
     772                 : /************************************************************************/
     773                 : HDF5GroupObjects* HDF5Dataset::HDF5FindDatasetObjectsbyPath
     774              43 :     ( HDF5GroupObjects *poH5Objects, char* pszDatasetPath )
     775                 : {
     776                 :     int i;
     777                 :     HDF5Dataset *poDS;
     778                 :     HDF5GroupObjects *poObjectsFound;
     779              43 :     poDS=this;
     780                 :     
     781              43 :     if( poH5Objects->nType == H5G_DATASET &&
     782                 :        EQUAL( poH5Objects->pszUnderscorePath,pszDatasetPath ) )  {
     783                 :       /*      printf("found it! %ld\n",(long) poH5Objects);*/
     784               9 :       return( poH5Objects );
     785                 :   }
     786                 :     
     787              34 :     if( poH5Objects->nbObjs >0 )
     788              40 :   for( i=0; i <poH5Objects->nbObjs; i++ )   {
     789                 :       poObjectsFound=
     790                 :     poDS->HDF5FindDatasetObjectsbyPath( poH5Objects->poHchild+i, 
     791              34 :                 pszDatasetPath );
     792                 : /* -------------------------------------------------------------------- */
     793                 : /*      Is this our dataset??                                           */
     794                 : /* -------------------------------------------------------------------- */
     795              34 :       if( poObjectsFound != NULL ) return( poObjectsFound );
     796                 :   }
     797                 : /* -------------------------------------------------------------------- */
     798                 : /*      Dataset has not been found!                                     */
     799                 : /* -------------------------------------------------------------------- */
     800              16 :     return( NULL );
     801                 :     
     802                 : }
     803                 : 
     804                 : 
     805                 : /************************************************************************/
     806                 : /*                       HDF5FindDatasetObjects()                       */
     807                 : /*      Find object by name                                             */
     808                 : /************************************************************************/
     809                 : HDF5GroupObjects* HDF5Dataset::HDF5FindDatasetObjects
     810              14 :     ( HDF5GroupObjects *poH5Objects, char* pszDatasetName )
     811                 : {
     812                 :     int i;
     813                 :     HDF5Dataset *poDS;
     814                 :     HDF5GroupObjects *poObjectsFound;
     815              14 :     poDS=this;
     816                 :     
     817              14 :     if( poH5Objects->nType == H5G_DATASET &&
     818                 :        EQUAL( poH5Objects->pszName,pszDatasetName ) )  {
     819                 :       /*      printf("found it! %ld\n",(long) poH5Objects);*/
     820               0 :       return( poH5Objects );
     821                 :   }
     822                 :     
     823              14 :     if( poH5Objects->nbObjs >0 )
     824              21 :   for( i=0; i <poH5Objects->nbObjs; i++ )   {
     825                 :       poObjectsFound=
     826                 :     poDS->HDF5FindDatasetObjects( poH5Objects->poHchild+i, 
     827              12 :                 pszDatasetName );
     828                 : /* -------------------------------------------------------------------- */
     829                 : /*      Is this our dataset??                                           */
     830                 : /* -------------------------------------------------------------------- */
     831              12 :       if( poObjectsFound != NULL ) return( poObjectsFound );
     832                 :       
     833                 :   }
     834                 : /* -------------------------------------------------------------------- */
     835                 : /*      Dataset has not been found!                                     */
     836                 : /* -------------------------------------------------------------------- */
     837              14 :     return( NULL );
     838                 :     
     839                 : }
     840                 : 
     841                 : 
     842                 : /************************************************************************/
     843                 : /*                        HDF5ListGroupObjects()                        */
     844                 : /*                                                                      */
     845                 : /*      List all objects in HDF5                                        */
     846                 : /************************************************************************/
     847                 : CPLErr HDF5Dataset::HDF5ListGroupObjects( HDF5GroupObjects *poRootGroup,
     848              52 :             int bSUBDATASET )
     849                 : {
     850                 :     int i;
     851                 :     char szTemp[8192];
     852                 :     char szDim[8192];
     853                 :     HDF5Dataset *poDS;
     854              52 :     poDS=this;
     855                 :     
     856              52 :     if( poRootGroup->nbObjs >0 )  
     857              70 :   for( i=0; i < poRootGroup->nbObjs; i++ ) {
     858              42 :       poDS->HDF5ListGroupObjects( poRootGroup->poHchild+i, bSUBDATASET );
     859                 :   }
     860                 :     
     861                 : 
     862              52 :     if( poRootGroup->nType == H5G_GROUP ) {
     863              34 :   CreateMetadata( poRootGroup, H5G_GROUP );
     864                 :     }
     865                 : 
     866                 : /* -------------------------------------------------------------------- */
     867                 : /*      Create Sub dataset list                                         */
     868                 : /* -------------------------------------------------------------------- */
     869              52 :     if( (poRootGroup->nType == H5G_DATASET ) && bSUBDATASET 
     870                 :         && poDS->GetDataType( poRootGroup->native ) == GDT_Unknown )
     871                 :     {
     872                 :         CPLDebug( "HDF5", "Skipping unsupported %s of type %s", 
     873                 :                   poRootGroup->pszUnderscorePath, 
     874               0 :                   poDS->GetDataTypeName( poRootGroup->native ) );
     875                 :     }
     876              52 :     else if( (poRootGroup->nType == H5G_DATASET ) && bSUBDATASET ) 
     877                 :     {
     878               2 :   szDim[0]='\0';
     879               2 :   switch( poRootGroup->nRank ) {
     880                 :   case 3: 
     881                 :       sprintf( szTemp,"%dx%dx%d",
     882                 :         (int)poRootGroup->paDims[0],
     883                 :         (int)poRootGroup->paDims[1],
     884               0 :         (int)poRootGroup->paDims[2] );
     885               0 :       break;
     886                 :       
     887                 :     case 2: 
     888                 :       sprintf( szTemp,"%dx%d",
     889                 :         (int)poRootGroup->paDims[0],
     890               2 :         (int)poRootGroup->paDims[1] );
     891               2 :     break;
     892                 :         default:
     893               0 :       return CE_None;
     894                 :       
     895                 :   }
     896               2 :   strcat( szDim,szTemp );
     897                 :   
     898               2 :   sprintf( szTemp, "SUBDATASET_%d_NAME", ++(poDS->nSubDataCount) );
     899                 : 
     900                 :   poDS->papszSubDatasets =
     901                 :       CSLSetNameValue( poDS->papszSubDatasets, szTemp,
     902                 :           CPLSPrintf( "HDF5:\"%s\":%s",
     903                 :           poDS->GetDescription(),
     904               2 :           poRootGroup->pszUnderscorePath ) );
     905                 :   
     906               2 :   sprintf(  szTemp, "SUBDATASET_%d_DESC", poDS->nSubDataCount );
     907                 :   
     908                 :   poDS->papszSubDatasets =
     909                 :       CSLSetNameValue( poDS->papszSubDatasets, szTemp,
     910                 :           CPLSPrintf( "[%s] %s (%s)", 
     911                 :           szDim,
     912                 :           poRootGroup->pszUnderscorePath,
     913                 :           poDS->GetDataTypeName
     914               2 :           ( poRootGroup->native ) ) );
     915                 : 
     916                 :     }
     917                 :     
     918              52 :     return CE_None;
     919                 : }
     920                 : 
     921                 : 
     922                 : /************************************************************************/
     923                 : /*                       ReadGlobalAttributes()                         */
     924                 : /************************************************************************/
     925              10 : CPLErr HDF5Dataset::ReadGlobalAttributes(int bSUBDATASET)
     926                 : {
     927                 :     
     928                 :     HDF5GroupObjects *poRootGroup;
     929                 :     
     930              10 :     poRootGroup = (HDF5GroupObjects*) CPLCalloc(sizeof(HDF5GroupObjects), 1);
     931                 :     
     932              10 :     poH5RootGroup=poRootGroup;
     933              10 :     poRootGroup->pszName   = CPLStrdup( "/" );
     934              10 :     poRootGroup->nType     = H5G_GROUP;
     935              10 :     poRootGroup->poHparent = NULL;
     936              10 :     poRootGroup->pszPath = NULL;
     937              10 :     poRootGroup->pszUnderscorePath = NULL;
     938                 : 
     939              10 :     if( hHDF5 < 0 )  {
     940               0 :   printf( "hHDF5 <0!!\n" );
     941               0 :   return CE_None;
     942                 :     }
     943                 :     
     944                 :     H5G_stat_t  oStatbuf;
     945              10 :     if( H5Gget_objinfo( hHDF5, "/", FALSE, &oStatbuf ) < 0  )
     946               0 :   return CE_Failure;
     947              10 :     poRootGroup->objno[0] = oStatbuf.objno[0];
     948              10 :     poRootGroup->objno[1] = oStatbuf.objno[1];
     949                 :     
     950              10 :     hGroupID = H5Gopen( hHDF5, "/" ); 
     951              10 :     if( hGroupID < 0 ){
     952               0 :   printf( "hGroupID <0!!\n" );
     953               0 :   return CE_None;
     954                 :     }
     955                 :     
     956              10 :     poRootGroup->nbAttrs = H5Aget_num_attrs( hGroupID );
     957                 : 
     958              10 :     H5Gget_num_objs( hGroupID, (hsize_t *) &( poRootGroup->nbObjs ) );
     959                 :     
     960              10 :     if( poRootGroup->nbObjs > 0 ) {
     961                 :   poRootGroup->poHchild = ( HDF5GroupObjects * ) 
     962                 :       CPLCalloc( poRootGroup->nbObjs,
     963              10 :     sizeof( HDF5GroupObjects ) );
     964                 :   H5Giterate( hGroupID, "/", NULL, 
     965              10 :        HDF5CreateGroupObjs, (void *)poRootGroup );
     966                 :     }
     967               0 :     else poRootGroup->poHchild = NULL;
     968                 :     
     969              10 :     HDF5ListGroupObjects( poRootGroup, bSUBDATASET );
     970              10 :     return CE_None;
     971                 : }

Generated by: LTP GCOV extension version 1.5