static int init_SDSs(coda_hdf4_product *product) { if (SDfileinfo(product->sd_id, &(product->num_sds), &(product->num_sd_file_attributes)) != 0) { coda_set_error(CODA_ERROR_HDF4, NULL); return -1; } if (product->num_sds > 0) { int i; product->sds = malloc(product->num_sds * sizeof(coda_hdf4_SDS *)); if (product->sds == NULL) { coda_set_error(CODA_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)", (long)product->num_sds * sizeof(coda_hdf4_SDS *), __FILE__, __LINE__); return -1; } for (i = 0; i < product->num_sds; i++) { product->sds[i] = NULL; } for (i = 0; i < product->num_sds; i++) { product->sds[i] = coda_hdf4_SDS_new(product, i); if (product->sds[i] == NULL) { return -1; } } } return 0; }
scan_sd(string infile) { int id, sds, n, i, j, k, ret, size, type, na, nd; char name[256]; id = SDstart(infile, DFACC_RDONLY); if (id<0) error("%s is probably not an HDF SD (scientific dataset)", infile); ret = SDfileinfo(id, &nd, &na); dprintf(0,"Found %d scientific data set%s in %s with %d attributes\n", nd,(nd > 1 ? "s" : ""),infile, na); for (k=0;;k++) { sds = SDselect(id, nd); ret = SDgetinfo(sds, name, &rank, shape, &type, &na); label[0] = unit[0] = fmt[0] = coordsys[0] = 0; ret = SDgetdatastrs(sds, label, unit, fmt, coordsys, 256); dprintf(0,"%d: %s(",k,label); for (i=0, size=1; i<rank; i++) { if (i==rank-1) dprintf(0,"%d)",shape[i]); else dprintf(0,"%d,",shape[i]); size *= shape[i]; } dprintf(0," %s ",unit); dprintf(0," -> [%d elements of type: %d]\n", size, type); /* ret = SDendaccess(sds); */ } SDend(id); }
CPLErr HDF4Dataset::ReadGlobalAttributes( int32 iHandler ) { /* -------------------------------------------------------------------- */ /* Obtain number of SDSs and global attributes in input file. */ /* -------------------------------------------------------------------- */ int32 nDatasets = 0; int32 nAttributes = 0; if ( SDfileinfo( iHandler, &nDatasets, &nAttributes ) != 0 ) return CE_Failure; char szAttrName[H4_MAX_NC_NAME] = {}; // TODO: Get this off the stack. // Loop through the all attributes for( int32 iAttribute = 0; iAttribute < nAttributes; iAttribute++ ) { int32 iNumType = 0; int32 nValues = 0; // Get information about the attribute. Note that the first // parameter is an SD interface identifier. SDattrinfo( iHandler, iAttribute, szAttrName, &iNumType, &nValues ); if ( STARTS_WITH_CI(szAttrName, "coremetadata") || STARTS_WITH_CI(szAttrName, "archivemetadata.") || STARTS_WITH_CI(szAttrName, "productmetadata.") || STARTS_WITH_CI(szAttrName, "badpixelinformation") || STARTS_WITH_CI(szAttrName, "product_summary") || STARTS_WITH_CI(szAttrName, "dem_specific") || STARTS_WITH_CI(szAttrName, "bts_specific") || STARTS_WITH_CI(szAttrName, "etse_specific") || STARTS_WITH_CI(szAttrName, "dst_specific") || STARTS_WITH_CI(szAttrName, "acv_specific") || STARTS_WITH_CI(szAttrName, "act_specific") || STARTS_WITH_CI(szAttrName, "etst_specific") || STARTS_WITH_CI(szAttrName, "level_1_carryover") ) { bIsHDFEOS = true; papszGlobalMetadata = TranslateHDF4EOSAttributes( iHandler, iAttribute, nValues, papszGlobalMetadata ); } // Skip "StructMetadata.N" records. We will fetch information // from them using HDF-EOS API else if ( STARTS_WITH_CI(szAttrName, "structmetadata.") ) { bIsHDFEOS = true; continue; } else { papszGlobalMetadata = TranslateHDF4Attributes( iHandler, iAttribute, szAttrName, iNumType, nValues, papszGlobalMetadata ); } } return CE_None; }
int list_sds(int32 infile_id, int32 outfile_id, int32 sd_id, int32 sd_out, list_table_t *list_tbl, dim_table_t *td1, dim_table_t *td2, options_t *options) { int32 sds_id, /* dataset identifier */ n_datasets, /* number of datasets in the file */ n_file_attrs, /* number of file attributes */ index, /* index of a dataset */ sds_ref, /* reference number */ dim_sizes[H4_MAX_VAR_DIMS],/* dimensions of an image */ data_type, /* number type */ rank, /* rank */ n_attrs; /* number of attributes */ char name[H4_MAX_GR_NAME]; /* name of dataset */ /* determine the number of data sets in the file and the number of file attributes */ if (SDfileinfo (sd_id, &n_datasets, &n_file_attrs)==FAIL){ printf("Could not get SDS info\n"); return FAIL; } for (index = 0; index < n_datasets; index++) { sds_id = SDselect (sd_id, index); SDgetinfo(sds_id, name, &rank, dim_sizes, &data_type, &n_attrs); sds_ref = SDidtoref(sds_id); /* check if already inserted in Vgroup; search all SDS tags */ if ( list_table_search(list_tbl,DFTAG_SD,sds_ref)>=0 || list_table_search(list_tbl,DFTAG_SDG,sds_ref)>=0 || list_table_search(list_tbl,DFTAG_NDG,sds_ref)>=0 ) { SDendaccess (sds_id); continue; } /* copy SDS */ if (copy_sds(sd_id,sd_out,TAG_GRP_DSET,sds_ref,0,NULL,options,list_tbl,td1,td2, infile_id,outfile_id)<0) goto out; /* terminate access to the current dataset */ SDendaccess (sds_id); } return SUCCEED; out: SDendaccess (sds_id); return FAIL; }
int list_glb(int32 infile_id, int32 outfile_id, int32 sd_id, int32 sd_out, int32 gr_id, int32 gr_out, list_table_t *list_tbl, options_t *options) { int32 n_datasets, /* number of datasets in the file */ n_file_attrs; /* number of file attributes */ if ( options->trip==0 ) { return SUCCEED; } /*------------------------------------------------------------------------- * copy SDS global attributes *------------------------------------------------------------------------- */ /* determine the number of data sets in the file and the number of file attributes */ if (SDfileinfo (sd_id, &n_datasets, &n_file_attrs)==FAIL) { printf("Could not get SDS info\n"); return FAIL; } if (copy_sds_attrs(sd_id,sd_out,n_file_attrs,options)<0) return FAIL; /*------------------------------------------------------------------------- * copy GR global attributes *------------------------------------------------------------------------- */ /* determine the number of data sets in the file and the number of file attributes */ if (GRfileinfo (gr_id, &n_datasets, &n_file_attrs)==FAIL) { printf("Could not get GR info\n"); return FAIL; } if (copy_gr_attrs(gr_id,gr_out,n_file_attrs,options)<0) return FAIL; return SUCCEED; }
int main(int argc, char *argv[]){ char filename[100], sds_name[100][MAX_NUM_SDS]; int32 file_ID, sds_ID, num_sds, num_file_attribute; int which_sds=0, i; char name[100], type_name[100]; int32 num_dim, dim_size[MAX_NUM_DIM]; int32 data_type, num_sds_attribute; strcpy( filename, "2B31.070101.52026.6.HDF"); /* * Read Data */ file_ID = SDstart( filename, DFACC_READ ); sds_ID = SDfileinfo( file_ID, &num_sds, &num_file_attribute ); printf( "\n there are %d SDSs in the file.\n", num_sds ); for( which_sds=0 ; which_sds<num_sds ; which_sds++ ){ sds_ID = SDselect( file_ID, which_sds ); SDgetinfo( sds_ID, name, &num_dim, dim_size, &data_type, &num_sds_attribute ); SDendaccess( sds_ID ); switch (data_type){ case 5: strcpy( type_name, "float32" ); break; case 20: strcpy( type_name, "int8" ); break; case 22: strcpy( type_name, "int16" ); break; case 24: strcpy( type_name, "int32" ); break; default: strcpy( type_name, "other" ); break; } strcpy( sds_name[which_sds], name ); printf( "%3d %10s %20s(", which_sds, type_name, sds_name[which_sds] ); for(i=0;i<num_dim;i++){ printf("%5d, ", dim_size[i]); } printf( ")\n" ); } SDend( file_ID ); exit(0); }
/* Obtain information about the specific HDF file. * */ int cuinquire_hdf(CuFile* file, int* ngdims, int* nvars, int* natts, int* recdim){ int t_ngdims, t_nvars, t_natts, t_recdim; int dimidx; int32 dimid, datatype, ndattrs; long len; /* Determine the contents of the file. */ if (SDfileinfo(file->internid1, (nvars ? nvars : &t_nvars), /* # of data sets in file */ (natts ? natts : &t_natts)) /* # of global attr. in file */ == -1 ) { CuError(CU_DRIVER,"Determining the contents of the HDF file %s", file->controlpath); cuerrorreport_hdf(); return -1; } if (ngdims) *ngdims = file->ndims; /* Look for an unlimited dimension */ if (recdim) { *recdim = -1; for (dimidx=0; dimidx<file->ndims; dimidx++){ if((dimid=cudimid2hdf(file, dimidx))==-1) return -1; if(SDdiminfo(dimid, NULL, &len, &datatype, &ndattrs)==-1){ cuerrorreport_hdf(); return -1; } if (len==0) *recdim = dimidx; } } /* Return success ( 0 ). */ return CU_SUCCESS; }
/* Open and read the HDF file. Return the file ID if successful, or * report error and send back failure status (-1). */ int cuopenread_hdf(const char* controlpath, const char* datapath){ CuFile* file; int32 cdfid; int nvars=0, natts=0; int varid, ndims, dimidx, maxdim, mindim; int32 dimid, sds_id; CuDim *dim; /* Open the HDF file. DFACC_RDONLY is defined in hdf.h. */ if ((cdfid=SDstart(controlpath, DFACC_RDONLY))==-1) { CuError(CU_EOPEN,"Opening HDF file %s",controlpath); cuerrorreport_hdf(); return -1; } /* Make sure there is a scientific dataset */ SDfileinfo(cdfid, &nvars, &natts); if (nvars==0 && natts==0){ CuError(CU_EOPEN,"HDF file %s does not contain any scientific datasets",controlpath); cuerrorreport_hdf(); return -1; } if((file = CuCreateFile(CuHdf))==(CuFile*)0){ return -1; } /* Set the file path and file ID */ strncpy(file->controlpath,controlpath,CU_MAX_PATH); file->internid1 = cdfid; /* Set up a mapping of cdunif dimid to HDF dimid: */ /* Go through all the dimensions, find min and max HDF_dimid. */ /* ASSUME THAT DIMENSION IDS ARE CONSECUTIVE NONNEGATIVE NUMBERS. */ /* Store base dimid in file->internid2. */ /* The mapping is 0 --> mindim, 1 --> mindim+1, etc. */ mindim = maxdim = -1; for (varid=0; varid<nvars; varid++){ if (cuvarinq_hdf(file, varid, NULL, NULL, &ndims, NULL, NULL)) return -1; if ((sds_id=SDselect(file->internid1, varid)) == -1) { cuerrorreport_hdf(); return -1; } for (dimidx=0; dimidx<ndims; dimidx++){ if((dimid=SDgetdimid(sds_id, dimidx))==-1){ cuerrorreport_hdf(); return -1; } if (maxdim==-1){ mindim = maxdim = dimid; } else{ mindim = MIN(mindim, dimid); maxdim = MAX(maxdim, dimid); } } } file->internid2 = mindim; file->ndims = maxdim-mindim+1; /* Return file ID */ return file->id; }
static intn test_dim1_SDS1(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 out_data[5]; int32 dimsize[1]; int32 sds_id, file_id, dim_id, index; int32 start=0, stride=1; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 num_type, array_rank, count; int32 n_datasets, n_file_attrs, n_local_attrs, n_vars = 0; intn datanum, ranknum, status =0, i, idx, idx1, idx2; hdf_varlist_t* var_list; intn is_coord = FALSE; char attr_name[H4_MAX_NC_NAME], attr_values[80]; intn num_errs = 0; /* number of errors so far */ file_id = SDstart(FILE1, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); /* Create a one-dim dataset named VAR1_NAME, of type DFNT_FLOAT32. */ dimsize[0] = 5; sds_id = SDcreate(file_id, VAR1_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as its dataset. */ dim_id = SDgetdimid(sds_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, VAR1_NAME); /* status = SDsetdimname(dim_id, VAR1_NAME); */ CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there is 1 dataset in the file. */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 1, "SDfileinfo"); /* Set an attribute to dimension VAR1_NAME. */ status = SDsetattr(dim_id, ATTR1_NAME, DFNT_CHAR8, ATTR1_LEN, ATTR1_VAL); CHECK(status, FAIL, "SDsetattr"); /* Set an attribute to dataset VAR1_NAME. */ status = SDsetattr(sds_id, ATTR2_NAME, DFNT_CHAR8, ATTR2_LEN, ATTR2_VAL); CHECK(status, FAIL, "SDsetattr"); /* Get file info and verify that there are 2 datasets in the file: 1 SDS and 1 coordinate variable (because of SDsetattr dim) */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); /* Write data to the SDS */ status = SDwritedata(sds_id, &start, &stride, dimsize, (VOIDP)sds1_data); CHECK(status, FAIL, "SDwritedata"); /* Close dataset and file. */ status = SDendaccess(sds_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Open the file again to check its data */ file_id = SDstart(FILE1, DFACC_RDWR); CHECK(file_id, FAIL, "SDstart"); /* Check variable type and attributes of each element in the file */ /* Get the number of variables of name VAR1_NAME */ status = SDgetnumvars_byname(file_id, VAR1_NAME, &n_vars); if (n_vars == 1) { /* Get index of dataset VAR1_NAME */ index = SDnametoindex(file_id, VAR1_NAME); CHECK(index, FAIL, "SDnametoindex"); } else { /* Get the list of all variables of named VAR1_NAME */ var_list = (hdf_varlist_t *)HDmalloc(n_vars * sizeof(hdf_varlist_t)); status = SDnametoindices(file_id, VAR1_NAME, var_list); /* In this case, the first variable is a dataset */ for (idx = 0; idx < n_vars; idx++) { if (var_list[idx].var_type == IS_SDSVAR) { index = var_list[idx].var_index; VERIFY(index, 0, "SDnametoindices"); } } } sds_id = SDselect(file_id, index); CHECK(sds_id, FAIL, "SDselect"); /* Verify that this variable is a dataset. */ is_coord = SDiscoordvar(sds_id); VERIFY(is_coord, FALSE, "SDiscoordvar"); /* Read and verify the information of the SDS' first attribute. */ status = SDattrinfo(sds_id, 0, attr_name, &num_type, &count); CHECK(status, FAIL, "SDattrinfo"); VERIFY(count, ATTR2_LEN, "SDattrinfo"); VERIFY(HDstrncmp(attr_name, ATTR2_NAME, 14), 0, "SDattrinfo"); /* Read and verify the values of the SDS' first attribute. */ status = SDreadattr(sds_id, 0, attr_values); CHECK(status, FAIL, "SDreadattr"); if (HDstrncmp(attr_values, ATTR2_VAL, ATTR2_LEN) != 0) { fprintf(stderr, "Unmatched attribute values for SDS %s: is <%s>, should be <%s>\n", VAR1_NAME, attr_values, ATTR2_VAL); num_errs++; } /* Get access to the SDS' first dimension. */ dim_id = SDgetdimid(sds_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); /* Read and verify the information of the dimension's first attribute. */ status = SDattrinfo(dim_id, 0, attr_name, &num_type, &count); CHECK(status, FAIL, "SDattrinfo"); VERIFY(count, 19, "SDattrinfo"); VERIFY(HDstrncmp(attr_name, ATTR1_NAME, 21), 0, "SDattrinfo"); /* Read and verify the values of the dimension's first attribute. */ status = SDreadattr(dim_id, 0, attr_values); CHECK(status, FAIL, "SDreadattr"); if (HDstrncmp(attr_values, ATTR1_VAL, ATTR1_LEN) != 0) { fprintf(stderr, "Unmatched attribute values for dimension %s: is <%s>, should be <%s>\n", VAR1_NAME, attr_values, ATTR1_VAL); num_errs++; } /* Verify again that the number of datasets in the file is 2, 1 SDS and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); VERIFY(n_file_attrs, 0, "SDfileinfo"); /* Read and verify the dataset's data */ status = SDreaddata (sds_id, &start, NULL, dimsize, &out_data); CHECK(status, FAIL, "SDreaddata"); for (idx1 = 0; idx1 < dimsize[0]; idx1++) if (out_data[idx1] != sds1_data[idx1]) { fprintf(stderr, "Read value (%f) differs from written (%f) at [%d]\n", out_data[idx1], sds1_data[idx1], idx1); num_errs++; } /* Close dataset and file. */ status = SDendaccess(sds_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_dim1_SDS1 */
static intn test_named_vars(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 sds2_data[2][3] = {{0.1, 2.3, 4.5}, {4.5, 6.7, 8.9}}; int32 dimsize[1], dimsize2[2]; int32 sds_id, sds1_id, sds2_id, sds3_id, sds4_id, sds5_id; int32 file_id, dim_id, index; int32 start=0, stride=1, stat; int32 start2[2]={0,0}, stride2[2]={1,1}; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 array_rank; int32 n_datasets, n_file_attrs, n_local_attrs, n_vars=0; float32 out_data2[2][3]; intn datanum, ranknum, status =0, idx, idx1, idx2; intn is_coordvar=FALSE; hdf_varlist_t *allvars, *varlistp; intn num_errs = 0; /* number of errors so far */ char line[40]; char contents[7][40]={ "#0 SDS 2-dim 'Common Name'", "#1 SDS 2-dim 'Common Name'", "#2 SDS 1-dim 'One Dimension'", "#3 Coordinate 1-dim 'Common Name'", "#4 SDS 1-dim 'One Dimension'", "#5 SDS 1-dim 'Another Name'", "#6 Coordinate 1-dim 'Another Name'"}; file_id = SDstart(FILE3, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); dimsize2[0] = 2; dimsize2[1] = 3; /* Create first COMMON_NAME data set. */ sds1_id = SDcreate(file_id, COMMON_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds1_id, FAIL, "SDcreate"); status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); /* Create second COMMON_NAME data set. */ sds2_id = SDcreate(file_id, COMMON_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds2_id, FAIL, "SDcreate"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); dimsize[0] = 5; sds3_id = SDcreate(file_id, ONEDIM_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds3_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the previous 2 datasets */ dim_id = SDgetdimid(sds3_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, COMMON_NAME); CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there are 3 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); /* Write values to the dimension COMMON_NAME (same name as first 2 datasets) */ status = SDsetdimscale (dim_id, dimsize[0], DFNT_INT32, scale1); CHECK(status, FAIL, "SDsetdimscale"); /* Get file info and verify that there are 4 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 4, "SDfileinfo"); dimsize[0] = 8; sds4_id = SDcreate(file_id, ONEDIM_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds4_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the previous 2 datasets */ dim_id = SDgetdimid(sds4_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, ANOTHER_NAME); CHECK(status, FAIL, "SDsetdimname"); sds5_id = SDcreate(file_id, ANOTHER_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds5_id, FAIL, "SDcreate"); /* Get file info and verify that there are 6 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 6, "SDfileinfo"); status = SDsetattr(dim_id, ATTR1_NAME, DFNT_CHAR8, ATTR1_LEN, ATTR1_VAL); CHECK(status, FAIL, "SDsetattr"); /* Get file info and verify that there are 7 datasets in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 7, "SDfileinfo"); /* Verify again that the number of datasets in the file is 7 */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 7, "SDfileinfo"); /* There are 3 variables of name COMMON_NAME */ status = SDgetnumvars_byname(file_id, COMMON_NAME, &n_vars); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_vars, 3, "SDfileinfo"); allvars = (hdf_varlist_t *)HDmalloc(n_vars * sizeof(hdf_varlist_t)); status = SDnametoindices(file_id, COMMON_NAME, allvars); CHECK(status, FAIL, "SDfileinfo"); /* Compare file contents with predefined text to verify */ for (idx = 0; idx < n_datasets; idx++) { sds_id = SDselect(file_id, idx); CHECK(sds_id, FAIL, "SDselect"); status = SDgetinfo(sds_id, sds_name, &array_rank, NULL, NULL, NULL); CHECK(status, FAIL, "SDgetinfo"); is_coordvar = SDiscoordvar(sds_id); if (is_coordvar) sprintf(line,"#%d Coordinate %d-dim '%s'\n", idx, array_rank, sds_name); else sprintf(line,"#%d SDS %d-dim '%s'\n", idx, array_rank, sds_name); if (strncmp(contents[idx], line, strlen(contents[idx])) != 0) { fprintf(stderr, "File contents are incorrect in testing variable types at variable of index %d\n", idx); } } status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_named_vars */
int get_data(char *filename, int *zonecode, int *sphercode, float *orientationangle, float *pixelsize, float *upperleftx, float *upperlefty, int *rows, int *cols) { int32 i, j, n, sd, n_sets, n_gattr, count, structmetadata_exists, number_type; float floatattr; double doubleattr; char projection[256]; char coordinate[256]; char attrib[256]; char attribu[256]; void metareader(int32 sd_id, char *type_of_meta, char *metastring, int32 *count, char *data); *zonecode = *sphercode = *rows = *cols = -1; *orientationangle = *pixelsize = -999.0; /* Make sure input file is HDF, is * readable, has SDSs, et cetera ***********************************/ if ((sd = SDstart(filename, DFACC_RDONLY)) == -1) { printf("Error: file '%s' can't be opened with SDstart(): cannot continue...\n", filename); exit(-2); } n_sets = 0; SDfileinfo(sd, &n_sets, &n_gattr); if (n_sets == 0) { printf("Error: file %s doesn't seem to have any SDSs: cannot continue...\n", filename); SDend(sd); exit(-4); } if (n_gattr == 0) { printf("Error: file %s doesn't seem to have any global attributes: cannot continue...\n", filename); SDend(sd); exit(-4); } structmetadata_exists = 0; for (j=0;j<n_gattr;j++) { SDattrinfo(sd, j, attrib, &number_type, &count); n = strlen(attrib); for (i=0;i<n;i++) attribu[i] = toupper(attrib[i]); if (strstr(attribu, "ORIENTATIONANGLE")) { SDreadattr(sd, j, &doubleattr); *orientationangle = (float)doubleattr; } if (strstr(attribu, "PIXELSIZE")) { SDreadattr(sd, j, &doubleattr); *pixelsize = (float)doubleattr; } if (strstr(attribu, "STRUCTMETADATA")) { structmetadata_exists = 1; } } if (structmetadata_exists == 0) { printf("Error: file %s doesn't seem to have any StructMetadata: cannot continue...\n", filename); SDend(sd); exit(-4); } metareader(sd, "STRUCTMETADATA\0", "Projection\0", &count, projection); if ( !strstr(projection, "GCTP_UTM\0") ) { printf("Error: file %s has projection %s, not UTM: cannot continue...\n", filename, projection); SDend(sd); exit(-4); } metareader(sd, "STRUCTMETADATA", "UpperLeftPointMtrs\0", &count, coordinate); parse_comma_sep(coordinate, upperleftx, upperlefty); coordinate[0] = '\0'; metareader(sd, "STRUCTMETADATA", "XDim\0", &count, coordinate); *cols = atoi(coordinate); coordinate[0] = '\0'; metareader(sd, "STRUCTMETADATA", "YDim\0", &count, coordinate); *rows = atoi(coordinate); coordinate[0] = '\0'; metareader(sd, "STRUCTMETADATA", "ZoneCode\0", &count, coordinate); *zonecode = atoi(coordinate); coordinate[0] = '\0'; metareader(sd, "STRUCTMETADATA", "SphereCode\0", &count, coordinate); *sphercode = atoi(coordinate); SDend(sd); if ( *zonecode == -1) { printf("Error reading zone code, cannot continue...\n"); exit(-5); } if ( *sphercode == -1) { printf("Error reading sphere code, cannot continue...\n"); exit(-5); } if ( *rows == -1) { printf("Error reading number of rows, cannot continue...\n"); exit(-5); } if ( *cols == -1) { printf("Error reading number of columns, cannot continue...\n"); exit(-5); } if ( *orientationangle < -998.0 ) { printf("Error reading orientation angle, cannot continue...\n"); exit(-5); } if ( *pixelsize < 0.0 ) { printf("Error reading pixel size, cannot continue...\n"); exit(-5); } /*printf("As read from file %s (%d rows by %d columns)\n", filename, *rows, *cols); printf("Zonecode %d: sphere code %d; Orientation angle %f; Pixelsize %f; UL: %f, %f\n", *zonecode, *sphercode, *orientationangle, *pixelsize, *upperleftx, *upperlefty); */ return(0); }
int main(int ac, char **av) { char input_file_path[256], output_file_path[256]; char hdf4sds_name[256], hdf4sds_attr_name[256]; char hdf4sds_str_attr_buff[256]; int hdf4sd_id, hdf4access_mode, hdf4status, hdf4n_datasets, hdf4n_file_attrs, hdf4sds_id, hdf4sds_index, hdf4sds_rank, hdf4sds_data_type, hdf4sds_n_attrs, hdf4sds_attr_data_type, hdf4sds_attr_n_values, hdf4sds_num_elements; int hdf4sds_dim_sizes[8], hdf4sds_read_start[8], hdf4sds_read_stride[8]; float *hdf4sds_flt_buff; hid_t hdf5file_id, hdf5dataset_id, hdf5space_id, hdf5attr_id, hdf5attr_space_id, hdf5str_type; herr_t hdf5status; hsize_t hdf5dataset_dims[8], hdf5attr_size; /* Get input file name from the command line, and create output file name */ if (ac < 2) { fprintf(stderr, "Usage is: hdf4tohdf5 inputfile outputfile\n"); fprintf(stderr, "If no output file is given, inputfile.h5 will be produced.\n"); return 1; } strcpy(input_file_path, av[1]); if (ac > 2) { strcpy(output_file_path, av[2]); } else { strcpy(output_file_path, input_file_path); strcat(output_file_path, ".h5"); } /* Open hdf4 file */ hdf4access_mode = DFACC_READ; hdf4sd_id = SDstart(input_file_path, hdf4access_mode); hdf4status = SDfileinfo(hdf4sd_id, &hdf4n_datasets, &hdf4n_file_attrs); if (hdf4status == FAIL) { fprintf(stderr, "Reading hdf4 file failed. Returning.\n"); return 1; } #ifdef DEBUG printf("Id: %i, Datasets: %i, File_attrs: %i\n", hdf4sd_id, hdf4n_datasets, hdf4n_file_attrs); #endif /* Open hdf5 file */ hdf5file_id = H5Fcreate(output_file_path, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); if (hdf5file_id < 0) { fprintf(stderr, "Failed to open HDF5 file %s for writing.\n", output_file_path); return 1; } /* Loop through datasets */ for(hdf4sds_index = 0; hdf4sds_index < hdf4n_datasets; hdf4sds_index++) { hdf4sds_id = SDselect(hdf4sd_id, hdf4sds_index); hdf4status = SDgetinfo(hdf4sds_id, hdf4sds_name, &hdf4sds_rank, hdf4sds_dim_sizes, &hdf4sds_data_type, &hdf4sds_n_attrs); #ifdef DEBUG printf("\nsds_id: %i, sds_name: %s, sds_rank: %i, sds_data_type: %i,\nn_attrs_: %i, dim_sizes: %i %i %i\n", hdf4sds_id, hdf4sds_name, hdf4sds_rank, hdf4sds_data_type, hdf4sds_n_attrs, hdf4sds_dim_sizes[0], hdf4sds_dim_sizes[1], hdf4sds_dim_sizes[2]); #endif /* Get data from SDS into buffer */ hdf4sds_num_elements = hdf4sds_dim_sizes[0]; hdf4sds_read_start[0] = 0; hdf4sds_read_stride[0] = 1; if (hdf4sds_rank > 1){ for(int i=1; i < hdf4sds_rank; i++) { hdf4sds_num_elements = hdf4sds_num_elements*hdf4sds_dim_sizes[i]; hdf4sds_read_start[i] = 0; hdf4sds_read_stride[i] = 1; } } #ifdef DEBUG printf("Total number of elements for this sds: %i\n", hdf4sds_num_elements); #endif /* Allocate the buffer to read in the data */ hdf4sds_flt_buff = malloc((sizeof (float))*hdf4sds_num_elements); hdf4status = SDreaddata(hdf4sds_id, hdf4sds_read_start, hdf4sds_read_stride, hdf4sds_dim_sizes, (VOIDP)hdf4sds_flt_buff); /* Have all of the data from the hdf4 file, now need to load it into hdf5 */ for (int i=0; i < hdf4sds_rank; i++) { hdf5dataset_dims[i] = (hsize_t)hdf4sds_dim_sizes[i]; } hdf5space_id = H5Screate_simple(hdf4sds_rank, hdf5dataset_dims, hdf5dataset_dims); if (hdf4sds_data_type == 5) { //Floats hdf5dataset_id = H5Dcreate(hdf5file_id, hdf4sds_name, H5T_IEEE_F32LE, hdf5space_id, H5P_DEFAULT); hdf5status = H5Dwrite(hdf5dataset_id, H5T_IEEE_F32LE, H5S_ALL, H5S_ALL, H5P_DEFAULT, hdf4sds_flt_buff); /* We've finished reading in the data. Free the hdf4 data buffer. */ free(hdf4sds_flt_buff); /*Assign the HDF5 attributes */ for(int i=0; i < hdf4sds_n_attrs; i++) { hdf4status = SDattrinfo(hdf4sds_id, i, hdf4sds_attr_name, &hdf4sds_attr_data_type, &hdf4sds_attr_n_values); #ifdef DEBUG printf("Attribute %i: Name = %s, Data type = %i, N_values = %i\n", i, hdf4sds_attr_name, hdf4sds_attr_data_type, hdf4sds_attr_n_values); #endif if(hdf4sds_attr_data_type == 4) { /* Read the string attributes */ hdf4status = SDreadattr(hdf4sds_id, i, (VOIDP)hdf4sds_str_attr_buff); hdf4sds_str_attr_buff[hdf4sds_attr_n_values]='\0'; #ifdef DEBUG printf("Value: %s\n", hdf4sds_str_attr_buff); #endif hdf5attr_size = (hsize_t)hdf4sds_attr_n_values; hdf5attr_space_id = H5Screate(H5S_SCALAR); hdf5str_type = H5Tcopy(H5T_C_S1); hdf5status = H5Tset_size(hdf5str_type, (size_t)hdf4sds_attr_n_values); hdf5attr_id = H5Acreate(hdf5dataset_id, hdf4sds_attr_name, hdf5str_type, hdf5attr_space_id, H5P_DEFAULT); hdf5status = H5Awrite(hdf5attr_id, hdf5str_type, hdf4sds_str_attr_buff); hdf5status = H5Aclose(hdf5attr_id); } } hdf5status = H5Dclose(hdf5dataset_id); } hdf5status = H5Sclose(hdf5space_id); hdf4status = SDendaccess(hdf4sds_id); } /* Close access to hdf4 file */ hdf4status = SDend(hdf4sd_id); /* Close access to HDF5 file */ hdf5status = H5Fclose(hdf5file_id); return 0; }
/* Opens an HDF file and reads all its SDS metadata, returning an SDSInfo * structure containing this metadata. Returns NULL on error. */ SDSInfo *open_h4_sds(const char *path) { int i, status; int sd_id = SDstart(path, DFACC_READ); CHECK_HDF_ERROR(path, sd_id); // get dataset and global att counts int32 n_datasets, n_global_atts; status = SDfileinfo(sd_id, &n_datasets, &n_global_atts); CHECK_HDF_ERROR(path, status); SDSInfo *sds = NEW0(SDSInfo); sds->path = xstrdup(path); sds->type = SDS_HDF4_FILE; sds->id = sd_id; // read global attributes sds->gatts = read_attributes(path, sd_id, n_global_atts); // read variables ('datasets') for (i = 0; i < n_datasets; i++) { int sds_id = SDselect(sd_id, i); CHECK_HDF_ERROR(path, sds_id); char buf[_H4_MAX_SDS_NAME + 1]; memset(buf, 0, sizeof(buf)); int32 rank, dim_sizes[H4_MAX_VAR_DIMS], type, natts; status = SDgetinfo(sds_id, buf, &rank, dim_sizes, &type, &natts); CHECK_HDF_ERROR(path, status); SDSVarInfo *var = NEW0(SDSVarInfo); var->name = xstrdup(buf); var->type = h4_to_sdstype(type); var->iscoord = SDiscoordvar(sds_id); var->ndims = rank; var->dims = read_dimensions(sds, sds_id, rank, dim_sizes); var->atts = read_attributes(path, sds_id, natts); var->id = i; // actually the sds_index comp_coder_t comp_type; comp_info c_info; status = SDgetcompinfo(sds_id, &comp_type, &c_info); CHECK_HDF_ERROR(path, status); switch (comp_type) { case COMP_CODE_NONE: var->compress = 0; break; case COMP_CODE_DEFLATE: var->compress = c_info.deflate.level; break; default: // any other compression method is 'worth' 1 imo *trollface* // better than claiming 0 to the user var->compress = 1; break; } var->sds = sds; var->next = sds->vars; sds->vars = var; status = SDendaccess(sds_id); CHECK_HDF_ERROR(path, status); } sds->vars = (SDSVarInfo *)list_reverse((List *)sds->vars); sds->dims = (SDSDimInfo *)list_reverse((List *)sds->dims); sds->funcs = &h4_funcs; return sds; }
GDALDataset *HDF4Dataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; CPLMutexHolderD(&hHDF4Mutex); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ // Attempt to increase maximum number of opened HDF files. #ifdef HDF4_HAS_MAXOPENFILES intn nCurrMax = 0; intn nSysLimit = 0; if ( SDget_maxopenfiles(&nCurrMax, &nSysLimit) >= 0 && nCurrMax < nSysLimit ) { /*intn res = */SDreset_maxopenfiles( nSysLimit ); } #endif /* HDF4_HAS_MAXOPENFILES */ int32 hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); if( hHDF4 <= 0 ) return NULL; Hclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); HDF4Dataset *poDS = new HDF4Dataset(); CPLAcquireMutex(hHDF4Mutex, 1000.0); if( poOpenInfo->fpL != NULL ) { VSIFCloseL(poOpenInfo->fpL); poOpenInfo->fpL = NULL; } /* -------------------------------------------------------------------- */ /* Open HDF SDS Interface. */ /* -------------------------------------------------------------------- */ poDS->hSD = SDstart( poOpenInfo->pszFilename, DFACC_READ ); if ( poDS->hSD == -1 ) { // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF4 file \"%s\" for SDS reading.", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Now read Global Attributes. */ /* -------------------------------------------------------------------- */ if ( poDS->ReadGlobalAttributes( poDS->hSD ) != CE_None ) { // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to read global attributes from HDF4 file \"%s\".", poOpenInfo->pszFilename ); return NULL; } poDS->SetMetadata( poDS->papszGlobalMetadata, "" ); /* -------------------------------------------------------------------- */ /* Determine type of file we read. */ /* -------------------------------------------------------------------- */ const char *pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Signature"); if ( pszValue != NULL && EQUAL( pszValue, pszGDALSignature ) ) { poDS->iSubdatasetType = H4ST_GDAL; poDS->pszSubdatasetType = "GDAL_HDF4"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-1A Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L1A; poDS->pszSubdatasetType = "SEAWIFS_L1A"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-2 Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L2; poDS->pszSubdatasetType = "SEAWIFS_L2"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) != NULL && EQUAL( pszValue, "SeaWiFS Level-3 Standard Mapped Image" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L3; poDS->pszSubdatasetType = "SEAWIFS_L3"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "L1 File Generated By")) != NULL && STARTS_WITH_CI(pszValue, "HYP version ") ) { poDS->iSubdatasetType = H4ST_HYPERION_L1; poDS->pszSubdatasetType = "HYPERION_L1"; } else { poDS->iSubdatasetType = H4ST_UNKNOWN; poDS->pszSubdatasetType = "UNKNOWN"; } /* -------------------------------------------------------------------- */ /* If we have HDF-EOS dataset, process it here. */ /* -------------------------------------------------------------------- */ int32 aiDimSizes[H4_MAX_VAR_DIMS] = {}; // TODO: Get this off of the stack. int32 iRank = 0; int32 iNumType = 0; int32 nAttrs = 0; bool bIsHDF = true; // Sometimes "HDFEOSVersion" attribute is not defined and we will // determine HDF-EOS datasets using other records // (see ReadGlobalAttributes() method). if ( poDS->bIsHDFEOS || CSLFetchNameValue(poDS->papszGlobalMetadata, "HDFEOSVersion") ) { /* -------------------------------------------------------------------- */ /* Process swath layers. */ /* -------------------------------------------------------------------- */ hHDF4 = SWopen( poOpenInfo->pszFilename, DFACC_READ ); if( hHDF4 < 0) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF-EOS file \"%s\" for swath reading.", poOpenInfo->pszFilename ); return NULL; } int32 nStrBufSize = 0; int32 nSubDatasets = SWinqswath(poOpenInfo->pszFilename, NULL, &nStrBufSize); #ifdef DEBUG CPLDebug( "HDF4", "Number of HDF-EOS swaths: %d", static_cast<int>( nSubDatasets ) ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszSwathList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); SWinqswath( poOpenInfo->pszFilename, pszSwathList, &nStrBufSize ); pszSwathList[nStrBufSize] = '\0'; #ifdef DEBUG CPLDebug( "HDF4", "List of HDF-EOS swaths: %s", pszSwathList ); #endif char **papszSwaths = CSLTokenizeString2( pszSwathList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszSwathList ); if ( nSubDatasets != CSLCount(papszSwaths) ) { CSLDestroy( papszSwaths ); // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Cannot parse list of HDF-EOS grids." ); return NULL; } for( int32 i = 0; i < nSubDatasets; i++) { const int32 hSW = SWattach( hHDF4, papszSwaths[i] ); const int32 nFields = SWnentries( hSW, HDFE_NENTDFLD, &nStrBufSize ); char *pszFieldList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); int32 *paiRank = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); int32 *paiNumType = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); SWinqdatafields( hSW, pszFieldList, paiRank, paiNumType ); #ifdef DEBUG { char * const pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of data fields in swath %d: %d", static_cast<int>( i ), static_cast<int>( nFields ) ); CPLDebug( "HDF4", "List of data fields in swath %d: %s", static_cast<int>( i ), pszFieldList ); CPLDebug( "HDF4", "Data fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif char **papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); char szTemp[256] = {'\0'}; // TODO: Get this off the stack. for( int32 j = 0; j < nFields; j++ ) { SWfieldinfo( hSW, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets. const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("HDF4_EOS:EOS_SWATH:\"%s\":%s:%s", poOpenInfo->pszFilename, papszSwaths[i], papszFields[j]) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s %s (%s)", pszString, papszFields[j], papszSwaths[i], poDS->GetDataTypeName(iNumType) ) ); CPLFree( pszString ); szTemp[0] = '\0'; } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); SWdetach( hSW ); } CSLDestroy( papszSwaths ); } SWclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Process grid layers. */ /* -------------------------------------------------------------------- */ hHDF4 = GDopen( poOpenInfo->pszFilename, DFACC_READ ); nSubDatasets = GDinqgrid( poOpenInfo->pszFilename, NULL, &nStrBufSize ); #ifdef DEBUG CPLDebug( "HDF4", "Number of HDF-EOS grids: %d", static_cast<int>( nSubDatasets ) ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszGridList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); GDinqgrid( poOpenInfo->pszFilename, pszGridList, &nStrBufSize ); #ifdef DEBUG CPLDebug( "HDF4", "List of HDF-EOS grids: %s", pszGridList ); #endif char **papszGrids = CSLTokenizeString2( pszGridList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszGridList ); if ( nSubDatasets != CSLCount(papszGrids) ) { CSLDestroy( papszGrids ); GDclose( hHDF4 ); // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLDebug( "HDF4", "Cannot parse list of HDF-EOS grids." ); return NULL; } for( int32 i = 0; i < nSubDatasets; i++) { const int32 hGD = GDattach( hHDF4, papszGrids[i] ); const int32 nFields = GDnentries( hGD, HDFE_NENTDFLD, &nStrBufSize ); char *pszFieldList = static_cast<char *>( CPLMalloc( nStrBufSize + 1 ) ); int32 *paiRank = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); int32 *paiNumType = static_cast<int32 *>( CPLMalloc( nFields * sizeof(int32) ) ); GDinqfields( hGD, pszFieldList, paiRank, paiNumType ); #ifdef DEBUG { char* pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of fields in grid %d: %d", static_cast<int>( i ), static_cast<int>( nFields ) ); CPLDebug( "HDF4", "List of fields in grid %d: %s", static_cast<int>( i ), pszFieldList ); CPLDebug( "HDF4", "Fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif char **papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); char szTemp[256]; for( int32 j = 0; j < nFields; j++ ) { GDfieldinfo( hGD, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_EOS:EOS_GRID:\"%s\":%s:%s", poOpenInfo->pszFilename, papszGrids[i], papszFields[j])); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("[%s] %s %s (%s)", pszString, papszFields[j], papszGrids[i], poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); GDdetach( hGD ); } CSLDestroy( papszGrids ); } GDclose( hHDF4 ); bIsHDF = ( nSubDatasets == 0 ); // Try to read as HDF } char szName[VSNAMELENMAX + 1]; if( bIsHDF ) { /* -------------------------------------------------------------------- */ /* Make a list of subdatasets from SDSs contained in input HDF file. */ /* -------------------------------------------------------------------- */ int32 nDatasets = 0; if ( SDfileinfo( poDS->hSD, &nDatasets, &nAttrs ) != 0 ) return NULL; char szTemp[256] = {'\0'}; // TODO: Get this off the stack. const char *pszName = NULL; for( int32 i = 0; i < nDatasets; i++ ) { const int32 iSDS = SDselect( poDS->hSD, i ); if ( SDgetinfo( iSDS, szName, &iRank, aiDimSizes, &iNumType, &nAttrs) != 0 ) return NULL; if ( iRank == 1 ) // Skip 1D datsets continue; // Do sort of known datasets. We will display only image bands if ( (poDS->iSubdatasetType == H4ST_SEAWIFS_L1A ) && !STARTS_WITH_CI(szName, "l1a_data") ) continue; else pszName = szName; // Add datasets with multiple dimensions to the list of GDAL // subdatasets. const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); // We will use SDS index as an identificator, because SDS names // are not unique. Filename also needed for further file opening poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_SDS:%s:\"%s\":%ld", poDS->pszSubdatasetType, poOpenInfo->pszFilename, static_cast<long>( i ) ) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s (%s)", pszString, pszName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); SDendaccess( iSDS ); szTemp[0] = '\0'; } SDend( poDS->hSD ); poDS->hSD = 0; } /* -------------------------------------------------------------------- */ /* Build a list of raster images. Note, that HDF-EOS dataset may */ /* contain a raster image as well. */ /* -------------------------------------------------------------------- */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); poDS->hGR = GRstart( hHDF4 ); if ( poDS->hGR != -1 ) { if ( GRfileinfo( poDS->hGR, &poDS->nImages, &nAttrs ) == -1 ) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } char szTemp[256] = {'\0'}; // TODO: Get this off the stack. for( int32 i = 0; i < poDS->nImages; i++ ) { const int32 iGR = GRselect( poDS->hGR, i ); // iRank in GR interface has another meaning. It represents number // of samples per pixel. aiDimSizes has only two dimensions. int32 iInterlaceMode = 0; if ( GRgetiminfo( iGR, szName, &iRank, &iNumType, &iInterlaceMode, aiDimSizes, &nAttrs ) != 0 ) { // Release mutex otherwise we will deadlock with GDALDataset // own mutex. CPLReleaseMutex(hHDF4Mutex); GRend( poDS->hGR ); poDS->hGR = 0; Hclose( hHDF4 ); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); return NULL; } const int nCount = CSLCount( poDS->papszSubDatasets ) / 2; snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_NAME", nCount + 1 ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp,CPLSPrintf( "HDF4_GR:UNKNOWN:\"%s\":%ld", poOpenInfo->pszFilename, static_cast<long>( i ) ) ); snprintf( szTemp, sizeof(szTemp), "SUBDATASET_%d_DESC", nCount + 1 ); char *pszString = SPrintArray( GDT_UInt32, aiDimSizes, 2, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%sx%ld] %s (%s)", pszString, static_cast<long>( iRank ), szName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); GRendaccess( iGR ); szTemp[0] = '\0'; } GRend( poDS->hGR ); poDS->hGR = 0; } Hclose( hHDF4 ); poDS->nRasterXSize = poDS->nRasterYSize = 512; // XXX: bogus values // Make sure we don't try to do any pam stuff with this dataset. poDS->nPamFlags |= GPF_NOSAVE; /* -------------------------------------------------------------------- */ /* If we have single subdataset only, open it immediately */ /* -------------------------------------------------------------------- */ if ( CSLCount( poDS->papszSubDatasets ) / 2 == 1 ) { char *pszSDSName = CPLStrdup( CSLFetchNameValue( poDS->papszSubDatasets, "SUBDATASET_1_NAME" )); // Release mutex otherwise we will deadlock with GDALDataset own mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; poDS = NULL; GDALDataset* poRetDS = reinterpret_cast<GDALDataset*>( GDALOpen( pszSDSName, poOpenInfo->eAccess ) ); CPLFree( pszSDSName ); CPLAcquireMutex(hHDF4Mutex, 1000.0); if (poRetDS) { poRetDS->SetDescription(poOpenInfo->pszFilename); } return poRetDS; } else { /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { // Release mutex otherwise we will deadlock with GDALDataset own // mutex. CPLReleaseMutex(hHDF4Mutex); delete poDS; CPLAcquireMutex(hHDF4Mutex, 1000.0); CPLError( CE_Failure, CPLE_NotSupported, "The HDF4 driver does not support update access to " "existing datasets." ); return NULL; } } return poDS; }
void metareader(int32 sd_id, char *type_of_meta, char *metastring, int32 *count, char *data) { #define XMAXLENGTH 1000 int32 i, ii, j, n_attr1, n_sets1, count1, number_type1, n_val; int start,within,wasjustobject; int obj_offset[10],n_obj; char attrib[XMAXLENGTH], attrib1[XMAXLENGTH]; char *charattr; char line[XMAXLENGTH], objs[XMAXLENGTH]; char lhs[XMAXLENGTH], rhs[XMAXLENGTH]; char uppers[XMAXLENGTH]; void get_a_line(char *text, int lengthoftext, int *start, char line[XMAXLENGTH]); SDfileinfo(sd_id, &n_sets1, &n_attr1); for (j=0;j<n_attr1;j++) { SDattrinfo(sd_id, j, attrib1, &number_type1, &count1); attrib[0] = '\0'; for (i=0;i<strlen(attrib1);i++) attrib[i] = toupper(attrib1[i]); attrib[i] = '\0'; start = 0; if (strstr(attrib,type_of_meta)) { if ((charattr = (char *)malloc((count1+1)*sizeof(char))) == NULL) { printf("Out of memory, array 'charattr'\n"); return; } SDreadattr(sd_id, j, charattr); count1 = strlen(charattr); if (!strcmp(type_of_meta, metastring)) { /* signal for no need to parse metadata */ strcpy(data, charattr); return; } n_obj=0; wasjustobject=0; objs[0] = '\0'; do { line[0] = '\0'; get_a_line(charattr,count1+1,&start,line); /* Get rid of whitespace, if not inside "..." characters. */ within=0; for (i=0,ii=0;i<strlen(line);i++) { if (line[i] == '"') { if (!within) within=1; else if (within) within=0; } if (within) line[ii++] = line[i]; else { if (line[i] != ' ') line[ii++] = line[i]; } } line[ii] = '\0'; /* Get left-hand-side, rhs of equation */ lhs[0] = rhs[0] = '\0'; if (strchr(line,'=')) { for (i=0,ii=0;i<(strchr(line,'=')-line);i++) { lhs[ii++]=line[i]; } lhs[ii] = '\0'; i++; for (ii=0;i<strlen(line)-1;i++,ii++) { rhs[ii]=line[i]; } rhs[ii] = '\0'; } if (!strcmp(lhs,"OBJECT")) { wasjustobject=1; obj_offset[n_obj++]=strlen(objs); strcat(objs,rhs); } if (!strcmp(lhs,"GROUP")) wasjustobject=0; if ((!strcmp(lhs,"CLASS"))&&(wasjustobject)) { for (i=0;i<strlen(rhs)-1;i++) rhs[i]=rhs[i+1]; rhs[i-1] = '\0'; strcat(objs,rhs); } if (!strcmp(lhs,"END_OBJECT")) { if (n_obj > 0) objs[obj_offset[--n_obj]] = '\0'; } if (!strcmp(lhs,"NUM_VAL")) { n_val=atoi(rhs); } if (!strcmp(lhs,"VALUE")) { /*printf("!%s! %d *%s*%s*\n", objs,n_obj,lhs,rhs);*/ if (!strcmp(objs, metastring)) { strcpy(data,rhs); *count=n_val; /*printf("!%s! %d *%s*%s*\n", objs,n_obj,lhs,rhs);*/ } } if ((!strcmp(lhs,"\0"))&&(wasjustobject)) { /*printf("!%s! %d *%s*%s*\n", objs,n_obj,lhs,rhs);*/ if (!strcmp(objs, metastring)) { strcat(data,line); *count+=n_val; /*printf("!%s! %d *%s*%s*\n", objs,n_obj,lhs,rhs);*/ } } /* special case for StructMetadata */ if ( (strstr(type_of_meta, "STRUCTMETADATA")) && ( strstr(lhs, metastring)) ) strcat(data, rhs); } while ( line[0] != '\0') ; free(charattr); } } /* for (j=0;j<n_attr1;j++) */ }
static intn test_dim1_SDS2(void) { char sds_name[20]; float32 sds1_data[] = {0.1, 2.3, 4.5, 6.7, 8.9}; float32 sds2_data[2][3] = {{0.1, 2.3, 4.5}, {4.5, 6.7, 8.9}}; int32 dimsize[1], dimsize2[2]; int32 sds1_id, sds2_id, file_id, dim_id, index; int32 start=0, stride=1, stat; int32 start2[2]={0,0}, stride2[2]={1,1}; int32 scale1 [5] = {101,102,103,104,105}, scale1_out[5]; int32 num_type, array_rank, attributes; int32 n_datasets, n_file_attrs, n_local_attrs; float32 out_data2[2][3]; intn datanum, ranknum, status =0, i, idx, idx1, idx2; intn num_errs = 0; /* number of errors so far */ file_id = SDstart(FILE2, DFACC_CREATE); CHECK(file_id, FAIL, "SDstart"); dimsize[0] = 5; dimsize2[0] = 2; dimsize2[1] = 3; sds1_id = SDcreate(file_id, VAR1_NAME, DFNT_FLOAT32, 1, dimsize); CHECK(sds1_id, FAIL, "SDcreate"); /* Set the dimension name to be the same as the next dataset (not created yet) */ dim_id = SDgetdimid(sds1_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); status = SDsetdimname(dim_id, VAR2_NAME); CHECK(status, FAIL, "SDsetdimname"); /* Get file info and verify that there is 1 dataset in the file */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 1, "SDfileinfo"); /* Create and write data to the second dataset VAR2_NAME */ sds2_id = SDcreate(file_id, VAR2_NAME, DFNT_FLOAT32, 2, dimsize2); CHECK(sds2_id, FAIL, "SDcreate"); stat = SDwritedata(sds2_id, start2, stride2, dimsize2, sds2_data); CHECK(status, FAIL, "SDwritedata"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); /* Get file info and verify that there are 2 datasets in the file. */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 2, "SDfileinfo"); /* Write values to the dimension VAR2_NAME (same name as VAR2_NAME) */ status = SDsetdimscale (dim_id, dimsize[0], DFNT_INT32, scale1); CHECK(status, FAIL, "SDsetdimscale"); /* Get file info and verify that there are 3 datasets in the file: 2 SDS and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); /* Close dataset and file */ status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Open the file again to check its data */ file_id = SDstart(FILE2, DFACC_RDWR); CHECK(file_id, FAIL, "SDstart"); /* Verify dimension scale of the first dimension of SDS VAR1_NAME */ /* Get access to dataset VAR1_NAME */ index = SDnametoindex(file_id, VAR1_NAME); CHECK(index, FAIL, "SDnametoindex"); sds1_id = SDselect(file_id, index); CHECK(sds1_id, FAIL, "SDselect"); /* Get access to its first dimension */ dim_id = SDgetdimid(sds1_id, 0); CHECK(dim_id, FAIL, "SDgetdimid"); /* Get dimension scale and verify the values */ status = SDgetdimscale (dim_id, scale1_out); CHECK(status, FAIL, "SDgetdimscale"); for (idx = 0; idx < dimsize[0]; idx++) if (scale1_out[idx] != scale1[idx]) { fprintf(stderr, "Read value (%d) differs from written (%d) at [%d]\n", scale1_out[idx], scale1[idx], idx); num_errs++; } /* End verifying dimension scale */ /* Verify dimension scale of the first dimension of SDS VAR1_NAME */ /* Get access to dataset VAR2_NAME */ index = SDnametoindex(file_id, VAR2_NAME); CHECK(index, FAIL, "SDnametoindex"); sds2_id = SDselect(file_id, index); CHECK(sds2_id, FAIL, "SDselect"); /* Get dataset's info and verify them */ status = SDgetinfo(sds2_id, sds_name, &array_rank, dimsize2, &num_type, &n_local_attrs); CHECK(status, FAIL, "SDgetinfo"); VERIFY(array_rank, 2, "SDfileinfo"); VERIFY(num_type, DFNT_FLOAT32, "SDfileinfo"); VERIFY(n_local_attrs, 0, "SDfileinfo"); /* Read and verify the dataset's data */ status = SDreaddata (sds2_id, start2, NULL, dimsize2, &out_data2); CHECK(status, FAIL, "SDreaddata"); for (idx1 = 0; idx1 < dimsize2[0]; idx1++) for (idx2 = 0; idx2 < dimsize2[1]; idx2++) { if (out_data2[idx1][idx2] != sds2_data[idx1][idx2]) { fprintf(stderr, "Read value (%f) differs from written (%f) at [%d][%d]\n", out_data2[idx1][idx2], sds2_data[idx1][idx2], idx1, idx2); num_errs++; } } /* Verify again that the number of datasets in the file is 3, 2 SDSs and 1 coordinate variable */ status = SDfileinfo(file_id, &n_datasets, &n_file_attrs); CHECK(status, FAIL, "SDfileinfo"); VERIFY(n_datasets, 3, "SDfileinfo"); status = SDendaccess(sds1_id); CHECK(status, FAIL, "SDendaccess"); status = SDendaccess(sds2_id); CHECK(status, FAIL, "SDendaccess"); status = SDend(file_id); CHECK(status, FAIL, "SDend"); /* Return the number of errors that's been kept track of so far */ return num_errs; } /* test_dim1_SDS2 */
GDALDataset *HDF4Dataset::Open( GDALOpenInfo * poOpenInfo ) { int32 i; if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ int32 hHDF4; hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); if( hHDF4 <= 0 ) return( NULL ); Hclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ HDF4Dataset *poDS; poDS = new HDF4Dataset(); poDS->fp = poOpenInfo->fp; poOpenInfo->fp = NULL; /* -------------------------------------------------------------------- */ /* Open HDF SDS Interface. */ /* -------------------------------------------------------------------- */ poDS->hSD = SDstart( poOpenInfo->pszFilename, DFACC_READ ); if ( poDS->hSD == -1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Now read Global Attributes. */ /* -------------------------------------------------------------------- */ if ( poDS->ReadGlobalAttributes( poDS->hSD ) != CE_None ) { delete poDS; return NULL; } poDS->SetMetadata( poDS->papszGlobalMetadata, "" ); /* -------------------------------------------------------------------- */ /* Determine type of file we read. */ /* -------------------------------------------------------------------- */ const char *pszValue; if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Signature")) && EQUAL( pszValue, pszGDALSignature ) ) { poDS->iSubdatasetType = H4ST_GDAL; poDS->pszSubdatasetType = "GDAL_HDF4"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-1A Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L1A; poDS->pszSubdatasetType = "SEAWIFS_L1A"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-2 Data" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L2; poDS->pszSubdatasetType = "SEAWIFS_L2"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "Title")) && EQUAL( pszValue, "SeaWiFS Level-3 Standard Mapped Image" ) ) { poDS->iSubdatasetType = H4ST_SEAWIFS_L3; poDS->pszSubdatasetType = "SEAWIFS_L3"; } else if ( (pszValue = CSLFetchNameValue(poDS->papszGlobalMetadata, "L1 File Generated By")) && EQUALN( pszValue, "HYP version ", 12 ) ) { poDS->iSubdatasetType = H4ST_HYPERION_L1; poDS->pszSubdatasetType = "HYPERION_L1"; } else { poDS->iSubdatasetType = H4ST_UNKNOWN; poDS->pszSubdatasetType = "UNKNOWN"; } /* -------------------------------------------------------------------- */ /* If we have HDF-EOS dataset, process it here. */ /* -------------------------------------------------------------------- */ char szName[VSNAMELENMAX + 1], szTemp[8192]; char *pszString; const char *pszName; int nCount; int32 aiDimSizes[H4_MAX_VAR_DIMS]; int32 iRank, iNumType, nAttrs; bool bIsHDF = true; // Sometimes "HDFEOSVersion" attribute is not defined and we will // determine HDF-EOS datasets using other records // (see ReadGlobalAttributes() method). if ( poDS->bIsHDFEOS || CSLFetchNameValue(poDS->papszGlobalMetadata, "HDFEOSVersion") ) { bIsHDF = false; int32 nSubDatasets, nStrBufSize; /* -------------------------------------------------------------------- */ /* Process swath layers. */ /* -------------------------------------------------------------------- */ hHDF4 = SWopen( poOpenInfo->pszFilename, DFACC_READ ); if( hHDF4 < 0) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open HDF4 `%s'.\n", poOpenInfo->pszFilename ); return NULL; } nSubDatasets = SWinqswath(poOpenInfo->pszFilename, NULL, &nStrBufSize); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS swaths: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszSwathList; char **papszSwaths; pszSwathList = (char *)CPLMalloc( nStrBufSize + 1 ); SWinqswath( poOpenInfo->pszFilename, pszSwathList, &nStrBufSize ); pszSwathList[nStrBufSize] = '\0'; #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS swaths: %s", pszSwathList ); #endif papszSwaths = CSLTokenizeString2( pszSwathList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszSwathList ); if ( nSubDatasets != CSLCount(papszSwaths) ) { CSLDestroy( papszSwaths ); delete poDS; CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hSW, nFields, j; hSW = SWattach( hHDF4, papszSwaths[i] ); nFields = SWnentries( hSW, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); SWinqdatafields( hSW, pszFieldList, paiRank, paiNumType ); #if DEBUG { char *pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of data fields in swath %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of data fields in swath %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Data fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { SWfieldinfo( hSW, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("HDF4_EOS:EOS_SWATH:\"%s\":%s:%s", poOpenInfo->pszFilename, papszSwaths[i], papszFields[j]) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s %s (%s)", pszString, papszFields[j], papszSwaths[i], poDS->GetDataTypeName(iNumType) ) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); SWdetach( hSW ); } CSLDestroy( papszSwaths ); } SWclose( hHDF4 ); /* -------------------------------------------------------------------- */ /* Process grid layers. */ /* -------------------------------------------------------------------- */ hHDF4 = GDopen( poOpenInfo->pszFilename, DFACC_READ ); nSubDatasets = GDinqgrid( poOpenInfo->pszFilename, NULL, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "Number of HDF-EOS grids: %d", (int)nSubDatasets ); #endif if ( nSubDatasets > 0 && nStrBufSize > 0 ) { char *pszGridList; char **papszGrids; pszGridList = (char *)CPLMalloc( nStrBufSize + 1 ); GDinqgrid( poOpenInfo->pszFilename, pszGridList, &nStrBufSize ); #if DEBUG CPLDebug( "HDF4", "List of HDF-EOS grids: %s", pszGridList ); #endif papszGrids = CSLTokenizeString2( pszGridList, ",", CSLT_HONOURSTRINGS ); CPLFree( pszGridList ); if ( nSubDatasets != CSLCount(papszGrids) ) { CSLDestroy( papszGrids ); delete poDS; CPLDebug( "HDF4", "Can not parse list of HDF-EOS grids." ); return NULL; } for ( i = 0; i < nSubDatasets; i++) { char *pszFieldList; char **papszFields; int32 *paiRank, *paiNumType; int32 hGD, nFields, j; hGD = GDattach( hHDF4, papszGrids[i] ); nFields = GDnentries( hGD, HDFE_NENTDFLD, &nStrBufSize ); pszFieldList = (char *)CPLMalloc( nStrBufSize + 1 ); paiRank = (int32 *)CPLMalloc( nFields * sizeof(int32) ); paiNumType = (int32 *)CPLMalloc( nFields * sizeof(int32) ); GDinqfields( hGD, pszFieldList, paiRank, paiNumType ); #if DEBUG { char* pszTmp = SPrintArray( GDT_UInt32, paiRank, nFields, "," ); CPLDebug( "HDF4", "Number of fields in grid %d: %d", (int) i, (int) nFields ); CPLDebug( "HDF4", "List of fields in grid %d: %s", (int) i, pszFieldList ); CPLDebug( "HDF4", "Fields ranks: %s", pszTmp ); CPLFree( pszTmp ); } #endif papszFields = CSLTokenizeString2( pszFieldList, ",", CSLT_HONOURSTRINGS ); for ( j = 0; j < nFields; j++ ) { GDfieldinfo( hGD, papszFields[j], &iRank, aiDimSizes, &iNumType, NULL ); if ( iRank < 2 ) continue; // Add field to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use the field index as an identificator. poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_EOS:EOS_GRID:\"%s\":%s:%s", poOpenInfo->pszFilename, papszGrids[i], papszFields[j])); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue( poDS->papszSubDatasets, szTemp, CPLSPrintf("[%s] %s %s (%s)", pszString, papszFields[j], papszGrids[i], poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); } CSLDestroy( papszFields ); CPLFree( paiNumType ); CPLFree( paiRank ); CPLFree( pszFieldList ); GDdetach( hGD ); } CSLDestroy( papszGrids ); GDclose( hHDF4 ); } GDclose( hHDF4 ); bIsHDF = ( nSubDatasets == 0 ); // Try to read as HDF } if( bIsHDF ) { /* -------------------------------------------------------------------- */ /* Make a list of subdatasets from SDSs contained in input HDF file. */ /* -------------------------------------------------------------------- */ int32 nDatasets; if ( SDfileinfo( poDS->hSD, &nDatasets, &nAttrs ) != 0 ) return NULL; for ( i = 0; i < nDatasets; i++ ) { int32 iSDS; iSDS = SDselect( poDS->hSD, i ); if ( SDgetinfo( iSDS, szName, &iRank, aiDimSizes, &iNumType, &nAttrs) != 0 ) return NULL; if ( iRank == 1 ) // Skip 1D datsets continue; // Do sort of known datasets. We will display only image bands if ( (poDS->iSubdatasetType == H4ST_SEAWIFS_L1A ) && !EQUALN( szName, "l1a_data", 8 ) ) continue; else pszName = szName; // Add datasets with multiple dimensions to the list of GDAL subdatasets nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); // We will use SDS index as an identificator, because SDS names // are not unique. Filename also needed for further file opening poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "HDF4_SDS:%s:\"%s\":%ld", poDS->pszSubdatasetType, poOpenInfo->pszFilename, (long)i) ); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, iRank, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%s] %s (%s)", pszString, pszName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); SDendaccess( iSDS ); } SDend( poDS->hSD ); poDS->hSD = 0; } /* -------------------------------------------------------------------- */ /* Build a list of raster images. Note, that HDF-EOS dataset may */ /* contain a raster image as well. */ /* -------------------------------------------------------------------- */ hHDF4 = Hopen(poOpenInfo->pszFilename, DFACC_READ, 0); poDS->hGR = GRstart( hHDF4 ); if ( poDS->hGR != -1 ) { if ( GRfileinfo( poDS->hGR, &poDS->nImages, &nAttrs ) == -1 ) return NULL; for ( i = 0; i < poDS->nImages; i++ ) { int32 iInterlaceMode; int32 iGR = GRselect( poDS->hGR, i ); // iRank in GR interface has another meaning. It represents number // of samples per pixel. aiDimSizes has only two dimensions. if ( GRgetiminfo( iGR, szName, &iRank, &iNumType, &iInterlaceMode, aiDimSizes, &nAttrs ) != 0 ) return NULL; nCount = CSLCount( poDS->papszSubDatasets ) / 2; sprintf( szTemp, "SUBDATASET_%d_NAME", nCount + 1 ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp,CPLSPrintf( "HDF4_GR:UNKNOWN:\"%s\":%ld", poOpenInfo->pszFilename, (long)i)); sprintf( szTemp, "SUBDATASET_%d_DESC", nCount + 1 ); pszString = SPrintArray( GDT_UInt32, aiDimSizes, 2, "x" ); poDS->papszSubDatasets = CSLSetNameValue(poDS->papszSubDatasets, szTemp, CPLSPrintf( "[%sx%ld] %s (%s)", pszString, (long)iRank, szName, poDS->GetDataTypeName(iNumType)) ); CPLFree( pszString ); GRendaccess( iGR ); } GRend( poDS->hGR ); poDS->hGR = 0; } Hclose( hHDF4 ); poDS->nRasterXSize = poDS->nRasterYSize = 512; // XXX: bogus values // Make sure we don't try to do any pam stuff with this dataset. poDS->nPamFlags |= GPF_NOSAVE; /* -------------------------------------------------------------------- */ /* If we have single subdataset only, open it immediately */ /* -------------------------------------------------------------------- */ if ( CSLCount( poDS->papszSubDatasets ) / 2 == 1 ) { char *pszSDSName; pszSDSName = CPLStrdup( CSLFetchNameValue( poDS->papszSubDatasets, "SUBDATASET_1_NAME" )); delete poDS; poDS = NULL; GDALDataset* poRetDS = (GDALDataset*) GDALOpen( pszSDSName, poOpenInfo->eAccess ); CPLFree( pszSDSName ); if (poRetDS) { poRetDS->SetDescription(poOpenInfo->pszFilename); } return poRetDS; } else { /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The HDF4 driver does not support update access to existing" " datasets.\n" ); return NULL; } } return( poDS ); }
bool RemapHDF4::setFile(QList<QString> fl) { m_fileName = fl; // list all image files in the directory QStringList imageNameFilter; imageNameFilter << "*.hdf"; QStringList files= QDir(m_fileName[0]).entryList(imageNameFilter, QDir::NoSymLinks| QDir::NoDotAndDotDot| QDir::Readable| QDir::Files); m_imageList.clear(); for(uint i=0; i<files.size(); i++) { QFileInfo fileInfo(m_fileName[0], files[i]); QString imgfl = fileInfo.absoluteFilePath(); m_imageList.append(imgfl); } m_depth = m_imageList.size(); /* Open the file and initiate the SD interface. */ int32 sd_id = SDstart(strdup(m_imageList[0].toAscii().data()), DFACC_READ); if (sd_id < 0) { QMessageBox::information(0, "Error", QString("Failed to open %1").arg(m_imageList[0])); return false; } /* Determine the contents of the file. */ int32 dim_sizes[MAX_VAR_DIMS]; int32 rank, num_type, attributes, istat; char name[64]; int32 n_datasets, n_file_attrs; istat = SDfileinfo(sd_id, &n_datasets, &n_file_attrs); /* Access the name of every data set in the file. */ QStringList varNames; for (int32 index = 0; index < n_datasets; index++) { int32 sds_id = SDselect(sd_id, index); istat = SDgetinfo(sds_id, name, &rank, dim_sizes, \ &num_type, &attributes); istat = SDendaccess(sds_id); if (rank == 2) varNames.append(name); } QString var; if (varNames.size() == 0) { QMessageBox::information(0, "Error", QString("No variables in file with rank of 2")); return false; } else if (varNames.size() == 1) { var = varNames[0]; } else { var = QInputDialog::getItem(0, "Select Variable to Extract", "Variable Names", varNames, 0, false); } m_Index = 0; for (int32 index = 0; index < n_datasets; index++) { int32 sds_id = SDselect(sd_id, index); istat = SDgetinfo(sds_id, name, &rank, dim_sizes, \ &num_type, &attributes); istat = SDendaccess(sds_id); if (var == QString(name)) { m_Index = index; break; } } { int32 sds_id = SDselect(sd_id, m_Index); istat = SDgetinfo(sds_id, name, &rank, dim_sizes, &num_type, &attributes); istat = SDendaccess(sds_id); } /* Terminate access to the SD interface and close the file. */ istat = SDend(sd_id); if (num_type == DFNT_CHAR8) m_voxelType = _Char; else if (num_type == DFNT_UCHAR8) m_voxelType = _UChar; else if (num_type == DFNT_INT8) m_voxelType = _Char; else if (num_type == DFNT_UINT8) m_voxelType = _UChar; else if (num_type == DFNT_INT16) m_voxelType = _Short; else if (num_type == DFNT_UINT16) m_voxelType = _UShort; else if (num_type == DFNT_INT32) m_voxelType = _Int; else if (num_type == DFNT_FLOAT32) m_voxelType = _Float; else { QMessageBox::information(0, "Error", QString("Cannot handle datatype %1").arg(num_type)); return false; } m_width = dim_sizes[0]; m_height = dim_sizes[1]; m_bytesPerVoxel = 1; if (m_voxelType == _UChar) m_bytesPerVoxel = 1; else if (m_voxelType == _Char) m_bytesPerVoxel = 1; else if (m_voxelType == _UShort) m_bytesPerVoxel = 2; else if (m_voxelType == _Short) m_bytesPerVoxel = 2; else if (m_voxelType == _Int) m_bytesPerVoxel = 4; else if (m_voxelType == _Float) m_bytesPerVoxel = 4; m_headerBytes = 0; if (m_voxelType == _UChar || m_voxelType == _Char || m_voxelType == _UShort || m_voxelType == _Short) { findMinMaxandGenerateHistogram(); } else { findMinMax(); generateHistogram(); } m_rawMap.append(m_rawMin); m_rawMap.append(m_rawMax); m_pvlMap.append(0); m_pvlMap.append(255); return true; }