Пример #1
0
/******************************************************************************

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 );
}
Пример #2
0
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
}
Пример #3
0
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
/* 
 * 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;
}
Пример #7
0
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 */