int datMap(HDSLoc *locator, const char *type_str, const char *mode_str, int ndim, const hdsdim dims[], void **pntr, int *status) { int isprim = 0; char normtypestr[DAT__SZTYP+1]; size_t nbytes = 0; hid_t h5type = 0; int isreg = 0; void *regpntr = NULL; void *mapped = NULL; hdsmode_t accmode = HDSMODE_UNKNOWN; haddr_t offset; hdsbool_t try_mmap = HDS_FALSE; unsigned intent = 0; size_t actbytes = 0; if (*status != SAI__OK) return *status; /* First have to validate the access mode */ switch (mode_str[0]) { case 'R': case 'r': accmode = HDSMODE_READ; break; case 'U': case 'u': accmode = HDSMODE_UPDATE; break; case 'W': case 'w': accmode = HDSMODE_WRITE; break; default: *status = DAT__MODIN; emsRepf("datMap_6", "Unrecognized mode string '%s' for datMap", status, mode_str); goto CLEANUP; } /* Validate input locator. */ dat1ValidateLocator( "datMap", 1, locator, (accmode & HDSMODE_READ), status ); /* Get the HDF5 type code and confirm this is a primitive type */ isprim = dau1CheckType( 1, type_str, &h5type, normtypestr, sizeof(normtypestr), status ); if (!isprim) { if (*status == SAI__OK) { *status = DAT__TYPIN; emsRepf("datMap_1", "datGet: Data type must be a primitive type and not '%s'", status, normtypestr); } goto CLEANUP; } /* Not allowed to map undefined data in READ or UPDATE mode */ if (accmode == HDSMODE_UPDATE || accmode == HDSMODE_READ) { hdsbool_t defined; if (*status == SAI__OK) { datState( locator, &defined, status ); if (!defined) { *status = DAT__UNSET; emsRepf("datMap_6bb", "Can not map an undefined primitive in mode '%s'", status, mode_str); goto CLEANUP; } } } /* How did we open this file? */ CALLHDFQ( H5Fget_intent( locator->file_id, &intent )); if (accmode == HDSMODE_UPDATE || accmode == HDSMODE_WRITE) { /* Must check whether the file was opened for write */ if ( intent == H5F_ACC_RDONLY ) { *status = DAT__ACCON; emsRepf("datMap_6b", "datMap: Can not map readonly locator in mode '%s'", status, mode_str); goto CLEANUP; } } /* Verify that the specified dimensions match the locator dimensions */ if (*status == SAI__OK) { hdsdim locdims[DAT__MXDIM]; int locndims; int i; datShape(locator, DAT__MXDIM, locdims, &locndims, status ); /* Note that if we are mapping as a scalar the locator should refer to a single element */ if (ndim == 0) { size_t nelem = 1; for (i=0; i<locndims; i++) { nelem *= locdims[i]; } if (nelem != 1) { *status = DAT__DIMIN; emsRepf("datMap_6e", "datMap: Attempt to map as a scalar but locator" " refers to a primitive with %zu elements", status, nelem); goto CLEANUP; } } else { if (ndim != locndims) { *status = DAT__DIMIN; emsRepf("datMap_6c", "datMap: Dimensionality mismatch --" " requested number: %d locator number: %d", status, ndim, locndims ); goto CLEANUP; } for (i=0; i<ndim; i++) { if ( locdims[i] != dims[i] ) { *status = DAT__DIMIN; emsRepf("datMap_6d", "datMap: Dimension %d has size %zu but requested size %zu", status, i, (size_t)locdims[i], (size_t)dims[i]); goto CLEANUP; } } } } /* There is a super-special case for datMap when called with a map type of "_CHAR". In that case we need to work out the size ourselves and adjust the type size */ if (strcmp( "_CHAR", normtypestr ) == 0 ) { size_t clen = 0; char tmpbuff[DAT__SZTYP+1]; datClen( locator, &clen, status ); CALLHDFQ( H5Tset_size( h5type, clen ) ); one_snprintf( tmpbuff, sizeof(tmpbuff), "*%zu", status, clen ); one_strlcat( normtypestr, tmpbuff, DAT__SZTYP+1, status ); } /* Now we want the HDSTYPE of the requested type so that we can work out how much memory we will need to allocate. */ CALLHDFE( size_t, nbytes, H5Tget_size( h5type ), DAT__HDF5E, emsRep("datLen_size", "datMap: Error obtaining size of requested data type", status) ); { int i; if (ndim > 0) { for (i = 0; i < ndim; i++) { nbytes *= dims[i]; } } } /* Work out whether memory mapping is possible -- at the moment I'm pretty sure the only safe use of mmap is when we are reading the data and the file itself was opened readonly. I'm not sure what happens if other components are removed or added -- will the offset change? Maybe we just try */ offset = H5Dget_offset( locator->dataset_id ); if (offset != HADDR_UNDEF) { hid_t dataset_h5type = 0; /* In theory we can do a memory map so now compare the data types of the request and the low-level dataset. */ CALLHDFE( hid_t, dataset_h5type, H5Dget_type( locator->dataset_id ), DAT__HDF5E, emsRep("datMap_type", "datType: Error obtaining data type of dataset", status) ); if (H5Tequal( dataset_h5type, h5type )) { try_mmap = HDS_TRUE; } H5Tclose(dataset_h5type); } /* If this is a locator to a slice then for now we can't memory map. In theory if we knew the slice was contiguous (e.g a vectorized slice, or a single plane of a cube then we could mmap it anyhow. We do not want to have to emulate HDF5 dataspaces here */ if (locator->isslice) try_mmap = 0; /* There seem to be issues doing this on files opened for update/write. For now only allow mmap for files opened read only */ if (intent != H5F_ACC_RDONLY) try_mmap = 0; /* If mmap has been disabled by tuning the environment we just force it off here. */ if (!hds1GetUseMmap()) try_mmap = 0; #if DEBUG_HDS { char *name_str; char * file_str; const char * reason; name_str = dat1GetFullName( locator->dataset_id, 0, NULL, status ); file_str = dat1GetFullName( locator->dataset_id, 1, NULL, status ); if (offset != HADDR_UNDEF) { reason = "[HAD offset]"; } else { reason = "[no offset]"; } if (!try_mmap) { printf("Will NOT attempt %s to mmap %s:%s\n",reason,file_str,name_str); } else { printf("WILL TRY %s to mmap OFFSET=%zu %s:%s\n", reason, (size_t)offset, file_str, name_str); } MEM_FREE(name_str); } #endif if (try_mmap) { int fd = 0; int flags = 0; int prot = 0; hdsbool_t opened_fd = 0; if ( intent == H5F_ACC_RDONLY || accmode == HDSMODE_READ ) { flags |= O_RDONLY; prot = PROT_READ; } else { flags |= O_RDWR; prot = PROT_READ | PROT_WRITE; } if (*status == SAI__OK) { /* see what file driver we have */ hid_t fapl_id = -1; hid_t fdriv_id = -1; void * file_handle = NULL; herr_t herr = -1; fapl_id = H5Fget_access_plist(locator->file_id); fdriv_id = H5Pget_driver(fapl_id); if (fdriv_id == H5FD_SEC2 || fdriv_id == H5FD_STDIO) { /* If this is a POSIX or STDIO driver we get the handle */ herr = H5Fget_vfd_handle( locator->file_id, fapl_id, (void**)&file_handle); if (herr >= 0) { if (fdriv_id == H5FD_SEC2) { fd = *((int *)file_handle); } else if (fdriv_id == H5FD_STDIO) { FILE * fh = (FILE *)file_handle; fd = fileno(fh); } } } if (fapl_id > 0) H5Pclose( fapl_id ); if (fd == 0) { /* We have to open the file ourselves! */ char * fname = NULL; fname = dat1GetFullName( locator->dataset_id, 1, NULL, status ); fd = open(fname, flags); opened_fd = 1; if (fname) MEM_FREE(fname); } if (fd > 0) { /* Set up for memory mapping */ int mflags = 0; mflags = MAP_SHARED | MAP_FILE; if (*status == SAI__OK) { mapped = dat1Mmap( nbytes, prot, mflags, fd, offset, &isreg, ®pntr, &actbytes, status ); if (*status == SAI__OK) { /* Store the file descriptor in the locator to allow us to close */ if (mapped) { if (opened_fd) locator->fdmap = fd; locator->uses_true_mmap = 1; } } else { /* Not currently fatal -- we can try without the file */ if (opened_fd) close(fd); emsAnnul(status); } } } } } /* If we have not been able to map anything yet, just get some memory. It is zeroed (for WRITE) to match mmap behavior. We rely on the OS to decide when it is reasonable to do an anonymous mmap. */ if (!regpntr) { hdsbool_t mustget; mustget = (accmode == HDSMODE_READ || accmode == HDSMODE_UPDATE); if (mustget) { regpntr = cnfMalloc( nbytes ); } else { regpntr = cnfCalloc( 1, nbytes ); } if (!regpntr) { *status = DAT__NOMEM; emsRepf("datMap_cnf","datMap: Unable to allocate %zu bytes of memory", status, nbytes); goto CLEANUP; } /* Populate the memory - check with datState occurred earlier */ if (mustget) { datGet( locator, normtypestr, ndim, dims, regpntr, status ); } } CLEANUP: /* Cleanups that must happen always */ if (h5type) H5Tclose(h5type); /* cleanups that only happen if status is bad */ if (*status != SAI__OK) { if (mapped) { if (isreg == 1) cnfUregp( regpntr ); if ( munmap( mapped, actbytes ) != 0 ) { emsSyser( "MESSAGE", errno ); emsRep("datMap_4", "Error unmapping mapped memory: ^MESSAGE", status); } mapped = NULL; } else if (regpntr) { cnfFree( regpntr ); } regpntr = NULL; } /* Update the locator to reflect the mapped status */ if (*status == SAI__OK) { int i; locator->pntr = mapped; locator->regpntr = regpntr; locator->bytesmapped = actbytes; locator->accmode = accmode; /* In order to copy the data back into the underlying HDF5 dataset we need to store additional information about how this was mapped to allow us to either call datPut later on or at least a new dataspace. For now store the arguments so we can pass them straight to datPut */ locator->ndims = ndim; for (i=0; i<ndim; i++) { (locator->mapdims)[i] = dims[i]; } star_strlcpy( locator->maptype, normtypestr, sizeof(locator->maptype) ); } /* Note that the returned pointer is not necessarily the same as the mapped pointer because of pagesize corrections */ *pntr = regpntr; return *status; }
GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; HDF5ImageDataset *poDS; char szFilename[2048]; if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) || strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 ) 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; } 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:\... */ /* -------------------------------------------------------------------- */ strcpy(szFilename, papszName[1]); if( strlen(papszName[1]) == 1 && papszName[3] != NULL ) { strcat(szFilename, ":"); strcat(szFilename, papszName[2]); poDS->SetSubdatasetName( papszName[3] ); } else poDS->SetSubdatasetName( papszName[2] ); CSLDestroy(papszName); papszName = NULL; if( !H5Fis_hdf5(szFilename) ) { delete poDS; return NULL; } poDS->SetPhysicalFilename( szFilename ); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ poDS->hHDF5 = H5Fopen(szFilename, 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, (char *)poDS->GetSubdatasetName() ); 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 ); 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->clas = 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 ); poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2]; // Y poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1]; // X alway last poDS->nBands=1; if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0]; for( i = 1; i <= poDS->nBands; i++ ) { HDF5ImageRasterBand *poBand = new HDF5ImageRasterBand( poDS, i, poDS->GetDataType( poDS->native ) ); poDS->SetBand( i, poBand ); if( poBand->bNoDataSet ) poBand->SetNoDataValue( 255 ); } poDS->CreateProjections( ); poDS->SetMetadata( poDS->papszMetadata ); /* -------------------------------------------------------------------- */ /* Setup/check for pam .aux.xml. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Setup overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return( poDS ); }
uint64_t DataSet::getOffset () const { haddr_t offset = H5Dget_offset (handle ()); if (offset == HADDR_UNDEF) Exception::error ("H5Dget_offset"); return Core::checked_cast<uint64_t> (offset); }
int ImageBase::readHDF5(size_t select_img) { bool isStack = false; H5infoProvider provider = getProvider(fhdf5); // Provider name int errCode = 0; hid_t dataset; /* Dataset and datatype identifiers */ hid_t filespace; hsize_t dims[4]; // We are not going to support more than 4 dimensions, at this moment. hsize_t nobjEman; hid_t cparms; int rank; String dsname = filename.getBlockName(); // Setting default dataset name if (dsname.empty()) { dsname = provider.second; switch (provider.first) { case EMAN: // Images in stack are stored in separated groups hid_t grpid; grpid = H5Gopen(fhdf5,"/MDF/images/", H5P_DEFAULT); /*herr_t err = */ H5Gget_num_objs(grpid, &nobjEman); dsname = formatString(dsname.c_str(), IMG_INDEX(select_img)); H5Gclose(grpid); break; default: break; } } else { switch (provider.first) { case EMAN: // Images in stack are stored in separated groups nobjEman=1; break; default: break; } } dataset = H5Dopen2(fhdf5, dsname.c_str(), H5P_DEFAULT); if( dataset < 0) REPORT_ERROR(ERR_IO_NOTEXIST, formatString("readHDF5: Dataset '%s' not found",dsname.c_str())); cparms = H5Dget_create_plist(dataset); /* Get properties handle first. */ // Get dataset rank and dimension. filespace = H5Dget_space(dataset); /* Get filespace handle first. */ // rank = H5Sget_simple_extent_ndims(filespace); rank = H5Sget_simple_extent_dims(filespace, dims, NULL); // Offset only set when it is possible to access to data directly offset = (H5D_CONTIGUOUS == H5Pget_layout(cparms))? H5Dget_offset(dataset) : 0; // status = H5Dread(dataset, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, bm_out); hid_t h5datatype = H5Dget_type(dataset); // Reading byte order switch(H5Tget_order(h5datatype)) { case H5T_ORDER_ERROR: REPORT_ERROR(ERR_IO, "readHDF5: error reading endianness."); break; case H5T_ORDER_LE: swap = IsBigEndian(); break; case H5T_ORDER_BE: swap = IsLittleEndian(); break; default: REPORT_ERROR(ERR_IO, "readHDF5: unknown endianness type, maybe mixed types."); break; } DataType datatype = datatypeH5(h5datatype); MDMainHeader.setValue(MDL_DATATYPE,(int) datatype); // Setting isStack depending on provider switch (provider.first) { case MISTRAL: // rank 3 arrays are stacks isStack = true; break; // case EMAN: // Images in stack are stored in separated groups default: break; } ArrayDim aDim; size_t nDimFile; aDim.xdim = dims[rank-1]; aDim.ydim = (rank>1)?dims[rank-2]:1; aDim.zdim = (rank>3 || (rank==3 && !isStack))?dims[rank-3]:1; if ( provider.first == EMAN ) nDimFile = nobjEman; else nDimFile = ( rank<3 || !isStack )?1:dims[0] ; if (select_img > nDimFile) REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS, formatString("readHDF5 (%s): Image number %lu exceeds stack size %lu", filename.c_str(), select_img, nDimFile)); aDim.ndim = replaceNsize = (select_img == ALL_IMAGES)? nDimFile :1 ; setDimensions(aDim); //Read header only if(dataMode == HEADER || (dataMode == _HEADER_ALL && aDim.ndim > 1)) return errCode; // EMAN stores each image in a separate dataset if ( provider.first == EMAN ) select_img = 1; size_t imgStart = IMG_INDEX(select_img); size_t imgEnd = (select_img != ALL_IMAGES) ? imgStart + 1 : aDim.ndim; MD.clear(); MD.resize(imgEnd - imgStart,MDL::emptyHeader); if (dataMode < DATA) // Don't read data if not necessary but read the header return errCode; if ( H5Pget_layout(cparms) == H5D_CONTIGUOUS ) //We can read it directly readData(fimg, select_img, datatype, 0); else // We read it by hyperslabs { // Allocate memory for image data (Assume xdim, ydim, zdim and ndim are already set //if memory already allocated use it (no resize allowed) mdaBase->coreAllocateReuse(); hid_t memspace; hsize_t offset[4]; // Hyperslab offset in the file hsize_t count[4]; // Size of the hyperslab in the file // Define the offset and count of the hyperslab to be read. switch (rank) { case 4: count[0] = 1; case 3: // if (stack) count[rank-3] = aDim.zdim; offset[rank-2] = 0; case 2: count[rank-2] = aDim.ydim; offset[rank-2] = 0; break; } count[rank-1] = aDim.xdim; offset[rank-1] = 0; aDim.xdim = dims[rank-1]; aDim.ydim = (rank>1)?dims[rank-2]:1; aDim.zdim = (rank == 4)?dims[1]:1; // size_t nDimFile = (rank>2)?dims[0]:1 ; // Define the memory space to read a hyperslab. memspace = H5Screate_simple(rank,count,NULL); size_t data = (size_t) this->mdaBase->getArrayPointer(); size_t pad = aDim.zyxdim*gettypesize(myT()); for (size_t idx = imgStart, imN = 0; idx < imgEnd; ++idx, ++imN) { // Set the offset of the hyperslab to be read offset[0] = idx; if ( H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) REPORT_ERROR(ERR_IO_NOREAD, formatString("readHDF5: Error selecting hyperslab %d from filename %s", imgStart, filename.c_str())); // movePointerTo(ALL_SLICES,imN); // Read if ( H5Dread(dataset, H5Datatype(myT()), memspace, filespace, H5P_DEFAULT, (void*)(data + pad*imN)) < 0 ) REPORT_ERROR(ERR_IO_NOREAD,formatString("readHDF5: Error reading hyperslab %d from filename %s", imgStart, filename.c_str())); } H5Sclose(memspace); } H5Pclose(cparms); H5Sclose(filespace); H5Dclose(dataset); return errCode; }
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; }
/*------------------------------------------------------------------------- * Function: test_1a * * Purpose: Tests a non-extendible dataset with a single external file. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Monday, November 23, 1998 * * Modifications: * *------------------------------------------------------------------------- */ static int test_1a(hid_t file) { hid_t dcpl=-1; /*dataset creation properties */ hid_t space=-1; /*data space */ hid_t dset=-1; /*dataset */ hsize_t cur_size[1]; /*data space current size */ hsize_t max_size[1]; /*data space maximum size */ int n; /*number of external files */ char name[256]; /*external file name */ off_t file_offset; /*external file offset */ hsize_t file_size; /*sizeof external file segment */ TESTING("fixed-size data space, exact storage"); /* Create the dataset */ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error; cur_size[0] = max_size[0] = 100; if(H5Pset_external(dcpl, "ext1.data", (off_t)0, (hsize_t)(max_size[0] * sizeof(int))) < 0) goto error; if((space = H5Screate_simple(1, cur_size, max_size)) < 0) goto error; if((dset = H5Dcreate2(file, "dset1", H5T_NATIVE_INT, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error; if(H5Dclose(dset) < 0) goto error; if(H5Sclose(space) < 0) goto error; if(H5Pclose(dcpl) < 0) goto error; /* Read dataset creation information */ if((dset = H5Dopen2(file, "dset1", H5P_DEFAULT)) < 0) goto error; /* Test dataset address. Should be undefined. */ if(H5Dget_offset(dset) != HADDR_UNDEF) goto error; if((dcpl = H5Dget_create_plist(dset)) < 0) goto error; if((n = H5Pget_external_count(dcpl)) < 0) goto error; if(1 != n) { H5_FAILED(); puts(" Returned external count is wrong."); printf(" got: %d\n ans: 1\n", n); goto error; } HDstrcpy(name + sizeof(name) - 4, "..."); if(H5Pget_external(dcpl, 0, sizeof(name) - 4, name, &file_offset, &file_size) < 0) goto error; if(file_offset != 0) { H5_FAILED(); puts(" Wrong file offset."); printf(" got: %lu\n ans: 0\n", (unsigned long)file_offset); goto error; } if(file_size != (max_size[0] * sizeof(int))) { H5_FAILED(); puts(" Wrong file size."); printf(" got: %lu\n ans: %lu\n", (unsigned long)file_size, (unsigned long)max_size[0]*sizeof(int)); goto error; } if (H5Pclose (dcpl) < 0) goto error; if (H5Dclose (dset) < 0) goto error; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Pclose(dcpl); H5Sclose(space); H5Dclose(dset); } H5E_END_TRY; return 1; }