/****************************************************************************** MODULE: CreateFileDescriptorMosaic PURPOSE: Creates a file descriptor using information from the MOSAIC descriptor RETURN VALUE: Type = FileDescriptor Value Description ----- ----------- file Success NULL Failure HISTORY: Version Date Programmer Code Reason ------- ----- --------------- ---- ------------------------------------- 07/02 Gail Schmidt Original Development NOTES: ******************************************************************************/ FileDescriptor *CreateFileDescriptorMosaic ( MosaicDescriptor *mosaic, /* I: session info */ int in_bandnum, /* I: number of the input band */ int out_bandnum, /* I: number of the output band */ FileOpenType fileopentype, /* I: reading or writing */ char *filename /* I: the file name */ ) { FileDescriptor *file = NULL; /* return value, new descriptor */ /* allocate a descriptor */ file = ( FileDescriptor * ) calloc( 1, sizeof( FileDescriptor ) ); if ( !file ) ErrorHandler( TRUE, "CreateFileDescriptorMosaic", ERROR_MEMORY, "File Descriptor" ); /* copy the file name */ file->filename = strdup( filename ); if ( !file->filename ) ErrorHandler( TRUE, "CreateFileDescriptorMosaic", ERROR_MEMORY, "File Name" ); /* get the info from the modis file */ file->fileopentype = fileopentype; file->filetype = mosaic->filetype; file->datatype = mosaic->bandinfo[in_bandnum].input_datatype; file->file_endianness = mosaic->input_file_endian; file->bandnum = out_bandnum; /* calculate the size of the data needed for a pixel */ file->datasize = DFKNTsize( file->datatype ); /* get the size for this band, the band number, and the size of a pixel */ file->nrows = mosaic->bandinfo[in_bandnum].nlines; file->ncols = mosaic->bandinfo[in_bandnum].nsamples; file->pixel_size = mosaic->bandinfo[in_bandnum].pixel_size; file->output_pixel_size = mosaic->bandinfo[in_bandnum].pixel_size; file->background_fill = mosaic->bandinfo[in_bandnum].background_fill; /* create an internal read/write buffer for this descriptor */ file->rowbuffer = ( void * ) calloc( file->ncols, file->datasize ); if ( !file->rowbuffer ) ErrorHandler( TRUE, "CreateFileDescriptorMosaic", ERROR_MEMORY, "Error allocating space for the row buffer" ); /* if we're reading, create the read buffers */ if ( fileopentype == FILE_READ_MODE ) CreateFileBuffers( file ); return ( file ); }
static int nxTypeSize(int dataType) { #ifdef XXXHDF4 return DFKNTsize(dataType); #else int type_size = 0; if ((dataType == NX_CHAR) || (dataType == NX_INT8) || (dataType == NX_UINT8)) { type_size = 1; } else if ((dataType == NX_INT16) || (dataType == NX_UINT16)) { type_size = 2; } else if ((dataType == NX_INT32) || (dataType == NX_UINT32) || (dataType == NX_FLOAT32)) { type_size = 4; } else if (dataType == NX_FLOAT64 || dataType == NX_INT64 || dataType == NX_UINT64) { type_size = 8; } else { printf("error in type %d\n", dataType); } return type_size; #endif }
int main(int argc, char *argv[]) { char *MOD021KMfile, *MOD02HKMfile, *MOD02QKMfile; char *filename; /* output file */ FILE *fp; int outfile_exists; char *ancpath; SDS sds[Nitems], outsds[Nbands], dem, height; int32 MOD02QKMfile_id, MOD02HKMfile_id, MOD021KMfile_id; int32 sd_id, attr_index, count, num_type; int ib, j, iscan, Nscans, irow, jcol, idx, crsidx; int nbands; char *SDSlocatorQKM[Nitems] = {"EV_250_RefSB", "EV_250_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB","EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "SolarZenith", "SensorZenith", "SolarAzimuth", "SensorAzimuth", "Longitude", "Latitude"}; char *SDSlocatorHKM[Nitems] = {"EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "EV_500_RefSB", "Reflectance_Img_I1","Reflectance_Img_I2","Reflectance_Img_I3", "EV_1KM_RefSB","EV_1KM_RefSB","EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB","SolZenAng_Mod", "SenZenAng_Mod", "SolAziAng_Mod", "SenAziAng_Mod", "Longitude", "Latitude" }; char *SDSlocator1KM[Nitems] = {"Reflectance_Mod_M5", "Reflectance_Mod_M7", "Reflectance_Mod_M3", "Reflectance_Mod_M4", "Reflectance_Mod_M8", "Reflectance_Mod_M10", "Reflectance_Mod_M11", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "EV_1KM_RefSB", "SolZenAng_Mod", "SenZenAng_Mod", "SolAziAng_Mod", "SenAziAng_Mod", "Longitude", "Latitude"}; char indexlocator[Nitems] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 7, 9, 10, 0, 0, 0, 0, 0, 0}; char numtypelocator[Nitems] = {DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16, DFNT_UINT16,DFNT_FLOAT32 ,DFNT_FLOAT32 ,DFNT_FLOAT32 ,DFNT_FLOAT32 , DFNT_FLOAT32, DFNT_FLOAT32}; uint16 *l1bdata[Nbands]; float32 *sola, *solz, *sena, *senz, *solzfill; float32 *lon, *lat, *lonfill, *latfill; char *attr_name; float64 scale_factor[Nitems], add_offset[Nitems]; unsigned char process[Nbands]; float refl, *mus, muv, phi; float *rhoray, *sphalb, *TtotraytH2O, *tOG; int aggfactor, crsrow1, crsrow2, crscol1, crscol2; int crsidx11, crsidx12, crsidx21, crsidx22; float mus0, mus11, mus12, mus21, mus22; float fractrow, fractcol, t, u; float rhoray0, rhoray11, rhoray12, rhoray21, rhoray22; float sphalb0, sphalb11, sphalb12, sphalb21, sphalb22; float reflmin=REFLMIN, reflmax=REFLMAX, maxsolz=MAXSOLZ; int bad; int write_mode = DFACC_CREATE; int st; size_t nbytes; int ftype; extern char *optarg; extern int optind, opterr; int option_index = 0; static int verbose, overwrite; static int gzip, append; static int output500m, output1km; static int sealevel, TOA, nearest; char dummy[H4_MAX_NC_NAME]; enum{OPT_BANDS = 1, OPT_RANGE, OPT_OUTFILE, OPT_MAXSOLZ}; static struct option long_options[] = { {"1km", no_argument, &output1km, 1}, {"500m", no_argument, &output500m, 1}, {"append", no_argument, &append, 1}, {"bands", required_argument, (int *) NULL, OPT_BANDS}, {"gzip", no_argument, &gzip, 1}, {"maxsolz", required_argument, (int *) NULL, OPT_MAXSOLZ}, {"nearest", no_argument, &nearest, 1}, {"of", required_argument, (int *) NULL, OPT_OUTFILE}, {"overwrite", no_argument, &overwrite, 1}, {"range", required_argument, (int *) NULL, OPT_RANGE}, {"sealevel", no_argument, &sealevel, 1}, {"toa", no_argument, &TOA, 1}, {"verbose", no_argument, &verbose, 1}, {(char *) NULL, 0, (int *) NULL, 0} }; int c; static char dem_filename_buff[MAXNAMELENGTH]; MOD021KMfile = MOD02HKMfile = MOD02QKMfile = (char *) NULL; filename = (char *) NULL; for (ib = 0; ib < Nbands; ib++) process[ib] = FALSE; /* default settings */ output500m = output1km = 0; append = gzip = nearest = sealevel = TOA = verbose = overwrite = 0; while ((c = getopt_long(argc, argv, "", long_options, &option_index)) >= 0) { switch (c) { case 0: /* do nothing for options which will have a flag set automatically by getopt_long() */ break; case OPT_BANDS: if (parse_bands(optarg, process)) { fputs("Invalid band(s) specified.\n", stderr); exit(1); } break; case OPT_RANGE: if (sscanf(optarg, "%g,%g", &reflmin, &reflmax) != 2) { fputs("Error parsing reflectance range.\n", stderr); exit(1); } if ( range_check(reflmin, 0.0F, 1.0F) || range_check(reflmax, 0.0F, 1.0F) || (reflmin >= reflmax) ) { fputs("Invalid reflectance range.\n", stderr); exit(1); } printf("Output reflectance range [%.3f,%.3f] requested.\n", reflmin, reflmax); break; case OPT_MAXSOLZ: maxsolz = (float) atof(optarg); if (range_check(maxsolz, 0.0F, 90.0F)) { fputs("Invalid max. solar zenith angle.\n", stderr); exit(1); } break; case OPT_OUTFILE: filename = optarg; break; default: usage(); exit(1); } } if (append) write_mode = DFACC_RDWR; /* at least one input file must follow */ if (optind >= argc) { usage(); exit(1); } /* check for conflicting options */ if (overwrite && append) { fputs("Options --overwrite and --append are mutually exclusive.\n", stderr); exit(1); } if (sealevel && TOA) { fputs("Options --sealevel and --toa are mutually exclusive.\n", stderr); exit(1); } #ifdef DEBUG printf("append = %d\n", append); if (filename) printf("output filename = %s\n", filename); printf("output1km = %d\n", (int) output1km); printf("output500m = %d\n", (int) output500m); printf("gzip = %d\n", gzip); printf("nearest = %d\n", nearest); printf("sealevel = %d\n", sealevel); printf("TOA = %d\n", TOA); printf("Max. solar zenith angle: %g degrees\n", maxsolz); if (filename) printf("Output file: %s.", filename); #endif if (verbose) puts("Verbose mode requested."); if (overwrite) puts("Overwriting existing output file."); if (gzip) puts("Gzip compression requested."); if (sealevel) puts("Sea-level atmospheric correction requested. Terrain height ignored."); if (TOA) puts("Top-of-the-atmosphere reflectance requested. No atmospheric correction."); if (output1km) puts("1km-resolution output requested."); if (nearest) puts("Interpolation disabled."); /* parse input file names */ for (j = optind; j < argc; j++) { ftype = input_file_type(argv[j]); switch (ftype) { case INPUT_1KM: MOD021KMfile = argv[j]; break; case INPUT_500M: MOD02HKMfile = argv[j]; break; case INPUT_250M: MOD02QKMfile = argv[j]; break; default: fprintf(stderr, "Unrecognized input file \"%s\".\n", argv[j]); MOD021KMfile = argv[j]; /* exit(1); I commented that*/ break; } } if (verbose && MOD021KMfile) printf("Input geolocation file: %s\n", MOD021KMfile); /* output file name is mandatory */ if (!filename) { fputs("Missing output file name.\n", stderr); exit(1); } #ifdef DEBUG if (MOD021KMfile) printf("MOD/MYD021KMfile = %s\n", MOD021KMfile); if (MOD02HKMfile) printf("MOD/MYD02HKMfile = %s\n", MOD02HKMfile); if (MOD02QKMfile) printf("MOD/MYD02QKMfile = %s\n", MOD02QKMfile); #endif /* 1KM file is mandatory for angles. HKM file is mandatory unless 1-km output is requested. QKM file is mandatory unless 500-m or 1-km output is requested. */ /* if ( (!MOD021KMfile) || (!MOD02HKMfile && !output1km) || (!MOD02QKMfile && !output500m && !output1km) ) { fputs("Invalid combination of input files.\n", stderr); exit(1); } commented that too Eric*/ /* count number of bands to process */ for (ib = nbands = 0; ib < Nbands; ib++) if (process[ib]) nbands++; if (nbands < 1) { process[BAND1] = process[BAND3] = process[BAND4] = TRUE; if (verbose) puts("No band(s) specified. Default is bands 1, 3, and 4."); } /* open input files */ if ( MOD02QKMfile && (!output500m) && !output1km && (MOD02QKMfile_id = SDstart(MOD02QKMfile, DFACC_READ)) == -1 ) { fprintf(stderr, "Cannot open input file %s.\n", MOD02QKMfile); exit(1); } if ( MOD02HKMfile && (!output1km) && (MOD02HKMfile_id = SDstart(MOD02HKMfile, DFACC_READ)) == -1 ) { fprintf(stderr, "Cannot open input file %s.\n", MOD02HKMfile); exit(1); } if ( MOD021KMfile && (MOD021KMfile_id = SDstart(MOD021KMfile, DFACC_READ)) == -1 ) { fprintf(stderr, "Cannot open input file %s.\n", MOD021KMfile); exit(1); } if (!sealevel && !TOA) { dem.filename = dem_filename_buff; if ((ancpath = getenv("ANCPATH")) == NULL) sprintf(dem.filename, "%s/%s", ANCPATH, DEMFILENAME); else sprintf(dem.filename, "%s/%s", ancpath, DEMFILENAME); if ( (dem.file_id = SDstart(dem.filename, DFACC_READ)) == -1 ) { fprintf(stderr, "Cannot open file %s.\n", dem.filename); exit(1); } } if ( (fp = fopen(filename, "r")) ) { (void) fclose(fp); outfile_exists = 1; } else outfile_exists = 0; if ((write_mode == DFACC_CREATE) && !overwrite && outfile_exists) { fprintf(stderr, "File \"%s\" already exits.\n", filename); exit(1); } if (output500m) { sds[BAND10].file_id =sds[BAND8].file_id = sds[BAND9].file_id = MOD02HKMfile_id; sds[BAND10].filename =sds[BAND8].filename = sds[BAND9].filename = MOD02HKMfile; } else { if (output1km) { sds[BAND1].file_id = sds[BAND2].file_id = MOD021KMfile_id; sds[BAND1].filename = sds[BAND2].filename = MOD021KMfile; } else { sds[BAND1].file_id = sds[BAND2].file_id = MOD02QKMfile_id; sds[BAND1].filename = sds[BAND2].filename = MOD02QKMfile; } } if (output1km) { sds[BAND3].file_id = sds[BAND4].file_id = sds[BAND5].file_id = sds[BAND6].file_id = sds[BAND7].file_id = MOD021KMfile_id; sds[BAND3].filename = sds[BAND4].filename = sds[BAND5].filename = sds[BAND6].filename = sds[BAND7].filename = MOD021KMfile; } else { sds[BAND3].file_id = sds[BAND4].file_id = sds[BAND5].file_id = sds[BAND6].file_id = sds[BAND7].file_id = MOD02HKMfile_id; sds[BAND3].filename = sds[BAND4].filename = sds[BAND5].filename = sds[BAND6].filename = sds[BAND7].filename = MOD02HKMfile; } sds[SOLZ].file_id = sds[SOLA].file_id = sds[SENZ].file_id = sds[SENA].file_id = sds[LON].file_id = sds[LAT].file_id = MOD021KMfile_id; sds[SOLZ].filename = sds[SOLA].filename = sds[SENZ].filename = sds[SENA].filename = sds[LON].filename = sds[LAT].filename = MOD021KMfile; sds[BAND11].file_id = sds[BAND12].file_id = sds[BAND13].file_id = sds[BAND14].file_id = sds[BAND15].file_id = sds[BAND16].file_id = MOD021KMfile_id; sds[BAND11].filename = sds[BAND12].filename = sds[BAND13].filename = sds[BAND14].filename = sds[BAND15].filename = sds[BAND16].filename = MOD021KMfile; for (ib=0; ib < Nitems; ib++) { /* initializing these fields will simplify releasing memory later */ sds[ib].data = sds[ib].fillvalue = (void *) NULL; if ( ib < Nbands && ! process[ib] ) { sds[ib].id = -1; continue; } if (output500m) sds[ib].name = SDSlocatorHKM[ib]; else if (output1km) sds[ib].name = SDSlocator1KM[ib]; else sds[ib].name = SDSlocatorQKM[ib]; if ( (sds[ib].index = SDnametoindex(sds[ib].file_id, sds[ib].name)) == -1 ) { fprintf(stderr, "Cannot find SDS %s in file %s.\n", sds[ib].name, sds[ib].filename); continue; } if ( (sds[ib].id = SDselect(sds[ib].file_id, sds[ib].index)) == -1 ) { fprintf(stderr, "Cannot select SDS no. %d\n", sds[ib].index); if (ib < Nbands) process[ib] = FALSE; continue; } /* Original code passed sds[ib].name as destination for SDS name in call to SDgetinfo(). This was causing a core dump, apparently because SDgetinfo() writes some additional characters beyond the terminating null at the end of the SDS name, so I replaced the argument with a dummy character array. */ if (SDgetinfo(sds[ib].id, dummy, &sds[ib].rank, sds[ib].dim_sizes, &sds[ib].num_type, &sds[ib].n_attr) == -1) { fprintf(stderr, "Can't get info from SDS \"%s\" in file %s.\n", sds[ib].name, sds[ib].filename); SDendaccess(sds[ib].id); sds[ib].id = -1; if (ib < Nbands) process[ib] = FALSE; continue; } sds[ib].factor = 1; if (ib < 5 ) sds[ib].factor = 2.441742e-05; attr_name = "scale_factor"; printf("band %d \n",ib); if ( (attr_index = SDfindattr(sds[ib].id, attr_name)) != -1 && SDattrinfo(sds[ib].id, attr_index, dummy, &num_type, &count) != -1 && SDreadattr(sds[ib].id, attr_index, scale_factor) != -1 ) sds[ib].factor = ((float32 *)scale_factor)[indexlocator[ib]]; else { attr_name = "Scale"; if ((attr_index = SDfindattr(sds[ib].id, attr_name)) != -1 && SDattrinfo(sds[ib].id, attr_index, dummy, &num_type, &count) != -1 && SDreadattr(sds[ib].id, attr_index, scale_factor) != -1 ) sds[ib].factor = *scale_factor; } sds[ib].offset = 0; attr_name = "reflectance_offsets"; if ( (attr_index = SDfindattr(sds[ib].id, attr_name)) != -1 && SDattrinfo(sds[ib].id, attr_index, dummy, &num_type, &count) != -1 && SDreadattr(sds[ib].id, attr_index, add_offset) != -1 ) sds[ib].offset = ((float32 *)add_offset)[indexlocator[ib]]; else { attr_name = "add_offset"; if ( (attr_index = SDfindattr(sds[ib].id, attr_name)) != -1 && SDattrinfo(sds[ib].id, attr_index, dummy, &num_type, &count) != -1 && SDreadattr(sds[ib].id, attr_index, add_offset) != -1 ) sds[ib].offset = *add_offset; } sds[ib].fillvalue = (void *) malloc(1 * DFKNTsize(sds[ib].num_type)); if ( SDgetfillvalue(sds[ib].id, sds[ib].fillvalue) != 0 ) { fprintf(stderr, "Cannot read fill value of SDS \"%s\".\n", sds[ib].name); /* exit(1); commmented that*/ } switch (sds[ib].rank) { case 2: sds[ib].Nl = sds[ib].dim_sizes[0]; sds[ib].Np = sds[ib].dim_sizes[1]; sds[ib].rowsperscan = (int)(NUM1KMROWPERSCAN * sds[ib].Np / (float)NUM1KMCOLPERSCAN + 0.5); sds[ib].start[1] = 0; sds[ib].edges[0] = sds[ib].rowsperscan; sds[ib].edges[1] = sds[ib].Np; break; case 3: sds[ib].Nl = sds[ib].dim_sizes[1]; sds[ib].Np = sds[ib].dim_sizes[2]; sds[ib].rowsperscan = (int)(NUM1KMROWPERSCAN * sds[ib].Np / (float)NUM1KMCOLPERSCAN + 0.5); sds[ib].start[0] = indexlocator[ib]; sds[ib].start[2] = 0; sds[ib].edges[0] = 1; sds[ib].edges[1] = sds[ib].rowsperscan; sds[ib].edges[2] = sds[ib].Np; break; default: fprintf(stderr, "SDS rank must be 2 or 3.\n"); continue; } if (verbose) printf("SDS \"%s\": %dx%d scale factor: %g offset: %g\n", sds[ib].name, sds[ib].Np, sds[ib].Nl, sds[ib].factor, sds[ib].offset); if (sds[ib].num_type != numtypelocator[ib]) { fprintf(stderr, "SDS \"%s\" has not the expected data type.\n", sds[ib].name); exit(-1); } sds[ib].data = malloc(sds[ib].Np * sds[ib].rowsperscan * DFKNTsize(sds[ib].num_type)); if (!sds[ib].data) { (void) fputs("Error allocating memory.\n", stderr); exit(1); } } if (sealevel || TOA) { dem.id = -1; dem.Nl = dem.Np = 0; } else { /* dem.name = strdup(DEMSDSNAME); */ dem.name = DEMSDSNAME; if ( (dem.index = SDnametoindex(dem.file_id, dem.name)) == -1 ) { fprintf(stderr, "Cannot find SDS %s in file %s.\n", dem.name, dem.filename); exit(1); } if ( (dem.id = SDselect(dem.file_id, dem.index)) == -1 ) { fprintf(stderr, "Cannot select SDS no. %d\n", dem.index); exit(1); } if (SDgetinfo(dem.id, dummy, &dem.rank, dem.dim_sizes, &dem.num_type, &dem.n_attr) == -1) { fprintf(stderr, "Can't get info from SDS \"%s\" in file %s.\n", dem.name, dem.filename); SDendaccess(dem.id); exit(1); } dem.Nl = dem.dim_sizes[0]; dem.Np = dem.dim_sizes[1]; dem.rowsperscan = (int)(NUM1KMROWPERSCAN * dem.Np / (float)NUM1KMCOLPERSCAN + 0.5); } if ( sds[SOLZ].id == -1 || sds[SOLA].id == -1 || sds[SENZ].id == -1 || sds[SENA].id == -1 || sds[LON].id == -1 || sds[LAT].id == -1 || ((dem.id == -1) && !sealevel && !TOA) ) { fprintf(stderr, "Solar and Sensor angles and DEM are necessary to process granule.\n"); exit(1); } if ( sds[REFSDS].Np != sds[SOLZ].Np || sds[REFSDS].Np != sds[SOLA].Np || sds[REFSDS].Np != sds[SENZ].Np || sds[REFSDS].Np != sds[SENA].Np || sds[REFSDS].Np != sds[LON].Np || sds[REFSDS].Np != sds[LAT].Np ) { fprintf(stderr, "Solar and Sensor angles must have identical dimensions.\n"); exit(1); } ib = 0; while (sds[ib].id == -1) ib++; if (ib >= Nbands) { fprintf(stderr, "No L1B SDS can be read successfully.\n"); exit(1); } Nscans = sds[ib].Nl / sds[ib].rowsperscan; /* finally, open output file */ if ( (sd_id = SDstart(filename, write_mode)) == -1 ) { fprintf(stderr, "Cannot open output file %s.\n", filename); exit(1); } if (!append) { if (write_global_attributes(sd_id, MOD021KMfile, MOD02HKMfile, MOD02QKMfile, maxsolz, sealevel, TOA, nearest)) { fputs("Error writing global attributes.\n", stderr); exit(1); } } /* create output SDSs and set SDS-specific attributes and dimension names */ if (init_output_sds(sd_id, process, outsds, sds, gzip, verbose)) exit(1); mus = (float *) malloc(sds[REFSDS].rowsperscan * sds[REFSDS].Np * sizeof(float)); height.data = (int16 *) malloc(sds[REFSDS].rowsperscan * sds[REFSDS].Np * sizeof(int16)); if (!mus || !height.data) { (void) fputs("Error allocating memory.\n", stderr); exit(1); } if (sealevel || TOA) dem.data = (void *) NULL; else { dem.data = (int16 *) malloc(dem.Nl * dem.Np * sizeof(int16)); if (!dem.data) { (void) fputs("Error allocating memory.\n", stderr); exit(1); } } if (!TOA) { nbytes = Nbands * sds[REFSDS].rowsperscan * sds[REFSDS].Np * sizeof(float); rhoray = (float *) malloc(nbytes); sphalb = (float *) malloc(nbytes); TtotraytH2O = (float *) malloc(nbytes); tOG = (float *) malloc(nbytes); if (!rhoray || !sphalb || !TtotraytH2O || !tOG) { (void) fputs("Error allocating memory.\n", stderr); exit(1); } } solz = sds[SOLZ].data; sola = sds[SOLA].data; senz = sds[SENZ].data; sena = sds[SENA].data; solzfill = sds[SOLZ].fillvalue; lon = sds[LON].data; lat = sds[LAT].data; lonfill = sds[LON].fillvalue; latfill = sds[LAT].fillvalue; for (ib = 0; ib < Nbands; ib++) l1bdata[ib] = sds[ib].data; /* don't need DEM if --sealevel or --toa specified */ if (!sealevel && !TOA) { dem.start[0] = 0; dem.start[1] = 0; dem.edges[0] = dem.Nl; dem.edges[1] = dem.Np; if (SDreaddata(dem.id, dem.start, NULL, dem.edges, dem.data) == -1) { fprintf(stderr, " Can't read DEM SDS \"%s\"\n", dem.name); exit(-1); } (void) SDendaccess(dem.id); (void) SDend(dem.file_id); } /* loop over each MODIS scan */ for (iscan = 0; iscan < Nscans; iscan++) { if ((iscan % NUM1KMROWPERSCAN == 0) && verbose) printf("Processing scan %d...\n", iscan); /* Fill scan buffer for each band to be processed. Exit scan loop if error occurred while reading. */ if (read_scan(iscan, sds)) break; for (idx = 0; idx < sds[REFSDS].rowsperscan*sds[REFSDS].Np; idx++) { if (solz[idx] * sds[SOLZ].factor >= maxsolz) solz[idx] = *solzfill; if (!sealevel && (lon[idx] == *lonfill || lat[idx] == *latfill)) solz[idx] = *solzfill; if (solz[idx] != *solzfill) { mus[idx] = cos(solz[idx] * sds[SOLZ].factor * DEG2RAD); if (sealevel || TOA) ((int16 *)height.data)[idx] = 0; else ((int16 *)height.data)[idx] = (int16) interp_dem(lat[idx], lon[idx], &dem); } } if (!TOA) { for (irow=0; irow<sds[REFSDS].rowsperscan; irow++) { for (jcol=0; jcol<sds[REFSDS].Np; jcol++) { idx = irow * sds[REFSDS].Np + jcol; if (solz[idx] == *solzfill) continue; phi = sola[idx] * sds[SOLA].factor - sena[idx] * sds[SENA].factor; muv = cos(senz[idx] * sds[SENZ].factor * DEG2RAD); if ( getatmvariables(mus[idx], muv, phi, ((int16 *)height.data)[idx], process, &sphalb[idx * Nbands], &rhoray[idx * Nbands], &TtotraytH2O[idx * Nbands], &tOG[idx * Nbands]) == -1 ) solz[idx] = *solzfill; /* printf(" some data %f %f %f %f %f \n",senz[idx],phi,mus[idx],rhoray[idx * Nbands],tOG[idx * Nbands]);*/ } } } for (ib=0; ib<Nbands; ib++) { if (! process[ib]) continue; aggfactor = outsds[ib].rowsperscan / sds[REFSDS].rowsperscan; for (irow=0; irow<outsds[ib].rowsperscan; irow++) { if (!nearest) { fractrow = (float)irow / aggfactor - 0.5; /* We want fractrow integer on coarse pixel center */ crsrow1 = floor(fractrow); crsrow2 = crsrow1 + 1; if (crsrow1 < 0) crsrow1 = crsrow2 + 1; if (crsrow2 > sds[REFSDS].rowsperscan - 1) crsrow2 = crsrow1 - 1; t = (fractrow - crsrow1) / (crsrow2 - crsrow1); } for (jcol=0; jcol<outsds[ib].Np; jcol++) { idx = irow * outsds[ib].Np + jcol; crsidx = (int)(irow / aggfactor) * sds[REFSDS].Np + (int)(jcol / aggfactor); if ( solz[crsidx] == *solzfill || /* Bad geolocation or night pixel */ l1bdata[ib][idx] >= 65528 ) { /* VIIRS SDR is read as uint16, fills start at 65528 */ if (l1bdata[ib][idx] == (65536 + MISSING)) ((int16 *)outsds[ib].data)[idx] = 32768 + MISSING; else ((int16 *)outsds[ib].data)[idx] = *(int16 *)outsds[ib].fillvalue; continue; } if (nearest) { mus0 = mus[crsidx]; if (! TOA) { rhoray0 = rhoray[crsidx * Nbands + ib]; sphalb0 = sphalb[crsidx * Nbands + ib]; if ( sphalb0 <= 0.0F ) { /* Atm variables not computed successfully in this band */ ((int16 *)outsds[ib].data)[idx] = *(int16 *)outsds[ib].fillvalue; continue; } } } else { fractcol = ((float) jcol) / aggfactor - 0.5F; /* We want fractcol integer on coarse pixel center */ crscol1 = (int) floor(fractcol); crscol2 = crscol1 + 1; if (crscol1 < 0) crscol1 = crscol2 + 1; if (crscol2 > sds[REFSDS].Np - 1) crscol2 = crscol1 - 1; u = (fractcol - crscol1) / (crscol2 - crscol1); /* We want u=0 on coarse pixel center */ crsidx11 = crsrow1 * sds[REFSDS].Np + crscol1; crsidx12 = crsrow1 * sds[REFSDS].Np + crscol2; crsidx21 = crsrow2 * sds[REFSDS].Np + crscol1; crsidx22 = crsrow2 * sds[REFSDS].Np + crscol2; /* mus0 = t * u * mus[crsidx22] + (1.0F - t) * u * mus[crsidx12] + t * (1.0F - u) * mus[crsidx21] + (1.0F - t) * (1.0F - u) * mus[crsidx11]; bad = (solz[crsidx11] == *solzfill) || (solz[crsidx12] == *solzfill) || (solz[crsidx21] == *solzfill) || (solz[crsidx22] == *solzfill); commented by eric to handle the viirs fill value hardcoding */ bad = (solz[crsidx11] <-900.) || (solz[crsidx12] <-900.) || (solz[crsidx21] <-900.) || (solz[crsidx22] <-900.); if (bad) { ((int16 *)outsds[ib].data)[idx] = *(int16 *)outsds[ib].fillvalue; continue; } if (! TOA) { rhoray11 = rhoray[crsidx11 * Nbands + ib]; rhoray12 = rhoray[crsidx12 * Nbands + ib]; rhoray21 = rhoray[crsidx21 * Nbands + ib]; rhoray22 = rhoray[crsidx22 * Nbands + ib]; rhoray0 = t * u * rhoray22 + (1.0F - t) * u * rhoray12 + t * (1.0F - u) * rhoray21 + (1.0F - t) * (1.0F - u) * rhoray11; sphalb11 = sphalb[crsidx11 * Nbands + ib]; sphalb12 = sphalb[crsidx12 * Nbands + ib]; sphalb21 = sphalb[crsidx21 * Nbands + ib]; sphalb22 = sphalb[crsidx22 * Nbands + ib]; bad = (sphalb11 <= 0.0F) || (sphalb12 <= 0.0F) || (sphalb21 <= 0.0F) || (sphalb22 <= 0.0F); if (bad) { ((int16 *)outsds[ib].data)[idx] = *(int16 *)outsds[ib].fillvalue; continue; } sphalb0 = t * u * sphalb22 + (1.0F - t) * u * sphalb12 + t * (1.0F - u) * sphalb21 + (1.0F - t) * (1.0F - u) * sphalb11; } } /* TOA reflectance */ /*printf(" mus0 is %f\n",mus0);*/ refl = (l1bdata[ib][idx] - sds[ib].offset) * sds[ib].factor /*/ mus0 commented by Eric who suspected something*/; /* corrected reflectance */ if (!TOA) refl = correctedrefl(refl, TtotraytH2O[crsidx * Nbands + ib], tOG[crsidx * Nbands + ib], rhoray0, sphalb0); /* reflectance bounds checking */ if (refl > reflmax) refl = reflmax; if (refl < reflmin) refl = reflmin; ((int16 *)outsds[ib].data)[idx] = (int16) (refl / outsds[ib].factor + 0.5); } } } /* write current scan line for all processed bands */ if (write_scan(iscan, process, outsds)) { fprintf(stderr, "Cannot write scan %d of SDS %s\n", iscan, outsds[ib].name); exit(1); } } /* end of scan loop */ for (ib = 0; ib < Nitems; ib++) if (sds[ib].id != -1) SDendaccess(sds[ib].id); for (ib = 0; ib < Nbands; ib++) if (process[ib]) SDendaccess(outsds[ib].id); SDend(MOD02QKMfile_id); SDend(MOD02HKMfile_id); SDend(MOD021KMfile_id); SDend(sd_id); /* ----- free memory ----- */ for (ib = 0; ib < Nitems; ib++) { if (sds[ib].fillvalue) free(sds[ib].fillvalue); if (sds[ib].data) free(sds[ib].data); } free(height.data); free(mus); if (!TOA) { free(tOG); free(TtotraytH2O); free(sphalb); free(rhoray); } /* not allocated if --sealevel specified */ if (dem.data) free(dem.data); return 0; }
int init_output_sds(int32 sd_id, unsigned char *process, SDS outsds[Nbands], SDS sds[Nitems], int gzip, int verbose) { int ib; int32 dim_id; char *dimname1, *dimname2; HDF_CHUNK_DEF chunk_def; /* same fill value will be used for all output SDSs */ static int16 fillvalue = FILL_INT16; /* band naming convention will be "CorrRefl_XX" (11 characters + terminating null) */ char name[16]; /* write SDS-specific attributes and dimension names */ for (ib = 0; ib < Nbands; ib++) { if (!process[ib]) continue; outsds[ib].num_type = DFNT_INT16; outsds[ib].factor = 0.0001; outsds[ib].offset = 0; outsds[ib].rank = 2; sprintf(name, "CorrRefl_%2.2d", ib + 1); if ( !(outsds[ib].name = strdup(name)) ) return 1; outsds[ib].Nl = outsds[ib].dim_sizes[0] = sds[ib].Nl; outsds[ib].Np = outsds[ib].dim_sizes[1] = sds[ib].Np; outsds[ib].rowsperscan = sds[ib].rowsperscan; if (verbose) printf("Creating SDS %s: %dx%d\n", outsds[ib].name, outsds[ib].Np, outsds[ib].Nl); if ((outsds[ib].id = SDcreate(sd_id, outsds[ib].name, outsds[ib].num_type, outsds[ib].rank, outsds[ib].dim_sizes)) == -1) { fprintf(stderr, "Cannot create SDS %s\n", outsds[ib].name); return 1; } outsds[ib].fillvalue = &fillvalue; if ( SDsetfillvalue(outsds[ib].id, outsds[ib].fillvalue) ) { fprintf(stderr, "Cannot write fill value of SDS %s\n", outsds[ib].name); return 1; } if ( SDsetattr(outsds[ib].id, "scale_factor", DFNT_FLOAT64, 1, &outsds[ib].factor) == -1 || SDsetattr(outsds[ib].id, "add_offset", DFNT_FLOAT64, 1, &outsds[ib].offset) == -1 ) { fprintf(stderr, "Cannot write scale factor and offset of SDS \"%s\"\n", outsds[ib].name); return 1; } if ( SDsetattr(outsds[ib].id, "units", DFNT_CHAR8, 4, "none") == -1 ) { fprintf(stderr, "Cannot write units attribute of SDS \"%s\"\n", outsds[ib].name); return 1; } /* set dimensions */ outsds[ib].start[1] = 0; outsds[ib].edges[0] = outsds[ib].rowsperscan; outsds[ib].edges[1] = outsds[ib].Np; /* allocate memory for band output data */ outsds[ib].data = malloc(outsds[ib].rowsperscan * outsds[ib].Np * DFKNTsize(outsds[ib].num_type)); if (!outsds[ib].data) { fputs("Error allocating memory.\n", stderr); return 1; } /* set optional compression */ if (gzip) { chunk_def.chunk_lengths[0] = chunk_def.comp.chunk_lengths[0] = outsds[ib].edges[0]; chunk_def.chunk_lengths[1] = chunk_def.comp.chunk_lengths[1] = outsds[ib].edges[1]; chunk_def.comp.comp_type = COMP_CODE_DEFLATE; chunk_def.comp.cinfo.deflate.level = 4; if (SDsetchunk(outsds[ib].id, chunk_def, HDF_CHUNK | HDF_COMP) == FAIL) { fprintf(stderr, "Cannot set chunks for SDS %s\n", outsds[ib].name); return 1; } } set_dimnames(outsds[ib].Np, &dimname1, &dimname2); if (verbose) printf("(%s x %s)\n", dimname1, dimname2); /* dimension names */ if ((dim_id = SDgetdimid(outsds[ib].id, 0)) == -1) { fputs("Error getting dimension ID1.\n", stderr); return 1; } if (SDsetdimname(dim_id, dimname1) == -1) { fprintf(stderr, "Cannot set first dimension name for SDS %s\n", outsds[ib].name); return 1; } if ((dim_id = SDgetdimid(outsds[ib].id, 1)) == -1) { fputs("Error getting dimension ID2.\n", stderr); return 1; } if (SDsetdimname(dim_id, dimname2) == -1) { fprintf(stderr, "Cannot set second dimension name for SDS %s\n", outsds[ib].name); return 1; } } return 0; }
static uint32 vdata_cmp(int32 vs1, int32 vs2, char *gname, char *cname, diff_opt_t * opt) { int32 i, j, k, iflag; uint32 err_cnt; int32 nv1, interlace1, vsize1; int32 vsotag1; char fields1[VSFIELDMAX*FIELDNAMELENMAX]; char vsclass1[VSNAMELENMAX], vsname1[VSNAMELENMAX]; int32 nv2, interlace2, vsize2; int32 vsotag2; char fields2[VSFIELDMAX*FIELDNAMELENMAX]; char vsclass2[VSNAMELENMAX], vsname2[VSNAMELENMAX]; uint8 *buf1, *buf2, *b1, *b2; int32 off1[60], off2[60]; DYN_VWRITELIST *w1, *w2; uint32 nfound=0; uint32 max_err_cnt = opt->max_err_cnt; VSinquire(vs1, &nv1, &interlace1, fields1, &vsize1, vsname1); VSinquire(vs2, &nv2, &interlace2, fields2, &vsize2, vsname2); vsotag1 = VSQuerytag(vs1); VSgetclass(vs1,vsclass1); vsotag2 = VSQuerytag(vs2); VSgetclass(vs2,vsclass2); if (vsotag1 != vsotag2 || nv1 != nv2 || interlace1 != interlace2 || strcmp(fields1, fields2) != 0 || strcmp(vsclass1, vsclass2) != 0 || (strcmp(vsclass1, "Attr0.0") != 0 && vsize1 != vsize2)) { printf("\n---------------------------\n"); printf("Vdata Name: %s <%s/%s> (Different attributes)\n", vsname1, gname, cname); printf("> <%d> nrec=%d interlace=%d fld=[%s] vsize=%d class={%s})\n", vsotag1, nv1, interlace1, fields1, vsize1, vsclass1); printf("< <%d> nrec=%d interlace=%d fld=[%s] vsize=%d class={%s})\n", vsotag2, nv2, interlace2, fields2, vsize2, vsclass2); return 0; } /* compare the data */ buf1 = (uint8 *) malloc((unsigned) (nv1 * vsize1)); buf2 = (uint8 *) malloc((unsigned) (nv2 * vsize2)); if (!buf1 || !buf2) { printf("Out of memory!"); opt->err_stat = 1; return 0; } VSsetfields(vs1, fields1); VSread(vs1, buf1, nv1, interlace1); w1 = (DYN_VWRITELIST*) vswritelist(vs1); VSsetfields(vs2, fields2); VSread(vs2, buf2, nv2, interlace2); w2 = (DYN_VWRITELIST*) vswritelist(vs2); b1 = buf1; b2 = buf2; for (j=0; j < w1->n; j++) off1[j] = DFKNTsize(w1->type[j] | DFNT_NATIVE); for (j=0; j < w2->n; j++) off2[j] = DFKNTsize(w2->type[j] | DFNT_NATIVE); iflag = 0; err_cnt = 0; if (vsize1 == vsize2) { for (i=0; i<nv1; i++) { if (memcmp(b1, b2, (size_t)vsize1) == 0) { b1 += vsize1; b2 += vsize2; continue; } if (iflag == 0) { iflag = 1; /* there is a difference */ printf("\n---------------------------\n"); printf("Vdata Name: %s (Data record comparison)\n", vsname1); nfound ++; } printf("> %d: ", i); for (j=0; j<w1->n; j++) { for (k=0; k<w1->order[j]; k++) { fmt_print(b1, w1->type[j]); b1 += off1[j]; if (w1->type[j] != DFNT_CHAR) putchar(' '); } } putchar('\n'); printf("< %d: ", i); for (j=0; j<w2->n; j++) { for (k=0; k<w2->order[j]; k++) { fmt_print(b2, w2->type[j]); b2 += off2[j]; if (w2->type[j] != DFNT_CHAR) putchar(' '); } } putchar('\n'); if (max_err_cnt > 0) { err_cnt++; if (err_cnt >= max_err_cnt) break; } } } else { printf("****....\n"); for (i=0; i<nv1; i++) { if (iflag == 0) { iflag = 1; /* there is a difference */ printf("\n---------------------------\n"); printf("Vdata Name: %s (Data record comparison)\n", vsname1); nfound ++; } printf("> %d: ", i); for (j=0; j<w1->n; j++) { for (k=0; k<w1->order[j]; k++) { fmt_print(b1, w1->type[j]); b1 += off1[j]; if (w1->type[j] != DFNT_CHAR) putchar(' '); } } putchar('\n'); printf("< %d: ", i); for (j=0; j<w2->n; j++) { for (k=0; k<w2->order[j]; k++) { fmt_print(b2, w2->type[j]); b1 += off2[j]; if (w2->type[j] != DFNT_CHAR) putchar(' '); } } putchar('\n'); if (max_err_cnt > 0) { err_cnt++; if (err_cnt >= max_err_cnt) break; } } } if (buf1)free((char *) buf1); if (buf2)free((char *) buf2); return nfound; }
/* * dumps attributes of vdata for vgroup */ intn dumpattr(int32 vid, int32 findex, intn isvs, file_format_t ff, FILE *fp) { intn i, k; intn cn = 0; intn nattrs; intn alloc_flag = 0; int32 i_type; int32 i_count; int32 i_size, e_size; int32 off; uint8 *buf = NULL; uint8 *ptr = NULL; intn (*vfmtfn)(VOIDP, file_format_t ff, FILE *); intn status; intn ret_value = SUCCEED; char name[FIELDNAMELENMAX+1]; uint8 attrbuf[BUFFER]; /* vdata or vgroup? */ if (isvs) nattrs = VSfnattrs(vid, findex); else /* nattrs = Vnattrs(vid); <- replaced with Vnattrs2 to catch all attributes; previously, SD attributes were missed by V API */ nattrs = Vnattrs2(vid); if (FAIL == nattrs) { fprintf(stderr,">>>dumpattr: Failed to get number of attributes for vid %d \n",(int)vid); ret_value = FAIL; goto done; } fprintf(fp, " number of attributes = %d \n", nattrs); /* loop for number of attributes to process */ for (i = 0; i < nattrs; i++) { /* get attribute infor of vdata/vgroup */ if (isvs) status = VSattrinfo(vid, findex, i, name, &i_type, &i_count, &e_size); else /* Changed to use updated func of Vattrinfo - BMR, 1/7/2013 */ status = Vattrinfo2(vid, i, name, &i_type,&i_count, &e_size, NULL, NULL); if (status == FAIL) { fprintf(stderr,">>>dumpattr: failed in getting %d'th attr info.\n",i); ret_value = FAIL; goto done; } /* get attribute hdfsize of vdata/vgroup */ if (isvs) status = VSattrhdfsize(vid, findex, i, &i_size); else status = Vattrhdfsize(vid, i, &i_size); if (status == FAIL) { fprintf(stderr,">>>dumpattr: failed in getting %d'th attr hdfsize.\n",i); ret_value = FAIL; goto done; } fprintf(fp," attr%d: name=%s type=%d count=%d size=%d\n", i, name, (int)i_type, (int)i_count, (int)i_size); /* we have two buffer sizes? */ if (e_size > BUFFER) { if (NULL == (buf = HDmalloc(e_size))) { fprintf(stderr,">>>dumpattr:can't allocate buf for %d'th attribute.\n",i); ret_value = FAIL; goto done; /* do we want exit here? */ } alloc_flag = 1; /* get attribute itself */ if (isvs) status = VSgetattr(vid, findex, i, (VOIDP)buf); else /* Changed to use updated func of Vgetattr - BMR, 1/7/2013 */ status = Vgetattr2(vid, i, (VOIDP)buf); if (status == FAIL) { fprintf(stderr,">>>dympattr: failed in getting %d'th attr .\n",i); ret_value = FAIL; goto done; } } else { /* get attribute itself */ if (isvs) status = VSgetattr(vid, findex, i, (VOIDP)attrbuf); else /* Changed to use updated func of Vgetattr - BMR, 1/7/2013 */ status = Vgetattr2(vid, i, (VOIDP)attrbuf); if (status == FAIL) { fprintf(stderr,">>>dympattr: failed in getting %d'th attr.\n",i); ret_value = FAIL; goto done; } } /* format output */ switch (i_type & 0xff) { case DFNT_CHAR: case DFNT_UCHAR: vfmtfn = fmtchar; break; case DFNT_UINT8: vfmtfn = fmtuint8; break; case DFNT_INT8: vfmtfn = fmtint8; break; case DFNT_UINT16: vfmtfn = fmtuint16; break; case DFNT_INT16: vfmtfn = fmtint16; break; case DFNT_UINT32: vfmtfn = fmtuint32; break; case DFNT_INT32: vfmtfn = fmtint32; break; case DFNT_FLOAT32: vfmtfn = fmtfloat32; break; case DFNT_FLOAT64: vfmtfn = fmtfloat64; break; default: fprintf(stderr,">>>dumpattr: sorry, type [%d] not supported\n", (int) i_type); ret_value = FAIL; goto done; } /* find offset */ off = DFKNTsize(i_type | DFNT_NATIVE); /* which buffer are we using? */ ptr = (alloc_flag) ? buf : attrbuf; putchar('\t'); cn = 0; for (k = 0; k < i_count; k++) { cn += vfmtfn((uint8 *)ptr, ff, fp); ptr += off; putchar(' '); cn++; if (cn > 55) { putchar('\n'); putchar('\t'); cn = 0; } } if (cn) putchar('\n'); /* free allocated space if any */ if (alloc_flag) { if ( buf != NULL) HDfree(buf); alloc_flag = 0; buf = NULL; } } /* for i */ done: if (ret_value == FAIL) { /* Failure cleanup */ if (buf != NULL) HDfree(buf); } /* Normal cleanup */ return ret_value; }
int32 dumpvd(int32 vd, file_format_t ff, int data_only, FILE *fp, char separater[2], int32 flds_indices[VSFIELDMAX], int dumpallfields) { char vdname[VSNAMELENMAX+1]; int32 j, i, t, interlace, nv, vsize; uint8 *bb = NULL; uint8 *b = NULL; DYN_VWRITELIST *w = NULL; intn (*vfmtfn[VSFIELDMAX]) (VOIDP , file_format_t ff, FILE *); int32 off[VSFIELDMAX]; int32 order[VSFIELDMAX]; int32 nattrs[VSFIELDMAX]; int32 bufsize; /* size of the buffer we are using */ int32 chunk; /* number of rows that will fit in the buffer */ int32 done; /* number of rows we have done */ int32 count; /* number of rows to do this time through the loop */ int32 nf; /* number of fields in this Vdata */ int32 x, display; int32 temp; int32 addr_width = 0; int32 num_digits; int32 address = 0; int32 nfields; int32 cnt1, cnt2; int32 cn = 0; int32 ret_value = SUCCEED; char fields[VSFIELDMAX*FIELDNAMELENMAX]; char flds[VSFIELDMAX*FIELDNAMELENMAX]; /* inquire about vdata */ if (FAIL == VSinquire(vd, &nv, &interlace, fields, &vsize, vdname)) { ret_value = FAIL; goto done; } if (nv * vsize > BUFFER) /* If the number of records in the vdata is bigger than the buffer size, then divide the records into chunks. */ { bufsize = BUFFER; chunk = BUFFER / vsize; } else /* Otherwise, all the records will be read in at one time. */ { bufsize = nv * vsize; chunk = nv; } done = 0; /* Allocate space for the buffer and terminate hdp if allocation fails. */ bb = (uint8 *) HDmalloc(bufsize); CHECK_ALLOC( fields, "fields", "dumpvd" ); if (FAIL == VSsetfields(vd, fields)) { fprintf(stderr,"dumpvd: VSsetfields failed for vd = %d \n",(int)vd); ret_value = FAIL; goto done; } w = vswritelist(vd); nf = w->n; x = 0; /* Used for accessing the array storing the indices of the selected fields. */ for (i = 0; i < nf; i++) /* Read in data of all the fields. */ { order[i] = w->order[i]; /* Set offset for the next element. */ off[i] = DFKNTsize(w->type[i] | DFNT_NATIVE); nattrs[i] = VSfnattrs(vd, i); if (FAIL == nattrs[i]) { fprintf(stderr,"dumpvd: VSfnattrs failed for vd = %d \n",(int)vd); ret_value = FAIL; goto done; } /* Display the header of a vdata if the user didn't specify the data-only option. */ if (!data_only) { if(ff==DASCII) { if ((dumpallfields) || (flds_indices[x] == i)) { fprintf(fp, "- field index %d: [%s], type=%d, order=%d\n", (int) i, w->name[i], w->type[i], w->order[i]); x++; } } /* display attributes - BMR moved this block inside if(!data_only) to keep the attributes from being printed - bug #231*/ if (FAIL == dumpattr(vd, i, 1, ff, fp)) { fprintf(stderr,"dumpvd: dumpattr() failed for vd = %d \n",(int)vd); ret_value = FAIL; goto done; } } /* if !data_only */ /* Choose a function for displaying a piece of data of a particular type. */ switch (w->type[i] & 0xff) { case DFNT_CHAR: case DFNT_UCHAR: vfmtfn[i] = fmtchar; break; case DFNT_UINT8: vfmtfn[i] = fmtuint8; break; case DFNT_INT8: vfmtfn[i] = fmtint8; break; case DFNT_UINT16: vfmtfn[i] = fmtuint16; break; case DFNT_INT16: vfmtfn[i] = fmtint16; break; case DFNT_UINT32: vfmtfn[i] = fmtuint32; break; case DFNT_INT32: vfmtfn[i] = fmtint32; break; case DFNT_FLOAT32: vfmtfn[i] = fmtfloat32; break; case DFNT_FLOAT64: vfmtfn[i] = fmtfloat64; break; default: fprintf(stderr, "sorry, type [%d] not supported\n", (int) w->type[i]); ret_value = FAIL; goto done; } /* switch */ } /* for */ cn = 0; done = count = 0; if(ff==DASCII) { /* If not just the data will be dumped out, then put an address-type column on the left so that the user can recognize which record he/she is looking at. */ if (!data_only) { temp = nv / 10; address = 0; addr_width = num_digits = 1; while (temp != 0) { if (temp != 1) addr_width++; temp = temp / 10; } fprintf(fp, "Loc."); for (j = 0; j < addr_width - 3; j++) fprintf(fp, " "); fprintf(fp, " Data\n"); /* The address of the first record is 0. Also, fill in the extra space on the left with 0's. */ while (num_digits <= addr_width) { fprintf(fp, "0"); num_digits++; cn++; } fprintf(fp, " "); cn += 6; if (addr_width == 2) { fprintf(fp, " "); cn++; } else if (addr_width == 1) { fprintf(fp, " "); cn += 2; } } /* while */ nfields = VSgetfields(vd, flds); if (FAIL == nfields ) { fprintf(stderr,"dumpvd: VSgetfields failed for vd = %d \n",(int)vd); ret_value = FAIL; goto done; } cnt1 = 0; cnt2 = 0; while (done != nv) { /* Determine the amount of data to be read this time. */ if ((nv - done) > chunk) count = chunk; else count = nv - done; /* read and update bookkeeping */ if (FAIL == VSread(vd, bb, count, interlace)) { /* If the data set has external element, get the external file name to provide information */ intn extfile_namelen = VSgetexternalfile(vd, 0, NULL, NULL); if (extfile_namelen > 0) { char *extfile_name = NULL; extfile_name = (char *)HDmalloc(sizeof(char *)*(extfile_namelen+1)); CHECK_ALLOC(extfile_name, "extfile_name", "dumpvd" ); /* Get the external file info, we don't need offset here */ extfile_namelen = VSgetexternalfile(vd, extfile_namelen+1, extfile_name, NULL); ERROR_GOTO_3( "in %s: VSread failed for vd(%d) with external file %s. Please verify the file exists in the same directory.", "dumpvd", (int)vd, extfile_name); } else ERROR_GOTO_2( "in %s: VSread failed for vd(%d)", "dumpvd", (int)vd ); } done += count; b = bb; /* Display the data. */ for (j = 0; j < count; j++) /* each iteration causes one record to be printed */ { cnt1++; x = 0; for (i = 0; i < nf; i++) /* display all fields in one record */ { if ((!dumpallfields) && (flds_indices[x] != i)) display = 0; else { display = 1; x++; } for (t = 0; t < order[i]; t++) { if(display) cn+=(vfmtfn[i]) (b, ff, fp); b += off[i]; if (display) { fprintf(fp, " "); cn++; cnt2++; } } if (display) { fprintf(fp, " "); cn++; cnt2++; } } /* for i to nf-1 */ if (cnt2 > 0) { address++; /* "separator" is the symbol used for separating different records. */ fprintf(fp, "%s ", separater); } if (!data_only) { if ((cnt1 * cnt2) > 30) { cnt1 = 0; cnt2 = 0; fprintf(fp, "\n"); cn = 0; /* As long as there is data to be displayed, fill in the extra space with 0's on the left of each address. */ if (j < (count - 1)) { temp = address; num_digits = 1; while ((temp = temp / 10) != 0) num_digits++; while (num_digits < addr_width) { fprintf(fp, "0"); num_digits++; cn++; } fprintf(fp, "%d ", (int)address); cn += 6 + num_digits; if (addr_width == 2) { fprintf(fp, " "); cn++; } else if (addr_width == 1) { fprintf(fp, " "); cn += 2; } } /* if (!data_only) */ } } else fprintf(fp, "\n"); } /* for (j=0; j<count; j++) */ } /* while (done != nv) */ /* ============================================ */ HDfree((VOIDP) bb); bb = NULL; fprintf(fp, "\n\n"); } /* for DASCII */ else { /* binary file */ nfields = VSgetfields(vd, flds); if (FAIL == nfields ) { fprintf(stderr,"dumpvd: VSgetfields failed for vd = %d \n",(int)vd); ret_value = FAIL; goto done; } cnt1 = 0; cnt2 = 0; while (done != nv) { /* Determine the amount of data to be read this time. */ if ((nv - done) > chunk) count = chunk; else count = nv - done; /* read and update bookkeeping */ if (FAIL == VSread(vd, bb, count, interlace)) { /* If the data set has external element, get the external file name to provide information */ intn extfile_namelen = VSgetexternalfile(vd, 0, NULL, NULL); if (extfile_namelen > 0) { char *extfile_name = NULL; extfile_name = (char *)HDmalloc(sizeof(char *)*(extfile_namelen+1)); CHECK_ALLOC(extfile_name, "extfile_name", "dumpvd" ); /* Get the external file info, we don't need offset here */ extfile_namelen = VSgetexternalfile(vd, extfile_namelen+1, extfile_name, NULL); ERROR_GOTO_3( "in %s: VSread failed for vd(%d) with external file %s. Please verify the file exists in the same directory", "dumpvd", (int)vd, extfile_name); } else ERROR_GOTO_2( "in %s: VSread failed for vd(%d)", "dumpvd", (int)vd ); } done += count; b = bb; /* Display the data. */ for (j = 0; j < count; j++) /* each iteration causes one record to be printed */ { cnt1++; x = 0; for (i = 0; i < nf; i++) /* display all fields in one record */ { if ((!dumpallfields) && (flds_indices[x] != i)) display = 0; else { display = 1; x++; } for (t = 0; t < order[i]; t++) { if(display) cn+=(vfmtfn[i]) (b, ff, fp); b += off[i]; if (display) { cn++; cnt2++; } } if (display) { cn++; cnt2++; } } /* for i to nf-1 */ if (cnt2 > 0) { address++; /* "separator" is the symbol used for separating different records. */ } } /* for (j=0; j<count; j++) */ } /* while (done != nv) */ /* ============================================ */ HDfree((VOIDP) bb); bb = NULL; } /* binary file */ done: if (ret_value == FAIL) { /* Failure cleanup */ if (bb != NULL) HDfree((VOIDP)bb); } /* Normal cleanup */ return ret_value; } /* dumpvd */