39 #include <geotiffio.h>
40 #include <geo_normalize.h>
41 #include <geo_tiffp.h>
47 #define ROOT2 1.4142135623730950488016887242096981
48 #define PI 3.14159265358979323846
49 #define BINBELOWTHRESH 110
51 #define CALLOC(ptr,typ,num) { \
52 (ptr) = (typ *)calloc((num) , sizeof(typ)); \
54 fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
62 int collect_bins(
int number_of_initial_points, XPoint *initial_point,
67 static int *binsoverlain =
NULL;
68 static int binsperpixel = 0;
69 static int numoverlain;
70 static int width, height;
87 static meta_l2Type meta_l2;
88 static char buf[65535];
99 double latmax = -90.0;
100 double latmin = 90.0;
101 double lonmin = 180.0;
102 double lonmax = -180.0;
109 uint32_t numbins, numoutpix;
112 float nrad, srad, wrad, erad;
113 int i,
j,
k, m, n, ii;
115 uint32_t mask_252, mask_253, all_masks;
116 uint32_t mask_glint = 0;
117 uint32_t required_mask;
120 uint8_t default_palfile = 0;
123 static uint16_t maxval = 250;
127 int32_t prod_num = -1;
138 if (
argc == 1 || strcmp(argv[1],
"-version") == 0 || strcmp(argv[1],
"--version") == 0) {
151 if (strcasecmp(
input.palfile,
"default") == 0) {
156 fp = fopen(
input.product_table,
"r");
158 fprintf(
stderr,
"SMIGEN product table \"%s\" not found.\n",
input.product_table);
163 while (fgets(buf, 128, fp) !=
NULL) {
164 if ((buf[0] >= 0x41) && (buf[0] <= 0x5a))
l3m_params++;
166 fseek(fp, 0, SEEK_SET);
178 while (fgets(buf, 128, fp) !=
NULL) {
179 if ((buf[0] >= 0x41) && (buf[0] <= 0x5a)) {
181 cptr = strtok(buf,
":");
185 cptr = strtok(
NULL,
":");
189 cptr = strtok(
NULL,
":");
190 unit_list[
i] = (
char*) malloc(strlen(cptr) + 1);
193 cptr = strtok(
NULL,
":");
197 cptr = strtok(
NULL,
":");
200 cptr = strtok(
NULL,
":");
203 cptr = strtok(
NULL,
":");
207 cptr = strtok(
NULL,
"\n");
225 if (
input.stype == 1)
strcpy(scale_type,
"linear");
226 if (
input.stype == 2)
strcpy(scale_type,
"logarithmic");
232 if (strcmp(scale_type,
"linear") == 0) {
234 strcpy(scale_type,
"LINEAR");
237 }
else if (strcmp(scale_type,
"logarithmic") == 0) {
239 strcpy(scale_type,
"LOG");
246 if (default_palfile) {
248 strcat(
input.palfile,
"/");
250 strcat(
input.palfile,
".pal");
253 if (!(
r = (
short *) calloc(256,
sizeof (
short)))) {
254 fprintf(
stderr,
"smigen: Error allocating space for red.\n");
257 if (!(
g = (
short *) calloc(256,
sizeof (
short)))) {
258 fprintf(
stderr,
"smigen: Error allocating space for green.\n");
261 if (!(
b = (
short *) calloc(256,
sizeof (
short)))) {
262 fprintf(
stderr,
"smigen: Error allocating space for blue.\n");
267 fprintf(
stderr,
"Error reading palette file %s\n",
input.palfile);
287 for (
i = 0;
i < 256;
i++) {
297 if (prod_num == -1) {
299 strcpy(scale_type,
"LINEAR");
300 if (
input.stype == 1)
strcpy(scale_type,
"linear");
301 if (
input.stype == 2)
strcpy(scale_type,
"logarithmic");
303 if (
input.datamin == 0.0)
input.datamin = 0.001;
304 if (
input.datamax == 0.0)
input.datamax = 1.0;
307 if (strcmp(scale_type,
"linear") == 0) {
309 strcpy(scale_type,
"LINEAR");
314 if (strcmp(scale_type,
"logarithmic") == 0) {
316 strcpy(scale_type,
"LOG");
324 strcat(
input.palfile,
"/default.pal");
326 if (!(
r = (
short *) calloc(256,
sizeof (
short)))) {
327 fprintf(
stderr,
"smigen: Error allocating space for red.\n");
330 if (!(
g = (
short *) calloc(256,
sizeof (
short)))) {
331 fprintf(
stderr,
"smigen: Error allocating space for green.\n");
334 if (!(
b = (
short *) calloc(256,
sizeof (
short)))) {
335 fprintf(
stderr,
"smigen: Error allocating space for blue.\n");
340 fprintf(
stderr,
"Error reading palette file %s\n",
input.palfile);
360 for (
i = 0;
i < 256;
i++) {
369 int singleInputFile = 0;
380 if (singleInputFile) {
385 if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
386 if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
387 if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
388 if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
391 fprintf(
stderr,
"Single HDF input\n");
397 fp = fopen(
input.ifile,
"r");
399 fprintf(
stderr,
"Input listing file: \"%s\" not found.\n",
input.ifile);
402 while (fgets(buf, 256, fp) !=
NULL) nfiles++;
404 fprintf(
stderr,
"%d input files\n", nfiles);
409 fp = fopen(
input.ifile,
"r");
410 for (
i = 0;
i < nfiles;
i++) {
412 buf[strlen(buf) - 1] = 0;
416 if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
417 if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
418 if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
419 if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
429 if (
input.flaguse[0] == 0) {
434 strcpy(buf, l2_str[0].flagnames);
435 setupflags(buf,
"HIGLINT", &mask_252, &required_mask, &
status,l2_str[0].l2_bits);
436 setupflags(buf,
"LAND", &mask_253, &required_mask, &
status,l2_str[0].l2_bits);
439 if ((all_masks & mask_252) != 0)
445 for (
j = 0;
j < nfiles;
j++) {
446 for (
i = 0;
i < l2_str[
j].nprod;
i++) {
447 if (strcmp(l2_str[
j].prodname[
i],
input.prod) == 0) {
454 fprintf(
stderr,
"Product %s not found in all L2 file(s)\n",
input.prod);
460 input.north = latmax;
461 input.south = latmin;
471 fprintf(
stderr,
"Mapping data to:\n N: %8.5f\n S: %8.5f\n W: %8.5f\n E: %8.5f\n",
474 fprintf(
stderr,
"Scale Type : %s\n", scale_type);
475 fprintf(
stderr,
"Data Min (abs) : %8.4f\n",
input.datamin);
476 fprintf(
stderr,
"Data Max (abs) : %8.4f\n",
input.datamax);
479 if (
input.apply_pal >= 1 || default_palfile == 0)
480 fprintf(
stderr,
"Applying palette: %s\n",
input.palfile);
482 fprintf(
stderr,
"Applying masking to flagged pixels\n");
485 fprintf(
stderr,
"The northernmost boundary must be greater than the ");
486 fprintf(
stderr,
"southernmost boundary.\n");
493 fprintf(
stderr,
"Width (%d) is too small to produce a useful image.\n",
498 height =
rint((nrad - srad) * width / (erad - wrad));
500 height =
rint((nrad - srad) * width / (erad - wrad + 2 *
PI));
502 numbins = width * height;
503 scale = height / (nrad - srad);
506 CALLOC(sum,
double, numbins);
515 for (
k = 0;
k < nfiles;
k++) {
519 nscans = l2_str[
k].nrec;
520 npix = l2_str[
k].nsamp;
521 fprintf(
stderr,
"pix: %d scan: %d\n",
npix, nscans);
523 if (strcmp(
input.prod,
"sst") == 0 || strcmp(
input.prod,
"sst4") == 0) {
526 for (
i = 0;
i < l2_str[
k].nprod;
i++) {
527 if (strcmp(
qual, l2_str[
k].prodname[
i]) == 0) {
533 for (
i = 0;
i < l2_str[
k].nprod;
i++)
534 if (strcmp(
input.prod, l2_str[
k].prodname[
i]) == 0) {
539 if (
npix <= 0 || nscans <= 0) {
541 "-E- %s line %d: Bad scene dimension: npix=%d nscans=%d in file, %s.\n",
547 progress = (
int) ceil(((
double) nscans / 78));
551 fprintf(
stderr,
"Mapping swath pixels to Plate Carree projection...\n");
552 for (
i = 0;
i < nscans;
i++) {
562 double sinplat, cosplat;
564 double sinc[2], cosc[2];
565 double sinaz[8], cosaz[8];
569 plat = l2_str[
k].latitude[
j] *
PI / 180.0;
570 plon = l2_str[
k].longitude[
j] *
PI / 180.0;
579 double sindlat2, sindlon2, cosnlat;
584 nlat = l2_str[
k].latitude[
j + 1] *
PI / 180.0;
585 nlon = l2_str[
k].longitude[
j + 1] *
PI / 180.0;
592 sindlat2 = sin(dlat / 2);
593 sindlon2 = sin(dlon / 2);
595 phw = asin(sqrt(sindlat2 * sindlat2 +
596 sindlon2 * sindlon2 *
619 cosplat * sin(nlat) - sinplat * cosnlat * cos(dlon)
624 for (ii = 1; ii < 8; ii++) {
631 for (ii = 0; ii < 8; ii++) {
638 lat = asin(sinplat * cosc[ec]
639 + cosplat * sinc[ec] * cosaz[ii]);
642 + atan2(sinc[ec] * sinaz[ii],
644 - sinplat * sinc[ec] * cosaz[ii]);
647 if (
lon >= wrad &&
lon > erad) {
648 corners[ii].x = (
lon - wrad) * scale;
649 }
else if (
lon < wrad &&
lon <= erad) {
650 corners[ii].x = (
lon - wrad + 2 *
PI) * scale;
651 }
else if (
lon - erad < wrad -
lon) {
652 corners[ii].x = (
lon - wrad + 2 *
PI) * scale;
654 corners[ii].x = (
lon - wrad) * scale;
657 corners[ii].x = (
lon - wrad) * scale;
659 corners[ii].y = (nrad -
lat) * scale;
661 if (corners[ii].
x < 0 || corners[ii].
x >= width
662 || corners[ii].
y < 0 || corners[ii].
y >= height)
out++;
669 if (
out == 8)
continue;
671 l2_flags = l2_str[
k].l2_flags[
j];
673 quality = l2_str[
k].l2_data[qualidx][
j];
682 for (m = 0; m < numoverlain; m++) {
693 if (
input.mask && qualidx < 0) {
694 if (l2_flags & mask_252 && mask_glint &&
695 strcmp(
input.prod,
"sst") != 0 &&
696 strcmp(
input.prod,
"sst4") != 0) {
698 }
else if (l2_flags & mask_253) {
700 }
else if (l2_flags & all_masks) {
703 }
else if (
input.mask && qualidx >= 0) {
704 if (l2_flags & mask_253) {
706 }
else if (quality >
input.quality) {
713 if (qualidx >= 0 && quality >
input.quality) goodpix = 0;
714 else if (qualidx < 0 && (l2_flags & all_masks) != 0) goodpix = 0;
717 val = l2_str[
k].l2_data[prodidx][
j];
725 if (
i != 0 &&
i % progress == 0) fprintf(
stderr,
".");
729 fprintf(
stderr,
"Finished Plate Carree projection mapping\n");
733 fprintf(
stderr,
"Computing means...\n");
735 for (n = 0; n < numbins; n++) {
746 if (strcmp(scale_type,
"LINEAR") == 0) {
748 }
else if (strcmp(scale_type,
"LOG") == 0) {
755 if ((
double) 100 * numoutpix / numbins < threshold) {
756 fprintf(
stderr,
"Number of output pixels (%u of a possible %u) ",
758 fprintf(
stderr,
"< threshold (%.2f%%). Output image not generated.\n",
763 if (
input.outmode == 1) {
766 if (strlen(
input.ofile) > 0) {
767 fprintf(
stderr,
"Writing out file: %s ...\n",
input.ofile);
768 outfp = fopen(
input.ofile,
"wb");
770 fprintf(
stderr,
"Writing out data to STDOUT...\n");
774 if (
input.apply_pal == 0 && default_palfile == 1) {
775 fprintf(outfp,
"P5\n%d %d\n255\n", width, height);
776 for (n = 0; n < numbins; n++) {
777 fputc((
int)
mean[n], outfp);
783 for (
i = 0;
i < numbins;
i++) {
789 fprintf(outfp,
"P6\n%d %d\n255\n", width, height);
790 fwrite(&
rgb[0], 1, width * height * 3, outfp);
799 }
else if (
input.outmode == 2) {
802 if (strlen(
input.ofile) > 0) {
803 fprintf(
stderr,
"Writing out file: %s ...\n",
input.ofile);
804 outfp = fopen(
input.ofile,
"wb");
806 fprintf(
stderr,
"Writing out data to STDOUT...\n");
810 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
813 fprintf(
stderr,
"l2mapgen: Error: Unable to create PNG write structure.\n");
817 png_infop info_ptr = png_create_info_struct(png_ptr);
819 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
820 fprintf(
stderr,
"l2mapgen: Error: Unable to create PNG info structure.\n");
823 if (setjmp(png_jmpbuf(png_ptr))) {
824 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
825 fprintf(
stderr,
"l2mapgen: Error: Unable to call PNG setjmp().\n");
828 png_init_io(png_ptr, outfp);
830 uint8_t * row_pointers[height];
831 for (
i = 0;
i < height;
i++)
832 row_pointers[
i] =
mean + (
i * width);
833 png_set_rows(png_ptr, info_ptr, row_pointers);
835 if (
input.apply_pal == 0 && default_palfile == 1) {
838 png_set_IHDR(png_ptr, info_ptr, width, height,
839 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
840 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
844 png_set_IHDR(png_ptr, info_ptr, width, height,
845 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
846 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
847 png_set_PLTE(png_ptr, info_ptr, (png_const_colorp)
input.palette, 256);
850 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY,
NULL);
853 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
861 }
else if (
input.outmode == 3) {
862 uint16_t *rr, *
gg, *bb;
867 if (strlen(
input.ofile) == 0) {
868 fprintf(
stderr,
"Can not write TIFF file to stdout.\n");
872 tiff = XTIFFOpen(
input.ofile,
"w");
874 fprintf(
stderr,
"Could not open outgoing image\n");
877 gtif = GTIFNew(tiff);
879 fprintf(
stderr,
"Could not create geoTIFF structure\n");
884 double tiepoints[6] = {0, 0, 0, 0, 0, 0};
885 double pixscale[3] = {0, 0, 0};
888 pixscale[0] = (
input.east -
input.west) / width;
891 pixscale[1] = (
input.north -
input.south) / height;
894 tiepoints[3] =
input.west;
895 tiepoints[4] =
input.north;
897 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
898 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
899 TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
900 TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
902 if (
input.apply_pal == 0 && default_palfile == 1) {
905 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
906 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
907 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
908 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
909 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
912 GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
913 GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
914 GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
918 fmean = (
float*) malloc(numbins *
sizeof (
float));
920 fprintf(
stderr,
"Could not allocate memory for TIFF grayscale mean\n");
925 for (
i = 0;
i < numbins;
i++) {
934 if (TIFFWriteEncodedStrip(tiff, 0, fmean, numbins *
sizeof (
float)) == 0) {
935 fprintf(
stderr,
"Could not write TIFF image\n");
943 rr = (uint16_t*) malloc(256 *
sizeof (uint16_t));
944 gg = (uint16_t*) malloc(256 *
sizeof (uint16_t));
945 bb = (uint16_t*) malloc(256 *
sizeof (uint16_t));
947 fprintf(
stderr,
"Could not allocate memory for TIFF color map\n");
952 for (
i = 0;
i < 256;
i++) {
958 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
959 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
960 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
961 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
962 TIFFSetField(tiff, TIFFTAG_COLORMAP, rr,
gg, bb);
965 GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
966 GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
967 GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
972 if (TIFFWriteEncodedStrip(tiff, 0,
mean, width * height) == 0) {
973 fprintf(
stderr,
"Could not write TIFF image\n");
990 fprintf(
stderr,
"l2mapgen: Error: invalid value for outmode - %d.\n",
input.outmode);
1019 fprintf(
stderr,
"Done.\n");
1091 register EdgeTableEntry *pAET;
1093 register int nPts = 0;
1094 register EdgeTableEntry *pWETE;
1095 register ScanLineList *pSLL;
1096 register XPoint *ptsOut;
1100 EdgeTableEntry *pPrevAET;
1103 EdgeTableEntry *pETEs;
1104 ScanLineListBlock SLLBlock;
1107 if (!(pETEs = (EdgeTableEntry *) malloc(
sizeof (EdgeTableEntry) *
count))) {
1110 ptsOut = FirstPoint;
1126 if (pSLL &&
y == pSLL->scanline) {
1144 if (pWETE == pAET) {
1145 ptsOut->x = pAET->bres.minor;
1147 *wdth++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
1155 ptsOut = FirstPoint;
1160 pWETE = pWETE->nextWETE;
1161 while (pWETE != pAET)
1163 pWETE = pWETE->nextWETE;
1188 int number_of_initial_points,
1189 XPoint *initial_point,
1200 for (
i = 0;
i < number_of_initial_points;
i++) {
1202 y = initial_point[
i].y;
1203 if (
y >= height ||
y < 0)
continue;
1206 x = initial_point[
i].
x,
1207 end = initial_point[
i].
x + span_width[
i];
1211 if (
x >= width ||
x < 0)
continue;
1212 if (numoverlain >= binsperpixel) {
1213 binsperpixel += 1024;
1214 binsoverlain = (
int *) realloc(binsoverlain, binsperpixel *
sizeof (
int));
1215 if (binsoverlain ==
NULL) {
1216 fprintf(
stderr,
"-E- %s line %d: ", __FILE__, __LINE__);
1218 "Memory allocation error (numoverlain=%d binsperpixel=%d\n",
1219 numoverlain, binsperpixel);
1224 binsoverlain[numoverlain++] =
y * width +
x;