ocssw  1.0
/disk01/web/ocssw/build/src/landbin/landtimebin.c (r8099/r4879)
Go to the documentation of this file.
00001 /*
00002     Modification history:
00003     Programmer       Organization      Date      Description of change
00004     --------------   ------------    --------    ---------------------
00005     Joel Gales       Futuretech      05/07/01    Original Development
00006 
00007 */
00008 
00009 
00010 #include <stdio.h>
00011 #include <math.h>
00012 #include <string.h>
00013 #include <time.h>
00014 #include "hdf.h"
00015 #include "mfhdf.h"
00016 
00017 int main (int argc, char *argv[])
00018 {
00019 
00020   int32 i;
00021   int32 j;
00022   int32 k;
00023   int32 sds_id;
00024   int32 dims[8];
00025   int32 rank;
00026   int32 dtype;
00027   int32 nattrs;
00028   int32 status;
00029 
00030   int32 HDFfid;
00031 
00032   static char buffer[2048];
00033   static char attr_buf[2048];
00034   char  *data;
00035   char  *data_w;
00036   char  *str_ptr;
00037   char  *comma;
00038   char  *tmp_str;
00039   int16 *eval_flds;
00040   int16 *fileindex[3];
00041   unsigned char *n_water_pix;
00042 
00043   int32 nfiles;
00044   int32 scan;
00045   int32 nscan;
00046   int32 ncol;
00047   int32 offset;
00048   int32 *HDFfid_r;
00049   int32 *sd_id_r;
00050   int32 HDFfid_w;
00051   int32 sd_id_w;
00052   int32 sds_id_w;
00053   int32 ndatasets;
00054   int32 nglobal_attr;
00055   int32 count;
00056   int32 dim_id_r;
00057   int32 dim_id_w;
00058   int32 start[2]={0,0};
00059   int32 start_w[2]={0,0};
00060   int32 edges[2]={0,0};
00061   int32 input_file_index;
00062   int32 mask_row_off=0;
00063   int32 mask_col_off=0;
00064   int32 sub_scan[2]={0,0};
00065   int32 sub_pixl[2]={0,0};
00066   int32 water_min=1000;
00067 
00068   int16 fillvalue = -32767;
00069   int16 water_val = -16384;
00070   int16 eval_flds_flag;
00071 
00072   int16 f_index;
00073   int16 f_ndvi;
00074   int16 f_blue;
00075 
00076   int16   icol, irow;
00077   float32 NIRreldiff, NIRness;
00078   float64 val1, val2, sum, weigh;
00079   float64 v1,v2;
00080 
00081 
00082   int16 maxNDVI = 0;
00083   int16 minBLUE = 1;
00084 
00085   int16 RADIUS = 2;
00086   int16 NEVALFLD = 4;
00087   int16 FILE_BSIZ = NEVALFLD*(2*RADIUS+1);
00088   int16 FIELD_BSIZ = 2*RADIUS+1;
00089 
00090   int16 NDVI = 0 * FIELD_BSIZ;
00091   int16 BLUE = 1 * FIELD_BSIZ;
00092   int16 RED  = 2 * FIELD_BSIZ;
00093   int16 NIR  = 3 * FIELD_BSIZ;
00094 
00095   int32 eval_flds_index[NEVALFLD];
00096 
00097   time_t tnow;
00098   struct tm *tmnow;
00099 
00100   FILE *fp, *mask_4km;
00101 
00102   double R3(double x);
00103 
00104   setlinebuf(stdout);
00105 
00106   printf("landtimebin V2.31 (02/12/02)\n");
00107 
00108   if (argc == 1) {
00109     printf("landtimebin <File containing list of input landbin files> <Output landbin file> <NDVI/BLUE/HYBRID>");
00110     return 0;
00111   }
00112 
00113   /* Determine number of input files */
00114   /* ------------------------------- */
00115   nfiles = 0;
00116   fp = fopen(argv[1], "r");
00117   if (fp == NULL) {
00118     printf("Input listing file: \"%s\" not found.\n", argv[1]);
00119     return -1;
00120   }
00121   while(fgets(buffer, 256, fp) != NULL) nfiles++;
00122   fclose(fp);
00123   printf("%d input files\n", nfiles);
00124 
00125 
00126   /* Open input files and initialize HDF interface */
00127   /* --------------------------------------------- */
00128   HDFfid_r = (int32 *) calloc(nfiles, sizeof(int32));
00129   sd_id_r = (int32 *) calloc(nfiles, sizeof(int32));
00130 
00131   fp = fopen(argv[1], "r");
00132   for (i=0; i<nfiles; i++) {
00133     fgets(buffer, 256, fp);
00134     buffer[strlen(buffer)-1] = 0;
00135     HDFfid_r[i] = Hopen(buffer, DFACC_READ, 0);
00136     if (HDFfid_r[i] == -1) {
00137       printf("Input file: \"%s\" not found.\n", buffer);
00138       return -1;
00139     }
00140     status = Vstart(HDFfid_r[i]);
00141     sd_id_r[i] = SDstart(buffer, DFACC_RDONLY);
00142 
00143     j = SDfindattr(sd_id_r[i], "Subset Scan Range");
00144     if (j != -1) status = SDreadattr(sd_id_r[i], j, (VOIDP) &sub_scan);
00145 
00146     j = SDfindattr(sd_id_r[i], "Subset Pixel Range");
00147     if (j != -1) status = SDreadattr(sd_id_r[i], j, (VOIDP) &sub_pixl);
00148   }
00149   fclose(fp);
00150 
00151 
00152   /* Create output HDF file */
00153   /* ---------------------- */
00154   HDFfid_w = Hopen(argv[2], DFACC_CREATE, 0);
00155   status = Vstart(HDFfid_w);
00156   sd_id_w = SDstart(argv[2], DFACC_RDWR);
00157 
00158 
00159   /* Set compositing flag */
00160   /* -------------------- */
00161   if (argc == 3 || (strcmp(argv[3], "NDVI") == 0))
00162     eval_flds_flag = 0;
00163   else if (strcmp(argv[3], "BLUE") == 0)
00164      eval_flds_flag = 1;
00165   else if (strcmp(argv[3], "HYBRID") == 0)
00166      eval_flds_flag = 2;
00167 
00168   printf("eval_flds_flag: %d\n", eval_flds_flag);
00169 
00170 
00171   /* Get # of scans and allocate dynamic arrays */
00172   /* ------------------------------------------ */
00173   sds_id = SDselect(sd_id_r[0], 0);
00174   status = SDgetinfo(sds_id, buffer, &rank, dims, &dtype, &nattrs);
00175   SDendaccess(sds_id);
00176   nscan = dims[0];
00177   ncol  = dims[1];
00178   data = (char *) calloc(nfiles * ncol * 2, sizeof(char));
00179   data_w = (char *) calloc(ncol * 2, sizeof(char));
00180   eval_flds = (int16 *) calloc(nfiles * ncol * FILE_BSIZ, sizeof(int16));
00181 
00182   n_water_pix = (unsigned char *) calloc(8640*FIELD_BSIZ, sizeof(unsigned char));
00183 
00184   printf("%d\n", argc);
00185   if (argc > 4) {
00186     water_min = atol(argv[4]);
00187   }
00188   printf("water_min: %4d\n", water_min);
00189 
00190   fileindex[0] = (int16 *) calloc(ncol*FIELD_BSIZ, sizeof(int16));
00191   fileindex[1] = (int16 *) calloc(ncol*FIELD_BSIZ, sizeof(int16));
00192   fileindex[2] = (int16 *) calloc(ncol*FIELD_BSIZ, sizeof(int16));
00193 
00194 
00195   /* Determine number of datasets in input files */
00196   /* ------------------------------------------- */
00197   SDfileinfo(sd_id_r[0], &ndatasets, &nglobal_attr);
00198 
00199 
00200   /* For each dataset in input file, create corresponding dataset in output file */
00201   /* --------------------------------------------------------------------------- */
00202   for (j=0; j<ndatasets; j++) {
00203     sds_id = SDselect(sd_id_r[0], j);
00204     status = SDgetinfo(sds_id, buffer, &rank, dims, &dtype, &nattrs);
00205     sds_id_w = SDcreate(sd_id_w, buffer, dtype, rank, dims);
00206 
00207 
00208     /* Find index number of compositing dataset */
00209     /* ---------------------------------------- */
00210     if (strcmp(buffer, "NDVI") == 0)     eval_flds_index[0] = j;
00211     if (strcmp(buffer, "refl_443") == 0) eval_flds_index[1] = j;
00212     if (strcmp(buffer, "refl_670") == 0) eval_flds_index[2] = j;
00213     if (strcmp(buffer, "refl_865") == 0) eval_flds_index[3] = j;
00214     if (strcmp(buffer, "input_file") == 0) input_file_index = j;
00215 
00216 
00217     /* Copy dataset attributes */
00218     /* ----------------------- */
00219     for (i=0; i<nattrs; i++) {
00220       status = SDreadattr(sds_id, i, (VOIDP) attr_buf);
00221       status = SDattrinfo(sds_id, i, buffer, &dtype, &count);
00222       status = SDsetattr(sds_id_w, buffer, dtype, count, (VOIDP) attr_buf);
00223     }
00224 
00225 
00226     /* Set output file dim names */
00227     /* ------------------------- */
00228     for (i=0; i<rank; i++) {
00229       dim_id_r = SDgetdimid(sds_id, i);
00230       dim_id_w = SDgetdimid(sds_id_w, i);
00231       SDdiminfo(dim_id_r, buffer, &count, &dtype, &nattrs);
00232       SDsetdimname(dim_id_w, buffer);
00233     }
00234 
00235     SDendaccess(sds_id_w);
00236     SDendaccess(sds_id);
00237   }
00238 
00239 
00240   /* Open 4km water pixel mask */
00241   /* ------------------------- */
00242   i = SDfindattr(sd_id_r[0], "Projection");
00243   status = SDattrinfo(sd_id_r[0], i, buffer, &dtype, &count);
00244   status = SDreadattr(sd_id_r[0], i, (VOIDP) attr_buf);
00245 
00246   tmp_str = getenv("OCDATAROOT");
00247   if (tmp_str == 0x0) {
00248     printf("Environment variable OCDATAROOT not defined.\n");
00249     exit(1);
00250   }
00251   strcpy(buffer, tmp_str);
00252 
00253   if (strcmp(attr_buf, "Plate Carree") == 0) {
00254     strcat(buffer, "/common/water_pix_4km_platte_carre.dat");
00255     mask_4km = fopen(buffer, "rb");
00256     if (mask_4km == 0x0) {
00257       printf("Water mask file: %s not found.\n", buffer);
00258       exit (1);
00259     }
00260   }
00261 
00262   if (strcmp(attr_buf, "Sinusoidal") == 0) {
00263     strcat(buffer, "/common/water_pix_4km_sinusoidal.dat");
00264     mask_4km = fopen(buffer, "rb");
00265     if (mask_4km == 0x0) {
00266       printf("Water mask file: %s not found.\n", buffer);
00267       exit (1);
00268     }
00269   }
00270 
00271 
00272   i = SDfindattr(sd_id_r[0], "Command line");
00273   status = SDattrinfo(sd_id_r[0], i, buffer, &dtype, &count);
00274   status = SDreadattr(sd_id_r[0], i, (VOIDP) attr_buf);
00275   str_ptr = strstr(attr_buf, "-box");
00276   if (str_ptr != 0x0) {
00277     str_ptr += 5;
00278     comma = strstr(str_ptr, ",");
00279     *comma = 0;
00280     mask_col_off = atoi(str_ptr);
00281     str_ptr = comma+1;
00282     comma = strstr(str_ptr, ",");
00283     *comma = 0;
00284     mask_row_off = atoi(str_ptr);
00285   }
00286 
00287 
00288   /* For each scan ... */
00289   /* ----------------- */
00290   offset = RADIUS;
00291   edges[1] = ncol;
00292 
00293   for (scan=0; scan<nscan; scan++) {
00294 
00295     if ((scan % 200) == 0) {
00296       time(&tnow);
00297       tmnow = localtime(&tnow);
00298       printf("Scan:%6d %s", scan, asctime(tmnow));
00299     }
00300 
00301     /* Read compositing dataset from each input file */
00302     /* --------------------------------------------- */
00303     if (scan == 0) {
00304       start[0] = scan;
00305       edges[0] = RADIUS + 1;
00306     }
00307     else if (scan < nscan-2) {
00308       start[0] = scan + RADIUS;
00309       edges[0] = 1;
00310     }
00311     else {
00312       goto DATA_WRITE;
00313     }
00314 
00315     for (i=0; i<nfiles; i++) {
00316       for (j=0; j<NEVALFLD; j++) {
00317     sds_id = SDselect(sd_id_r[i], eval_flds_index[j]);
00318     status = SDgetinfo(sds_id, buffer, &rank, dims, &dtype, &nattrs);
00319 
00320     status = SDreaddata(sds_id, start, NULL, edges, 
00321                 (VOIDP) &eval_flds[(FILE_BSIZ*i+FIELD_BSIZ*j+offset)*ncol]);
00322       }
00323     } /* file loop */
00324 
00325 
00326 
00327     /* Read 4km land/water/mixed mask */
00328     /* ------------------------------ */
00329     fseek(mask_4km, (mask_row_off + start[0]) * 8640, SEEK_SET);
00330     fread(&n_water_pix[8640*offset], edges[0] * 8640, 1, mask_4km);
00331 
00332 
00333     /* Determine file index for compositing */
00334     /* ------------------------------------ */
00335     for (k=offset; k<FIELD_BSIZ; k++) {
00336       for (j=0; j<ncol; j++) {
00337     fileindex[maxNDVI][ncol*k+j] = 0;
00338     fileindex[minBLUE][ncol*k+j] = 0;
00339       }
00340     }
00341 
00342 
00343     /* Max NDVI fileindex */
00344     /* ------------------ */
00345     for (k=offset; k<FIELD_BSIZ; k++) {
00346       for (i=1; i<nfiles; i++) {
00347     for (j=0; j<ncol; j++) {
00348       f_index = fileindex[maxNDVI][ncol*k+j];
00349       if (eval_flds[ncol*(FILE_BSIZ*i       + NDVI + k) + j] > 
00350           eval_flds[ncol*(FILE_BSIZ*f_index + NDVI + k) + j]) 
00351         fileindex[maxNDVI][ncol*k+j] = i;
00352     }
00353       }
00354     }
00355 
00356     /* Min Blue fileindex */
00357     /* ------------------ */
00358     for (k=offset; k<FIELD_BSIZ; k++) {
00359       for (i=1; i<nfiles; i++) {
00360     for (j=0; j<ncol; j++) {
00361       f_index = fileindex[minBLUE][ncol*k+j];
00362 
00363       if (eval_flds[ncol*(FILE_BSIZ*f_index + BLUE + k) + j] < 0 &&
00364           eval_flds[ncol*(FILE_BSIZ*i + BLUE + k) + j] >= 0)
00365         fileindex[minBLUE][ncol*k+j] = i;
00366 
00367       if (eval_flds[ncol*(FILE_BSIZ*f_index + BLUE + k) + j] >= 0 &&
00368           eval_flds[ncol*(FILE_BSIZ*i       + BLUE + k) + j] >= 0 &&
00369           eval_flds[ncol*(FILE_BSIZ*i + RED + k) + j] >= 0 &&
00370           (eval_flds[ncol*(FILE_BSIZ*i       + BLUE + k) + j] < 
00371            eval_flds[ncol*(FILE_BSIZ*f_index + BLUE + k) + j]))
00372         fileindex[minBLUE][ncol*k+j] = i;
00373 
00374       if (eval_flds[ncol*(FILE_BSIZ*f_index + RED + k) + j] < 0 &&
00375           eval_flds[ncol*(FILE_BSIZ*i       + RED + k) + j] < 0 &&
00376           (eval_flds[ncol*(FILE_BSIZ*i       + RED + k) + j] >
00377            eval_flds[ncol*(FILE_BSIZ*f_index + RED + k) + j]))
00378         fileindex[minBLUE][ncol*k+j] = i;
00379 
00380     }
00381       }
00382     }
00383 
00384 
00385     /* Fill Value Handling */
00386     /* ------------------- */
00387     for (k=offset; k<FIELD_BSIZ; k++) {
00388       for (j=0; j<ncol; j++) {
00389 
00390     f_index = fileindex[maxNDVI][ncol*k+j];
00391     if (eval_flds[ncol*(FILE_BSIZ*f_index + NDVI + k) + j] == -32767) 
00392       fileindex[maxNDVI][ncol*k+j] = fillvalue;
00393 
00394     f_index = fileindex[minBLUE][ncol*k+j];
00395     if (eval_flds[ncol*(FILE_BSIZ*f_index + BLUE + k) + j] < 0) 
00396       fileindex[minBLUE][ncol*k+j] = fillvalue;
00397       }
00398     }
00399 
00400 
00401 
00402     if (eval_flds_flag != 2) goto DATA_WRITE;
00403 
00404 
00405     /* HYBRID */
00406     /* ------ */
00407     for (j=0; j<ncol; j++) {
00408 
00409       f_ndvi = fileindex[maxNDVI][ncol*RADIUS+j];
00410       f_blue = fileindex[minBLUE][ncol*RADIUS+j];
00411 
00412       fileindex[2][ncol*RADIUS+j] = f_blue;
00413       
00414       if (f_blue != fillvalue && 
00415       f_ndvi != fillvalue && 
00416       n_water_pix[(8640*offset)+(mask_col_off+j)] == 0 &&
00417       eval_flds[ncol*(FILE_BSIZ*f_ndvi + NIR  + RADIUS) + j] != fillvalue &&
00418       eval_flds[ncol*(FILE_BSIZ*f_blue + NIR  + RADIUS) + j] != fillvalue &&
00419       eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j] != fillvalue) {
00420 
00421     if (eval_flds[ncol*(FILE_BSIZ*f_blue + NIR + RADIUS) + j] != 0) {
00422       NIRreldiff = ((eval_flds[ncol*(FILE_BSIZ*f_ndvi + NIR + RADIUS) + j] -
00423              eval_flds[ncol*(FILE_BSIZ*f_blue + NIR + RADIUS) + j]) /
00424             fabs(eval_flds[ncol*(FILE_BSIZ*f_blue + NIR + RADIUS) + j]));
00425     } else {
00426       NIRreldiff = 1.0;
00427     }
00428 
00429     if (eval_flds[ncol*(FILE_BSIZ*f_blue + BLUE + RADIUS) + j] != 0 &&
00430         eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j] != 0) {
00431     
00432       if (NIRreldiff > 0.10) {
00433         val1 = 0;
00434         val2 = 0;
00435         sum = 0;
00436 
00437         for (irow=0; irow<2*RADIUS+1; irow++) {
00438         
00439           for (icol=j-RADIUS; icol<=j+RADIUS; icol++) {
00440         if (icol < 0 || icol > ncol) break;
00441 
00442         weigh = R3(fabs(0.5 * (irow-RADIUS))) * R3(fabs(0.5 * (icol-j)));
00443         sum += weigh;
00444 
00445         f_ndvi = fileindex[maxNDVI][ncol*irow+icol];
00446         f_blue = fileindex[minBLUE][ncol*irow+icol];
00447 
00448         if (f_ndvi != fillvalue) 
00449           v1 = weigh * eval_flds[ncol*(FILE_BSIZ*f_ndvi + NIR + irow) + icol];
00450         else
00451           v1 = 0.0;
00452 
00453         if (f_blue != fillvalue) 
00454           v2 = weigh * eval_flds[ncol*(FILE_BSIZ*f_blue + NIR + irow) + icol];
00455         else
00456           v2 = 0.0;
00457 
00458         if (v1 < 0.0) v1 = 0.0;
00459         if (v2 < 0.0) v2 = 0.0;
00460 
00461         val1 += v1;
00462         val2 += v2;
00463 
00464           } /* icol loop */
00465         } /* irow loop */
00466         
00467         if (sum > 0) {
00468           val1 /= sum;
00469           val2 /= sum;
00470         }
00471 
00472 
00473         f_ndvi = fileindex[maxNDVI][ncol*RADIUS+j];
00474         f_blue = fileindex[minBLUE][ncol*RADIUS+j];
00475 
00476         NIRness = (eval_flds[ncol*(FILE_BSIZ*f_ndvi + NIR  + RADIUS) + j] -
00477                eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j]) /
00478           fabs(eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j]);
00479 
00480         if (fabs(NIRness) > 0.2 &&
00481         eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j] < 2500 &&
00482         fabs(val1 - eval_flds[ncol*(FILE_BSIZ*f_ndvi + NIR + RADIUS) + j]) <=
00483         fabs(val2 - eval_flds[ncol*(FILE_BSIZ*f_blue + NIR + RADIUS) + j]) &&
00484 
00485         (eval_flds[ncol*(FILE_BSIZ*f_ndvi + NDVI + RADIUS) + j] < 3000 ||
00486          eval_flds[ncol*(FILE_BSIZ*f_ndvi + BLUE + RADIUS) + j] <  500 ||
00487          eval_flds[ncol*(FILE_BSIZ*f_blue + NIR  + RADIUS) + j] == 0)) {
00488           fileindex[2][ncol*RADIUS+j] = f_ndvi;
00489         }
00490         
00491       } /* (NIRreldiff > 0.10) */
00492     }
00493       }
00494       
00495     } /* HYBRID col loop */
00496 
00497 
00498 
00499   DATA_WRITE:
00500 
00501     start[0] = scan;
00502     edges[0] = 1;
00503 
00504     /* For each dataset ... */
00505     /* -------------------- */
00506     for (j=0; j<ndatasets; j++) {
00507       sds_id = SDselect(sd_id_r[0], j);
00508       status = SDgetinfo(sds_id, buffer, &rank, dims, &dtype, &nattrs);
00509       SDendaccess(sds_id);
00510 
00511       if (strcmp(buffer, "input_file") == 0) {
00512     memcpy(&data_w[0], &fileindex[eval_flds_flag][ncol*RADIUS], 2*ncol);
00513       }
00514       else {
00515     /* For each file read dataset */
00516     /* -------------------------- */
00517     for (i=0; i<nfiles; i++) {
00518       sds_id = SDselect(sd_id_r[i], j);
00519       edges[1] = ncol;
00520       status = SDreaddata(sds_id, start, NULL, edges, 
00521                   (VOIDP) &data[2*i*ncol]);
00522       SDendaccess(sds_id);
00523     }
00524 
00525     /* Store compositing data in write buffer */
00526     /* -------------------------------------- */
00527     for (i=0; i<ncol; i++) {
00528       if (fileindex[eval_flds_flag][ncol*RADIUS+i] == fillvalue) {
00529         memcpy(&data_w[2*i], &fillvalue, 2);
00530       }
00531 
00532       /* mask water and mixed with water val = -16384 (JMG) */
00533 
00534       else if (n_water_pix[(8640*offset)+(mask_col_off+i)] >= water_min) {
00535         memcpy(&data_w[2*i], &water_val, 2);
00536       }
00537       else { 
00538         memcpy(&data_w[2*i], &data[2*(fileindex[eval_flds_flag][ncol*RADIUS+i]*ncol+i)], 2);
00539       }
00540     }
00541       } /* if "input_file" */
00542 
00543       /* Write to output file */
00544       sds_id_w = SDselect(sd_id_w, j);
00545       status = SDwritedata(sds_id_w, start, NULL, edges, (VOIDP) data_w);
00546       SDendaccess(sds_id_w);
00547     } /* dataset loop */
00548 
00549 
00550     /* Rotate Arrays */
00551     /* ------------- */
00552     for (k=1; k<FIELD_BSIZ; k++) {
00553       for (i=0; i<nfiles; i++) {
00554     memcpy(&eval_flds[ncol*(FILE_BSIZ*i + NDVI + (k-1))],
00555            &eval_flds[ncol*(FILE_BSIZ*i + NDVI + k)],
00556            ncol*sizeof(int16));
00557 
00558     memcpy(&eval_flds[ncol*(FILE_BSIZ*i + BLUE + (k-1))],
00559            &eval_flds[ncol*(FILE_BSIZ*i + BLUE + k)],
00560            ncol*sizeof(int16));
00561 
00562     memcpy(&eval_flds[ncol*(FILE_BSIZ*i + NIR + (k-1))],
00563            &eval_flds[ncol*(FILE_BSIZ*i + NIR + k)],
00564            ncol*sizeof(int16));
00565       }
00566 
00567       memcpy(&fileindex[maxNDVI][ncol*(k-1)],
00568          &fileindex[maxNDVI][ncol*k],
00569          ncol*sizeof(int16));
00570 
00571       memcpy(&fileindex[minBLUE][ncol*(k-1)],
00572          &fileindex[minBLUE][ncol*k],
00573          ncol*sizeof(int16));
00574 
00575       memcpy(&n_water_pix[8640*(k-1)],
00576          &n_water_pix[8640*k],
00577          8640*sizeof(int16));
00578     }
00579 
00580     offset = 2 * RADIUS;
00581 
00582 
00583   } /* scan loop */
00584 
00585 
00586   /* Write Global Attributes */
00587   /* ----------------------- */
00588   i = SDfindattr(sd_id_r[0], "Projection");
00589   status = SDattrinfo(sd_id_r[0], i, buffer, &dtype, &count);
00590   status = SDreadattr(sd_id_r[0], i, (VOIDP) attr_buf);
00591   status = SDsetattr(sd_id_w, buffer, dtype, count, (VOIDP) attr_buf);
00592 
00593   i = SDfindattr(sd_id_r[0], "Pixel size (meters)");
00594   status = SDattrinfo(sd_id_r[0], i, buffer, &dtype, &count);
00595   status = SDreadattr(sd_id_r[0], i, (VOIDP) attr_buf);
00596   status = SDsetattr(sd_id_w, buffer, dtype, count, (VOIDP) attr_buf);
00597 
00598   i = SDfindattr(sd_id_r[0], "Compositing criterion");
00599   status = SDattrinfo(sd_id_r[0], i, buffer, &dtype, &count);
00600   status = SDreadattr(sd_id_r[0], i, (VOIDP) attr_buf);
00601   status = SDsetattr(sd_id_w, buffer, dtype, count, (VOIDP) attr_buf);
00602 
00603    if ((sub_scan[0] !=0) || (sub_scan[1] != 0) ||
00604        (sub_pixl[0] !=0) || (sub_pixl[1] != 0)) {
00605      status = SDsetattr(sd_id_w, "Subset Scan Range", DFNT_INT32, 2, sub_scan);
00606      status = SDsetattr(sd_id_w, "Subset Pixel Range", DFNT_INT32, 2,&sub_pixl);
00607    }
00608 
00609   fp = fopen(argv[1], "r");
00610   attr_buf[0] = 0;
00611   while(fgets(buffer, 256, fp) != NULL) {
00612     buffer[strlen(buffer)-1] = 0;
00613     strcat(buffer, "\n,");
00614     strcat(attr_buf, buffer);
00615   }
00616   fclose(fp);
00617   attr_buf[strlen(attr_buf)-1] = 0;
00618   SDsetattr(sd_id_w, "File list", DFNT_CHAR8, (int)strlen(attr_buf) + 1, attr_buf);
00619 
00620 
00621 
00622   /* Close input files */
00623   /* ----------------- */
00624   for (i=0; i<nfiles; i++) {
00625     SDend(sd_id_r[i]);
00626     Hclose(HDFfid_r[i]);
00627     Vend(HDFfid_r[i]);
00628   }
00629   free(HDFfid_r);
00630   free(sd_id_r);
00631   free(data);
00632   free(data_w);
00633   free(eval_flds);
00634   free(fileindex[0]);
00635   free(fileindex[1]);
00636   free(fileindex[2]);
00637   free(n_water_pix);
00638 
00639 
00640   /* Close output file */
00641   /* ----------------- */
00642   SDend(sd_id_w);
00643   Hclose(HDFfid_w);
00644   Vend(HDFfid_w);
00645 
00646   fclose(mask_4km);
00647 
00648   return 0;
00649 }
00650 
00651 
00652 
00653 double R3(double x)
00654 {
00655   if (x < 0  ||  x >= 2)
00656     return 0;
00657   else if (x <= 1)                              /* 0 <= x <= 1 */
00658     return 2 / 3. + x * x * x / 2. - x * x;
00659   else                                          /* 1 <= x <= 2 */
00660     return (2 - x) * (2 - x) * (2 - x) / 6;
00661 }
00662 
00663