Exemple #1
0
void deskew(const char *infile, const char *outfile)
{
    meta_parameters *meta = meta_read(infile);

    int nl = meta->general->line_count;
    int np = meta->general->sample_count;
    int nb = meta->general->band_count;
    char **band_name = extract_band_names(meta->general->bands, nb);
    int band, line, samp, deskewed = meta->sar->deskewed != 0;

    if (!meta->sar)
        asfPrintError("Cannot deskew data without a sar block!\n");

    char *tmp_outfile;
    int do_rename = FALSE;
    if (strcmp(infile, outfile) == 0 && nb>1) {
        // user wants to deskew in-place
        // we can't actually do that on multi-band data, too much to keep in memory
        // use a temporary file, then clobber input file
        tmp_outfile = appendToBasename(outfile, "_tmp");
        do_rename = TRUE;
    } else {
        // normal case: either
        // 1) single-band in-place deskew
        // 2) not in-place deskew (single or multi)
        tmp_outfile = STRDUP(outfile);
    }

    // calculate the amount of shift necessary
    double fac = calc_shift(meta, 0, 0);
    // Not sure if we need this or not...
    //fac *= meta->general->x_pixel_size / meta->general->y_pixel_size;

    // the "lower" array stores the required shifts, indexed by column
    // (the amount of shift is row-independent)
    int *lower = MALLOC(np * sizeof(int));
    for (samp=0; samp<np; ++samp)
        lower[samp] = (int) floor(fac*(double)samp);

    if (meta->sar->deskewed) {
        asfPrintStatus("Data is already deskewed.\n");
    } else {
        asfPrintStatus("Far-range shift amount: ");
        if (lower[np-1] > 0)
            asfPrintStatus("%d pixels down.\n", lower[np-1]);
        else
            asfPrintStatus("%d pixels up.\n", -lower[np-1]);
    }

    float *ibuf = MALLOC(np * sizeof(float));
    float *obuf = CALLOC(np*nl, sizeof(float));

    FILE *fpi = fopenImage(infile, "rb");

    for (band=0; band<nb; ++band) {
        if (nb>1)
            asfPrintStatus("Deskewing band: %s\n", band_name[band]);

        // apply deskewing to this band
        for (line=0; line<nl; ++line) {
            get_float_line(fpi, meta, line + nl*band, ibuf);

            for (samp=0; samp<np; ++samp) {
                int out_line = deskewed ? line : line + lower[samp];
                if (out_line >= 0 && out_line < nl)
                    obuf[out_line*np+samp] = ibuf[samp];
            }

            asfLineMeter(line,nl);
        }

        // write out this band
        FILE *fpo = fopenImage(tmp_outfile, band>0 ? "ab" : "wb");
        put_float_lines(fpo, meta, band*nl, nl, obuf);
        FCLOSE(fpo);
    }

    FCLOSE(fpi);
    FREE(obuf);
    FREE(ibuf);
    FREE(lower);

    // if we output to a temporary file, clobber the input
    if (do_rename) {
        char *tmp_outfile_img = appendExt(tmp_outfile, ".img");
        char *outfile_img = appendExt(outfile, ".img");
        //printf("Renaming: %s -> %s\n", tmp_outfile_img, outfile_img);
        rename(tmp_outfile_img, outfile_img);
        FREE(tmp_outfile_img);
        FREE(outfile_img);
    }
    FREE(tmp_outfile);

    // only need to update the deskewed flag in the metadata
    meta->sar->deskewed = 1;
    meta_write(meta, outfile);
    meta_free(meta);
}
Exemple #2
0
int main(int argc, char **argv)
{
  double min, max;             /* Minimum & maximum sample values       */
  double sum_of_samples=0.0;   /* Sum of all samples accounted for      */
  double sum_of_squared_samples=0.0; /* Sum of all squared samples accounted for*/
  double trim_fraction;        /* Fraction used to trim the histogram   */
  int ii;                      /* Loop index                            */
  long samples_counted=0;      /* Number of all samples accounted for   */
  float *data_line;           /* Buffer for a line of samples          */
  long line, sample;            /* Line and sample indices               */
  long num_lines, num_samples;  /* Number of lines and samples           */
  int percent_complete=0;      /* Percent of data sweep completed       */
  int overmeta_flag=FALSE;     /* If TRUE write over current .meta file */
  int overstat_flag=FALSE;     /* If TRUE write over current .stat file */
  int nometa_flag=FALSE;       /* If TRUE do not write .meta file       */
  int nostat_flag=FALSE;       /* If TRUE do not write .stat file       */
  int mask_flag=FALSE;         /* TRUE if user specifies a mask value   */
  int trim_flag=FALSE;         /* If TRUE trim histogram                */
  double mask=NAN;             /* Value to ignore while caculating stats*/
  char meta_name[261];         /* Meta file name                        */
  meta_parameters *meta;       /* SAR meta data structure               */
  char sar_name[256];          /* SAR file name WITH extention          */
  FILE *sar_file;              /* SAR data file pointer to take stats on*/
  stat_parameters *stats;      /* Statistics structure                  */
  char stat_name[261];         /* Stats file name                       */
  extern int currArg;          /* Pre-initialized to 1                  */

  /* We initialize these to a magic number for checking. */
  long start_line = -1;         /* Window starting line.                 */
  long start_sample = -1;       /* Window starting sample.               */
  long window_height = -1;      /* Window height in lines.               */
  long window_width = -1;       /* Window width in samples.              */

/* parse command line */
  handle_license_and_version_args(argc, argv, "stats");
  logflag=quietflag=FALSE;
  while (currArg < (argc-1)) {
    char *key = argv[currArg++];
    if (strmatch(key,"-quiet")) {
      quietflag=TRUE;
    }
    else if (strmatch(key,"-log")) {
      CHECK_ARG(1);
      strcpy(logFile,GET_ARG(1));
      fLog = FOPEN(logFile, "a");
      logflag=TRUE;
    }
    else if (strmatch(key,"-mask")) {
      CHECK_ARG(1);
      mask = atof(GET_ARG(1));
      mask_flag=TRUE;
    }
    else if (strmatch(key,"-overmeta")) {
      overmeta_flag=TRUE;
    }
    else if (strmatch(key,"-overstat")) {
      overstat_flag=TRUE;
    }
    else if (strmatch(key,"-nometa")) {
      nometa_flag=TRUE;
    }
    else if (strmatch(key,"-nostat")) {
      nostat_flag=TRUE;
    }
    else if (strmatch(key,"-startline")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      start_line = atol(GET_ARG(1));
      if ( start_line < 0 ) {
        printf("error: -startline argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-startsample")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      start_sample = atol(GET_ARG(1));
      if ( start_sample < 0 ) {
        printf("error: -startsample argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-width")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      window_width = atol(GET_ARG(1));
      if ( window_width < 0 ) {
        printf("error: -width argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-height")) {
      CHECK_ARG(1);
      nometa_flag=TRUE; /* Implied.  */
      window_height = atol(GET_ARG(1));
      if ( window_height < 0 ) {
        printf("error: -height argument must be greater than or equal to zero\n");
        usage(argv[0]);
      }
    }
    else if (strmatch(key,"-trim")) {
      CHECK_ARG(1);
      trim_flag=TRUE; /* Implied.  */
      trim_fraction = atof(GET_ARG(1));
    }
    else {printf( "\n**Invalid option:  %s\n",argv[currArg-1]); usage(argv[0]);}
  }

  if ((argc-currArg)<1) {printf("Insufficient arguments.\n"); usage(argv[0]);}
  strcpy (sar_name, argv[currArg]);
  char *ext = findExt(sar_name);
  if (ext == NULL || strcmp("IMG", uc(ext)) != 0) {
    strcpy(sar_name, appendExt(sar_name, ".img"));
  }
  create_name(meta_name, sar_name, ".meta");
  create_name(stat_name, sar_name, ".stat");

  printf("\nProgram: stats\n\n");
  if (logflag) {
    fprintf(fLog, "\nProgram: stats\n\n");
  }
  printf("\nCalculating statistics for %s\n\n", sar_name);
  if (logflag) {
    fprintf(fLog,"\nCalculating statistics for %s\n\n", sar_name);
  }
  meta = meta_read(meta_name);
  num_lines = meta->general->line_count;
  num_samples = meta->general->sample_count;

  if ( start_line == -1 ) start_line = 0;
  if ( start_line > num_lines ) {
    printf("error: -startline argument is larger than index of last line in image\n");
    exit(EXIT_FAILURE);
  }
  if ( start_sample == -1 ) start_sample = 0;
  if ( start_sample > num_samples ) {
    printf("error: -startsample argument is larger than index of last sample in image\n");
    exit(EXIT_FAILURE);
  }
  if ( window_height == -1 ) window_height = num_lines;
  if ( start_line + window_height > num_lines ) {
    printf("warning: window specified with -startline, -height options doesn't fit in image\n");
  }
  if ( window_width == -1 ) window_width = num_samples;
  if ( start_sample + window_width > num_samples ) {
    printf("warning: window specified with -startsample, -width options doesn't fit in image\n");
  }

/* Make sure we don't over write any files that we don't want to */
  if (meta->stats && !overmeta_flag && !nometa_flag) {
    printf(" ** The meta file already has a populated statistics structure.\n"
           " ** If you want to run this program and replace that structure,\n"
           " ** then use the -overmeta option to do so. If you want to run\n"
           " ** this program, but don't want to replace the structure, use\n"
           " ** the -nometa option.\n");
    if (logflag) {
      fprintf(fLog,
      " ** The meta file already has a populated statistics structure.\n"
      " ** If you want to run this program and replace that structure,\n"
      " ** then use the -overmeta option to do so. If you want to run\n"
      " ** this program, but don't want to replace the structure, use\n"
      " ** the -nometa option.\n");
    }
    exit(EXIT_FAILURE);
  }
  if (fileExists(stat_name) && !overstat_flag && !nostat_flag) {
    printf(" ** The file, %s, already exists. If you want to\n"
           " ** overwrite it, then use the -overstat option to do so.\n"
           " ** If you want to run the progam but don't want to write\n"
           " ** over the current file, then use the -nostat option.\n",
           stat_name);
    if (logflag) {
      fprintf(fLog,
      " ** The file, %s, already exists. If you want to\n"
      " ** overwrite it, then use the -overstat option to do so.\n"
      " ** If you want to run the progam but don't want to write\n"
      " ** over the current file, then use the -nostat option.\n",
      stat_name);
    }
    exit(EXIT_FAILURE);
  }

/* Let user know the window in which the stats will be taken */
  if ((start_line!=0) || (start_sample!=0)
      || (window_height!=num_lines) || (window_width!=num_samples)) {
        if (!quietflag) {
      printf("Taking statistics on a window with upper left corner (%ld,%ld)\n"
      "  and lower right corner (%ld,%ld)\n",
      start_sample, start_line,
      window_width+start_sample, window_height+start_line);
    }
    if (logflag && !quietflag) {
      fprintf(fLog,
        "Taking statistics on a window with upper left corner (%ld,%ld)\n"
      "  and lower right corner (%ld,%ld)\n",
      start_sample, start_line,
      window_width+start_sample, window_height+start_line);
    }

  }

/* Allocate line buffer */
  data_line = (float *)MALLOC(sizeof(float)*num_samples);
  if (meta->stats) FREE(meta->stats);
  if (meta->general->band_count <= 0) {
    printf(" ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n");
    if (logflag) {
      fprintf(fLog, " ** Band count in the existing data is missing or less than zero.\nDefaulting to one band.\n");
    }
    meta->general->band_count = 1;
  }
  meta->stats = meta_statistics_init(meta->general->band_count);
  if (!meta->stats) {
    printf(" ** Cannot allocate memory for statistics data structures.\n");
    if (logflag) {
      fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n");
    }
    exit(EXIT_FAILURE);
  }
  stats = (stat_parameters *)MALLOC(sizeof(stat_parameters) * meta->stats->band_count);
  if (!stats) {
    printf(" ** Cannot allocate memory for statistics data structures.\n");
    if (logflag) {
      fprintf(fLog, " ** Cannot allocate memory for statistics data structures.\n");
    }
    exit(EXIT_FAILURE);
  }

  int  band;
  long band_offset;
  for (band = 0; band < meta->stats->band_count; band++) {
    /* Find min, max, and mean values */
    if (!quietflag) printf("\n");
    if (logflag && !quietflag) fprintf(fLog,"\n");
    min = 100000000;
    max = -100000000;
    sum_of_samples=0.0;
    sum_of_squared_samples=0.0;
    percent_complete=0;
    band_offset = band * meta->general->line_count;
    sar_file = FOPEN(sar_name, "r");
    for (line=start_line+band_offset; line<start_line+window_height+band_offset; line++) {
      if (!quietflag) asfPercentMeter((float)(line-start_line-band_offset)/(float)(window_height-start_line));
      get_float_line(sar_file, meta, line, data_line);
      for (sample=start_sample; sample<start_sample+window_width; sample++) {
        if ( mask_flag && FLOAT_EQUIVALENT(data_line[sample],mask) )
          continue;
        if (data_line[sample] < min) min=data_line[sample];
        if (data_line[sample] > max) max=data_line[sample];
        sum_of_samples += data_line[sample];
        sum_of_squared_samples += SQR(data_line[sample]);
        samples_counted++;
      }
    }
    if (!quietflag) asfPercentMeter(1.0);
//    if (!quietflag) printf("\rFirst data sweep: 100%% complete.\n");
    FCLOSE(sar_file);

    stats[band].min = min;
    stats[band].max = max;
    stats[band].upper_left_line = start_line;
    stats[band].upper_left_samp = start_sample;
    stats[band].lower_right_line = start_line + window_height;
    stats[band].lower_right_samp = start_sample + window_width;
    stats[band].mask = mask;

    stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples,
                      samples_counted, mask_flag);


  /* Remove outliers and trim the histogram by resetting the minimum and
    and maximum */
    if (trim_flag) {
      register int sum=0, num_pixels, minDex=0, maxDex=255;
      double overshoot, width;

      num_pixels = (int)(samples_counted*trim_fraction);
      minDex = 0;
      while (sum < num_pixels)
        sum += stats[band].histogram[minDex++];
      if (minDex-1>=0)
        overshoot = (double)(num_pixels-sum)/stats[band].histogram[minDex-1];
      else
        overshoot = 0;
      stats[band].min = (minDex-overshoot-stats[band].offset)/stats[band].slope;

      sum=0;
      while (sum < num_pixels)
        sum += stats[band].histogram[maxDex--];
      if (maxDex+1<256)
        overshoot = (double)(num_pixels-sum)/stats[band].histogram[maxDex+1];
      else
        overshoot = 0;
      stats[band].max = (maxDex+1+overshoot-stats[band].offset)/stats[band].slope;

      /* Widening the range for better visual effect */
      width = (stats[band].max-stats[band].min)*(1/(1.0-2*trim_fraction)-1);
      stats[band].min -= width/2;
      stats[band].max += width/2;

      /* Couple useful corrections borrowed from SARview */
      if ((stats[band].max-stats[band].min) < 0.01*(max-min)) {
        stats[band].max = max;
        stats[band].min = min;
      }
      if (min == 0.0)
        stats[band].min=0.0;
      if (stats[band].min == stats[band].max)
        stats[band].max = stats[band].min + MICRON;

      stats[band].slope = 255.0/(stats[band].max-stats[band].min);
      stats[band].offset = -stats[band].slope*stats[band].min;

      stats[band] = calc_hist(stats[band], sar_name, band, meta, sum_of_samples,
                        samples_counted, mask_flag);
    }
  }
  if(data_line)FREE(data_line);

  /* Populate meta->stats structure */
  char **band_names = NULL;
  if (meta_is_valid_string(meta->general->bands) &&
      strlen(meta->general->bands)               &&
      meta->general->band_count > 0)
  {
    band_names = extract_band_names(meta->general->bands, meta->general->band_count);
  }
  else {
    if (meta->general->band_count <= 0) meta->general->band_count = 1;
    band_names = (char **) MALLOC (meta->general->band_count * sizeof(char *));
    int i;
    for (i=0; i<meta->general->band_count; i++) {
      band_names[i] = (char *) MALLOC (64 * sizeof(char));
      sprintf(band_names[i], "%02d", i);
    }
  }
  int band_no;
  for (band_no = 0; band_no < meta->stats->band_count; band_no++) {
    strcpy(meta->stats->band_stats[band_no].band_id, band_names[band_no]);
    meta->stats->band_stats[band_no].min = stats[band_no].min;
    meta->stats->band_stats[band_no].max = stats[band_no].max;
    meta->stats->band_stats[band_no].mean = stats[band_no].mean;
    meta->stats->band_stats[band_no].rmse = stats[band_no].rmse;
    meta->stats->band_stats[band_no].std_deviation = stats[band_no].std_deviation;
    meta->stats->band_stats[band_no].mask = stats[band_no].mask;
  }
  if (band_names) {
    int i;
    for (i=0; i<meta->general->band_count; i++) {
      if (band_names[i]) FREE (band_names[i]);
    }
    FREE(band_names);
  }

/* Print findings to the screen (and log file if applicable)*/
  if (!quietflag) {
    printf("\n");
    printf("Statistics found:\n");
    if (mask_flag)
      { printf("Used mask %-16.11g\n",mask); }
    printf("Number of bands: %d\n", meta->stats->band_count);
    for (band=0; band<meta->stats->band_count; band++) {
      printf("\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id);
      printf("Minimum = %-16.11g\n",stats[band].min);
      printf("Maximum = %-16.11g\n",stats[band].max);
      printf("Mean = %-16.11g\n",stats[band].mean);
      printf("Root mean squared error = %-16.11g\n",
            stats[band].rmse);
      printf("Standard deviation = %-16.11g\n",
            stats[band].std_deviation);
      printf("\n");
      printf("Data fit to [0..255] using equation:  byte = %g * sample + %g\n",
            stats[band].slope, stats[band].offset);
                  if (trim_flag)
                    printf("Trimming fraction = %.3g\n", trim_fraction);
      printf("\n");
      printf("Histogram:\n");
      for (ii=0; ii<256; ii++) {
        if (ii%8 == 0) {
          printf("%s%3i-%3i:",
            (ii==0) ? "" : "\n",
            ii, ii+7);
        }
        printf(" %8i", stats[band].histogram[ii]);
      }
      printf("\n");
    }
  }
  if (logflag && !quietflag) {
    fprintf(fLog,"Statistics found:\n");
    if (mask_flag)
      { fprintf(fLog,"Used mask %-16.11g\n",mask); }
    fprintf(fLog,"Number of bands: %d\n", meta->stats->band_count);
    for (band=0; band<meta->stats->band_count; band++) {
      fprintf(fLog,"\n\nBand name = \"%s\"\n", meta->stats->band_stats[band].band_id);
      fprintf(fLog,"Minimum = %-16.11g\n",stats[band].min);
      fprintf(fLog,"Maximum = %-16.11g\n",stats[band].max);
      fprintf(fLog,"Mean = %-16.11g\n",stats[band].mean);
      fprintf(fLog,"Root mean squared error = %-16.11g\n",
             stats[band].rmse);
      fprintf(fLog,"Standard deviation = %-16.11g\n",
             stats[band].std_deviation);
      fprintf(fLog,"\n");
      fprintf(fLog,"Data fit to [0..255] using equation:  byte = %g * sample + %g\n",
             stats[band].slope, stats[band].offset);
      if (trim_flag)
        fprintf(fLog,"Trimming fraction = %.3g\n", trim_fraction);
      fprintf(fLog,"\n");
      fprintf(fLog,"Histogram:\n");
      for (ii=0; ii<256; ii++) {
        if (ii%8 == 0) {
          fprintf(fLog,"%s%3i-%3i:",
                 (ii==0) ? "" : "\n",
                 ii, ii+7);
        }
        fprintf(fLog," %8i", stats[band].histogram[ii]);
      }
      fprintf(fLog,"\n");
    }
  }

/* Write out .meta and .stat files */
  if (!nometa_flag) meta_write(meta, meta_name);
  if (!nostat_flag) stat_write(stats, stat_name, meta->stats->band_count);

/* Free the metadata structure */
  meta_free(meta);

/* Report */
  if (!quietflag) {
    printf("\n");
    printf("Statistics taken on image file %s.\n",sar_name);
    if (!nometa_flag)
      printf("Statistics written to the stats block in %s.\n",
        meta_name);
    if (!nostat_flag)
      printf("Statistics plus histogram written to %s.\n",
        stat_name);
    printf("\n");
  }
  if (logflag && !quietflag) {
    fprintf(fLog,"\n");
    fprintf(fLog,"Statistics taken on image file '%s'\n",sar_name);
    if (!nometa_flag)
      fprintf(fLog,"Statistics written to the stats block in %s\n",
        meta_name);
    if (!nostat_flag)
      fprintf(fLog,"Statistics plus histogram written to %s\n",
        stat_name);
    fprintf(fLog,"\n");
  }

  if (fLog) FCLOSE(fLog);
  return 0;
}
Exemple #3
0
int sr2gr_pixsiz(const char *infile, const char *outfile, float grPixSize)
{
	int    in_np,  in_nl;               /* input number of pixels,lines  */
	int    out_np, out_nl;              /* output number of pixels,lines */
	int    ii,line,band;
	float  oldX,oldY;
	float  sr2gr[MAX_IMG_SIZE];
	float  ml2gr[MAX_IMG_SIZE];
	int    a_lower[MAX_IMG_SIZE];
	int    lower[MAX_IMG_SIZE], upper[MAX_IMG_SIZE];
	float  a_ufrac[MAX_IMG_SIZE], a_lfrac[MAX_IMG_SIZE];
	float  ufrac[MAX_IMG_SIZE], lfrac[MAX_IMG_SIZE];
	float *ibuf1,*ibuf2,*obuf;
	char   infile_name[512],inmeta_name[512];
	char   outfile_name[512],outmeta_name[512];
	FILE  *fpi, *fpo;
	meta_parameters *in_meta;
	meta_parameters *out_meta;

        create_name (infile_name, infile, ".img");
        create_name (outfile_name, outfile, ".img");

        create_name (inmeta_name, infile, ".meta");
        create_name (outmeta_name, outfile, ".meta");

	in_meta  = meta_read(inmeta_name);
	out_meta = meta_copy(in_meta);
	in_nl = in_meta->general->line_count;
	in_np = in_meta->general->sample_count;
	
	if (in_meta->sar->image_type != 'S')
	{
            asfPrintError("sr2gr only works with slant range images!\n");
	}

      	oldX = in_meta->general->x_pixel_size * in_meta->sar->sample_increment;
	oldY = in_meta->general->y_pixel_size * in_meta->sar->line_increment;

        /* If user didn't specify a pixel size, make the pixels square & leave
           the y pixel size unchanged */
        if (grPixSize < 0)
            grPixSize = oldY;

	/*Update metadata for new pixel size*/
	out_meta->sar->time_shift  += ((in_meta->general->start_line)
				* in_meta->sar->azimuth_time_per_pixel);
	out_meta->sar->slant_shift -= ((in_meta->general->start_sample)
				* in_meta->general->x_pixel_size);
	out_meta->general->start_line   = 0.0;
	out_meta->general->start_sample = 0.0;
	out_meta->sar->azimuth_time_per_pixel *= grPixSize
					/ in_meta->general->y_pixel_size;
	out_meta->sar->line_increment   = 1.0;
        out_meta->sar->sample_increment = 1.0;
        if (out_meta->transform)
          out_meta->transform->target_pixel_size = grPixSize;	
	/*Create ground/slant and azimuth conversion vectors*/
	out_meta->sar->image_type       = 'G'; 
	out_meta->general->x_pixel_size = grPixSize;
	out_meta->general->y_pixel_size = grPixSize;
	sr2gr_vec(out_meta,oldX,grPixSize,sr2gr);
	ml_vec(oldY,grPixSize,ml2gr);

	out_np = MAX_IMG_SIZE;
	out_nl = MAX_IMG_SIZE;
	for (ii=MAX_IMG_SIZE-1; ii>0; ii--)
		if ((int)sr2gr[ii] > in_np)
			out_np = ii;
	for (ii=MAX_IMG_SIZE-1; ii>0; ii--)
		if ((int)ml2gr[ii] > in_nl)
			out_nl = ii;
	
	out_meta->general->line_count   = out_nl;
        out_meta->general->line_scaling *= (double)in_nl/(double)out_nl;
        out_meta->general->sample_scaling = 1;
	out_meta->general->sample_count = out_np;
	if (out_meta->projection) {
		out_meta->projection->perX = grPixSize;
		out_meta->projection->perY = grPixSize;
	}

	meta_write(out_meta,outmeta_name);
	
	fpi = fopenImage(infile_name,"rb");
	fpo = fopenImage(outfile_name,"wb");
	
	for (ii=0; ii<MAX_IMG_SIZE; ii++)
	{
		lower[ii] = (int) sr2gr[ii];
		upper[ii] = lower[ii] + 1;
		ufrac[ii] = sr2gr[ii] - (float) lower[ii];
		lfrac[ii] = 1.0 - ufrac[ii]; 
		
		a_lower[ii] = (int) ml2gr[ii];
		a_ufrac[ii] = ml2gr[ii] - (float) a_lower[ii];
		a_lfrac[ii] = 1.0 - a_ufrac[ii]; 
	}

	ibuf1 = (float *) MALLOC ((in_np+FUDGE_FACTOR)*sizeof(float));
	ibuf2 = (float *) MALLOC ((in_np+FUDGE_FACTOR)*sizeof(float));
	obuf = (float *) MALLOC (out_np*sizeof(float));

	/* Initialize input arrays to 0 */
	for (ii=0;ii<in_np+FUDGE_FACTOR;ii++) {
		ibuf1[ii]=ibuf2[ii]=0.0;
	}

        /* Get the band info */
        int bc = in_meta->general->band_count;
        char **band_name = extract_band_names(in_meta->general->bands, bc);

	/* Work dat magic! */
        for (band=0; band<bc; ++band) {
          asfPrintStatus("Working on band: %s\n", band_name[band]);
          for (line=0; line<out_nl; line++)
          {
            if (a_lower[line]+1 < in_nl)
            {
              get_band_float_line(fpi,in_meta,band,a_lower[line],  ibuf1);
              get_band_float_line(fpi,in_meta,band,a_lower[line]+1,ibuf2);
            }
            
            for (ii=0; ii<out_np; ii++)
            {
              int val00,val01,val10,val11,tmp1,tmp2;
              val00 = ibuf1[lower[ii]];
              val01 = ibuf1[upper[ii]];
              val10 = ibuf2[lower[ii]];
              val11 = ibuf2[upper[ii]];
              
              tmp1 = val00*lfrac[ii] + val01*ufrac[ii];
              tmp2 = val10*lfrac[ii] + val11*ufrac[ii];
              
              obuf[ii] = tmp1*a_lfrac[line] + tmp2*a_ufrac[line];
            }
            put_band_float_line(fpo,out_meta,band,line,obuf);
            asfLineMeter(line, out_nl);
          }
        }
        for (band=0; band<bc; ++band)
          FREE(band_name[band]);
        FREE(band_name);
        meta_free(in_meta);
        meta_free(out_meta);
	FCLOSE(fpi);
	FCLOSE(fpo);
	
        return TRUE;
}
Exemple #4
0
static void add_pixels(BandedFloatImage *out, char *file,
                       int size_x, int size_y,
                       double start_x, double start_y,
                       double per_x, double per_y)
{
    meta_parameters *meta = meta_read(file);

    if (!meta) {
        asfPrintError("Couldn't read metadata for: %s!\n", file);
    }

    // figure out where in the giant image these pixels will go
    int start_line, start_sample;

    // this should work even if per_x / per_y are negative...
    start_sample = (int) ((meta->projection->startX - start_x) / per_x + .5);
    start_line = (int) ((meta->projection->startY - start_y) / per_y + .5);

    int ns = meta->general->sample_count;
    int nl = meta->general->line_count;
    int nb = meta->general->band_count;
    char **bands = extract_band_names(meta->general->bands, nb);

    asfPrintStatus("  Location in combined is S:%d-%d, L:%d-%d\n",
        start_sample, start_sample + ns,
        start_line, start_line + nl);

    if (start_sample + ns > out->images[0]->size_x || 
	start_line + nl > out->images[0]->size_y) {
        asfPrintError("Image extents were not calculated correctly!\n");
    }

    FILE *img = fopenImage(file, "rb");
    if (!img) {
        asfPrintError("Couldn't open image file: %s!\n", file);
    }

    float *line = MALLOC(sizeof(float)*ns);

    int z;
    for (z=0; z<nb; ++z) {

      asfPrintStatus("  Band: %s\n", bands[z]);

      int y;
      for (y=0; y<nl; ++y) {
        get_band_float_line(img, meta, z, y, line);
	
        int x;
        for (x=0; x<ns; ++x) {
	  float v = line[x];
	  
	  // don't write out "no data" values
	  if (v != meta->general->no_data)
	    banded_float_image_set_pixel(out, z, 
					 x+start_sample, y+start_line, v);
        }
	
        asfLineMeter(y, nl);
      }
    }

    fclose(img);
    free(line);
    meta_free(meta);
}
Exemple #5
0
int clip(char *inFile, char *maskFile, char *outFile)
{
  meta_parameters *metaIn, *metaMask;
  metaIn = meta_read(inFile);
  metaMask = meta_read(maskFile);

  // Check whether mask file looks legitimate. The only indication that we
  // have is that it should be BYTE and have one band.
  if (metaMask->general->data_type != ASF_BYTE)
    asfPrintStatus("Mask image does not have data type 'BYTE'!\n");
  if (metaMask->general->band_count != 1)
    asfPrintStatus("Mask image should have only one band!\n");

  // Check whether input and mask file have the same projection parameters
  if (metaIn->projection && metaMask->projection) {

    // Create temporary processing directory (move outside this loop once
    // we have non-projected case covered)
    char *tmpDir = (char *) MALLOC(sizeof(char)*(strlen(outFile)+25));
    sprintf(tmpDir, "%s-", outFile);
    strcat(tmpDir, time_stamp_dir());
    create_clean_dir(tmpDir);
    char *mask = (char *) MALLOC(sizeof(char)*(strlen(tmpDir)+20));
    sprintf(mask, "%s/mask", tmpDir);
    
    // Check whether mask needs to be re-projected
    if (metaIn->projection->type != metaMask->projection->type) {
      asfPrintWarning("Mask needs to be re-projected!\n");
      project_parameters_t *pp = 
	(project_parameters_t *) MALLOC(sizeof(project_parameters_t));
      *pp = metaIn->projection->param;
      /*
      asf_geocode(pp, metaIn->projection->type, FALSE, 
		  RESAMPLE_NEAREST_NEIGHBOR, metaIn->projection->height, 
		  metaIn->projection->datum, metaIn->projection->perX, 
		  NULL, inFile, mask, metaIn->general->no_data, FALSE);
      */
      FREE(pp);
    }
    else {
      // Check whether mask needs to be resampled
      if ((metaIn->projection->perX != metaMask->projection->perX ||
	   metaIn->projection->perY != metaMask->projection->perY) &&
	  proj_params_match(metaIn, metaMask)) {
	asfPrintWarning("Mask needs to be resampled!\n");
	resample(inFile, mask, metaIn->projection->perX, 
		 fabs(metaIn->projection->perY));
      }
      else if (!proj_params_match(metaIn, metaMask)) {
	asfPrintWarning("Mask needs to be re-projected!\n");
	project_parameters_t *pp = 
	  (project_parameters_t *) MALLOC(sizeof(project_parameters_t));
	*pp = metaIn->projection->param;
	/*
	asf_geocode(pp, metaIn->projection->type, FALSE, 
		    RESAMPLE_NEAREST_NEIGHBOR, metaIn->projection->height, 
		    metaIn->projection->datum, metaIn->projection->perX, 
		    NULL, inFile, mask, metaIn->general->no_data, FALSE);
	*/
	FREE(pp);
      }
      else 
	copyImgAndMeta(maskFile, mask);
    }
    meta_free(metaMask);

    // Now we should have matching projections in both input files
    // Let's figure out the overlapping part of the two input files
    metaMask = meta_read(mask);
    int nl = metaMask->general->line_count;
    int ns = metaMask->general->sample_count;
    
    int startLine = (int)
      ((metaMask->projection->startY - metaIn->projection->startY + 0.5) /
       metaMask->projection->perY) - metaMask->general->start_line;
    int startSample = (int)
      ((metaMask->projection->startX - metaIn->projection->startX + 0.5) /
       metaMask->projection->perX) - metaMask->general->start_sample;
    int endLine = startLine + metaMask->general->line_count;
    int endSample = startSample + metaMask->general->sample_count;
    double coverage = 
      (endLine-startLine) * (endSample-startSample) * 100.0 / (ns*nl);
    printf("startLine: %i, startSample: %i\n", startLine, startSample);
    printf("endLine: %i, endSample: %i\n", endLine, endSample);
    printf("Converage: %.1f %%\n", coverage);

    // Fail when there is no overlap
    if (startLine > metaIn->general->line_count || endLine < 0 ||
	startSample > metaIn->general->sample_count || endSample < 0) {
      asfPrintStatus("Mask image does not cover the input image!\n");
      return (1);
    }

    // Setup files and memory
    char *inImg = appendExt(inFile, ".img");
    char *maskImg = appendExt(maskFile, ".img");
    char *outImg = appendExt(outFile, ".img");
    float *inBuf = 
      (float *) MALLOC(sizeof(float)*metaIn->general->sample_count);
    unsigned char *maskBuf = (unsigned char *) MALLOC(sizeof(char)*ns);
    float *outBuf = (float *) MALLOC(sizeof(float)*ns);
    char **band_name = extract_band_names(metaIn->general->bands,
					  metaIn->general->band_count);
    FILE *fpIn = FOPEN(inImg, "rb");
    FILE *fpMask = FOPEN(maskImg, "rb");
    FILE *fpOut = FOPEN(outImg, "wb");

    // Write metadata for output
    meta_parameters *metaOut = meta_read(maskFile);
    metaOut->general->band_count = metaIn->general->band_count;
    metaOut->general->data_type = metaIn->general->data_type;
    meta_write(metaOut, outFile);

    // Rock and roll
    int ii, jj, kk;
    for (ii=0; ii<nl; ii++) {
      get_byte_line(fpMask, metaMask, ii, maskBuf);
      for (kk=0; kk<metaIn->general->band_count; kk++) {
	if ((startLine+ii) >= 0 && ii < endLine)
	  get_band_float_line(fpIn, metaIn, kk, startLine+ii, inBuf);
	else
	  for (jj=0; jj<ns; jj++)
	    inBuf[jj] = 0.0;
	for (jj=0; jj<ns; jj++) {
	  if (maskBuf[jj] == 0 || inBuf[startSample+jj] == 0 ||
	      (startSample+jj) < 0 || jj > endSample)
	    outBuf[jj] = metaIn->general->no_data;
	  else
	    outBuf[jj] = inBuf[startSample+jj]*maskBuf[jj];
	}
	put_band_float_line(fpOut, metaOut, kk, ii, outBuf);
      }
      asfLineMeter(ii, nl);
    }
    FCLOSE(fpIn);
    FCLOSE(fpMask);
    FCLOSE(fpOut);

    // Clean up
    for (ii=0; ii<metaIn->general->band_count; ii++)
      FREE(band_name[ii]);
    FREE(band_name);
    FREE(inBuf);
    FREE(maskBuf);
    FREE(outBuf);
    meta_free(metaIn);
    meta_free(metaMask);
    meta_free(metaOut);
    remove_dir(tmpDir);
    FREE(tmpDir);
  }
  else
    asfPrintError("Non-projected case not covered yet!\n");

  return 0;
}
Exemple #6
0
// Main program body.
int
main (int argc, char *argv[])
{
  output_format_t format = 0;
  meta_parameters *md;
  char *in_base_name, *output_name;
  char **band_names=NULL;
  int rgb=0;
  int true_color;
  int false_color;
  int num_bands_found;
  int ignored[3] = {0, 0, 0};
  int num_ignored = 0;

  in_base_name = (char *) MALLOC(sizeof(char)*255);
  output_name = (char *) MALLOC(sizeof(char)*255);

/**********************BEGIN COMMAND LINE PARSING STUFF**********************/
  // Command line input goes in it's own structure.
  command_line_parameters_t command_line;
  strcpy (command_line.format, "");
  command_line.size = NO_MAXIMUM_OUTPUT_SIZE;
  strcpy (command_line.in_data_name, "");
  strcpy (command_line.in_meta_name, "");
  strcpy (command_line.output_name, "");
  command_line.verbose = FALSE;
  command_line.quiet = FALSE;
  strcpy (command_line.leader_name, "");
  strcpy (command_line.cal_params_file, "");
  strcpy (command_line.cal_comment, "");
  command_line.sample_mapping = 0;
  strcpy(command_line.red_channel, "");
  strcpy(command_line.green_channel, "");
  strcpy(command_line.blue_channel, "");
  strcpy(command_line.band, "");
  strcpy(command_line.look_up_table_name, "");

  int formatFlag, logFlag, quietFlag, byteFlag, rgbFlag, bandFlag, lutFlag;
  int truecolorFlag, falsecolorFlag;
  int needed_args = 3;  //command & argument & argument
  int ii;
  char sample_mapping_string[25];

  //Check to see which options were specified
  if (   (checkForOption("--help", argc, argv) != FLAG_NOT_SET)
      || (checkForOption("-h", argc, argv) != FLAG_NOT_SET)
      || (checkForOption("-help", argc, argv) != FLAG_NOT_SET) ) {
      print_help();
  }
  get_asf_share_dir_with_argv0(argv[0]);
  handle_license_and_version_args(argc, argv, ASF_NAME_STRING);

  formatFlag = checkForOption ("-format", argc, argv);
  logFlag = checkForOption ("-log", argc, argv);
  quietFlag = checkForOption ("-quiet", argc, argv);
  byteFlag = checkForOption ("-byte", argc, argv);
  rgbFlag = checkForOption ("-rgb", argc, argv);
  bandFlag = checkForOption ("-band", argc, argv);
  lutFlag = checkForOption ("-lut", argc, argv);
  truecolorFlag = checkForOption("-truecolor", argc, argv);
  falsecolorFlag = checkForOption("-falsecolor", argc, argv);

  if ( formatFlag != FLAG_NOT_SET ) {
    needed_args += 2;           // Option & parameter.
  }
  if ( quietFlag != FLAG_NOT_SET ) {
    needed_args += 1;           // Option & parameter.
  }
  if ( logFlag != FLAG_NOT_SET ) {
    needed_args += 2;           // Option & parameter.
  }
  if ( byteFlag != FLAG_NOT_SET ) {
    needed_args += 2;           // Option & parameter.
  }
  if ( rgbFlag != FLAG_NOT_SET ) {
    needed_args += 4;           // Option & 3 parameters.
  }
  if ( bandFlag != FLAG_NOT_SET ) {
    needed_args += 2;           // Option & parameter.
  }
  if ( lutFlag != FLAG_NOT_SET ) {
    needed_args += 2;           // Option & parameter.
  }
  if ( truecolorFlag != FLAG_NOT_SET ) {
    needed_args += 1;           // Option only
  }
  if ( falsecolorFlag != FLAG_NOT_SET ) {
    needed_args += 1;           // Option only
  }

  if ( argc != needed_args ) {
    print_usage ();                   // This exits with a failure.
  }

  // We also need to make sure the last three options are close to
  // what we expect.
  if ( argv[argc - 1][0] == '-' || argv[argc - 2][0] == '-' ) {
    print_usage (); // This exits with a failure.
  }

  // Make sure any options that have parameters are followed by
  // parameters (and not other options) Also make sure options'
  // parameters don't bleed into required arguments.
  if ( formatFlag != FLAG_NOT_SET ) {
    if ( argv[formatFlag + 1][0] == '-' || formatFlag >= argc - 3 ) {
      print_usage ();
    }
  }
  if ( byteFlag != FLAG_NOT_SET ) {
    if ( argv[byteFlag + 1][0] == '-' || byteFlag >= argc - 3 ) {
      print_usage ();
    }
  }
  if ( rgbFlag != FLAG_NOT_SET ) {
    if (( argv[rgbFlag + 1][0] == '-' && argv[rgbFlag + 2][0] == '-' &&
          argv[rgbFlag + 3][0] == '-' ) || rgbFlag >= argc - 5 ) {
      print_usage ();
    }
  }
  if ( bandFlag != FLAG_NOT_SET ) {
    if ( argv[bandFlag + 1][0] == '-' || bandFlag >= argc - 3 ) {
      print_usage ();
    }
  }
  if ( lutFlag != FLAG_NOT_SET ) {
    if ( argv[lutFlag + 1][0] == '-' || lutFlag >= argc - 3 ) {
      print_usage ();
    }
  }
  if ( logFlag != FLAG_NOT_SET ) {
    if ( argv[logFlag + 1][0] == '-' || logFlag >= argc - 3 ) {
      print_usage ();
    }
  }

  // Make sure there are no flag incompatibilities
  if ( (rgbFlag != FLAG_NOT_SET           &&
        (bandFlag != FLAG_NOT_SET         ||
         truecolorFlag != FLAG_NOT_SET    ||
         falsecolorFlag != FLAG_NOT_SET))
     ||
       (bandFlag != FLAG_NOT_SET         &&
        (rgbFlag != FLAG_NOT_SET         ||
         truecolorFlag != FLAG_NOT_SET   ||
         falsecolorFlag != FLAG_NOT_SET))
     ||
       (truecolorFlag != FLAG_NOT_SET    &&
        (bandFlag != FLAG_NOT_SET        ||
         rgbFlag != FLAG_NOT_SET         ||
         falsecolorFlag != FLAG_NOT_SET))
     ||
       (falsecolorFlag != FLAG_NOT_SET   &&
        (bandFlag != FLAG_NOT_SET        ||
         truecolorFlag != FLAG_NOT_SET   ||
         rgbFlag != FLAG_NOT_SET))
     )
  {
    asfPrintWarning("The following options may only be used one at a time:\n"
        "    %s\n    %s\n    %s\n    %s\n    %s\n    %s\n",
        "-rgb", "-truecolor", "-falsecolor", "-band");
    print_help();
  }
  if ( (rgbFlag != FLAG_NOT_SET         ||
        truecolorFlag != FLAG_NOT_SET   ||
        falsecolorFlag != FLAG_NOT_SET) &&
        lutFlag != FLAG_NOT_SET
     )
    asfPrintError("Look up table option can only be used on single-band "
          "images.\n");

  if( logFlag != FLAG_NOT_SET ) {
    strcpy(logFile, argv[logFlag+1]);
  }
  else {
    sprintf(logFile, "tmp%i.log", (int)getpid());
  }
  logflag = TRUE; // Since we always log, set the old school logflag to true
  fLog = FOPEN (logFile, "a");

  // Set old school quiet flag (for use in our libraries)
  quietflag = ( quietFlag != FLAG_NOT_SET ) ? TRUE : FALSE;

  // We're good enough at this point... print the splash screen.
  asfSplashScreen (argc, argv);

  // Grab the input and output name
  strcpy (in_base_name, argv[argc - 2]);
  strcpy (output_name, argv[argc - 1]);
  strcpy (command_line.output_name, output_name);

  // If user added ".img", strip it.
  char *ext = findExt(in_base_name);
  if (ext && strcmp(ext, ".img") == 0) *ext = '\0';

  // Set default output type
  if( formatFlag != FLAG_NOT_SET ) {
    strcpy (command_line.format, argv[formatFlag + 1]);
  }
  else {
    // Default behavior: produce a geotiff.
    strcpy (command_line.format, "geotiff");
  }

  // Compose input metadata name
  strcpy (command_line.in_meta_name, in_base_name);
  strcat (command_line.in_meta_name, ".meta");

  // for some validation, need the metadata
  md = meta_read (command_line.in_meta_name);

  // Convert the string to upper case.
  for ( ii = 0 ; ii < strlen (command_line.format) ; ++ii ) {
    command_line.format[ii] = toupper (command_line.format[ii]);
  }
  if (strcmp (command_line.format, "PGM") == 0 &&
      (rgbFlag != FLAG_NOT_SET      ||
      truecolorFlag != FLAG_NOT_SET ||
      falsecolorFlag != FLAG_NOT_SET)
     )
  {
    asfPrintWarning("Greyscale PGM output is not compatible with color options:\n"
                    "(RGB, True Color, False Color, color look-up tables, etc\n)"
                    "...Defaulting to producing separate greyscale PGM files for available band.\n");
    rgbFlag = FLAG_NOT_SET;
    truecolorFlag = FLAG_NOT_SET;
    falsecolorFlag = FLAG_NOT_SET;
  }

  // Set the default byte scaling mechanisms
  if (md->optical) {
     // for optical data, default sample mapping is NONE
      command_line.sample_mapping = NONE;
  }
  // for other data, default is based on the output type
  else if (strcmp (command_line.format, "TIFF") == 0 ||
           strcmp (command_line.format, "TIF")  == 0 ||
           strcmp (command_line.format, "JPEG") == 0 ||
           strcmp (command_line.format, "JPG")  == 0 ||
           strcmp (command_line.format, "PNG")  == 0 ||
           strcmp (command_line.format, "PGM")  == 0 ||
	   strcmp (command_line.format, "PNG_ALPHA") == 0 ||
	   strcmp (command_line.format, "PNG_GE") == 0)
  {
    command_line.sample_mapping = SIGMA;
  }
  else if (strcmp (command_line.format, "GEOTIFF") == 0) {
    command_line.sample_mapping = NONE;
  }

  if ( quietFlag != FLAG_NOT_SET )
    command_line.quiet = TRUE;
  else
    command_line.quiet = FALSE;

  // Set rgb combination
  if ( rgbFlag != FLAG_NOT_SET ) {
    int i;

    for (i=0, num_ignored = 0; i<3; i++) {
      ignored[i] = strncmp("IGNORE", uc(argv[rgbFlag + i + 1]), 6) == 0 ? 1 : 0;
      num_ignored += ignored[i] ? 1 : 0;
    }
    asfRequire(num_ignored < 3,
               "Cannot ignore all bands.  Exported image would be blank.\n");

    strcpy (command_line.red_channel, ignored[0] ? "Ignored" : argv[rgbFlag + 1]);
    strcpy (command_line.green_channel, ignored[1] ? "Ignored" : argv[rgbFlag + 2]);
    strcpy (command_line.blue_channel, ignored[2] ? "Ignored" : argv[rgbFlag + 3]);

    // Check to see if the bands are numeric and in range
    int r_channel = atoi(command_line.red_channel);
    int g_channel = atoi(command_line.green_channel);
    int b_channel = atoi(command_line.blue_channel);

    /////////// Numeric channel case ////////////
    // Remove trailing non-numeric characters from the channel number
    // string and pad front end nicely with a zero
    if (!ignored[0] && is_numeric(command_line.red_channel) &&
        r_channel >= 1 && r_channel <= MAX_BANDS) {
      sprintf(command_line.red_channel, "%02d", atoi(command_line.red_channel));
    }
    if (!ignored[1] && is_numeric(command_line.green_channel) &&
        g_channel >= 1 && g_channel <= MAX_BANDS) {
      sprintf(command_line.green_channel, "%02d", atoi(command_line.green_channel));
    }
    if (!ignored[2] && is_numeric(command_line.blue_channel) &&
        b_channel >= 1 && b_channel <= MAX_BANDS) {
      sprintf(command_line.blue_channel, "%02d", atoi(command_line.blue_channel));
    }
  }

  // Set up the bands for true or false color optical data
  true_color = false_color = 0;
  int with_sigma = FALSE;
  if (truecolorFlag != FLAG_NOT_SET || falsecolorFlag != FLAG_NOT_SET) {
    int ALOS_optical = (md->optical && strncmp(md->general->sensor, "ALOS", 4) == 0) ? 1 : 0;
    if (md->optical && truecolorFlag != FLAG_NOT_SET) {
      if (ALOS_optical) {
        with_sigma = TRUE;
        strcpy(command_line.red_channel,   "03");
        strcpy(command_line.green_channel, "02");
        strcpy(command_line.blue_channel,  "01");
        true_color = 1;
        asfPrintStatus("Applying True Color contrast expansion to following channels:");
      }
      else {
        char **bands = extract_band_names(md->general->bands, 3);
        asfRequire(bands != NULL,
                   "-truecolor option specified for non-true color optical image.\n");

        asfPrintWarning("Attempting to use the -truecolor option with non-ALOS\n"
            "optical data.\n");
        strcpy(command_line.red_channel, bands[2]);
        strcpy(command_line.green_channel, bands[1]);
        strcpy(command_line.blue_channel, bands[0]);
        int i;
        for (i=0; i<3; i++) {
          FREE(bands[i]);
        }
        FREE(bands);
      }
    }
    if (md->optical && falsecolorFlag != FLAG_NOT_SET) {
      if (ALOS_optical) {
        with_sigma = TRUE;
        strcpy(command_line.red_channel,   "04");
        strcpy(command_line.green_channel, "03");
        strcpy(command_line.blue_channel,  "02");
        false_color = 1;
        asfPrintStatus("Applying False Color contrast expansion to the following channels:");
      }
      else {
        char **bands = extract_band_names(md->general->bands, 4);
        asfRequire(bands != NULL,
                   "-falsecolor option specified for an optical image with fewer than 4 bands.\n");

        asfPrintWarning("Attempting to use the -falsecolor option with non-ALOS\n"
            "optical data.\n");
        strcpy(command_line.red_channel, bands[3]);
        strcpy(command_line.green_channel, bands[2]);
        strcpy(command_line.blue_channel, bands[1]);
        int i;
        for (i=0; i<3; i++) {
          FREE(bands[i]);
        }
        FREE(bands);
      }
    }
    if (!ALOS_optical && !md->optical) {
      asfPrintError("-truecolor or -falsecolor option selected with non-optical data\n");
    }
  }

  if (rgbFlag != FLAG_NOT_SET ||
     truecolorFlag != FLAG_NOT_SET ||
     falsecolorFlag != FLAG_NOT_SET)
  {
    char red_band[16], green_band[16], blue_band[16];

    asfPrintStatus("\nRed channel  : %s %s\n", command_line.red_channel, sigma_str(with_sigma));
    asfPrintStatus("Green channel: %s %s\n", command_line.green_channel, sigma_str(with_sigma));
    asfPrintStatus("Blue channel : %s %s\n\n", command_line.blue_channel, sigma_str(with_sigma));

    if (is_numeric(command_line.red_channel) &&
        is_numeric(command_line.green_channel) &&
        is_numeric(command_line.blue_channel))
    {
      sprintf(red_band, "%02d", atoi(command_line.red_channel));
      sprintf(green_band, "%02d", atoi(command_line.green_channel));
      sprintf(blue_band, "%02d", atoi(command_line.blue_channel));
      band_names = find_bands(in_base_name, rgbFlag,
                              red_band,
                              green_band,
                              blue_band,
                              &num_bands_found);
    }
    else {
      band_names = find_bands(in_base_name, rgbFlag,
                              command_line.red_channel,
                              command_line.green_channel,
                              command_line.blue_channel,
                              &num_bands_found);
    }
  }

  // Set band
  if ( bandFlag != FLAG_NOT_SET) {
    strcpy (command_line.band, argv[bandFlag + 1]);
    band_names = find_single_band(in_base_name, command_line.band,
                  &num_bands_found);
  }
  else if (rgbFlag == FLAG_NOT_SET &&
          truecolorFlag == FLAG_NOT_SET &&
          falsecolorFlag == FLAG_NOT_SET &&
          bandFlag == FLAG_NOT_SET) {
    bandFlag=1; // For proper messaging to the user
    strcpy (command_line.band, "all");
    band_names = find_single_band(in_base_name, command_line.band,
                                  &num_bands_found);
  }

  // Read look up table name
  if ( lutFlag != FLAG_NOT_SET) {
    strcpy(command_line.look_up_table_name, argv[lutFlag + 1]);
    rgb = 1;
  }

  // Set scaling mechanism
  if ( byteFlag != FLAG_NOT_SET ) {
    strcpy (sample_mapping_string, argv[byteFlag + 1]);
    for ( ii = 0; ii < strlen(sample_mapping_string); ii++) {
      sample_mapping_string[ii] = toupper (sample_mapping_string[ii]);
    }
    if ( strcmp (sample_mapping_string, "TRUNCATE") == 0 )
      command_line.sample_mapping = TRUNCATE;
    else if ( strcmp(sample_mapping_string, "MINMAX") == 0 )
      command_line.sample_mapping = MINMAX;
    else if ( strcmp(sample_mapping_string, "SIGMA") == 0 )
      command_line.sample_mapping = SIGMA;
    else if ( strcmp(sample_mapping_string, "HISTOGRAM_EQUALIZE") == 0 )
      command_line.sample_mapping = HISTOGRAM_EQUALIZE;
    else if ( strcmp(sample_mapping_string, "NONE") == 0 ) {
        asfPrintWarning("Sample remapping method (-byte option) is set to NONE\n"
                "which doesn't make sense.  Defaulting to TRUNCATE...\n");
        command_line.sample_mapping = TRUNCATE;
    }
    else
      asfPrintError("Unrecognized byte scaling method '%s'.\n",
                    sample_mapping_string);
  }

  int is_polsarpro = (md->general->bands && strstr(md->general->bands, "POLSARPRO") != NULL) ? 1 : 0;
  if ( !is_polsarpro               &&
       lutFlag != FLAG_NOT_SET     &&
       bandFlag == FLAG_NOT_SET    &&
       md->general->band_count > 1)
  {
    asfPrintError("Look up tables can only be applied to single band"
          " images\n");
  }

  if ( !is_polsarpro                       &&
       lutFlag != FLAG_NOT_SET             &&
       command_line.sample_mapping == NONE &&
       md->general->data_type != BYTE      &&
       md->general->band_count == 1)
  {
    asfPrintError("Look up tables can only be applied to byte output"
          " images\n");
  }

  // Report what is going to happen
  if (rgbFlag != FLAG_NOT_SET ||
     truecolorFlag != FLAG_NOT_SET ||
     falsecolorFlag != FLAG_NOT_SET)
  {
    if (num_bands_found >= 3) {
      asfPrintStatus("Exporting multiband image ...\n\n");
      rgb = 1;
    }
    else {
      asfPrintError("Not all RGB channels found.\n");
    }
  }
  else if (bandFlag != FLAG_NOT_SET) {
    if (strcmp_case(command_line.band, "ALL") == 0) {
      if (multiband(command_line.format, 
		    extract_band_names(md->general->bands, md->general->band_count), 
		    md->general->band_count))
	asfPrintStatus("Exporting multiband image ...\n\n");
      else  if (num_bands_found > 1)
        asfPrintStatus("Exporting each band into individual greyscale files ...\n\n");
    }
    else if (num_bands_found == 1) {
      if (lutFlag != FLAG_NOT_SET)
    asfPrintStatus("Exporting band '%s' applying look up table ...\n\n",
               command_line.band);
      else
    asfPrintStatus("Exporting band '%s' as greyscale ...\n\n",
               command_line.band);
    }
    else
      asfPrintError("Band could not be found in the image.\n");
  }
  else if (lutFlag != FLAG_NOT_SET)
    asfPrintStatus("Exporting applying look up table.\n\n");
  else
    asfPrintStatus("Exporting as greyscale.\n\n");

  //If user added ".img", strip it.
  ext = findExt(in_base_name);
  if (ext && strcmp(ext, ".img") == 0) *ext = '\0';
  meta_free(md);

/***********************END COMMAND LINE PARSING STUFF***********************/

  if ( strcmp (command_line.format, "ENVI") == 0 ) {
    format = ENVI;
  }
  else if ( strcmp (command_line.format, "ESRI") == 0 ) {
    format = ESRI;
  }
  else if ( strcmp (command_line.format, "GEOTIFF") == 0 ||
            strcmp (command_line.format, "GEOTIF") == 0) {
    format = GEOTIFF;
  }
  else if ( strcmp (command_line.format, "TIFF") == 0 ||
            strcmp (command_line.format, "TIF") == 0) {
    format = TIF;
  }
  else if ( strcmp (command_line.format, "JPEG") == 0 ||
            strcmp (command_line.format, "JPG") == 0) {
    format = JPEG;
  }
  else if ( strcmp (command_line.format, "PGM") == 0 ) {
    format = PGM;
  }
  else if ( strcmp (command_line.format, "PNG") == 0 ) {
    format = PNG;
  }
  else if ( strcmp (command_line.format, "PNG_ALPHA") == 0 ) {
    format = PNG_ALPHA;
  }
  else if ( strcmp (command_line.format, "PNG_GE") == 0 ) {
    format = PNG_GE;
  }
  else if ( strcmp (command_line.format, "KML") == 0 ) {
    format = KML;
  }
  else if ( strcmp (command_line.format, "POLSARPRO") == 0 ) {
    format = POLSARPRO_HDR;
  }
  else if ( strcmp (command_line.format, "HDF5") == 0 ) {
    format = HDF;
  }
  else if ( strcmp (command_line.format, "NETCDF") == 0 ) {
    format = NC;
  }
  else {
    asfPrintError("Unrecognized output format specified\n");
  }

  /* Complex data generally can't be output into meaningful images, so
     we refuse to deal with it.  */
  /*
  md = meta_read (command_line.in_meta_name);
  asfRequire (   md->general->data_type == BYTE
              || md->general->data_type == INTEGER16
              || md->general->data_type == INTEGER32
              || md->general->data_type == REAL32
              || md->general->data_type == REAL64,
              "Cannot cope with complex data, exiting...\n");

  meta_free (md);
  */

  // Do that exporting magic!
  asf_export_bands(format, command_line.sample_mapping, rgb,
                   true_color, false_color,
                   command_line.look_up_table_name,
                   in_base_name, command_line.output_name, band_names,
                   NULL, NULL);

  // If the user didn't ask for a log file then nuke the one that's been kept
  // since everything has finished successfully
  if (logFlag == FLAG_NOT_SET) {
      fclose (fLog);
      remove(logFile);
  }

  for (ii = 0; ii<num_bands_found; ii++) {
    FREE(band_names[ii]);
  }
  FREE(band_names);
  FREE(in_base_name);
  FREE(output_name);
  exit (EXIT_SUCCESS);
}
Exemple #7
0
static int
proj_to_sr(const char *infile, const char *outfile, double pixel_size)
{
    int ii, jj, kk;
    const float_image_sample_method_t sampling_method =
        FLOAT_IMAGE_SAMPLE_METHOD_BILINEAR;

    // overall algorithm:
    // 1. find extents in time/slant space
    // 2. for each pixel in output, resample in input space

    meta_parameters *inMeta = meta_read(infile);
    int nl = inMeta->general->line_count;
    int ns = inMeta->general->sample_count;

    if (!inMeta->projection && !inMeta->transform)
        asfPrintError("Expected a projection/transform block!\n");
    if (!inMeta->state_vectors)
        asfPrintError("Input data does not have state vectors!\n");

    //asfPrintStatus("Converting %s to slant range...\n", infile);

    // first, find extents in time/slant space
    // do this by projecting image corners to time/slant
    int tl_x=0,    tl_y=0;
    int tr_x=ns-1, tr_y=0;
    int bl_x=0,    bl_y=nl-1;
    int br_x=ns-1, br_y=nl-1;

    // we have to find the "real" corners of the image
    // do this using the first band of the input image as a reference
    if (inMeta->general->band_count == 1)
        asfPrintStatus("Tiling the input image...\n");
    else
        asfPrintStatus("Tiling the reference band of the input image...\n");

    FloatImage *in = float_image_new_from_metadata(inMeta, infile);

    // find top left pixel -- TOP-most non-no-data pixel in the image
    for (ii=0; ii<nl; ++ii)
        for (jj=0; jj<ns; ++jj) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                tl_x = jj; tl_y = ii;
                goto found_tl;
            }
        }

    asfPrintError("Couldn't find top-left pixel! Entire image no data?\n");

  found_tl:

    // find top right pixel -- RIGHT-most non-no-data pixel in the image
    for (jj=ns-1; jj>=0; --jj)
        for (ii=0; ii<nl; ++ii) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                tr_x = jj; tr_y = ii;
                goto found_tr;
            }
        }

    asfPrintError("Couldn't find top-right pixel! Entire image no data?\n");

  found_tr:

    // find bottom left pixel -- LEFT-most non-no-data pixel in the image
    for (jj=0; jj<ns; ++jj)
        for (ii=nl-1; ii>=0; --ii) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                bl_x = jj; bl_y = ii;
                goto found_bl;
            }
        }

    asfPrintError("Couldn't find bottom-left pixel! Entire image no data?\n");

  found_bl:

    // find bottom right pixel -- BOTTOM-most non-no-data pixel in the image
    for (ii=nl-1; ii>=0; --ii)
        for (jj=ns-1; jj>=0; --jj) {
            double val = float_image_get_pixel(in, jj, ii);
            if (val != inMeta->general->no_data && val != 0.0) {
                br_x = jj; br_y = ii;
                goto found_br;
            }
        }

    asfPrintError("Couldn't find bottom-right pixel! Entire image no data?\n");

  found_br:

    asfPrintStatus("Determining image extents in time/slant coordinates.\n");
    //asfPrintStatus("Corners are at: TL (%d,%d)\n", tl_y, tl_x);
    //asfPrintStatus(" (line,sample)  TR (%d,%d)\n", tr_y, tr_x);
    //asfPrintStatus("                BL (%d,%d)\n", bl_y, bl_x);
    //asfPrintStatus("                BR (%d,%d)\n", br_y, br_x);

    double tl_time, tl_slant;
    double tr_time, tr_slant;
    double bl_time, bl_slant;
    double br_time, br_slant;

    meta_get_timeSlantDop(inMeta, tl_y, tl_x, &tl_time, &tl_slant, NULL);
    meta_get_timeSlantDop(inMeta, tr_y, tr_x, &tr_time, &tr_slant, NULL);
    meta_get_timeSlantDop(inMeta, bl_y, bl_x, &bl_time, &bl_slant, NULL);
    meta_get_timeSlantDop(inMeta, br_y, br_x, &br_time, &br_slant, NULL);

    //asfPrintStatus("Corners are at: TL (%f,%f)\n", tl_time, tl_slant);
    //asfPrintStatus(" (time,slant)   TR (%f,%f)\n", tr_time, tr_slant);
    //asfPrintStatus("                BL (%f,%f)\n", bl_time, bl_slant);
    //asfPrintStatus("                BR (%f,%f)\n", br_time, br_slant);

    double slant_start = min4(tl_slant, tr_slant, bl_slant, br_slant);
    double slant_end = max4(tl_slant, tr_slant, bl_slant, br_slant);

    double time_min = min4(tl_time, tr_time, bl_time, br_time);
    double time_max = max4(tl_time, tr_time, bl_time, br_time);

    double slant_incr;
    double time_start, time_end, time_incr;
    int onl, ons;

    if (pixel_size > 0) {
        slant_incr = pixel_size;
        ons = (slant_end - slant_start) / slant_incr;

        if (inMeta->sar) {
            // in this case, the original data has a SAR block, we will use the
            // same azimuth time per pixel.
            time_incr = inMeta->sar->azimuth_time_per_pixel;

            // we always want to be DECREASING in time
            // latest time is on top (line 1), earliest on bottom (line ONL)
            if (time_incr > 0) {
                time_incr = -time_incr;
                inMeta->sar->azimuth_time_per_pixel =
                    -inMeta->sar->azimuth_time_per_pixel;
            }

            time_start = time_max;
            time_end = time_min;

            onl = (time_end - time_start) / time_incr;
        }
        else {
            // here, no sar block in the original data, just make a square
            // image with decreasing time
            onl = ons;
            time_incr = (time_min - time_max) / (double)onl;
            time_start = time_max;
            time_end = time_min;
        }
    }
    else {
        // not provided a slant range pixel size, we'll figure something out

        if (inMeta->sar) {
            // use the same azimuth time per pixel.
            time_incr = inMeta->sar->azimuth_time_per_pixel;

            // we always want to be DECREASING in time
            // latest time is on top (line 1), earliest on bottom (line ONL)
            if (time_incr > 0) {
                time_incr = -time_incr;
                inMeta->sar->azimuth_time_per_pixel =
                    -inMeta->sar->azimuth_time_per_pixel;
            }

            time_start = time_max;
            time_end = time_min;

            onl = (time_end - time_start) / time_incr;
        }
        else {
            // no info... determine azimuth time per pixel by keeping
            // the height the same as in the original image
            onl = nl;
            time_incr = (time_min - time_max) / (double)onl;
            time_start = time_max;
            time_end = time_min;
        }

        // make it square, to get the slant range pixel size
        ons = onl;
        pixel_size = slant_incr = (slant_end - slant_start) / (double)ons;
    }

    asfRequire(onl > 0, "Internal Error: Invalid output line count: %d\n", onl);
    asfRequire(ons > 0, "Internal Error: Invalid output sample count: %d\n", ons);

    asfPrintStatus("  Slant range values: %f -> %f\n", slant_start, slant_end);
    asfPrintStatus("  Slant range pixel size: %f\n", pixel_size);
    asfPrintStatus("  Time values: %f -> %f\n", time_start, time_end);
    asfPrintStatus("  Output Image will be %5d x %5d LxS\n", onl, ons);
    asfPrintStatus("      (Input Image was %5d x %5d LxS)\n", nl, ns);

    // generate a grid over the image, to generate our splines
    // this grid size seems to work pretty well...
    int n = 120;

    asfPrintStatus("Creating %dx%d mapping grid...\n", n, n);
 
    // changed how these are calculated, so that the spline will cover
    // the entire value range
    double time_grid_incr = fabs(time_end - time_start) / (double)(n-1);
    if (time_incr < 0) time_grid_incr = -time_grid_incr;
    double slant_grid_incr = fabs(slant_end - slant_start) / (double)(n-1);
    if (slant_incr < 0) slant_grid_incr = -slant_grid_incr;    

    // allocating memory for the splines, and the arrays to generate them
    gsl_interp_accel **samp_accels = MALLOC(sizeof(gsl_interp_accel *) * n);
    gsl_spline **samp_splines = MALLOC(sizeof(gsl_spline *) * n);

    gsl_interp_accel **line_accels = MALLOC(sizeof(gsl_interp_accel *) * n);
    gsl_spline **line_splines = MALLOC(sizeof(gsl_spline *) * n);

    double *slant_in = MALLOC(sizeof(double)*n);
    double *line_out = MALLOC(sizeof(double)*n);
    double *samp_out = MALLOC(sizeof(double)*n);

    // an alias -- use the same array (to save memory -- these are not used
    // at the same time), but create an alias for it, so it is not so confusing
    double *time_in = slant_in;
    //double max_err = 0;

    // set up the vertical splines
    for (jj=0; jj<n; ++jj) {
        double slant = slant_start + jj*slant_grid_incr;

        for (ii=0; ii<n; ++ii) {
            // splines need strictly increasing range variables
            if (time_grid_incr > 0)
                time_in[ii] = time_start + ii*time_grid_incr;
            else
                time_in[ii] = time_end - ii*time_grid_incr;

            ts2ls(inMeta, time_in[ii], slant, &line_out[ii], &samp_out[ii]);
            //printf("time: %f, slant: %f ==> line: %f, samp %f\n",
            //       time_in[ii], slant, line_out[ii], samp_out[ii]);
        }

        samp_accels[jj] = gsl_interp_accel_alloc();
        samp_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n);
        gsl_spline_init(samp_splines[jj], time_in, samp_out, n);

        line_accels[jj] = gsl_interp_accel_alloc();
        line_splines[jj] = gsl_spline_alloc(gsl_interp_cspline, n);
        gsl_spline_init(line_splines[jj], time_in, line_out, n);
    }

    // now, we're on to the resampling stage.. loop through output pixels
    asfPrintStatus("Generating slant range image...\n");

    double no_data_value = meta_is_valid_double(inMeta->general->no_data) ?
        inMeta->general->no_data : 0;

    // keep track of error sizes
    double max_error = 0;
    double avg_error = 0;
    int count = 0;

    // these stride values allow us to track when we're in between grid points
    int ii_n = onl/n;
    int jj_n = ons/n;
    int ii_n2 = ii_n/2;
    int jj_n2 = jj_n/2;

    // set up output metadata
    meta_parameters *outMeta = meta_read(infile);

    if (outMeta->transform) {
        FREE(outMeta->transform);
        outMeta->transform = NULL;
    }

    if (outMeta->projection) {
        FREE(outMeta->projection);
        outMeta->projection = NULL;
    }

    outMeta->general->line_count = onl;
    outMeta->general->sample_count = ons;

    if (!outMeta->sar)
        outMeta->sar = meta_sar_init();

    outMeta->sar->image_type = 'S';

    outMeta->sar->azimuth_time_per_pixel = time_incr;
    assert(outMeta->sar->azimuth_time_per_pixel < 0);

    outMeta->sar->time_shift = time_start;

    outMeta->general->y_pixel_size = inMeta->sar->azimuth_time_per_pixel / 
                                     time_incr * inMeta->general->y_pixel_size;
    assert(outMeta->general->y_pixel_size > 0);

    outMeta->sar->slant_range_first_pixel = slant_start;
    outMeta->general->x_pixel_size = slant_incr;

    outMeta->sar->line_increment = outMeta->sar->sample_increment = 1;
    outMeta->general->start_sample = outMeta->general->start_line = 0;

    outMeta->general->no_data = no_data_value;

    char **band_name = extract_band_names(inMeta->general->bands,
                                          inMeta->general->band_count);

    // now generate output image
    char *img_file = appendExt(outfile, ".img");
    float *out = MALLOC(sizeof(float) * ons);

    for (kk=0; kk<inMeta->general->band_count; ++kk) {
        if (inMeta->general->band_count != 1)
            asfPrintStatus("Working on band: %s\n", band_name[kk]);

        // for the 2nd and higher bands, free the band from the previous iteration,
        // and read in the next band from the input image
        if (kk>0) {
            float_image_free(in);
            asfPrintStatus("Loading input...\n");
            in = float_image_band_new_from_metadata(inMeta, kk, infile);
        }

        FILE *ofp = FOPEN(img_file, kk==0 ? "wb" : "ab");
        asfPrintStatus("Generating output...\n");
        for (ii=0; ii<onl; ++ii) {
            asfLineMeter(ii,onl);
            double time = time_start + ii * time_incr;

            // set up horizontal splines for this row
            gsl_interp_accel *samp_accel = gsl_interp_accel_alloc();
            gsl_spline *samp_spline = gsl_spline_alloc(gsl_interp_cspline, n);

            gsl_interp_accel *line_accel = gsl_interp_accel_alloc();
            gsl_spline *line_spline = gsl_spline_alloc(gsl_interp_cspline, n);

            //printf("time: %f slant: %f\n", time, slant_start);
            for (jj=0; jj<n; ++jj) {
                slant_in[jj] = slant_start + jj * slant_grid_incr;
                //printf("time: %f slant: %f\n", time, slant_in[jj]);
                samp_out[jj] = gsl_spline_eval_check(samp_splines[jj], time,
                                               samp_accels[jj]);
                line_out[jj] = gsl_spline_eval_check(line_splines[jj], time,
                                               line_accels[jj]);
                //printf("samp_out: %f line_out: %f\n", samp_out[jj], line_out[jj]);
            }

            gsl_spline_init(samp_spline, slant_in, samp_out, n);
            gsl_spline_init(line_spline, slant_in, line_out, n);

            // use the splines to produce output pixels
            for (jj=0; jj<ons; ++jj) {
                double slant = slant_start + jj * slant_incr;
                double samp = gsl_spline_eval_check(samp_spline, slant, samp_accel);
                double line = gsl_spline_eval_check(line_spline, slant, line_accel);

                // check the spline every so often (halfway between grid points)
                // only do this on band #1 (the reference band)
                if (kk==0 && ii%ii_n2==0 && 
                    ii%ii_n!=0 && jj%jj_n2==0 && jj%jj_n!=0)
                {
                    double samp_real, line_real;
                    ts2ls(inMeta, time, slant, &line_real, &samp_real);

                    double err = (line-line_real)*(line-line_real) +
                                 (samp-samp_real)*(samp-samp_real);

                    //printf("(%d,%d) -- Actual: (%f,%f) Splined: (%f,%f)\n",
                    //       ii, jj, line_real, samp_real, line, samp);

                    if (err > max_error) max_error = err;
                    avg_error += err;
                    ++count;
                }

                // now interpolate within the original image
                // if we are outside, use "no_data" from metadata
                double val = no_data_value;
                if (line > 0 && line < nl-1 && samp > 0 && samp < ns-1)
                    val = float_image_sample(in, samp, line, sampling_method);

                out[jj] = (float)val;
            }

            gsl_interp_accel_free(samp_accel);
            gsl_spline_free(samp_spline);

            gsl_interp_accel_free(line_accel);
            gsl_spline_free(line_spline);

            put_float_line(ofp, outMeta, ii, out);
        }

        fclose(ofp);
    }

    // free the last band of the input
    float_image_free(in);

    FREE(slant_in);
    FREE(line_out);
    FREE(samp_out);

    for (ii=0; ii<n; ++ii) {
        gsl_interp_accel_free(samp_accels[ii]);
        gsl_spline_free(samp_splines[ii]);
        gsl_interp_accel_free(line_accels[ii]);
        gsl_spline_free(line_splines[ii]);
    }

    FREE(samp_accels);
    FREE(samp_splines);
    FREE(line_accels);
    FREE(line_splines);

    FREE(out);

    for (kk=0; kk<inMeta->general->band_count; ++kk)
        FREE(band_name[kk]);
    FREE(band_name);

    // see how bad our errors were
    avg_error /= (double)count;
    asfPrintStatus("Model max error: %f, avg: %f\n",
                   max_error, avg_error);

    double thresh = 0.1;
    if (max_error > 100*thresh)
        asfPrintError("Maximum error exceeded threshold: %f > %f\n",
                      max_error, 100*thresh);
    else if (avg_error > 10*thresh)
        asfPrintError("Average error exceeded threshold: %f > %f\n",
                      avg_error, 10*thresh);
    if (max_error > 10*thresh)
        asfPrintWarning("Maximum error exceeds threshold: %f > %f\n",
                        max_error, 10*thresh);
    if (avg_error > thresh)
        asfPrintWarning("Average error exceeds threshold: %f > %f\n",
                        avg_error, thresh);

    char *meta_file = appendExt(outfile, ".meta");
    asfPrintStatus("Writing %s\n", meta_file);
    meta_write(outMeta, meta_file);
    free(meta_file);
    free(img_file);

    meta_free(outMeta);
    meta_free(inMeta);

    return 0; //success
}
int asf_calibrate(const char *inFile, const char *outFile, 
		  radiometry_t outRadiometry, int wh_scaleFlag)
{
  meta_parameters *metaIn = meta_read(inFile);
  meta_parameters *metaOut = meta_read(inFile);

  if (!metaIn->calibration) {
    asfPrintError("This data cannot be calibrated, missing calibration block.\n");
  }

  // Check for valid output radiometry
  if (outRadiometry == r_AMP || outRadiometry == r_POWER)
    asfPrintError("Invalid radiometry (%s) passed into calibration function!\n",
		  radiometry2str(outRadiometry));

  // Check whether output radiometry fits with Woods Hole scaling flag
  if (wh_scaleFlag && outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA)
    outRadiometry += 3;

  // This can only work if the image is in some SAR geometry
  if (metaIn->projection && metaIn->projection->type != SCANSAR_PROJECTION)
    asfPrintError("Can't apply calibration factors to map projected images\n"
                  "(Amplitude or Power only)\n");

  radiometry_t inRadiometry = metaIn->general->radiometry;
  asfPrintStatus("Calibrating %s image to %s image\n\n", 
		 radiometry2str(inRadiometry), radiometry2str(outRadiometry));
  // FIXME: This function should be able to remap between different
  //        radiometry projections.
  if (metaIn->general->radiometry != r_AMP)
    asfPrintError("Currently only AMPLITUDE as radiometry is supported!\n");

  metaOut->general->radiometry = outRadiometry;
  int dbFlag = FALSE;
  if (outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA)
    metaOut->general->no_data = 0.0001;
  if (outRadiometry >= r_SIGMA_DB && outRadiometry <= r_GAMMA_DB) {
    metaOut->general->no_data = -40.0;
    dbFlag = TRUE;
  }
  if (metaIn->general->image_data_type != POLARIMETRIC_IMAGE) {
    if (outRadiometry == r_SIGMA || outRadiometry == r_SIGMA_DB)
      metaOut->general->image_data_type = SIGMA_IMAGE;
    else if (outRadiometry == r_BETA || outRadiometry == r_BETA_DB)
      metaOut->general->image_data_type = BETA_IMAGE;
    else if (outRadiometry == r_GAMMA || outRadiometry == r_GAMMA_DB)
      metaOut->general->image_data_type = GAMMA_IMAGE;
  }
  if (wh_scaleFlag)
    metaOut->general->data_type = ASF_BYTE;

  char *input = appendExt(inFile, ".img");
  char *output = appendExt(outFile, ".img");
  FILE *fpIn = FOPEN(input, "rb");
  FILE *fpOut = FOPEN(output, "wb");

  int dualpol = strncmp_case(metaIn->general->mode, "FBD", 3) == 0 ? 1 : 0;
  int band_count = metaIn->general->band_count;
  int sample_count = metaIn->general->sample_count;
  int line_count = metaIn->general->line_count;
  char **bands = 
    extract_band_names(metaIn->general->bands, band_count);

  float *bufIn = (float *) MALLOC(sizeof(float)*sample_count);
  float *bufOut = (float *) MALLOC(sizeof(float)*sample_count);
  float *bufIn2 = NULL, *bufOut2 = NULL, *bufOut3 = NULL;
  if (dualpol && wh_scaleFlag) {
    bufIn2 = (float *) MALLOC(sizeof(float)*sample_count);
    bufOut2 = (float *) MALLOC(sizeof(float)*sample_count);
    bufOut3 = (float *) MALLOC(sizeof(float)*sample_count);
    metaOut->general->band_count = 3;
    sprintf(metaOut->general->bands, "%s,%s,%s-%s", 
	    bands[0], bands[1], bands[0], bands[1]);
  }

  int ii, jj, kk;
  float cal_dn, cal_dn2;
  double incid;
  if (dualpol && wh_scaleFlag) {
    metaOut->general->image_data_type = RGB_STACK;
    for (ii=0; ii<line_count; ii++) {
      get_band_float_line(fpIn, metaIn, 0, ii, bufIn);
      get_band_float_line(fpIn, metaIn, 1, ii, bufIn2);
      for (jj=0; jj<sample_count; jj++) {
	// Taking the remapping of other radiometries out for the moment
	//if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB)
	//bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]);
	incid = meta_incid(metaIn, ii, jj);
	cal_dn = 
	  get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[0], dbFlag);
	cal_dn2 = 
	  get_cal_dn(metaOut, incid, jj, bufIn2[jj], bands[1], dbFlag);
	if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data) ||
	    cal_dn == cal_dn2) {
	  bufOut[jj] = 0;
	  bufOut2[jj] = 0;
	  bufOut3[jj] = 0;
	}
	else {
	  bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5;
	  bufOut2[jj] = (cal_dn2 + 31) / 0.15 + 1.5;
	  bufOut3[jj] = bufOut[jj] - bufOut2[jj];
	}
      }
      put_band_float_line(fpOut, metaOut, 0, ii, bufOut);
      put_band_float_line(fpOut, metaOut, 1, ii, bufOut2);
      put_band_float_line(fpOut, metaOut, 2, ii, bufOut3);
      asfLineMeter(ii, line_count);
    }
  }
  else {
    for (kk=0; kk<band_count; kk++) {
      for (ii=0; ii<line_count; ii++) {
	get_band_float_line(fpIn, metaIn, kk, ii, bufIn);
	for (jj=0; jj<sample_count; jj++) {
	  // Taking the remapping of other radiometries out for the moment
	  //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB)
	  //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]);
	  if (strstr(bands[kk], "PHASE") == NULL) {
	    incid = meta_incid(metaIn, ii, jj);
	    cal_dn =
	      get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[kk], dbFlag);
	    if (wh_scaleFlag) {
	      if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data))
		bufOut[jj] = 0;
	      else
		bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5;
	    }
	    else
	      bufOut[jj] = cal_dn;
	  }
	  else // PHASE band, do nothing
	    bufOut[jj] = bufIn[jj];
	}
	put_band_float_line(fpOut, metaOut, kk, ii, bufOut);
	asfLineMeter(ii, line_count);
      }
      if (kk==0)
	sprintf(metaOut->general->bands, "%s-%s", 
		radiometry2str(outRadiometry), bands[kk]);
      else {
	char tmp[255];
	sprintf(tmp, ",%s-%s", radiometry2str(outRadiometry), bands[kk]);
	strcat(metaOut->general->bands, tmp);
      }
    }
  }
  meta_write(metaOut, outFile);
  meta_free(metaIn);
  meta_free(metaOut);
  FREE(bufIn);
  FREE(bufOut);
  if (dualpol) {
    FREE(bufIn2);
    FREE(bufOut2);
    FREE(bufOut3);
  }
  for (kk=0; kk<band_count; ++kk)
    FREE(bands[kk]);
  FREE(bands);
  FCLOSE(fpIn);
  FCLOSE(fpOut);
  FREE(input);
  FREE(output);

  return FALSE;
}
Exemple #9
0
static int gr2sr_pixsiz_imp(const char *infile, const char *outfile,
                            float srPixSize, int apply_pp_earth_radius_fix)
{
  meta_parameters *inMeta, *outMeta;

  int   np, nl;         /* in number of pixels,lines       */
  int   onp, onl;       /* out number of pixels,lines      */
  int   nBands;         /* number of bands in input/output */
  int   ii;
  float *gr2sr;    /* GR 2 SR resampling vector for Range  */
  int   *lower;    /* floor of gr2sr vector                */
  int   *upper;    /* ceiling of gr2sr vector              */
  float *ufrac;    /* Upper fraction from gr2sr vector     */
  float *lfrac;    /* Lower fraction from gr2sr vector     */

  float *inBuf;          /* Input buffer                  */
  float *outBuf;         /* Output buffer                 */
  FILE  *fpi, *fpo;      /* File pointers                 */
  int   line;            /* Loop counter                  */
  int   band;            /* Loop counter                  */
  char  *iimgfile;       /* .img input file               */
  char  *oimgfile;       /* .img output file              */
 
  gr2sr = (float *) MALLOC(sizeof(float) * MAX_IMG_SIZE);
  upper = (int *) MALLOC(sizeof(int) * MAX_IMG_SIZE);
  lower = (int *) MALLOC(sizeof(int) * MAX_IMG_SIZE);
  ufrac = (float *) MALLOC(sizeof(float) * MAX_IMG_SIZE);
  lfrac = (float *) MALLOC(sizeof(float) * MAX_IMG_SIZE);

  inMeta = meta_read(infile);

  if (srPixSize < 0) {
    /*
      In an e-mail from Rick:
       Slant Range Pixel Size = C (speed of light) / [SampleRate (sample 
       rate) * 2,000,000.]

       SampleRate can be extracted from the L1 metadata :
          RNG CMPLX SAMPLE RATE        18.9599991

       The meta->sar->range_sampling_rate is 10^6 times the value above,
       so we use C/(2*meta->sar->range_sampling_rate)
    */
    int osc = inMeta->sar->original_sample_count;
    if (osc < 0) osc = inMeta->general->sample_count;
    srPixSize = SPD_LIGHT / ((2.0 * inMeta->sar->range_sampling_rate) *
      inMeta->general->sample_count / osc);
  }

  nl = inMeta->general->line_count;
  np = inMeta->general->sample_count;
  nBands = inMeta->general->band_count;

  char **band_name = extract_band_names(inMeta->general->bands, nBands);

  onl=nl;
  gr2sr_vec(inMeta, srPixSize, gr2sr, apply_pp_earth_radius_fix);
  
  /* Determine the output image size */
  onp = 0;
  for (ii=0; ii<MAX_IMG_SIZE; ii++) {
     if (gr2sr[ii]<np) onp=ii; /* gr input still in range-- keep output */
     else break; /* gr input is off end of image-- stop sr output */
  }
  asfPrintStatus("Input image is %dx%d\n", nl, np);
  asfPrintStatus("Output image will be %dx%d\n", onl, onp);
  
  /* Split gr2sr into resampling coefficients */
  for (ii=0; ii<onp; ii++) {
     lower[ii] = (int) gr2sr[ii];
     upper[ii] = lower[ii] + 1;
     ufrac[ii] = gr2sr[ii] - (float) lower[ii];
     lfrac[ii] = 1.0 - ufrac[ii];
     if (lower[ii]>=np) lower[ii]=np-1; /* range clip */
     if (upper[ii]>=np) upper[ii]=np-1; /* range clip */
  }
  
  outMeta = meta_read(infile);
  outMeta->sar->slant_shift += ((inMeta->general->start_sample)
                                * inMeta->general->x_pixel_size);
  outMeta->general->start_sample = 0.0;
  outMeta->sar->sample_increment = 1.0;
  outMeta->sar->image_type       = 'S';
  outMeta->general->x_pixel_size = srPixSize;
  outMeta->general->sample_count = onp;
  if (outMeta->sar){
    update_doppler(np, onp, gr2sr, outMeta);
  }

  iimgfile = replExt(infile, "img");
  oimgfile = replExt(outfile, "img");

  fpi = FOPEN(iimgfile,"rb");
  fpo = FOPEN(oimgfile,"wb");
  inBuf = (float *) MALLOC (np*sizeof(float));
  outBuf = (float *) MALLOC (onp*sizeof(float));

  for (band = 0; band < nBands; band++) {
    if (inMeta->general->band_count != 1)
      asfPrintStatus("Converting to slant range: band %s\n", band_name[band]);
    for (line = 0; line < onl; line++) {
      get_float_line(fpi, inMeta, line + band*onl, inBuf);
      for (ii=0; ii<onp; ii++) { /* resample to slant range */
         outBuf[ii] = inBuf[lower[ii]]*lfrac[ii]+inBuf[upper[ii]]*ufrac[ii];
      }
      put_float_line(fpo,outMeta,line + band*onl,outBuf);
      asfLineMeter(line,onl);
    }
  }

  for (ii=0; ii < inMeta->general->band_count; ii++)
    FREE(band_name[ii]);
  FREE(band_name);

  meta_write(outMeta, outfile);
  meta_free(inMeta);
  meta_free(outMeta);

  FREE(ufrac);
  FREE(lfrac);
  FREE(gr2sr);
  FREE(upper);
  FREE(lower);

  FREE(inBuf);
  FREE(outBuf);
  FCLOSE(fpi);
  FCLOSE(fpo);
  FREE(iimgfile);
  FREE(oimgfile);

  return TRUE;
}
void import_radarsat2(const char *inBaseName, radiometry_t radiometry,
		      const char *outBaseName, int ampOnly)
{
  FILE *fp;
  radarsat2_meta *radarsat2;
  meta_parameters *meta;
  char **inDataNames=NULL, inDataName[1024], *inMetaName=NULL;
  char *outDataName=NULL, str[512];
  float *amp = NULL, *phase = NULL, *tmp = NULL, re, im;
  int band, sample;

  // Check radiometry
  if (radiometry != r_AMP) {
    asfPrintWarning("Radiometry other than AMPLITUDE is currently not "
		    "supported.\n");
    radiometry = r_AMP;
  }
  
  if (!fileExists(inBaseName))
    inMetaName = appendExt(inBaseName, ".xml");
  else {
    inMetaName = (char *) MALLOC(sizeof(char)*1024);
    strcpy(inMetaName, inBaseName);
  }
  outDataName = appendExt(outBaseName, ".img");

  radarsat2 = read_radarsat2_meta(inMetaName);
  asfPrintStatus("   DataType: %s, ProductType: %s\n",
		 radarsat2->dataType, radarsat2->productType);
  if (strcmp_case(radarsat2->dataType, "COMPLEX") != 0)
    asfPrintError("Currently only complex data supported!\n");
  meta = radarsat2meta(radarsat2);
  meta_write(meta, outDataName);

  // Let's check the GeoTIFF data.
  // Unfortunately, there is no identifier in the GeoTIFF that would identify
  // the data as Radarsat-2 data.
  //
  // The only thing that we can actually do is to look whether the data in the
  // GeoTIFF file fit the general bill. We can the image dimensions. The data
  // needs to have 2 bands (I and Q) and 16 bit. The citation geokey needs to
  // be the really non-descriptive "Uncorrected Satellite Data".

  TIFF *tiff = NULL;
  GTIF *gtif = NULL;
  data_type_t data_type;
  short sample_format, bits_per_sample, planar_config;
  short num_bands;
  int is_scanline_format, is_palette_color_tiff, wrong=FALSE;
  char *error_message = (char *) MALLOC(sizeof(char)*2048);

  inDataNames = extract_band_names(meta->general->basename, 
				   meta->general->band_count);
  fp = FOPEN(outDataName, "wb");

  int band_count = radarsat2->band_count;
  if (ampOnly) {
    strcpy(meta->general->bands, "AMP");
    meta->general->band_count = 1;
    band_count = 1;
  }
  for (band=0; band<band_count; band++) {

    // path from the xml (metadata) file
    char *path = get_dirname(inBaseName);
    if (strlen(path)>0) {
      strcpy(inDataName, path);
      if (inDataName[strlen(inDataName)-1] != '/')
        strcat(inDataName, "/");
    }
    else
      strcpy(inDataName, "");
    free(path);
    strcat(inDataName, inDataNames[band]);

    tiff = XTIFFOpen(inDataName, "r");
    if (!tiff)
      asfPrintError("Could not open data file (%s)\n", inDataName);
    gtif = GTIFNew(tiff);
    if (!gtif)
      asfPrintError("Could not read GeoTIFF keys from data file (%s)\n",
		    inDataName);

    // Check image dimensions
    uint32 tif_sample_count;
    uint32 tif_line_count;

    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &tif_line_count);
    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &tif_sample_count);
    if ((meta->general->sample_count != tif_sample_count) ||
	(meta->general->line_count != tif_line_count))
      asfPrintError(error_message, 
		    "Problem with image dimensions. Was looking for %d lines "
		    "and %d samples.\nFound %ld lines and %ld samples instead!"
		    "\n", 
		    meta->general->line_count, meta->general->sample_count, 
		    tif_line_count, tif_sample_count);

    // Check general TIFF tags
    get_tiff_data_config(tiff, &sample_format, &bits_per_sample, &planar_config,
			 &data_type, &num_bands, &is_scanline_format, 
			 &is_palette_color_tiff, REPORT_LEVEL_WARNING);

    // The specs say the data is supposed to be unsigned but it is not.
    // Let is pass as long as we are talking about integer data here
    strcpy(error_message, "");
    if (sample_format != SAMPLEFORMAT_UINT && 
	sample_format != SAMPLEFORMAT_INT) {
      strcat(error_message, 
	     "Problem with sampling format. Was looking for integer, ");
      if (sample_format == SAMPLEFORMAT_COMPLEXIEEEFP)
	strcat(error_message, "found complex floating point instead!\n");
      else if (sample_format == SAMPLEFORMAT_COMPLEXINT)
	strcat(error_message, "found complex integer instead!\n");
      else if (sample_format == SAMPLEFORMAT_IEEEFP)
	strcat(error_message, "found floating point instead!\n");
      else if (sample_format == SAMPLEFORMAT_VOID)
	strcat(error_message, "found void instead!\n");
      wrong = TRUE;
    }
    if (bits_per_sample != 16) {
      sprintf(str, "Problem with bits per sample. Was looking for 16, found %d "
	      "instead!\n", bits_per_sample);
      strcat(error_message, str);
      wrong = TRUE;
    }
    if (data_type != INTEGER16) {
      strcat(error_message, "Problem with data type. Was looking INTEGER16, ");
      if (data_type == ASF_BYTE)
	strcat(error_message, "found BYTE instead!\n");
      else if (data_type == INTEGER32)
	strcat(error_message, "found INTEGER32 instead!\n");
      else if (data_type == REAL32)
	strcat(error_message, "found REAL32 instead!\n");
      else if (data_type == REAL64)
	strcat(error_message, "found REAL64 instead!\n");
      else if (data_type == COMPLEX_BYTE)
	strcat(error_message, "found COMPLEX_BYTE instead!\n");
      else if (data_type == COMPLEX_INTEGER16)
	strcat(error_message, "found COMPLEX_INTEGER16 instead!\n");
      else if (data_type == COMPLEX_INTEGER32)
	strcat(error_message, "found COMPLEX_INTEGER32 instead!\n");
      else if (data_type == COMPLEX_REAL32)
	strcat(error_message, "found COMPLEX_REAL32 instead!\n");
      else if (data_type == COMPLEX_REAL64)
	strcat(error_message, "found COMPLEX_REAL64 instead!\n");
      wrong = TRUE;
    }
    if (num_bands != 2) {
      sprintf(str, "Problem with number of bands. Was looking for 2, "
	      "found %d instead!\n", num_bands);
      strcat(error_message, str);
      wrong = TRUE;
    }
    if (wrong)
      asfPrintError(error_message);

    // Check GTCitationGeoKey
    char *citation = NULL;
    int citation_length, typeSize;
    tagtype_t citation_type;

    citation_length = GTIFKeyInfo(gtif, GTCitationGeoKey, &typeSize,
				  &citation_type);
    if (citation_length > 0) {
      citation = (char *) MALLOC(citation_length * typeSize);
      GTIFKeyGet(gtif, GTCitationGeoKey, citation, 0, citation_length);
      if (citation && 
	  strcmp_case(citation, "UNCORRECTED SATELLITE DATA") != 0) {
	asfPrintError("Problem with GTCitationGeoKey. Was looking for "
		      "'Uncorrected Satellite Data',\nfound '%s' instead!\n", 
		      citation);
      }
    }
    else
      asfPrintError("Problem with GTCitationGeoKey. Was looking for "
		    "'Uncorrected Satellite Data',\ndid not find any key!\n");

    tiff_type_t tiffInfo;
    get_tiff_type(tiff, &tiffInfo);
    if (tiffInfo.format != SCANLINE_TIFF &&
	tiffInfo.format != STRIP_TIFF    &&
	tiffInfo.format != TILED_TIFF)
      asfPrintError("Can't read the GeoTIFF file (%s). Unrecognized TIFF "
		    "type!\n", inDataNames[band]);

    // If we made it here, we are reasonably sure that we have the file that
    // we are looking for.
    asfPrintStatus("\n   Importing %s ...\n", inDataNames[band]);

    uint32 scanlineSize = TIFFScanlineSize(tiff);
    tdata_t *tiff_real_buf = _TIFFmalloc(scanlineSize);
    tdata_t *tiff_imag_buf = _TIFFmalloc(scanlineSize);
    if (!tiff_real_buf || !tiff_imag_buf)
      asfPrintError("Can't allocate buffer for reading TIFF lines!\n");

    amp = (float *) MALLOC(sizeof(float)*meta->general->sample_count);
    phase = (float *) MALLOC(sizeof(float)*meta->general->sample_count);

    // Check whether we need to flip the image in any fashion
    int flip_vertical = FALSE;
    if (strcmp_case(radarsat2->lineTimeOrdering, "DECREASING") == 0) {
      asfPrintStatus("   Data will be flipped vertically while ingesting!\n");
      flip_vertical = TRUE;
    }
    int flip_horizontal = FALSE;
    if (strcmp_case(radarsat2->pixelTimeOrdering, "DECREASING") == 0) {
      asfPrintStatus("   Data will be flipped horizontally while ingesting!\n");
      flip_horizontal = TRUE;
    }
    if (flip_horizontal)
      tmp = (float *) MALLOC(sizeof(float)*meta->general->sample_count);

    // FIXME: still need to implement flipping vertically
    // Read file line by line
    uint32 row;
    int sample_count = meta->general->sample_count;
    int line_count = meta->general->line_count;
    for (row=0; row<(uint32)meta->general->line_count; row++) {
      asfLineMeter(row, meta->general->line_count);
      if (flip_vertical) {
	switch (tiffInfo.format) 
	  {
	  case SCANLINE_TIFF:
	    TIFFReadScanline(tiff, tiff_real_buf, line_count-row-1, 0);
	    TIFFReadScanline(tiff, tiff_imag_buf, line_count-row-1, 1);
	    break;
	  case STRIP_TIFF:
	    ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, 
					 line_count-row-1, 0);
	    ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, 
					 line_count-row-1, 1);
	    break;
	  case TILED_TIFF:
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, 
					   line_count-row-1, 0);
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, 
					   line_count-row-1, 1);
	    break;
	  default:
	    asfPrintError("Can't read this TIFF format!\n");
	    break;
	  }
      }
      else {
	switch (tiffInfo.format) 
	  {
	  case SCANLINE_TIFF:
	    TIFFReadScanline(tiff, tiff_real_buf, row, 0);
	    TIFFReadScanline(tiff, tiff_imag_buf, row, 1);
	    break;
	  case STRIP_TIFF:
	    ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, row, 0);
	    ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, row, 1);
	    break;
	  case TILED_TIFF:
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, row, 0);
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, row, 1);
	    break;
	  default:
	    asfPrintError("Can't read this TIFF format!\n");
	    break;
	  }
      }
      for (sample=0; sample<sample_count; sample++) {
	switch (sample_format)
	  {
	  case SAMPLEFORMAT_UINT:
	    re = (float)(((uint16*)tiff_real_buf)[sample]);
	    im = (float)(((uint16*)tiff_imag_buf)[sample]);
	    break;
	  case SAMPLEFORMAT_INT:
	    re = (float)(((int16*)tiff_real_buf)[sample]);
	    im = (float)(((int16*)tiff_imag_buf)[sample]);
	    break;
	  }
	amp[sample] = sqrt(re*re + im*im);
	phase[sample] = atan2(im, re);
      }
      if (flip_horizontal) {
	for (sample=0; sample<sample_count; sample++)
	  tmp[sample] = amp[sample];
	for (sample=0; sample<sample_count; sample++)
	  amp[sample] = tmp[sample_count-sample-1];
      }
	  
      put_band_float_line(fp, meta, band*2, (int)row, amp);
      if (!ampOnly)
	put_band_float_line(fp, meta, band*2+1, (int)row, phase);
    }
      
    FREE(amp);
    FREE(phase);
    if (tmp)
      FREE(tmp);
    _TIFFfree(tiff_real_buf);
    _TIFFfree(tiff_imag_buf);
    GTIFFree(gtif);
    XTIFFClose(tiff);
  }

  // update the name field with directory name
  char *path = get_dirname(inBaseName);
  if (strlen(path)<=0)
    path = g_get_current_dir();
  char *p = path, *q = path;
  while (q) {
    if ((q = strchr(p, DIR_SEPARATOR)) != NULL)
      p = q+1;
  }
  sprintf(meta->general->basename, "%s", p);
  FREE(path);
  meta_write(meta, outDataName);

  meta_free(meta);
  FREE(radarsat2);
  FCLOSE(fp);
}