50 #include <geotiffio.h>
51 #include <geo_normalize.h>
52 #include <geo_tiffp.h>
61 #define ROOT2 1.4142135623730950488016887242096981
65 #define BYTE unsigned char
67 #define BINBELOWTHRESH 110
69 #define MALLOC(ptr,typ,num) { \
70 (ptr) = (typ *)malloc((num) * sizeof(typ)); \
72 fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
77 #define CALLOC(ptr,typ,num) { \
78 (ptr) = (typ *)calloc((num) , sizeof(typ)); \
80 fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
93 static int *binsoverlain =
NULL;
94 static int binsperpixel = 0;
95 static int numoverlain;
96 static int width, height;
97 static double imscale;
102 int main(
int argc,
char *argv[]) {
122 int want_linscale = 0;
123 int want_atmocor = 0;
135 char outfile[FILENAME_MAX] =
"\0";
143 uint32_t numbins, bin, numoutpix;
145 float64 threshold, outpixpercent;
146 float32 north, south, west, east;
147 float32 nrad, srad, wrad, erad;
149 float32 sr_r, sr_g, sr_b;
164 for (
i = 0;
i < argc;
i++) {
165 if ((strcmp(argv[
i],
"-h") == 0) || (strcmp(argv[
i],
"-help") == 0)) {
188 printf(
"-E- %s: Error parsing input parameters.\n", argv[0]);
194 width =
input->width;
195 threshold =
input->threshold;
196 want_linscale =
input->stype;
197 if (
input->atmocor == 1)
203 north =
input->north;
204 south =
input->south;
212 printf(
"-E- %s: Error opening %s for reading.\n", argv[0],
220 if (
r < 0 ||
g < 0 ||
b < 0) {
221 printf(
"-E- Invalid RGB set for this sensor\n");
223 printf(
" Invalid R: %d\n",
input->rgb[0]);
225 printf(
" Invalid G: %d\n",
input->rgb[1]);
227 printf(
" Invalid B: %d\n",
input->rgb[2]);
235 printf(
"-E- %s: Unable to allocate L1 record.\n", argv[0]);
257 nscan = (escan - sscan) / sfactor + 1;
270 if (north == -999 || south == -999 || east == -999 || south == -999) {
272 "Not all boundaries defined, grabbing from file...patience please...\n");
276 int32_t sd_id = SDstart(
l1file.name, DFACC_RDONLY);
278 printf(
"-E- lonlat2pixline: Error opening %s for reading.\n",
289 south = floorf(tmpf);
309 fprintf(
stderr,
"-E- %s Line %d: error reading %s at scan %d.\n",
318 north = ceilf(meta->northern_lat);
320 south = floorf(meta->southern_lat);
322 east = ceilf(meta->eastern_lon);
324 west = floorf(meta->western_lon);
326 if (strcmp(meta->start_node, meta->end_node) != 0) {
327 printf(
"-E- Crossing the pole! Won't continue.\n");
336 fprintf(
stderr,
"N: %f S: %f E: %f W:%f\n", north, south, east, west);
337 nrad = north *
PI / 180;
338 srad = south *
PI / 180;
339 wrad = west *
PI / 180;
340 erad = east *
PI / 180;
344 "The northernmost boundary must be greater than the ");
345 fprintf(
stderr,
"southernmost boundary.\n");
351 "Width (%d) is too small to produce a useful image.\n",
357 height =
rint((nrad - srad) * width / (erad - wrad));
359 height =
rint((nrad - srad) * width / (erad - wrad + 2 *
PI));
361 numbins = width * height;
362 imscale = height / (nrad - srad);
364 for (bb = 0; bb < 3; bb++) {
365 CALLOC(sum[bb], float64, numbins);
371 progress = (
int) ceil(((
double)
nscan / 78));
374 printf(
"Using r,g,b = %d, %d, %d\n",
input->rgb[0],
input->rgb[1],
380 if (
iscan % progress == 0)
384 "-E- %s Line %d: error reading %s at scan %d.\n",
392 "-E- %s Line %d: error loading %s at scan %d.\n",
401 int32_t
msec = (int32_t) (dsec * 1.e3);
402 int32_t yr = (int32_t)
year;
403 int32_t dy = (int32_t)
day;
406 for (iw = 0; iw <
l1file.nbands; iw++) {
419 for (ip = 0; ip <
npix; ip++) {
422 double sinplat, cosplat;
424 double sinc[2], cosc[2];
425 double sinaz[8], cosaz[8];
431 plat =
l1rec.lat[ip] *
PI / 180;
432 plon =
l1rec.lon[ip] *
PI / 180;
441 double sindlat2, sindlon2, cosnlat;
445 nlat =
l1rec.lat[ip + 1] *
PI / 180;
446 nlon =
l1rec.lon[ip + 1] *
PI / 180;
455 if (dlon > 5.) dlon = nlon - plon - 2 *
PI;
456 if (dlon < -5.) dlon = nlon + 2 *
PI - plon;
458 sindlat2 = sin(dlat / 2);
459 sindlon2 = sin(dlon / 2);
461 phw = asin(sqrt(sindlat2 * sindlat2 +
462 sindlon2 * sindlon2 *
483 atan2(cosnlat * sin(dlon),
484 cosplat * sin(nlat) -
485 sinplat * cosnlat * cos(dlon)
490 for (
i = 1;
i < 8;
i++) {
497 for (
i = 0;
i < 8;
i++) {
504 lat = asin(sinplat * cosc[ec]
505 + cosplat * sinc[ec] * cosaz[
i]);
508 + atan2(sinc[ec] * sinaz[
i], cosplat * cosc[ec]
509 - sinplat * sinc[ec] * cosaz[
i]);
512 if (
lon >= wrad &&
lon > erad) {
513 corners[
i].x = (
lon - wrad) * imscale;
514 }
else if (
lon < wrad &&
lon <= erad) {
515 corners[
i].x = (
lon - wrad + 2 *
PI) * imscale;
516 }
else if (
lon - erad < wrad -
lon) {
517 corners[
i].x = (
lon - wrad + 2 *
PI) * imscale;
519 corners[
i].x = (
lon - wrad) * imscale;
522 corners[
i].x = (
lon - wrad) * imscale;
525 corners[
i].y = (nrad -
lat) * imscale;
527 if (corners[
i].
x < 0 || corners[
i].
x >= width
528 || corners[
i].
y < 0 || corners[
i].
y >= height)
539 if (
l1rec.Lt[ip *
l1rec.l1file->nbands +
r] <= 0.01)
541 else if (want_atmocor) {
562 if (want_linscale == 1) {
588 for (
i = 0;
i < numoverlain;
i++) {
589 bin = binsoverlain[
i];
591 for (bb = 0; bb < 3; bb++) {
592 sum[bb][bin] +=
rgb[bb];
606 for (bin = 0; bin < numbins; bin++) {
607 if (
count[bin] == 0) {
608 mean[3 * bin] =
mean[3 * bin + 1] =
mean[3 * bin + 2] = 0;
611 mean[3 * bin] = sum[0][bin] /
count[bin];
612 mean[3 * bin + 1] = sum[1][bin] /
count[bin];
613 mean[3 * bin + 2] = sum[2][bin] /
count[bin];
614 if ((
mean[3 * bin] +
mean[3 * bin + 1] +
mean[3 * bin + 2]) == 0) {
615 mean[3 * bin] =
mean[3 * bin + 1] =
mean[3 * bin + 2] = 1;
621 outpixpercent = (
double) 100 * numoutpix / numbins;
623 if (outpixpercent < threshold) {
624 fprintf(
stderr,
"Number of output pixels (%u of a possible %u) ",
627 "< threshold (%.2lf%%). Output image not generated.\n",
635 if (strcmp(
input->oformat,
"PPM") == 0) {
636 if ((outfp = fopen(outfile,
"w")) ==
NULL) {
637 printf(
"%s: Error: Unable to open %s for writing.\n",
641 fprintf(outfp,
"P6\n");
642 fprintf(outfp,
"%d\n", width);
643 fprintf(outfp,
"%d\n", height);
644 fprintf(outfp,
"255\n");
645 fwrite(
mean, 3, numbins, outfp);
649 }
else if (strcmp(
input->oformat,
"PNG") == 0) {
650 if ((outfp = fopen(outfile,
"w")) ==
NULL) {
651 printf(
"%s: Error: Unable to open %s for writing.\n",
656 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
659 fprintf(
stderr,
"%s: Error: Unable to create PNG write structure.\n", argv[0]);
663 png_infop info_ptr = png_create_info_struct(png_ptr);
665 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
666 fprintf(
stderr,
"%s: Error: Unable to create PNG info structure.\n", argv[0]);
669 if (setjmp(png_jmpbuf(png_ptr))) {
670 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
671 fprintf(
stderr,
"%s: Error: Unable to call PNG setjmp().\n", argv[0]);
674 png_init_io(png_ptr, outfp);
676 uint8_t * row_pointers[height];
677 for (
i = 0;
i < height;
i++)
678 row_pointers[
i] =
mean + (
i * width * 3);
679 png_set_rows(png_ptr, info_ptr, row_pointers);
681 png_set_IHDR(png_ptr, info_ptr, width, height,
682 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
683 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
685 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY,
NULL);
688 png_destroy_write_struct(&png_ptr, (png_infopp)
NULL);
692 }
else if (strcmp(
input->oformat,
"TIFF") == 0) {
696 tiff = XTIFFOpen(outfile,
"w");
698 fprintf(
stderr,
"Could not open outgoing image\n");
701 gtif = GTIFNew(tiff);
703 fprintf(
stderr,
"Could not create geoTIFF structure\n");
708 TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
709 TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
711 TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
712 TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
713 TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
714 TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
717 double tiepoints[6] = {0, 0, 0, 0, 0, 0};
718 double pixscale[3] = {0, 0, 0};
721 pixscale[0] = (east - west) / width;
724 pixscale[1] = (north - south) / height;
728 tiepoints[4] = north;
730 TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
731 TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
734 GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
735 GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
736 GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
741 if (TIFFWriteEncodedStrip(tiff, 0,
mean, width * height * 3) == 0) {
742 fprintf(
stderr,
"Could not write TIFF image\n");
751 fprintf(
stderr,
"%s Error: oformat=%s not valid.\n", argv[0],
input->oformat);
822 register EdgeTableEntry *pAET;
824 register int nPts = 0;
825 register EdgeTableEntry *pWETE;
826 register ScanLineList *pSLL;
827 register XPoint *ptsOut;
831 EdgeTableEntry *pPrevAET;
834 EdgeTableEntry *pETEs;
835 ScanLineListBlock SLLBlock;
840 (EdgeTableEntry *) malloc(
sizeof (EdgeTableEntry) *
count))) {
859 if (pSLL &&
y == pSLL->scanline) {
878 ptsOut->x = pAET->bres.minor;
880 *wdth++ = pAET->nextWETE->bres.minor - pAET->bres.minor;
893 pWETE = pWETE->nextWETE;
894 while (pWETE != pAET)
896 pWETE = pWETE->nextWETE;
921 XPoint * initial_point,
int *span_width) {
930 for (
i = 0;
i < number_of_initial_points;
i++) {
932 y = initial_point[
i].y;
933 if (
y >= height ||
y < 0)
936 for (
x = initial_point[
i].
x,
937 end = initial_point[
i].
x + span_width[
i];
x < end;
x++) {
938 if (
x >= width ||
x < 0)
940 if (numoverlain >= binsperpixel) {
941 binsperpixel += 1024;
943 (
int *) realloc(binsoverlain,
944 binsperpixel *
sizeof (
int));
945 if (binsoverlain ==
NULL) {
946 fprintf(
stderr,
"-E- %s line %d: ", __FILE__, __LINE__);
948 "Memory allocation error (numoverlain=%d binsperpixel=%d\n",
949 numoverlain, binsperpixel);
954 binsoverlain[numoverlain++] =
y * width +
x;