LCOV - code coverage report
Current view: directory - frmts/hdf5 - hdf5imagedataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 374 278 74.3 %
Date: 2013-03-30 Functions: 26 19 73.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: hdf5imagedataset.cpp 25801 2013-03-25 17:26:49Z antonio $
       3                 :  *
       4                 :  * Project:  Hierarchical Data Format Release 5 (HDF5)
       5                 :  * Purpose:  Read subdatasets of HDF5 file.
       6                 :  * Author:   Denis Nadeau <denis.nadeau@gmail.com>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #define H5_USE_16_API
      31                 : 
      32                 : #include "hdf5.h"
      33                 : 
      34                 : #include "gdal_pam.h"
      35                 : #include "gdal_priv.h"
      36                 : #include "cpl_string.h"
      37                 : #include "hdf5dataset.h"
      38                 : #include "ogr_spatialref.h"
      39                 : 
      40                 : CPL_CVSID("$Id: hdf5imagedataset.cpp 25801 2013-03-25 17:26:49Z antonio $");
      41                 : 
      42                 : CPL_C_START
      43                 : void GDALRegister_HDF5Image(void);
      44                 : CPL_C_END
      45                 : 
      46                 : /* release 1.6.3 or 1.6.4 changed the type of count in some api functions */
      47                 : 
      48                 : #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6 \
      49                 :        && (H5_VERS_MINOR < 6 || H5_VERS_RELEASE < 3)
      50                 : #  define H5OFFSET_TYPE hssize_t
      51                 : #else
      52                 : #  define H5OFFSET_TYPE  hsize_t
      53                 : #endif
      54                 : 
      55                 : class HDF5ImageDataset : public HDF5Dataset
      56                 : {
      57                 :     typedef enum
      58                 :     {
      59                 :         UNKNOWN_PRODUCT=0,
      60                 :         CSK_PRODUCT
      61                 :     } Hdf5ProductType;
      62                 : 
      63                 :     typedef enum
      64                 :     {
      65                 :         PROD_UNKNOWN=0,
      66                 :         PROD_CSK_L0,
      67                 :         PROD_CSK_L1A,
      68                 :         PROD_CSK_L1B,
      69                 :         PROD_CSK_L1C,
      70                 :         PROD_CSK_L1D
      71                 :     } HDF5CSKProductEnum;
      72                 : 
      73                 :     friend class HDF5ImageRasterBand;
      74                 : 
      75                 :     char        *pszProjection;
      76                 :     char        *pszGCPProjection;
      77                 :     GDAL_GCP    *pasGCPList;
      78                 :     int         nGCPCount;
      79                 :     OGRSpatialReference oSRS;
      80                 : 
      81                 :     hsize_t      *dims,*maxdims;
      82                 :     HDF5GroupObjects *poH5Objects;
      83                 :     int          ndims,dimensions;
      84                 :     hid_t        dataset_id;
      85                 :     hid_t        dataspace_id;
      86                 :     hsize_t      size;
      87                 :     haddr_t      address;
      88                 :     hid_t        datatype;
      89                 :     hid_t        native;
      90                 :     H5T_class_t  clas;
      91                 :     int          iSubdatasetType;
      92                 :     double       adfGeoTransform[6];
      93                 :     bool         bHasGeoTransform;
      94                 : 
      95                 : public:
      96                 :     HDF5ImageDataset();
      97                 :     ~HDF5ImageDataset();
      98                 : 
      99                 :     CPLErr CreateProjections( );
     100                 :     static GDALDataset  *Open( GDALOpenInfo * );
     101                 :     static int           Identify( GDALOpenInfo * );
     102                 : 
     103                 :     const char          *GetProjectionRef();
     104                 :     virtual int         GetGCPCount( );
     105                 :     virtual const char  *GetGCPProjection();
     106                 :     virtual const GDAL_GCP *GetGCPs( ); 
     107                 :     virtual CPLErr GetGeoTransform( double * padfTransform );
     108                 : 
     109                 :     /**
     110                 :      * Identify if the subdataset has a known product format
     111                 :      * It stores a product identifier in iSubdatasetType,
     112                 :      * UNKNOWN_PRODUCT, if it isn't a recognizable format.
     113                 :      */
     114                 :     void IdentifyProductType();
     115                 : 
     116                 :     /**
     117                 :      * Captures Geolocation information from a COSMO-SKYMED
     118                 :      * file.
     119                 :      * The geoid will allways be WGS84
     120                 :      * The projection type may be UTM or UPS, depending on the
     121                 :      * latitude from the center of the image.
     122                 :      * @param iProductType type of HDF5 subproduct, see HDF5CSKProduct
     123                 :      */
     124                 :     void CaptureCSKGeolocation(int iProductType);
     125                 : 
     126                 :     /**
     127                 :     * Get Geotransform information for COSMO-SKYMED files
     128                 :     * In case of sucess it stores the transformation
     129                 :     * in adfGeoTransform. In case of failure it doesn't
     130                 :     * modify adfGeoTransform
     131                 :     * @param iProductType type of HDF5 subproduct, see HDF5CSKProduct
     132                 :     */
     133                 :     void CaptureCSKGeoTransform(int iProductType);
     134                 :     
     135                 :     /**
     136                 :      * @param iProductType type of HDF5 subproduct, see HDF5CSKProduct
     137                 :      */
     138                 :     void CaptureCSKGCPs(int iProductType);    
     139                 : };
     140                 : 
     141                 : /************************************************************************/
     142                 : /* ==================================================================== */
     143                 : /*                              HDF5ImageDataset                        */
     144                 : /* ==================================================================== */
     145                 : /************************************************************************/
     146                 : 
     147                 : /************************************************************************/
     148                 : /*                           HDF5ImageDataset()                         */
     149                 : /************************************************************************/
     150              14 : HDF5ImageDataset::HDF5ImageDataset()
     151                 : {
     152              14 :     nGCPCount       = 0;
     153              14 :     pszProjection   = NULL;
     154              14 :     pszGCPProjection= NULL;
     155              14 :     pasGCPList      = NULL;
     156              14 :     poH5Objects     = NULL;
     157              14 :     poH5RootGroup   = NULL;
     158              14 :     dims            = NULL;
     159              14 :     maxdims         = NULL;
     160              14 :     papszMetadata   = NULL;
     161              14 :     adfGeoTransform[0] = 0.0;
     162              14 :     adfGeoTransform[1] = 1.0;
     163              14 :     adfGeoTransform[2] = 0.0;
     164              14 :     adfGeoTransform[3] = 0.0;
     165              14 :     adfGeoTransform[4] = 0.0;
     166              14 :     adfGeoTransform[5] = 1.0;
     167              14 :     iSubdatasetType    = UNKNOWN_PRODUCT;
     168              14 :     bHasGeoTransform   = false;
     169              14 : }
     170                 : 
     171                 : /************************************************************************/
     172                 : /*                            ~HDF5ImageDataset()                       */
     173                 : /************************************************************************/
     174              14 : HDF5ImageDataset::~HDF5ImageDataset( )
     175                 : {
     176              14 :     FlushCache();
     177                 : 
     178              14 :     CPLFree(pszProjection);
     179              14 :     CPLFree(pszGCPProjection);
     180                 : 
     181              14 :     if( dims )
     182              14 :         CPLFree( dims );
     183                 : 
     184              14 :     if( maxdims )
     185              14 :         CPLFree( maxdims );
     186                 : 
     187              14 :     if( nGCPCount > 0 )
     188                 :     {
     189               5 :         for( int i = 0; i < nGCPCount; i++ )
     190                 :         {
     191               4 :             if( pasGCPList[i].pszId )
     192               4 :                 CPLFree( pasGCPList[i].pszId );
     193               4 :             if( pasGCPList[i].pszInfo )
     194               4 :                 CPLFree( pasGCPList[i].pszInfo );
     195                 :         }
     196                 : 
     197               1 :         CPLFree( pasGCPList );
     198                 :     }
     199              14 : }
     200                 : 
     201                 : /************************************************************************/
     202                 : /* ==================================================================== */
     203                 : /*                            Hdf5imagerasterband                       */
     204                 : /* ==================================================================== */
     205                 : /************************************************************************/
     206                 : class HDF5ImageRasterBand : public GDALPamRasterBand
     207                 : {
     208                 :     friend class HDF5ImageDataset;
     209                 : 
     210                 :     int         bNoDataSet;
     211                 :     double      dfNoDataValue;
     212                 : 
     213                 : public:
     214                 : 
     215                 :     HDF5ImageRasterBand( HDF5ImageDataset *, int, GDALDataType );
     216                 :     ~HDF5ImageRasterBand();
     217                 : 
     218                 :     virtual CPLErr      IReadBlock( int, int, void * );
     219                 :     virtual double      GetNoDataValue( int * );
     220                 :     virtual CPLErr      SetNoDataValue( double );
     221                 :     /*  virtual CPLErr          IWriteBlock( int, int, void * ); */
     222                 : };
     223                 : 
     224                 : /************************************************************************/
     225                 : /*                        ~HDF5ImageRasterBand()                        */
     226                 : /************************************************************************/
     227                 : 
     228              14 : HDF5ImageRasterBand::~HDF5ImageRasterBand()
     229                 : {
     230                 : 
     231              14 : }
     232                 : /************************************************************************/
     233                 : /*                           HDF5ImageRasterBand()                      */
     234                 : /************************************************************************/
     235              14 : HDF5ImageRasterBand::HDF5ImageRasterBand( HDF5ImageDataset *poDS, int nBand,
     236              14 :                                           GDALDataType eType )
     237                 : 
     238                 : {
     239                 :     char          **papszMetaGlobal;
     240              14 :     this->poDS    = poDS;
     241              14 :     this->nBand   = nBand;
     242              14 :     eDataType     = eType;
     243              14 :     bNoDataSet    = FALSE;
     244              14 :     dfNoDataValue = -9999;
     245              14 :     nBlockXSize   = poDS->GetRasterXSize( );
     246              14 :     nBlockYSize   = 1;
     247                 : 
     248                 : /* -------------------------------------------------------------------- */
     249                 : /*      Take a copy of Global Metadata since  I can't pass Raster       */
     250                 : /*      variable to Iterate function.                                   */
     251                 : /* -------------------------------------------------------------------- */
     252              14 :     papszMetaGlobal = CSLDuplicate( poDS->papszMetadata );
     253              14 :     CSLDestroy( poDS->papszMetadata );
     254              14 :     poDS->papszMetadata = NULL;
     255                 : 
     256              14 :     if( poDS->poH5Objects->nType == H5G_DATASET ) {
     257              14 :         poDS->CreateMetadata( poDS->poH5Objects, H5G_DATASET );
     258                 :     }
     259                 : 
     260                 : /* -------------------------------------------------------------------- */
     261                 : /*      Recover Global Metadat and set Band Metadata                    */
     262                 : /* -------------------------------------------------------------------- */
     263                 : 
     264              14 :     SetMetadata( poDS->papszMetadata );
     265                 : 
     266              14 :     CSLDestroy( poDS->papszMetadata );
     267              14 :     poDS->papszMetadata = CSLDuplicate( papszMetaGlobal );
     268              14 :     CSLDestroy( papszMetaGlobal );
     269                 : 
     270                 :     /* check for chunksize and set it as the blocksize (optimizes read) */
     271              14 :     hid_t listid = H5Dget_create_plist(((HDF5ImageDataset * )poDS)->dataset_id);
     272              14 :     if (listid>0)
     273                 :     {
     274              14 :         if(H5Pget_layout(listid) == H5D_CHUNKED)
     275                 :         {
     276                 :             hsize_t panChunkDims[3];
     277               4 :             int nDimSize = H5Pget_chunk(listid, 3, panChunkDims);
     278               4 :             nBlockXSize   = (int) panChunkDims[nDimSize-1];
     279               4 :             nBlockYSize   = (int) panChunkDims[nDimSize-2];
     280                 :         }
     281              14 :         H5Pclose(listid);
     282                 :     }
     283                 : 
     284              14 : }
     285                 : 
     286                 : /************************************************************************/
     287                 : /*                           GetNoDataValue()                           */
     288                 : /************************************************************************/
     289               3 : double HDF5ImageRasterBand::GetNoDataValue( int * pbSuccess )
     290                 : 
     291                 : {
     292               3 :     if( bNoDataSet )
     293                 :     {
     294               0 :         if( pbSuccess )
     295               0 :             *pbSuccess = bNoDataSet;
     296                 : 
     297               0 :         return dfNoDataValue;
     298                 :     }
     299                 :     else
     300               3 :         return GDALPamRasterBand::GetNoDataValue( pbSuccess );
     301                 : }
     302                 : 
     303                 : /************************************************************************/
     304                 : /*                           SetNoDataValue()                           */
     305                 : /************************************************************************/
     306               0 : CPLErr HDF5ImageRasterBand::SetNoDataValue( double dfNoData )
     307                 : 
     308                 : {
     309               0 :     bNoDataSet = TRUE;
     310               0 :     dfNoDataValue = dfNoData;
     311                 : 
     312               0 :     return CE_None;
     313                 : }
     314                 : 
     315                 : /************************************************************************/
     316                 : /*                             IReadBlock()                             */
     317                 : /************************************************************************/
     318             919 : CPLErr HDF5ImageRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     319                 :                                         void * pImage )
     320                 : {
     321                 :     herr_t      status;
     322                 :     hsize_t     count[3];
     323                 :     H5OFFSET_TYPE offset[3];
     324                 :     int         nSizeOfData;
     325                 :     hid_t       memspace;
     326                 :     hsize_t     col_dims[3];
     327                 :     hsize_t     rank;
     328                 : 
     329             919 :     HDF5ImageDataset    *poGDS = ( HDF5ImageDataset * ) poDS;
     330                 : 
     331             919 :     if( poGDS->eAccess == GA_Update ) {
     332                 :         memset( pImage, 0,
     333                 :             nBlockXSize * nBlockYSize *
     334               0 :             GDALGetDataTypeSize( eDataType )/8 );
     335               0 :         return CE_None;
     336                 :     }
     337                 : 
     338             919 :     rank=2;
     339                 : 
     340             919 :     if( poGDS->ndims == 3 ){
     341               0 :         rank=3;
     342               0 :         offset[0]   = nBand-1;
     343               0 :         count[0]    = 1;
     344               0 :         col_dims[0] = 1;
     345                 :     }
     346                 : 
     347             919 :     offset[poGDS->ndims - 2] = nBlockYOff*nBlockYSize;
     348             919 :     offset[poGDS->ndims - 1] = nBlockXOff*nBlockXSize;
     349             919 :     count[poGDS->ndims - 2]  = nBlockYSize;
     350             919 :     count[poGDS->ndims - 1]  = nBlockXSize;
     351                 : 
     352             919 :     nSizeOfData = H5Tget_size( poGDS->native );
     353             919 :     memset( pImage,0,nBlockXSize*nBlockYSize*nSizeOfData );
     354                 : 
     355                 :     /*  blocksize may not be a multiple of imagesize */
     356            1845 :     count[poGDS->ndims - 2]  = MIN( size_t(nBlockYSize),
     357                 :                                     poDS->GetRasterYSize() -
     358            1845 :                                             offset[poGDS->ndims - 2]);
     359            2757 :     count[poGDS->ndims - 1]  = MIN( size_t(nBlockXSize),
     360                 :                                     poDS->GetRasterXSize()-
     361            2757 :                                             offset[poGDS->ndims - 1]);
     362                 : 
     363                 : /* -------------------------------------------------------------------- */
     364                 : /*      Select block from file space                                    */
     365                 : /* -------------------------------------------------------------------- */
     366                 :     status =  H5Sselect_hyperslab( poGDS->dataspace_id,
     367                 :                                    H5S_SELECT_SET,
     368                 :                                    offset, NULL,
     369             919 :                                    count, NULL );
     370                 : 
     371                 : /* -------------------------------------------------------------------- */
     372                 : /*      Create memory space to receive the data                         */
     373                 : /* -------------------------------------------------------------------- */
     374             919 :     col_dims[poGDS->ndims-2]=nBlockYSize;
     375             919 :     col_dims[poGDS->ndims-1]=nBlockXSize;
     376             919 :     memspace = H5Screate_simple( (int) rank, col_dims, NULL );
     377             919 :     H5OFFSET_TYPE mem_offset[3] = {0, 0, 0};
     378                 :     status =  H5Sselect_hyperslab(memspace,
     379                 :                                   H5S_SELECT_SET,
     380                 :                                   mem_offset, NULL,
     381             919 :                                   count, NULL);
     382                 : 
     383                 :     status = H5Dread ( poGDS->dataset_id,
     384                 :                        poGDS->native,
     385                 :                        memspace,
     386                 :                        poGDS->dataspace_id,
     387                 :                        H5P_DEFAULT,
     388             919 :                        pImage );
     389                 : 
     390             919 :     H5Sclose( memspace );
     391                 : 
     392             919 :     if( status < 0 )
     393                 :     {
     394                 :         CPLError( CE_Failure, CPLE_AppDefined,
     395               0 :                   "H5Dread() failed for block." );
     396               0 :         return CE_Failure;
     397                 :     }
     398                 :     else
     399             919 :         return CE_None;
     400                 : }
     401                 : 
     402                 : /************************************************************************/
     403                 : /*                              Identify()                              */
     404                 : /************************************************************************/
     405                 : 
     406           10129 : int HDF5ImageDataset::Identify( GDALOpenInfo *poOpenInfo )
     407                 : 
     408                 : {
     409           10129 :     if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) )
     410           10129 :         return FALSE;
     411                 :     else
     412               0 :         return TRUE;
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                                Open()                                */
     417                 : /************************************************************************/
     418            1733 : GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo )
     419                 : {
     420                 :     int i;
     421                 :     HDF5ImageDataset    *poDS;
     422                 :     char szFilename[2048];
     423                 : 
     424            1733 :     if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) ||
     425                 :         strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 )
     426            1719 :         return NULL;
     427                 : 
     428                 : /* -------------------------------------------------------------------- */
     429                 : /*      Confirm the requested access is supported.                      */
     430                 : /* -------------------------------------------------------------------- */
     431              14 :     if( poOpenInfo->eAccess == GA_Update )
     432                 :     {
     433                 :         CPLError( CE_Failure, CPLE_NotSupported,
     434                 :                   "The HDF5ImageDataset driver does not support update access to existing"
     435               0 :                   " datasets.\n" );
     436               0 :         return NULL;
     437                 :     }
     438                 : 
     439              14 :     poDS = new HDF5ImageDataset();
     440                 : 
     441                 :     /* -------------------------------------------------------------------- */
     442                 :     /*      Create a corresponding GDALDataset.                             */
     443                 :     /* -------------------------------------------------------------------- */
     444                 :     /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */
     445                 :     char **papszName =
     446                 :         CSLTokenizeString2(  poOpenInfo->pszFilename,
     447              14 :                              ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES );
     448                 : 
     449              14 :     if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) )
     450                 :     {
     451               0 :         CSLDestroy(papszName);
     452               0 :         delete poDS;
     453               0 :         return NULL;
     454                 :     }
     455                 : 
     456              14 :     poDS->SetDescription( poOpenInfo->pszFilename );
     457                 : 
     458                 :     /* -------------------------------------------------------------------- */
     459                 :     /*    Check for drive name in windows HDF5:"D:\...                      */
     460                 :     /* -------------------------------------------------------------------- */
     461              14 :     strcpy(szFilename, papszName[1]);
     462                 : 
     463              14 :     if( strlen(papszName[1]) == 1 && papszName[3] != NULL )
     464                 :     {
     465               0 :         strcat(szFilename, ":");
     466               0 :         strcat(szFilename, papszName[2]);
     467                 : 
     468               0 :         poDS->SetSubdatasetName( papszName[3] );
     469                 :     }
     470                 :     else
     471              14 :         poDS->SetSubdatasetName( papszName[2] );
     472                 : 
     473              14 :     CSLDestroy(papszName);
     474              14 :     papszName = NULL;
     475                 : 
     476              14 :     if( !H5Fis_hdf5(szFilename) ) {
     477               0 :         delete poDS;
     478               0 :         return NULL;
     479                 :     }
     480                 : 
     481              14 :     poDS->SetPhysicalFilename( szFilename );
     482                 : 
     483                 :     /* -------------------------------------------------------------------- */
     484                 :     /*      Try opening the dataset.                                        */
     485                 :     /* -------------------------------------------------------------------- */
     486                 :     poDS->hHDF5 = H5Fopen(szFilename,
     487                 :                           H5F_ACC_RDONLY,
     488              14 :                           H5P_DEFAULT );
     489                 : 
     490              14 :     if( poDS->hHDF5 < 0 )
     491                 :     {
     492               0 :         delete poDS;
     493               0 :         return NULL;
     494                 :     }
     495                 : 
     496              14 :     poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" );
     497              14 :     if( poDS->hGroupID < 0 )
     498                 :     {
     499               0 :         poDS->bIsHDFEOS=false;
     500               0 :         delete poDS;
     501               0 :         return NULL;
     502                 :     }
     503                 : 
     504                 : /* -------------------------------------------------------------------- */
     505                 : /*      THIS IS AN HDF5 FILE                                            */
     506                 : /* -------------------------------------------------------------------- */
     507              14 :     poDS->bIsHDFEOS=TRUE;
     508              14 :     poDS->ReadGlobalAttributes( FALSE );
     509                 : 
     510                 : /* -------------------------------------------------------------------- */
     511                 : /*      Create HDF5 Data Hierarchy in a link list                       */
     512                 : /* -------------------------------------------------------------------- */
     513                 :     poDS->poH5Objects =
     514                 :         poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup,
     515              14 :                                             (char *)poDS->GetSubdatasetName() );
     516                 : 
     517              14 :     if( poDS->poH5Objects == NULL ) {
     518               0 :         delete poDS;
     519               0 :         return NULL;
     520                 :     }
     521                 : /* -------------------------------------------------------------------- */
     522                 : /*      Retrieve HDF5 data information                                  */
     523                 : /* -------------------------------------------------------------------- */
     524              14 :     poDS->dataset_id   = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath );
     525              14 :     poDS->dataspace_id = H5Dget_space( poDS->dataset_id );
     526              14 :     poDS->ndims        = H5Sget_simple_extent_ndims( poDS->dataspace_id );
     527              14 :     poDS->dims         = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) );
     528              14 :     poDS->maxdims      = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) );
     529                 :     poDS->dimensions   = H5Sget_simple_extent_dims( poDS->dataspace_id,
     530                 :                                                     poDS->dims,
     531              14 :                                                     poDS->maxdims );
     532              14 :     poDS->datatype = H5Dget_type( poDS->dataset_id );
     533              14 :     poDS->clas     = H5Tget_class( poDS->datatype );
     534              14 :     poDS->size     = H5Tget_size( poDS->datatype );
     535              14 :     poDS->address = H5Dget_offset( poDS->dataset_id );
     536              14 :     poDS->native  = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND );
     537                 : 
     538              14 :     poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2];   // Y
     539              14 :     poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1];   // X alway last
     540                 : 
     541              14 :     poDS->nBands=1;
     542                 : 
     543              14 :     if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0];
     544                 : 
     545                 : 
     546              28 :     for(  i = 1; i <= poDS->nBands; i++ ) {
     547                 :         HDF5ImageRasterBand *poBand =
     548                 :             new HDF5ImageRasterBand( poDS, i,
     549              14 :                             poDS->GetDataType( poDS->native ) );
     550                 : 
     551              14 :         poDS->SetBand( i, poBand );
     552              14 :         if( poBand->bNoDataSet )
     553               0 :             poBand->SetNoDataValue( 255 );
     554                 :     }
     555                 : 
     556                 :     // CSK code in IdentifyProductType() and CreateProjections() 
     557                 :     // uses dataset metadata.
     558              14 :     poDS->SetMetadata( poDS->papszMetadata );
     559                 : 
     560                 :     // Check if the hdf5 is a well known product type
     561              14 :     poDS->IdentifyProductType();
     562                 : 
     563              14 :     poDS->CreateProjections( );
     564                 : 
     565                 : /* -------------------------------------------------------------------- */
     566                 : /*      Setup/check for pam .aux.xml.                                   */
     567                 : /* -------------------------------------------------------------------- */
     568              14 :     poDS->TryLoadXML();
     569                 : 
     570                 : /* -------------------------------------------------------------------- */
     571                 : /*      Setup overviews.                                                */
     572                 : /* -------------------------------------------------------------------- */
     573              14 :     poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" );
     574                 : 
     575              14 :     return( poDS );
     576                 : }
     577                 : 
     578                 : 
     579                 : /************************************************************************/
     580                 : /*                        GDALRegister_HDF5Image()                      */
     581                 : /************************************************************************/
     582             610 : void GDALRegister_HDF5Image( )
     583                 : 
     584                 : {
     585                 :     GDALDriver  *poDriver;
     586                 : 
     587             610 :     if (! GDAL_CHECK_VERSION("HDF5Image driver"))
     588               0 :         return;
     589                 : 
     590             610 :     if(  GDALGetDriverByName( "HDF5Image" ) == NULL )
     591                 :     {
     592             588 :         poDriver = new GDALDriver( );
     593                 : 
     594             588 :         poDriver->SetDescription( "HDF5Image" );
     595                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
     596             588 :                                    "HDF5 Dataset" );
     597                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC,
     598             588 :                                    "frmt_hdf5.html" );
     599             588 :         poDriver->pfnOpen = HDF5ImageDataset::Open;
     600             588 :         poDriver->pfnIdentify = HDF5ImageDataset::Identify;
     601                 : 
     602             588 :         GetGDALDriverManager( )->RegisterDriver( poDriver );
     603                 :     }
     604                 : }
     605                 : 
     606                 : /************************************************************************/
     607                 : /*                         CreateProjections()                          */
     608                 : /************************************************************************/
     609              14 : CPLErr HDF5ImageDataset::CreateProjections()
     610                 : {
     611              14 :     switch(iSubdatasetType)
     612                 :     {
     613                 :     case CSK_PRODUCT:
     614                 :     {
     615               2 :         const char *osMissionLevel = NULL;
     616               2 :         int productType = PROD_UNKNOWN;
     617                 : 
     618               2 :         if(GetMetadataItem("Product_Type")!=NULL)
     619                 :         {
     620                 :             //Get the format's level
     621               2 :             osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type");
     622                 : 
     623               2 :             if(EQUALN(osMissionLevel,"RAW",3))
     624               0 :                 productType  = PROD_CSK_L0;
     625                 : 
     626               2 :             if(EQUALN(osMissionLevel,"SSC",3))
     627               0 :                 productType  = PROD_CSK_L1A;
     628                 : 
     629               2 :             if(EQUALN(osMissionLevel,"DGM",3))
     630               1 :                 productType  = PROD_CSK_L1B;
     631                 : 
     632               2 :             if(EQUALN(osMissionLevel,"GEC",3))
     633               1 :                 productType  = PROD_CSK_L1C;
     634                 : 
     635               2 :             if(EQUALN(osMissionLevel,"GTC",3))
     636               0 :                 productType  = PROD_CSK_L1D;
     637                 :         }
     638                 :             
     639               2 :         CaptureCSKGeoTransform(productType);
     640               2 :         CaptureCSKGeolocation(productType);
     641               2 :         CaptureCSKGCPs(productType);
     642                 :         
     643               2 :         break;
     644                 :     }
     645                 :     case UNKNOWN_PRODUCT:
     646                 :     {
     647                 : #define NBGCPLAT 100
     648                 : #define NBGCPLON 30
     649                 : 
     650              12 :     hid_t LatitudeDatasetID  = -1;
     651              12 :     hid_t LongitudeDatasetID = -1;
     652                 :     hid_t LatitudeDataspaceID;
     653                 :     hid_t LongitudeDataspaceID;
     654                 :     float* Latitude;
     655                 :     float* Longitude;
     656                 :     int    i,j;
     657                 :     int   nDeltaLat;
     658                 :     int   nDeltaLon;
     659                 : 
     660              12 :     nDeltaLat = nRasterYSize / NBGCPLAT;
     661              12 :     nDeltaLon = nRasterXSize / NBGCPLON;
     662                 : 
     663              12 :     if( nDeltaLat == 0 || nDeltaLon == 0 )
     664              10 :         return CE_None;
     665                 : 
     666                 :     /* -------------------------------------------------------------------- */
     667                 :     /*      Create HDF5 Data Hierarchy in a link list                       */
     668                 :     /* -------------------------------------------------------------------- */
     669               2 :     poH5Objects=HDF5FindDatasetObjects( poH5RootGroup,  "Latitude" );
     670               2 :     if( !poH5Objects ) {
     671               2 :         return CE_None;
     672                 :     }
     673                 :     /* -------------------------------------------------------------------- */
     674                 :     /*      The Lattitude and Longitude arrays must have a rank of 2 to     */
     675                 :     /*      retrieve GCPs.                                                  */
     676                 :     /* -------------------------------------------------------------------- */
     677               0 :     if( poH5Objects->nRank != 2 ) {
     678               0 :         return CE_None;
     679                 :     }
     680                 : 
     681                 :     /* -------------------------------------------------------------------- */
     682                 :     /*      Retrieve HDF5 data information                                  */
     683                 :     /* -------------------------------------------------------------------- */
     684               0 :     LatitudeDatasetID   = H5Dopen( hHDF5,poH5Objects->pszPath );
     685               0 :     LatitudeDataspaceID = H5Dget_space( dataset_id );
     686                 : 
     687               0 :     poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" );
     688               0 :     LongitudeDatasetID   = H5Dopen( hHDF5,poH5Objects->pszPath );
     689               0 :     LongitudeDataspaceID = H5Dget_space( dataset_id );
     690                 : 
     691               0 :     if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) {
     692                 : 
     693                 :         Latitude         = ( float * ) CPLCalloc(  nRasterYSize*nRasterXSize,
     694               0 :                             sizeof( float ) );
     695                 :         Longitude         = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize,
     696               0 :                             sizeof( float ) );
     697               0 :         memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof(  float ) );
     698               0 :         memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) );
     699                 : 
     700                 :         H5Dread ( LatitudeDatasetID,
     701                 :             H5T_NATIVE_FLOAT,
     702                 :             H5S_ALL,
     703                 :             H5S_ALL,
     704                 :             H5P_DEFAULT,
     705               0 :             Latitude );
     706                 : 
     707                 :         H5Dread ( LongitudeDatasetID,
     708                 :             H5T_NATIVE_FLOAT,
     709                 :             H5S_ALL,
     710                 :             H5S_ALL,
     711                 :             H5P_DEFAULT,
     712               0 :             Longitude );
     713                 : 
     714               0 :         oSRS.SetWellKnownGeogCS( "WGS84" );
     715               0 :         CPLFree(pszProjection);
     716               0 :         CPLFree(pszGCPProjection);
     717               0 :         oSRS.exportToWkt( &pszProjection );
     718               0 :         oSRS.exportToWkt( &pszGCPProjection );
     719                 : 
     720                 :     /* -------------------------------------------------------------------- */
     721                 :     /*  Fill the GCPs list.                                                 */
     722                 :     /* -------------------------------------------------------------------- */
     723               0 :         nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon;
     724                 : 
     725                 :         pasGCPList = ( GDAL_GCP * )
     726               0 :             CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) );
     727                 : 
     728               0 :         GDALInitGCPs( nGCPCount, pasGCPList );
     729               0 :         int k=0;
     730                 : 
     731               0 :         int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat;
     732               0 :         int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon;
     733               0 :         for( j = 0; j < nYLimit; j+=nDeltaLat )
     734                 :         {
     735               0 :             for( i = 0; i < nXLimit; i+=nDeltaLon )
     736                 :             {
     737               0 :                 int iGCP =  j * nRasterXSize + i;
     738               0 :                 pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0;
     739               0 :                 pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP];
     740                 : 
     741               0 :                 pasGCPList[k].dfGCPPixel = i + 0.5;
     742               0 :                 pasGCPList[k++].dfGCPLine =  j + 0.5;
     743                 : 
     744                 :             }
     745                 :         }
     746                 : 
     747               0 :         CPLFree( Latitude );
     748               0 :         CPLFree( Longitude );
     749                 :     }
     750                 :         break;
     751                 :     }
     752                 :     }
     753               2 :     return CE_None;
     754                 : 
     755                 : }
     756                 : /************************************************************************/
     757                 : /*                          GetProjectionRef()                          */
     758                 : /************************************************************************/
     759                 : 
     760               1 : const char *HDF5ImageDataset::GetProjectionRef( )
     761                 : 
     762                 : {
     763               1 :     if( pszProjection )
     764               1 :         return pszProjection;
     765                 :     else
     766               0 :         return GDALPamDataset::GetProjectionRef();
     767                 : }
     768                 : 
     769                 : /************************************************************************/
     770                 : /*                            GetGCPCount()                             */
     771                 : /************************************************************************/
     772                 : 
     773               1 : int HDF5ImageDataset::GetGCPCount( )
     774                 : 
     775                 : {
     776               1 :     if( nGCPCount > 0 )
     777               1 :         return nGCPCount;
     778                 :     else
     779               0 :         return GDALPamDataset::GetGCPCount();
     780                 : }
     781                 : 
     782                 : /************************************************************************/
     783                 : /*                          GetGCPProjection()                          */
     784                 : /************************************************************************/
     785                 : 
     786               1 : const char *HDF5ImageDataset::GetGCPProjection( )
     787                 : 
     788                 : {
     789               1 :     if( nGCPCount > 0 )
     790               1 :         return pszGCPProjection;
     791                 :     else
     792               0 :         return GDALPamDataset::GetGCPProjection();
     793                 : }
     794                 : 
     795                 : /************************************************************************/
     796                 : /*                               GetGCPs()                              */
     797                 : /************************************************************************/
     798                 : 
     799               1 : const GDAL_GCP *HDF5ImageDataset::GetGCPs( )
     800                 : {
     801               1 :     if( nGCPCount > 0 )
     802               1 :         return pasGCPList;
     803                 :     else
     804               0 :         return GDALPamDataset::GetGCPs();
     805                 : }
     806                 : 
     807                 : /************************************************************************/
     808                 : /*                         GetGeoTransform()                            */
     809                 : /************************************************************************/
     810                 : 
     811               1 : CPLErr HDF5ImageDataset::GetGeoTransform( double * padfTransform )
     812                 : {
     813               1 :     if ( bHasGeoTransform )
     814                 :     {
     815               1 :         memcpy( padfTransform, adfGeoTransform, sizeof(double) * 6 );
     816               1 :         return CE_None;
     817                 :     }
     818                 :     else
     819               0 :         return GDALPamDataset::GetGeoTransform(padfTransform);
     820                 : }
     821                 : 
     822                 : /************************************************************************/
     823                 : /*                       IdentifyProductType()                          */
     824                 : /************************************************************************/
     825                 : 
     826                 : /**
     827                 :  * Identify if the subdataset has a known product format
     828                 :  * It stores a product identifier in iSubdatasetType,
     829                 :  * UNKNOWN_PRODUCT, if it isn't a recognizable format.
     830                 :  */
     831              14 : void HDF5ImageDataset::IdentifyProductType()
     832                 : {
     833              14 :     iSubdatasetType = UNKNOWN_PRODUCT;
     834                 : 
     835                 : /************************************************************************/
     836                 : /*                               COSMO-SKYMED                           */
     837                 : /************************************************************************/
     838                 :    const char *pszMissionId;
     839                 : 
     840                 :     //Get the Mission Id as a char *, because the
     841                 :     //field may not exist
     842              14 :     pszMissionId = HDF5Dataset::GetMetadataItem("Mission_ID");
     843                 : 
     844                 :     //If there is a Mission_ID field
     845              14 :      if(pszMissionId != NULL && strstr(GetDescription(), "QLK") == NULL)
     846                 :          //Check if the mission type is CSK
     847               2 :          if(EQUAL(pszMissionId,"CSK"))
     848               2 :              iSubdatasetType = CSK_PRODUCT;
     849              14 : }
     850                 : 
     851                 : /************************************************************************/
     852                 : /*                       CaptureCSKGeolocation()                        */
     853                 : /************************************************************************/
     854                 : 
     855                 : /**
     856                 :  * Captures Geolocation information from a COSMO-SKYMED
     857                 :  * file.
     858                 :  * The geoid will allways be WGS84
     859                 :  * The projection type may be UTM or UPS, depending on the
     860                 :  * latitude from the center of the image.
     861                 :  * @param iProductType type of CSK subproduct, see HDF5CSKProduct
     862                 :  */
     863               2 : void HDF5ImageDataset::CaptureCSKGeolocation(int iProductType)
     864                 : {
     865                 :     double *dfProjFalseEastNorth;
     866                 :     double *dfProjScaleFactor;
     867                 :     double *dfCenterCoord;
     868                 : 
     869               3 :     if(iProductType == PROD_CSK_L1C||iProductType == PROD_CSK_L1D)
     870                 :     {
     871                 :         //Check if all the metadata attributes are present
     872               2 :         if(HDF5ReadDoubleAttr("Map Projection False East-North", &dfProjFalseEastNorth) == CE_Failure||
     873                 :            HDF5ReadDoubleAttr("Map Projection Scale Factor", &dfProjScaleFactor) == CE_Failure||
     874                 :            HDF5ReadDoubleAttr("Map Projection Centre", &dfCenterCoord) == CE_Failure||
     875               1 :            GetMetadataItem("Projection_ID") == NULL)
     876                 :         {
     877                 : 
     878               0 :             pszProjection = CPLStrdup("");
     879               0 :             pszGCPProjection = CPLStrdup("");
     880                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     881               0 :                       "The CSK hdf5 file geolocation information is malformed\n" );
     882                 :         }
     883                 :         else
     884                 :         {
     885                 : 
     886                 :             //Fetch projection Type
     887               1 :             CPLString osProjectionID = GetMetadataItem("Projection_ID");
     888                 : 
     889                 :             //If the projection is UTM
     890               1 :             if(EQUAL(osProjectionID,"UTM"))
     891                 :             {
     892                 :                 // @TODO: use SetUTM
     893               1 :                 oSRS.SetProjCS(SRS_PT_TRANSVERSE_MERCATOR);
     894                 :                 oSRS.SetTM(dfCenterCoord[0],
     895                 :                            dfCenterCoord[1],
     896                 :                            dfProjScaleFactor[0],
     897                 :                            dfProjFalseEastNorth[0], 
     898               1 :                            dfProjFalseEastNorth[1]);
     899                 :             }
     900                 :             else
     901                 :             {
     902                 :                 //TODO Test! I didn't had any UPS projected files to test!
     903                 :                 //If the projection is UPS
     904               0 :                 if(EQUAL(osProjectionID,"UPS"))
     905                 :                 {
     906               0 :                     oSRS.SetProjCS(SRS_PT_POLAR_STEREOGRAPHIC);
     907                 :                     oSRS.SetPS(dfCenterCoord[0], 
     908                 :                                dfCenterCoord[1],
     909                 :                                dfProjScaleFactor[0],
     910                 :                                dfProjFalseEastNorth[0],
     911               0 :                                dfProjFalseEastNorth[1]);
     912                 :                 }
     913                 :             }
     914                 : 
     915                 :             //Export Projection to Wkt.
     916                 :             //In case of error then clean the projection
     917               1 :             if (oSRS.exportToWkt(&pszProjection) != OGRERR_NONE)
     918               0 :                 pszProjection = CPLStrdup("");
     919                 : 
     920               1 :             CPLFree(dfCenterCoord);
     921               1 :             CPLFree(dfProjScaleFactor);
     922               1 :             CPLFree(dfProjFalseEastNorth);
     923                 :         }
     924                 :     }
     925                 :     else
     926                 :     {
     927                 :         //Set the ellipsoid to WGS84
     928               1 :         oSRS.SetWellKnownGeogCS( "WGS84" );
     929                 : 
     930                 :         //Export GCPProjection to Wkt.
     931                 :         //In case of error then clean the projection
     932               1 :         if(oSRS.exportToWkt(&pszGCPProjection) != OGRERR_NONE)
     933               0 :             pszGCPProjection = CPLStrdup("");
     934                 :     }
     935               2 : }
     936                 : 
     937                 : /************************************************************************/
     938                 : /*                       CaptureCSKGeoTransform()                       */
     939                 : /************************************************************************/
     940                 : 
     941                 : /**
     942                 : * Get Geotransform information for COSMO-SKYMED files
     943                 : * In case of sucess it stores the transformation
     944                 : * in adfGeoTransform. In case of failure it doesn't
     945                 : * modify adfGeoTransform
     946                 : * @param iProductType type of CSK subproduct, see HDF5CSKProduct
     947                 : */
     948               2 : void HDF5ImageDataset::CaptureCSKGeoTransform(int iProductType)
     949                 : {
     950                 :     double *pdOutUL;
     951                 :     double *pdLineSpacing;
     952                 :     double *pdColumnSpacing;
     953                 : 
     954               2 :     CPLString osULCoord;
     955               2 :     CPLString osULPath;
     956               2 :     CPLString osLineSpacingPath, osColumnSpacingPath;
     957                 : 
     958               2 :     const char *pszSubdatasetName = GetSubdatasetName();
     959                 : 
     960               2 :     bHasGeoTransform = FALSE;
     961                 :     //If the product level is not L1C or L1D then
     962                 :     //it doesn't have a valid projection
     963               2 :     if(iProductType == PROD_CSK_L1C||iProductType == PROD_CSK_L1D)
     964                 :     {
     965                 :         //If there is a subdataset
     966               1 :         if(pszSubdatasetName != NULL)
     967                 :         {
     968                 : 
     969               1 :             osULPath = pszSubdatasetName ;
     970               1 :             osULPath += "/Top Left East-North";
     971                 : 
     972               1 :             osLineSpacingPath = pszSubdatasetName;
     973               1 :             osLineSpacingPath += "/Line Spacing";
     974                 : 
     975               1 :             osColumnSpacingPath = pszSubdatasetName;
     976               1 :             osColumnSpacingPath += "/Column Spacing";
     977                 : 
     978                 : 
     979                 :             //If it could find the attributes on the metadata
     980               1 :             if(HDF5ReadDoubleAttr(osULPath.c_str(), &pdOutUL) == CE_Failure ||
     981                 :                HDF5ReadDoubleAttr(osLineSpacingPath.c_str(), &pdLineSpacing) == CE_Failure ||
     982                 :                HDF5ReadDoubleAttr(osColumnSpacingPath.c_str(), &pdColumnSpacing) == CE_Failure)
     983                 :             {
     984               0 :                 bHasGeoTransform = FALSE;
     985                 :             }
     986                 :             else
     987                 :             {
     988                 : //              geotransform[1] : width of pixel
     989                 : //              geotransform[4] : rotational coefficient, zero for north up images.
     990                 : //              geotransform[2] : rotational coefficient, zero for north up images.
     991                 : //              geotransform[5] : height of pixel (but negative)
     992                 : 
     993               1 :                 adfGeoTransform[0] = pdOutUL[0];
     994               1 :                 adfGeoTransform[1] = pdLineSpacing[0];
     995               1 :                 adfGeoTransform[2] = 0;
     996               1 :                 adfGeoTransform[3] = pdOutUL[1];
     997               1 :                 adfGeoTransform[4] = 0;
     998               1 :                 adfGeoTransform[5] = -pdColumnSpacing[0];
     999                 : 
    1000                 : 
    1001               1 :                 CPLFree(pdOutUL);
    1002               1 :                 CPLFree(pdLineSpacing);
    1003               1 :                 CPLFree(pdColumnSpacing);
    1004                 : 
    1005               1 :                 bHasGeoTransform = TRUE;
    1006                 :             }
    1007                 :         }
    1008               2 :     }
    1009               2 : }
    1010                 : 
    1011                 : 
    1012                 : /************************************************************************/
    1013                 : /*                          CaptureCSKGCPs()                            */
    1014                 : /************************************************************************/
    1015                 : 
    1016                 : /**
    1017                 :  * Retrieves and stores the GCPs from a COSMO-SKYMED dataset
    1018                 :  * It only retrieves the GCPs for L0, L1A and L1B products
    1019                 :  * for L1C and L1D products, geotransform is provided.
    1020                 :  * The GCPs provided will be the Image's corners.
    1021                 :  * @param iProductType type of CSK product @see HDF5CSKProductEnum
    1022                 :  */
    1023               2 : void HDF5ImageDataset::CaptureCSKGCPs(int iProductType)
    1024                 : {
    1025                 :     //Only retrieve GCPs for L0,L1A and L1B products
    1026               2 :     if(iProductType == PROD_CSK_L0||iProductType == PROD_CSK_L1A||
    1027                 :        iProductType == PROD_CSK_L1B)
    1028                 :     {
    1029                 :         int i;
    1030                 :         double *pdCornerCoordinates;
    1031                 : 
    1032               1 :         nGCPCount=4;
    1033               1 :         pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),4);
    1034               1 :         CPLString osCornerName[4];
    1035                 :         double pdCornerPixel[4];
    1036                 :         double pdCornerLine[4];
    1037                 : 
    1038               2 :         const char *pszSubdatasetName = GetSubdatasetName();
    1039                 : 
    1040                 :         //Load the subdataset name first
    1041               5 :         for(i=0;i <4;i++)
    1042               4 :             osCornerName[i] = pszSubdatasetName;
    1043                 : 
    1044                 :         //Load the attribute name, and raster coordinates for
    1045                 :         //all the corners
    1046               1 :         osCornerName[0] += "/Top Left Geodetic Coordinates";
    1047               1 :         pdCornerPixel[0] = 0;
    1048               1 :         pdCornerLine[0] = 0;
    1049                 : 
    1050               1 :         osCornerName[1] += "/Top Right Geodetic Coordinates";
    1051               1 :         pdCornerPixel[1] = GetRasterXSize();
    1052               1 :         pdCornerLine[1] = 0;
    1053                 : 
    1054               1 :         osCornerName[2] += "/Bottom Left Geodetic Coordinates";
    1055               1 :         pdCornerPixel[2] = 0;
    1056               1 :         pdCornerLine[2] = GetRasterYSize();
    1057                 : 
    1058               1 :         osCornerName[3] += "/Bottom Right Geodetic Coordinates";
    1059               1 :         pdCornerPixel[3] = GetRasterXSize();
    1060               1 :         pdCornerLine[3] = GetRasterYSize();
    1061                 : 
    1062                 :         //For all the image's corners
    1063               5 :         for(i=0;i<4;i++)
    1064                 :         {
    1065               4 :             GDALInitGCPs( 1, pasGCPList + i );
    1066                 : 
    1067               4 :             CPLFree( pasGCPList[i].pszId );
    1068               4 :             pasGCPList[i].pszId = NULL;
    1069                 : 
    1070                 :             //Retrieve the attributes
    1071               4 :             if(HDF5ReadDoubleAttr(osCornerName[i].c_str(), 
    1072                 :                                   &pdCornerCoordinates) == CE_Failure)
    1073                 :             {
    1074                 :                 CPLError( CE_Failure, CPLE_OpenFailed,
    1075               0 :                              "Error retrieving CSK GCPs\n" );
    1076                 :                 // Free on failure, e.g. in case of QLK subdataset.
    1077               0 :                 for( int i = 0; i < 4; i++ )
    1078                 :                 {
    1079               0 :                     if( pasGCPList[i].pszId )
    1080               0 :                         CPLFree( pasGCPList[i].pszId );
    1081               0 :                     if( pasGCPList[i].pszInfo )
    1082               0 :                         CPLFree( pasGCPList[i].pszInfo );
    1083                 :               }
    1084               0 :                 CPLFree( pasGCPList );
    1085               0 :                 pasGCPList = NULL;
    1086               0 :                 nGCPCount = 0;
    1087               0 :                 break;
    1088                 :             }
    1089                 : 
    1090                 :             //Fill the GCPs name
    1091               4 :             pasGCPList[i].pszId = CPLStrdup( osCornerName[i].c_str() );
    1092                 : 
    1093                 :             //Fill the coordinates
    1094               4 :             pasGCPList[i].dfGCPX = pdCornerCoordinates[1];
    1095               4 :             pasGCPList[i].dfGCPY = pdCornerCoordinates[0];
    1096               4 :             pasGCPList[i].dfGCPZ = pdCornerCoordinates[2];
    1097               4 :             pasGCPList[i].dfGCPPixel = pdCornerPixel[i];
    1098               4 :             pasGCPList[i].dfGCPLine = pdCornerLine[i];
    1099                 : 
    1100                 :             //Free the returned coordinates
    1101               4 :             CPLFree(pdCornerCoordinates);
    1102               1 :         }
    1103                 :     }
    1104               2 : }
    1105                 : 

Generated by: LCOV version 1.7