Go to the documentation of this file.
37 #define BYTE unsigned char
45 #define MALLOC(ptr,typ,num) { \
46 (ptr) = (typ *)malloc((num) * sizeof(typ)); \
48 fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
59 unsigned char *raster,
61 int32_t height,
unsigned char *palette,
char *
label) {
64 if (DFR8setpalette(palette) ==
FAIL) {
66 "-E- %s line %d: DFR8setpalette() failed for file, %s.\n",
67 __FILE__, __LINE__, fname);
70 if (DFR8addimage(fname, raster, width, height, COMP_NONE) ==
FAIL) {
72 "-E- %s line %d: DFR8addimage() failed for file, %s.\n",
73 __FILE__, __LINE__, fname);
79 "-E- %s line %d: DFR8lastref() failed for file, %s.\n",
80 __FILE__, __LINE__, fname);
83 if (DFANputlabel(fname, DFTAG_RIG,
ref,
"brs_data")) {
85 "-E- %s line %d: DFANputlabel() failed for file, %s.\n",
86 __FILE__, __LINE__, fname);
94 int main(
int argc,
char *argv[]) {
105 int32_t sfactor = 10;
121 int want_atmocor = 0;
122 int want_linscale = 0;
125 float sr_r, sr_g, sr_b;
135 char outfile[FILENAME_MAX] =
"";
144 int32_t start_w[3] = {0, 0, 0};
145 int32_t count_w[3] = {1, 1, 3};
152 unsigned char palette[768];
153 unsigned char *raster;
165 png_structp png_ptr =
NULL;
166 png_infop info_ptr =
NULL;
178 for (
i = 0;
i < argc;
i++) {
179 if ((strcmp(argv[
i],
"-h") == 0) || (strcmp(argv[
i],
"-help") == 0)) {
202 printf(
"-E- %s: Error parsing input parameters.\n", argv[0]);
207 want_linscale =
input->stype;
208 if (
input->atmocor == 1)
216 printf(
"-E- %s: Error opening %s for reading.\n", argv[0],
224 if (
r < 0 ||
g < 0 ||
b < 0) {
225 printf(
"-E- Invalid RGB set for this sensor\n");
227 printf(
" Invalid R: %d\n",
input->rgb[0]);
229 printf(
" Invalid G: %d\n",
input->rgb[1]);
231 printf(
" Invalid B: %d\n",
input->rgb[2]);
244 printf(
"-E- %s: Unable to allocate L1 record.\n", argv[0]);
266 nscan = (escan - sscan) / sfactor + 1;
278 printf(
"Using r,g,b = %d, %d, %d\n",
input->rgb[0],
input->rgb[1],
281 if (strcmp(
input->oformat,
"HDF4") == 0) {
282 if (strcmp(
input->oformat_depth,
"8bit") == 0)
286 }
else if (strcmp(
input->oformat,
"BIN") == 0)
288 else if (strcmp(
input->oformat,
"PNG") == 0)
290 else if (strcmp(
input->oformat,
"PPM") == 0)
293 if (want_ppm + want_24bit + want_8bit + want_bin + want_png > 1) {
294 printf(
"%s: Error: More than one output format has been chosen.\n", argv[0]);
297 if (want_ppm + want_24bit + want_8bit + want_bin + want_png < 1) {
300 if (want_8bit || want_24bit) {
306 if ((outfp = fopen(outfile,
"w")) ==
NULL) {
307 printf(
"%s: Error: Unable to open %s for writing.\n",
312 fprintf(outfp,
"P6\n");
313 fprintf(outfp,
"%d\n",
npix);
314 fprintf(outfp,
"%d\n",
nscan);
315 fprintf(outfp,
"255\n");
317 }
else if (want_hdf) {
322 sd_id_w = SDstart(outfile, DFACC_CREATE);
327 sds_id_lon = SDcreate(sd_id_w,
"longitude",
DFNT_INT16,
rank, dims);
329 SDsetdimname(SDgetdimid(sds_id_lon, 0),
"Number of Scans");
330 SDsetdimname(SDgetdimid(sds_id_lon, 1),
"Pixels per Scan");
340 sds_id_lat = SDcreate(sd_id_w,
"latitude",
DFNT_INT16,
rank, dims);
342 SDsetdimname(SDgetdimid(sds_id_lat, 0),
"Number of Scans");
343 SDsetdimname(SDgetdimid(sds_id_lat, 1),
"Pixels per Scan");
360 sds_id_rgb = SDcreate(sd_id_w,
"rgb", DFNT_UINT8,
rank, dims);
362 SDsetdimname(SDgetdimid(sds_id_rgb, 0),
"Number of Scans");
363 SDsetdimname(SDgetdimid(sds_id_rgb, 1),
"Pixels per Scan");
364 SDsetdimname(SDgetdimid(sds_id_rgb, 2),
"Number of Colors");
366 lineBuffer = (
unsigned char*) malloc(
npix * 3);
376 }
else if (want_bin) {
378 if ((outfp = fopen(outfile,
"w")) ==
NULL) {
379 printf(
"%s: Error: Unable to open %s for writing.\n",
385 length = 12 +
npix * 2 * 4 +
npix * 3;
391 fwrite(hdr,
sizeof (hdr), 1, outfp);
392 fseek(outfp, length, SEEK_SET);
394 }
else if (want_png) {
396 if ((outfp = fopen(outfile,
"w")) ==
NULL) {
397 printf(
"%s: Error: Unable to open %s for writing.\n",
402 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
405 fprintf(
stderr,
"%s: Error: Unable to create PNG write structure.\n", argv[0]);
409 info_ptr = png_create_info_struct(png_ptr);
411 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
412 fprintf(
stderr,
"%s: Error: Unable to create PNG info structure.\n", argv[0]);
415 if (setjmp(png_jmpbuf(png_ptr))) {
416 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
417 fprintf(
stderr,
"%s: Error: Unable to call PNG setjmp().\n", argv[0]);
420 png_init_io(png_ptr, outfp);
421 png_set_IHDR(png_ptr, info_ptr,
npix,
nscan,
422 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
423 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
424 png_write_info(png_ptr, info_ptr);
426 lineBuffer = (
unsigned char*) malloc(
npix * 3);
428 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
429 fprintf(
stderr,
"%s: Error: Unable to allocate line buffer.\n", argv[0]);
436 printf(
"%s: Error: No output format specified.\n", argv[0]);
448 "-E- %s Line %d: error reading %s at scan %d.\n",
455 int32_t
msec = (int32_t) (dmsec * 1.e3);
457 fwrite(&
year, 4, 1, outfp);
458 fwrite(&
day, 4, 1, outfp);
459 fwrite(&
msec, 4, 1, outfp);
461 for (ip = 0; ip <
npix; ip++) {
462 fwrite(&
l1rec.lon[ip], 4, 1, outfp);
464 for (ip = 0; ip <
npix; ip++) {
465 fwrite(&
l1rec.lat[ip], 4, 1, outfp);
468 }
else if (want_hdf) {
469 start_w[0] = (
iscan - sscan) / sfactor;
470 for (ip = 0; ip <
npix; ip++) {
471 if (
l1rec.lon[ip] >= 0)
472 lonBuffer[ip] = (
int16) ((
l1rec.lon[ip] * 180) + 0.5);
473 if (
l1rec.lon[ip] < 0)
474 lonBuffer[ip] = (
int16) ((
l1rec.lon[ip] * 180) - 0.5);
476 if (
l1rec.lat[ip] >= 0)
477 latBuffer[ip] = (
int16) ((
l1rec.lat[ip] * 360) + 0.5);
478 if (
l1rec.lat[ip] < 0)
479 latBuffer[ip] = (
int16) ((
l1rec.lat[ip] * 360) - 0.5);
482 SDwritedata(sds_id_lon, start_w,
NULL, count_w,
485 SDwritedata(sds_id_lat, start_w,
NULL, count_w,
493 "-E- %s Line %d: error loading %s at scan %d.\n",
499 int32_t yr = (int32_t)
year;
500 int32_t dy = (int32_t)
day;
504 for (iw = 0; iw <
nbands; iw++) {
509 for (ip = 0; ip <
npix; ip++) {
514 if (
input->cirrus_opt)
515 rhoc =
l1rec.rho_cirrus[ip] / twc;
528 if (want_linscale == 1) {
549 if (want_bin || want_ppm) {
550 fwrite(
rgb, 1, 3, outfp);
551 }
else if (want_hdf) {
555 lineBuffer[
i++] =
rgb[0];
556 lineBuffer[
i++] =
rgb[1];
557 lineBuffer[
i] =
rgb[2];
558 }
else if (want_8bit) {
564 }
else if (want_png) {
566 lineBuffer[
i++] =
rgb[0];
567 lineBuffer[
i++] =
rgb[1];
568 lineBuffer[
i] =
rgb[2];
574 SDwritedata(sds_id_rgb, start_w,
NULL, count_w,
577 }
else if (want_png) {
578 png_write_row(png_ptr, lineBuffer);
592 SetChrGA(ds_id,
"Product Name", outfile);
594 sprintf(strbuf,
"%s Level-1 Browse Data",
605 "NASA/GSFC %s Level-1 quasi-true-color browse data, day %d, %d",
610 SDsetattr(sd_id_w,
"Number of Scan Lines",
DFNT_INT32, 1,
612 SDsetattr(sd_id_w,
"Pixels per Scan Line",
DFNT_INT32, 1,
620 if (want_bin || want_ppm) {
622 }
else if (want_hdf) {
625 SDendaccess(sds_id_rgb);
629 MALLOC(raster,
unsigned char, numoutpix);
643 SDendaccess(sds_id_lon);
644 SDendaccess(sds_id_lat);
648 }
else if (want_png) {
649 png_write_end(png_ptr, info_ptr);
650 png_destroy_write_struct(&png_ptr, &info_ptr);
char * ydhmsf(double dtime, char zone)
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
int readl1(filehandle *l1file, int32_t recnum, l1str *l1rec)
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
int l2gen_init_options(clo_optionList_t *list, const char *prog)
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
void filehandle_init(filehandle *file)
img_rgb_t * img_new(int w, int h)
int msl12_option_input(int argc, char *argv[], clo_optionList_t *list, char *progName, filehandle *l1file)
double esdist_(int32_t *year, int32_t *day, int32_t *msec)
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
void img_free(img_rgb_t *img)
BYTE logscale(float val, float min, float max)
int clo_setString(clo_optionList_t *list, const char *key, const char *val, const char *source)
#define MALLOC(ptr, typ, num)
int l2gen_usage(const char *prog)
int bindex_get(int32_t wave)
clo_optionList_t * clo_createList()
BYTE linscale(float val, float min, float max)
void unix2yds(double usec, short *year, short *day, double *secs)
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
void closel1(filehandle *l1file)
const char * sensorId2SensorName(int sensorId)
int SetChrGA(idDS ds_id, const char *name, const char *value)
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific the sector rotation may actually occur during one of the scans earlier than the one where it is first reported As a the b1 values are about the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT to fill pixels affected by dead subframes with a special value Output the metadata of noisy and dead subframe Dead Subframe EV and Detector Quality Flag2 Removed the function call of Fill_Dead_Detector_SI to stop interpolating SI values for dead but also for all downstream products for science test only Changes from v5 which will affect scientific to conform to MODIS requirements Removed the Mixed option from the ScanType in the code because the L1A Scan Type is never Mixed Changed for ANSI C compliance and comments to better document the fact that when the HDF_EOS metadata is stricly the and products are off by and in the track respectively Corrected some misspelling of RCS swir_oob_sending_detector to the Reflective LUTs to enable the SWIR OOB correction detector so that if any of the sending detectors becomes noisy or non near by good detectors from the same sending band can be specified as the substitute in the new look up table Code change for adding an additional dimension of mirror side to the Band_21_b1 LUT to separate the coefficient of the two mirror sides for just like other thermal emissive so that the L1B code can calibrate Band scan to scan with mirror side dependency which leads better calibration result Changes which do not affect scientific when the EV data are not provided in this Crosstalk Correction will not be performed to the Band calibration data Changes which do not affect scientific and BB_500m in L1A Logic was added to turn off the or to spatial aggregation processes and the EV_250m_Aggr1km_RefSB and EV_500m_Aggr1km_RefSB fields were set to fill values when SDSs EV_250m and EV_500m are absent in L1A file Logic was added to skip the processing and turn off the output of the L1B QKM and HKM EV data when EV_250m and EV_500m are absent from L1A In this the new process avoids accessing and reading the and L1A EV skips and writing to the L1B and EV omits reading and subsampling SDSs from geolocation file and writing them to the L1B and omits writing metadata to L1B and EV and skips closing the L1A and L1B EV and SDSs Logic was added to turn off the L1B OBC output when the high resolution OBC SDSs are absent from L1A This is accomplished by skipping the openning the writing of metadata and the closing of the L1B OBC hdf which is Bit in the scan by scan bit QA has been changed Until now
Extra metadata that will be written to the HDF4 file l2prod rank
float toa_reflect(l1str *l1rec, int32_t ip, int32_t ib)
real *8 function esdist(iyr, iday, msec)
int32_t alloc_l1(filehandle *l1file, l1str *l1rec)
void dfr8_addimage(char *fname, unsigned char *raster, int32_t width, int32_t height, unsigned char *palette, char *label)
void img_color_palette_quantization(img_rgb_t *in_image, int num_colors, uint8_t *palette, uint8_t *out_image)
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int main(int argc, char *argv[])
int loadl1(filehandle *l1file, l1str *l1rec)
int openl1(filehandle *l1file)
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")