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;
83 int main(
int argc,
char *argv[]) {
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;
381 if (singleInputFile) {
386 if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
387 if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
388 if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
389 if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
392 fprintf(
stderr,
"Single HDF input\n");
398 fp = fopen(
input.ifile,
"r");
400 fprintf(
stderr,
"Input listing file: \"%s\" not found.\n",
input.ifile);
403 while (fgets(buf, 256, fp) !=
NULL) nfiles++;
405 fprintf(
stderr,
"%d input files\n", nfiles);
410 fp = fopen(
input.ifile,
"r");
411 for (
i = 0;
i < nfiles;
i++) {
413 buf[strlen(buf) - 1] = 0;
417 if (meta_l2.northlat >= latmax) latmax = meta_l2.northlat;
418 if (meta_l2.southlat <= latmin) latmin = meta_l2.southlat;
419 if (meta_l2.westlon <= lonmin) lonmin = meta_l2.westlon;
420 if (meta_l2.eastlon >= lonmax) lonmax = meta_l2.eastlon;
429 if (
input.flaguse[0] == 0) {
434 strcpy(buf, l2_str[0].flagnames);
438 if ((all_masks & mask_252) != 0)
444 for (
j = 0;
j < nfiles;
j++) {
445 for (
i = 0;
i < l2_str[
j].nprod;
i++) {
446 if (strcmp(l2_str[
j].prodname[
i],
input.prod) == 0) {
453 fprintf(
stderr,
"Product %s not found in all L2 file(s)\n",
input.prod);
459 input.north = latmax;
460 input.south = latmin;
470 fprintf(
stderr,
"Mapping data to:\n N: %8.5f\n S: %8.5f\n W: %8.5f\n E: %8.5f\n",
473 fprintf(
stderr,
"Scale Type : %s\n", scale_type);
474 fprintf(
stderr,
"Data Min (abs) : %8.4f\n",
input.datamin);
475 fprintf(
stderr,
"Data Max (abs) : %8.4f\n",
input.datamax);
478 if (
input.apply_pal >= 1 || default_palfile == 0)
479 fprintf(
stderr,
"Applying palette: %s\n",
input.palfile);
481 fprintf(
stderr,
"Applying masking to flagged pixels\n");
484 fprintf(
stderr,
"The northernmost boundary must be greater than the ");
485 fprintf(
stderr,
"southernmost boundary.\n");
492 fprintf(
stderr,
"Width (%d) is too small to produce a useful image.\n",
497 height =
rint((nrad - srad) * width / (erad - wrad));
499 height =
rint((nrad - srad) * width / (erad - wrad + 2 *
PI));
501 numbins = width * height;
502 scale = height / (nrad - srad);
505 CALLOC(sum,
double, numbins);
514 for (
k = 0;
k < nfiles;
k++) {
518 nscans = l2_str[
k].nrec;
519 npix = l2_str[
k].nsamp;
520 fprintf(
stderr,
"pix: %d scan: %d\n",
npix, nscans);
522 if (strcmp(
input.prod,
"sst") == 0 || strcmp(
input.prod,
"sst4") == 0) {
525 for (
i = 0;
i < l2_str[
k].nprod;
i++) {
526 if (strcmp(
qual, l2_str[
k].prodname[
i]) == 0) {
532 for (
i = 0;
i < l2_str[
k].nprod;
i++)
533 if (strcmp(
input.prod, l2_str[
k].prodname[
i]) == 0) {
538 if (
npix <= 0 || nscans <= 0) {
540 "-E- %s line %d: Bad scene dimension: npix=%d nscans=%d in file, %s.\n",
546 progress = (
int) ceil(((
double) nscans / 78));
550 fprintf(
stderr,
"Mapping swath pixels to Plate Carree projection...\n");
551 for (
i = 0;
i < nscans;
i++) {
561 double sinplat, cosplat;
563 double sinc[2], cosc[2];
564 double sinaz[8], cosaz[8];
568 plat = l2_str[
k].latitude[
j] *
PI / 180.0;
569 plon = l2_str[
k].longitude[
j] *
PI / 180.0;
578 double sindlat2, sindlon2, cosnlat;
583 nlat = l2_str[
k].latitude[
j + 1] *
PI / 180.0;
584 nlon = l2_str[
k].longitude[
j + 1] *
PI / 180.0;
591 sindlat2 = sin(dlat / 2);
592 sindlon2 = sin(dlon / 2);
594 phw = asin(sqrt(sindlat2 * sindlat2 +
595 sindlon2 * sindlon2 *
618 cosplat * sin(nlat) - sinplat * cosnlat * cos(dlon)
623 for (ii = 1; ii < 8; ii++) {
630 for (ii = 0; ii < 8; ii++) {
637 lat = asin(sinplat * cosc[ec]
638 + cosplat * sinc[ec] * cosaz[ii]);
641 + atan2(sinc[ec] * sinaz[ii],
643 - sinplat * sinc[ec] * cosaz[ii]);
646 if (
lon >= wrad &&
lon > erad) {
647 corners[ii].x = (
lon - wrad) * scale;
648 }
else if (
lon < wrad &&
lon <= erad) {
649 corners[ii].x = (
lon - wrad + 2 *
PI) * scale;
650 }
else if (
lon - erad < wrad -
lon) {
651 corners[ii].x = (
lon - wrad + 2 *
PI) * scale;
653 corners[ii].x = (
lon - wrad) * scale;
656 corners[ii].x = (
lon - wrad) * scale;
658 corners[ii].y = (nrad -
lat) * scale;
660 if (corners[ii].
x < 0 || corners[ii].
x >= width
661 || corners[ii].
y < 0 || corners[ii].
y >= height)
out++;
668 if (
out == 8)
continue;
670 l2_flags = l2_str[
k].l2_flags[
j];
672 quality = l2_str[
k].l2_data[qualidx][
j];
681 for (m = 0; m < numoverlain; m++) {
692 if (
input.mask && qualidx < 0) {
693 if (l2_flags & mask_252 && mask_glint &&
694 strcmp(
input.prod,
"sst") != 0 &&
695 strcmp(
input.prod,
"sst4") != 0) {
697 }
else if (l2_flags & mask_253) {
699 }
else if (l2_flags & all_masks) {
702 }
else if (
input.mask && qualidx >= 0) {
703 if (l2_flags & mask_253) {
705 }
else if (quality >
input.quality) {
712 if (qualidx >= 0 && quality >
input.quality) goodpix = 0;
713 else if (qualidx < 0 && (l2_flags & all_masks) != 0) goodpix = 0;
716 val = l2_str[
k].l2_data[prodidx][
j];
724 if (
i != 0 &&
i % progress == 0) fprintf(
stderr,
".");
728 fprintf(
stderr,
"Finished Plate Carree projection mapping\n");
732 fprintf(
stderr,
"Computing means...\n");
734 for (n = 0; n < numbins; n++) {
745 if (strcmp(scale_type,
"LINEAR") == 0) {
747 }
else if (strcmp(scale_type,
"LOG") == 0) {
754 if ((
double) 100 * numoutpix / numbins < threshold) {
755 fprintf(
stderr,
"Number of output pixels (%u of a possible %u) ",
757 fprintf(
stderr,
"< threshold (%.2f%%). Output image not generated.\n",
762 if (
input.outmode == 1) {
765 if (strlen(
input.ofile) > 0) {
766 fprintf(
stderr,
"Writing out file: %s ...\n",
input.ofile);
767 outfp = fopen(
input.ofile,
"wb");
769 fprintf(
stderr,
"Writing out data to STDOUT...\n");
773 if (
input.apply_pal == 0 && default_palfile == 1) {
774 fprintf(outfp,
"P5\n%d %d\n255\n", width, height);
775 for (n = 0; n < numbins; n++) {
776 fputc((
int)
mean[n], outfp);
782 for (
i = 0;
i < numbins;
i++) {
788 fprintf(outfp,
"P6\n%d %d\n255\n", width, height);
789 fwrite(&
rgb[0], 1, width * height * 3, outfp);
798 }
else if (
input.outmode == 2) {
801 if (strlen(
input.ofile) > 0) {
802 fprintf(
stderr,
"Writing out file: %s ...\n",
input.ofile);
803 outfp = fopen(
input.ofile,
"wb");
805 fprintf(
stderr,
"Writing out data to STDOUT...\n");
809 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
812 fprintf(
stderr,
"l2mapgen: Error: Unable to create PNG write structure.\n");
816 png_infop info_ptr = png_create_info_struct(png_ptr);
818 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
819 fprintf(
stderr,
"l2mapgen: Error: Unable to create PNG info structure.\n");
822 if (setjmp(png_jmpbuf(png_ptr))) {
823 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
824 fprintf(
stderr,
"l2mapgen: Error: Unable to call PNG setjmp().\n");
827 png_init_io(png_ptr, outfp);
829 uint8_t * row_pointers[height];
830 for (
i = 0;
i < height;
i++)
831 row_pointers[
i] =
mean + (
i * width);
832 png_set_rows(png_ptr, info_ptr, row_pointers);
834 if (
input.apply_pal == 0 && default_palfile == 1) {
837 png_set_IHDR(png_ptr, info_ptr, width, height,
838 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,
839 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
843 png_set_IHDR(png_ptr, info_ptr, width, height,
844 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
845 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
846 png_set_PLTE(png_ptr, info_ptr, (png_const_colorp)
input.palette, 256);
849 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY,
NULL);
852 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
860 }
else if (
input.outmode == 3) {
861 uint16_t *rr, *
gg, *bb;
866 if (strlen(
input.ofile) == 0) {
867 fprintf(
stderr,
"Can not write TIFF file to stdout.\n");
871 tiff = XTIFFOpen(
input.ofile,
"w");
873 fprintf(
stderr,
"Could not open outgoing image\n");
876 gtif = GTIFNew(tiff);
878 fprintf(
stderr,
"Could not create geoTIFF structure\n");
883 double tiepoints[6] = {0, 0, 0, 0, 0, 0};
884 double pixscale[3] = {0, 0, 0};
887 pixscale[0] = (
input.east -
input.west) / width;
890 pixscale[1] = (
input.north -
input.south) / height;
893 tiepoints[3] =
input.west;
894 tiepoints[4] =
input.north;
896 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
897 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
898 TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
899 TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
901 if (
input.apply_pal == 0 && default_palfile == 1) {
904 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
905 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
906 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
907 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
908 TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
911 GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
912 GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
913 GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
917 fmean = (
float*) malloc(numbins *
sizeof (
float));
919 fprintf(
stderr,
"Could not allocate memory for TIFF grayscale mean\n");
924 for (
i = 0;
i < numbins;
i++) {
933 if (TIFFWriteEncodedStrip(tiff, 0, fmean, numbins *
sizeof (
float)) == 0) {
934 fprintf(
stderr,
"Could not write TIFF image\n");
942 rr = (uint16_t*) malloc(256 *
sizeof (uint16_t));
943 gg = (uint16_t*) malloc(256 *
sizeof (uint16_t));
944 bb = (uint16_t*) malloc(256 *
sizeof (uint16_t));
946 fprintf(
stderr,
"Could not allocate memory for TIFF color map\n");
951 for (
i = 0;
i < 256;
i++) {
957 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
958 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
959 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
960 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
961 TIFFSetField(tiff, TIFFTAG_COLORMAP, rr,
gg, bb);
964 GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
965 GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
966 GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
971 if (TIFFWriteEncodedStrip(tiff, 0,
mean, width * height) == 0) {
972 fprintf(
stderr,
"Could not write TIFF image\n");
989 fprintf(
stderr,
"l2mapgen: Error: invalid value for outmode - %d.\n",
input.outmode);
1018 fprintf(
stderr,
"Done.\n");
1090 register EdgeTableEntry *pAET;
1092 register int nPts = 0;
1093 register EdgeTableEntry *pWETE;
1094 register ScanLineList *pSLL;
1095 register XPoint *ptsOut;
1099 EdgeTableEntry *pPrevAET;
1102 EdgeTableEntry *pETEs;
1103 ScanLineListBlock SLLBlock;
1106 if (!(pETEs = (EdgeTableEntry *) malloc(
sizeof (EdgeTableEntry) *
count))) {
1109 ptsOut = FirstPoint;
1125 if (pSLL &&
y == pSLL->scanline) {
1143 if (pWETE == pAET) {
1144 ptsOut->x = pAET->bres.minor;
1146 *wdth++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
1154 ptsOut = FirstPoint;
1159 pWETE = pWETE->nextWETE;
1160 while (pWETE != pAET)
1162 pWETE = pWETE->nextWETE;
1187 int number_of_initial_points,
1188 XPoint *initial_point,
1199 for (
i = 0;
i < number_of_initial_points;
i++) {
1201 y = initial_point[
i].y;
1202 if (
y >= height ||
y < 0)
continue;
1205 x = initial_point[
i].
x,
1206 end = initial_point[
i].
x + span_width[
i];
1210 if (
x >= width ||
x < 0)
continue;
1211 if (numoverlain >= binsperpixel) {
1212 binsperpixel += 1024;
1213 binsoverlain = (
int *) realloc(binsoverlain, binsperpixel *
sizeof (
int));
1214 if (binsoverlain ==
NULL) {
1215 fprintf(
stderr,
"-E- %s line %d: ", __FILE__, __LINE__);
1217 "Memory allocation error (numoverlain=%d binsperpixel=%d\n",
1218 numoverlain, binsperpixel);
1223 binsoverlain[numoverlain++] =
y * width +
x;