GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo ) { if(!STARTS_WITH_CI(poOpenInfo->pszFilename, "HDF5:") ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The HDF5ImageDataset driver does not support update access " " to existing datasets.\n" ); return NULL; } HDF5ImageDataset *poDS = new HDF5ImageDataset(); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */ char **papszName = CSLTokenizeString2( poOpenInfo->pszFilename, ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES ); if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) ) { CSLDestroy(papszName); delete poDS; return NULL; } poDS->SetDescription( poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Check for drive name in windows HDF5:"D:\... */ /* -------------------------------------------------------------------- */ CPLString osSubdatasetName; CPLString osFilename(papszName[1]); if( strlen(papszName[1]) == 1 && papszName[3] != NULL ) { osFilename += ":"; osFilename += papszName[2]; osSubdatasetName = papszName[3]; } else osSubdatasetName = papszName[2]; poDS->SetSubdatasetName( osSubdatasetName ); CSLDestroy(papszName); papszName = NULL; if( !H5Fis_hdf5(osFilename) ) { delete poDS; return NULL; } poDS->SetPhysicalFilename( osFilename ); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ poDS->hHDF5 = H5Fopen(osFilename, H5F_ACC_RDONLY, H5P_DEFAULT ); if( poDS->hHDF5 < 0 ) { delete poDS; return NULL; } poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" ); if( poDS->hGroupID < 0 ) { poDS->bIsHDFEOS=false; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* THIS IS AN HDF5 FILE */ /* -------------------------------------------------------------------- */ poDS->bIsHDFEOS=TRUE; poDS->ReadGlobalAttributes( FALSE ); /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poDS->poH5Objects = poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup, osSubdatasetName ); if( poDS->poH5Objects == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ poDS->dataset_id = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath ); poDS->dataspace_id = H5Dget_space( poDS->dataset_id ); poDS->ndims = H5Sget_simple_extent_ndims( poDS->dataspace_id ); if( poDS->ndims < 0 ) { delete poDS; return NULL; } poDS->dims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->maxdims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->dimensions = H5Sget_simple_extent_dims( poDS->dataspace_id, poDS->dims, poDS->maxdims ); poDS->datatype = H5Dget_type( poDS->dataset_id ); poDS->class_ = H5Tget_class( poDS->datatype ); poDS->size = H5Tget_size( poDS->datatype ); poDS->address = H5Dget_offset( poDS->dataset_id ); poDS->native = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND ); // CSK code in IdentifyProductType() and CreateProjections() // uses dataset metadata. poDS->SetMetadata( poDS->papszMetadata ); // Check if the hdf5 is a well known product type poDS->IdentifyProductType(); poDS->nRasterYSize=static_cast<int>(poDS->dims[poDS->GetYIndex()]); // nRows poDS->nRasterXSize=static_cast<int>(poDS->dims[poDS->GetXIndex()]); // nCols if( poDS->IsComplexCSKL1A() ) { poDS->nBands=(int) poDS->dims[2]; // nBands } else if( poDS->ndims == 3 ) { poDS->nBands=(int) poDS->dims[0]; } else { poDS->nBands=1; } for( int i = 1; i <= poDS->nBands; i++ ) { HDF5ImageRasterBand * const poBand = new HDF5ImageRasterBand( poDS, i, poDS->GetDataType( poDS->native ) ); poDS->SetBand( i, poBand ); if( poBand->bNoDataSet ) poBand->SetNoDataValue( 255 ); } poDS->CreateProjections( ); /* -------------------------------------------------------------------- */ /* Setup/check for pam .aux.xml. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Setup overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return poDS; }
CPLErr HDF5ImageRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { HDF5ImageDataset *poGDS = reinterpret_cast<HDF5ImageDataset * >(poDS); if( poGDS->eAccess == GA_Update ) { memset( pImage, 0, nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eDataType )/8 ); return CE_None; } hsize_t count[3] = {0, 0, 0}; H5OFFSET_TYPE offset[3] = {0, 0, 0}; hsize_t col_dims[3] = {0, 0, 0}; hsize_t rank = 2; if( poGDS->IsComplexCSKL1A() ) { rank = 3; offset[2] = nBand-1; count[2] = 1; col_dims[2] = 1; } else if( poGDS->ndims == 3 ) { rank = 3; offset[0] = nBand-1; count[0] = 1; col_dims[0] = 1; } // Defaults to rank = 2; offset[poGDS->GetYIndex()] = nBlockYOff*static_cast<hsize_t>(nBlockYSize); offset[poGDS->GetXIndex()] = nBlockXOff*static_cast<hsize_t>(nBlockXSize); count[poGDS->GetYIndex()] = nBlockYSize; count[poGDS->GetXIndex()] = nBlockXSize; const int nSizeOfData = static_cast<int>(H5Tget_size( poGDS->native )); memset( pImage,0,nBlockXSize*nBlockYSize*nSizeOfData ); /* blocksize may not be a multiple of imagesize */ count[poGDS->GetYIndex()] = MIN( size_t(nBlockYSize), poDS->GetRasterYSize() - offset[poGDS->GetYIndex()]); count[poGDS->GetXIndex()] = MIN( size_t(nBlockXSize), poDS->GetRasterXSize()- offset[poGDS->GetXIndex()]); /* -------------------------------------------------------------------- */ /* Select block from file space */ /* -------------------------------------------------------------------- */ herr_t status = H5Sselect_hyperslab( poGDS->dataspace_id, H5S_SELECT_SET, offset, NULL, count, NULL ); if( status < 0 ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Create memory space to receive the data */ /* -------------------------------------------------------------------- */ col_dims[poGDS->GetYIndex()]=nBlockYSize; col_dims[poGDS->GetXIndex()]=nBlockXSize; const hid_t memspace = H5Screate_simple( static_cast<int>(rank), col_dims, NULL ); H5OFFSET_TYPE mem_offset[3] = {0, 0, 0}; status = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, mem_offset, NULL, count, NULL); if( status < 0 ) return CE_Failure; status = H5Dread ( poGDS->dataset_id, poGDS->native, memspace, poGDS->dataspace_id, H5P_DEFAULT, pImage ); H5Sclose( memspace ); if( status < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "H5Dread() failed for block." ); return CE_Failure; } return CE_None; }