示例#1
0
int main(int argc, char *argv[])
{
  // Allocate some memory
  char *inFile = (char *) MALLOC(sizeof(char)*512);
  char *outFile = (char *) MALLOC(sizeof(char)*512);

  // Parse command line
  if (argc < 3) {
    printf("Insufficient arguments.\n"); 
    usage(argv[0]);
  }  
  strcpy(inFile, argv[1]);
  strcpy(outFile, argv[2]);
  int grid_line_count = atoi(argv[3]);

  asfSplashScreen (argc, argv);

  // Deal with metadata
  meta_parameters *metaIn = meta_read(inFile);
  meta_parameters *metaOut = meta_read(inFile);
  int nl = metaIn->general->line_count;
  int ns = metaIn->general->sample_count;
  metaOut->general->data_type = ASF_BYTE;
  meta_write(metaOut, outFile);

  // Replace image with grid
  float on_grid = 0.0;
  float off_grid = 255.0;
  float *outLine = (float *) MALLOC(sizeof(float)*ns);
  float *inLine = (float *) MALLOC(sizeof(float)*ns);

  FILE *fpIn = FOPEN(appendExt(inFile, ".img"), "rb");
  FILE *fpOut = FOPEN(appendExt(outFile, ".img"), "wb");
  int ii, kk;;
  for (ii=0; ii<nl; ii++) {
    get_float_line(fpIn, metaIn, ii, inLine);
    for (kk=0; kk<ns; kk++) {
      if (ii == 0 || ii == nl -1 || ii % (ns/grid_line_count) == 0)
	outLine[kk] = on_grid;
      else if (kk % (ns/grid_line_count) == 0)
	outLine[kk] = on_grid;
      else
	outLine[kk] = off_grid;
    }
    outLine[0] = outLine[ns-1] = on_grid;
    put_float_line(fpOut, metaOut, ii, outLine);
    asfLineMeter(ii, nl);
  }

  // Clean up
  FREE(inFile);
  FREE(outFile);
  meta_free(metaIn);
  meta_free(metaOut);

  exit(0);
}
示例#2
0
static void add_pixels(FloatImage *out, char *file,
                       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;

    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->size_x || start_line + nl > out->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 y;
    for (y=0; y<nl; ++y) {
        get_float_line(img, meta, 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)
                float_image_set_pixel(out, x + start_sample, y + start_line, v);
        }

        asfLineMeter(y, nl);
    }

    fclose(img);
    free(line);
    meta_free(meta);
}
static void ingest_polarimetry_data(char *inFile, char *inBaseName, 
				    char *outFile, char band, int create)
{
  FILE *fpIn, *fpOut;
  meta_parameters *meta = NULL;
  char tmp[10];
  int ii, kk;
  float *power = NULL;
  char *byteBuf = NULL;
  
  fpIn = FOPEN(inFile, "rb");
  append_ext_if_needed(outFile, ".img", NULL);
  if (create)
    fpOut = FOPEN(outFile, "wb");
  else
    fpOut = FOPEN(outFile, "ab");
  
  if (create) {
    meta = import_airsar_meta(inFile, inBaseName, TRUE);
    meta->general->data_type = REAL32;
    meta->general->band_count = 1;
    sprintf(meta->general->bands, "AMP-%c", band);
    meta->general->image_data_type = IMAGE_LAYER_STACK;
  }
  else {
    meta = meta_read(outFile);
    meta->general->band_count += 1;
    sprintf(tmp, ",AMP-%c", band);
    strcat(meta->general->bands, tmp);
  }      

  power = (float *) MALLOC(sizeof(float)*meta->general->sample_count);
  byteBuf = (char *) MALLOC(sizeof(char)*10);
  airsar_header *header = read_airsar_header(inFile);
  long offset = header->first_data_offset;
  FSEEK(fpIn, offset, SEEK_SET);
  for (ii=0; ii<meta->general->line_count; ii++) {
    for (kk=0; kk<meta->general->sample_count; kk++) {
      FREAD(byteBuf, sizeof(char), 10, fpIn);
      power[kk] = sqrt(((float)byteBuf[1]/254.0 + 1.5) * pow(2, byteBuf[0]));
    }
    put_float_line(fpOut, meta, ii, power);
    asfLineMeter(ii, meta->general->line_count);
  }
  FCLOSE(fpIn);
  FCLOSE(fpOut);
  meta_write(meta, outFile);
  if (power)
    FREE(power);
  if (byteBuf)
    FREE(byteBuf);
  if (meta)
    meta_free(meta);
}
示例#4
0
int
dem_to_mask(char *inDemFile, char *outMaskFile, float cutoff)
{
    meta_parameters *inDemMeta = meta_read(inDemFile);
    meta_parameters *outDemMeta = meta_read(inDemFile);

    // out metadata will differ from in only in the data type
    outDemMeta->general->data_type = ASF_BYTE;

    int x_size = inDemMeta->general->sample_count;
    int y_size = inDemMeta->general->line_count;

    float *maskbuffer = MALLOC(sizeof(float) * x_size);
    float *floatbuffer = MALLOC(sizeof(float) * x_size);

    FILE *in = fopenImage(inDemFile, "rb");
    FILE *out = fopenImage(outMaskFile, "wb");

    float mv = masked_value();
    float umv = unmasked_value();

    int y,x;
    for (y=0; y<y_size; y++) 
    {
        get_float_line(in, inDemMeta, y, floatbuffer);

        for (x=0; x < x_size; x++)            
            maskbuffer[x] = floatbuffer[x] <= cutoff ? mv : umv;

        put_float_line(out, outDemMeta, y, maskbuffer);
        asfLineMeter(y, y_size);
    }

    FCLOSE(in);
    FCLOSE(out);

    FREE(floatbuffer);
    FREE(maskbuffer);

    meta_write(outDemMeta, outMaskFile);

    meta_free(inDemMeta);
    meta_free(outDemMeta);

    asfPrintStatus("Created Mask file '%s' from DEM '%s'.\n",
                   outMaskFile, inDemFile);

    return 0;
}
void import_gridfloat(char *inBaseName, char *outBaseName)
{
    int i, j;
    int column_count, row_count;
    char *flt_file = appendExt(inBaseName, ".flt");

    // create the metadata
    char *meta_filename = appendExt(outBaseName, ".meta");

    asfPrintStatus("Building %s ...\n", meta_filename);

    meta_parameters *meta = read_meta_gridfloat_ext(inBaseName, flt_file,
						    &column_count, &row_count);

    meta_write(meta, meta_filename);

    // Now read/write the actual data.  Read as INT16, cast to
    // floats so we can use put_float_line (which will write
    // INT16 data, since we asked for it in the metadata)
    char *data_filename = appendExt(outBaseName, ".img");

    asfPrintStatus("Reading %s, writing %s ...\n", flt_file, data_filename);

    float *floats = MALLOC(sizeof(float)*column_count);
    FILE *fp = FOPEN(flt_file, "rb");
    FILE *out = FOPEN(data_filename, "wb");

    for (i=0; i<row_count; ++i) {
        FREAD(floats, sizeof(float), column_count, fp);
	//if (msbfirst) {
            for (j=0; j<column_count; ++j) {
                big32(floats[j]);
            }
	    //}
        put_float_line(out, meta, i, floats);
        asfLineMeter(i,row_count);
    }

    fclose(fp);
    fclose(out);

    free(data_filename);
    free(floats);

    free(flt_file);
}
示例#6
0
static float *
read_dem(meta_parameters *meta_dem, const char *demImg)
{
  int ns = meta_dem->general->sample_count;
  int nl = meta_dem->general->line_count;
  float *demData = MALLOC(sizeof(float)*ns*nl);

  FILE *fp = FOPEN(demImg, "rb");

  int ii;
  for (ii=0; ii<nl; ++ii) {
    get_float_line(fp, meta_dem, ii, demData + ii*ns);
    asfLineMeter(ii,nl);
  }

  FCLOSE(fp);
  return demData;
}
示例#7
0
int asf_logscale(const char *inFile, const char *outFile)
{
  int ii, jj, kk;
  meta_parameters *meta = meta_read(inFile);
  int band_count = meta->general->band_count;
  int sample_count = meta->general->sample_count;
  int line_count = meta->general->line_count;
  float *bufIn = (float *) MALLOC(sizeof(float)*sample_count);
  float *bufOut = (float *) MALLOC(sizeof(float)*sample_count);
  
  char *input = appendExt(inFile, ".img");
  char *output = appendExt(outFile, ".img");
  FILE *fpIn = FOPEN(input, "rb");
  FILE *fpOut = FOPEN(output, "wb");
  for (kk=0; kk<band_count; kk++) {
    for (ii=0; ii<line_count; ii++) {
      get_band_float_line(fpIn, meta, kk, ii, bufIn);
      for (jj=0; jj<sample_count; jj++) {
	if (FLOAT_EQUIVALENT(bufIn[jj], 0.0))
	  bufOut[jj] = 0.0;
	else
	  bufOut[jj] = 10.0 * log10(bufIn[jj]);
      }
      put_band_float_line(fpOut, meta, kk, ii, bufOut);
      asfLineMeter(ii, line_count);
    }
  }
  meta_write(meta, outFile);
  meta_free(meta);
  FCLOSE(fpIn);
  FCLOSE(fpOut);
  FREE(bufIn);
  FREE(bufOut);
  FREE(input);
  FREE(output);

  return FALSE;
}
UInt8Image *tiff_to_band_byte_image (TIFF *tif, int num_bands)
{
  // Get the raster width and height of the image.
  uint32  width;
  uint32  height;
  tsize_t scanlineSize;
  uint16  planarConfiguration;
  uint16  bitsPerSample;
  uint16  sampleFormat;
  int band;
  uint32  offset;
  uint8   *sample;

  // Get TIFF image boundary, planar configuration, and data type info
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarConfiguration);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
  TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
  if (num_bands > 1) {
    asfRequire(planarConfiguration == PLANARCONFIG_CONTIG,
              "\nTIFFs with multi-plane data not supported\n");
  }
  if (sampleFormat != SAMPLEFORMAT_UINT  &&
      sampleFormat != SAMPLEFORMAT_INT   &&
      sampleFormat != SAMPLEFORMAT_IEEEFP)
  {
    asfPrintWarning("TIFFTAG_SAMPLEFORMAT is missing or an unsupported type.  The import\n"
        "will continue but the data type will be assumed according to how many\n"
        "bits per sample exist.  This may cause unexpected results:\n"
        "    8-bits: Unsigned Integer8 (uint8) data is assumed.\n"
        "   16-bits: Signed Integer16 (int16) data is assumed.\n"
        "   32-bits: IEEE 32-Bit Floating Point (float) is assumed.\n"
        "     Other: Unsupported.\n");
  }

  // FIXME: Use resampling to reduce 16- and 32-bit data down to 8-bit byte data...
  // This situation/need is not expected to happen, or at least very rarely.
  if (bitsPerSample > 8) {
    asfPrintWarning("Image contains 16- or 32-bit data but is being imported as an 8-bit (byte) image.\n"
        "Truncation of data values may occur.\n");
  }

  // Pull the actual image data out of the TIFF and store it as a
  // byte image.
  UInt8Image *bim = uint8_image_new (width, height * num_bands);
  if (bim == NULL) return bim; // But note to you: uint8_image_new() asserts on a g_new() if it fails
  offset = height;

  // Allocate a buffer for a line of pixels.
  scanlineSize = TIFFScanlineSize(tif);
  tdata_t buf = _TIFFmalloc (scanlineSize);
  sample = (uint8*)MALLOC(sizeof(uint8)*num_bands);

  uint32 current_row;
  for (current_row = 0 ; current_row < height; current_row++) {
    asfLineMeter(current_row, height);
    TIFFReadScanline (tif, buf, current_row, 0);
    uint32 current_column;
    for (current_column = 0 ; current_column < width ; current_column++) {
      // Read chunky-formatted data, e.g. greyscale values or rgb interlaced values
      switch(bitsPerSample) {
        case 8:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((uint8*)buf)[(current_column*num_bands)+band]);
          }
          break;
        case 16:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((uint16*)buf)[(current_column*num_bands)+band]);
          }
          break;
        case 32:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((float*)buf)[(current_column*num_bands)+band]);
          }
          break;
        default:
          asfPrintError("\nUnsupported TIFF pixel data type\n");
      }
      for (band = 0; band < num_bands; band++) {
        // Write a band-sequential float image file for ASF internal use
        uint8_image_set_pixel (bim, current_column, (band*offset)+current_row,
                               sample[band]);
      }
    }
  }
  if (buf) _TIFFfree(buf);
  FREE(sample);

  return bim;
}
示例#9
0
int asf_windspeed(platform_type_t platform_type, char *band_id,
                  double wind_dir, int cmod4,
                  double landmaskHeight, char *landmaskFile, char *demFile,
                  char *inBaseName, char *colormapName, char *outBaseName)
{
  char *inDataName, outDataName[1024], outMetaName[1024];
  FILE *in = NULL, *out = NULL;

  asfPrintStatus("\n   Determining windspeeds in: %s\n", inBaseName);

  strcpy(outDataName, outBaseName);
  strcpy(outMetaName, outBaseName);
  inDataName = (char *)MALLOC(sizeof(char) * (strlen(inBaseName) + 10));
  strcpy(inDataName, inBaseName);
  append_ext_if_needed(inDataName, ".img", NULL);
  append_ext_if_needed(outDataName, ".img", NULL);
  append_ext_if_needed(outMetaName, ".meta", NULL);

  // New images for processing in to out
  meta_parameters *imd = meta_read(inBaseName);
  meta_general *img = imd->general; // convenience ptr
  meta_parameters *omd = meta_read(inBaseName);
  meta_general *omg = omd->general; // convenience ptr
  meta_sar *oms = omd->sar; // convenience ptr
  omg->band_count = 0;
  strcpy(omg->bands, "");
  strcpy(oms->polarization, "");
  if (strstr(img->bands, "VV") == NULL && strstr(img->bands, "HH") == NULL) {
    asfPrintError("Cannot find any VV or HH polarized bands in this data.  Available\n"
        "bands are %s).  Wind speeds can only be determined on Sigma0-\n"
        "calibrated SAR data in HH or VV polarizations.\n", img->bands);
  }
  in = (FILE *)FOPEN(inDataName, "rb");
  out = (FILE *)FOPEN(outDataName, "wb");
  FREE(inDataName);

  // For each band
  double alpha = 1.0; // Default for VV polarization;
  int band_num;
  float *data = (float *)MALLOC(sizeof(float) * img->sample_count);
  for (band_num = 0; band_num < img->band_count; band_num++) {
    // Get band name, check for proper polarization, and create new output bandname, set alpha
    char *band_name = get_band_name(img->bands, img->band_count, band_num);
    long offset = img->line_count * band_num;
    char polarization[2]="";
    if (strncmp_case(band_name, "SIGMA-VV", 8) == 0 ||
        strncmp_case(band_name, "SIGMA-HH", 8) == 0)
    {
      asfPrintStatus("\nProcessing wind speed calculations on band %s...\n\n", band_name);

      (omg->band_count)++;
      strcpy(polarization, (strstr(band_name, "VV") != NULL) ? "VV" : "HH");
      strcpy(oms->polarization, polarization);
      sprintf(&omg->bands[strlen(omg->bands)], "%s%s%s", WINDSPEED_BAND_BASENAME, polarization,
              (band_num < img->band_count - 1 && img->band_count > 0) ? ", " : "");
      alpha = (strcmp(polarization, "VV") == 0) ? 1.0 : DEFAULT_HH_POL_ALPHA; // For CMODx
    }
    else {
      asfPrintStatus("\nFound band: %s (Cannot calculate wind speed on this type of band)\n\n",
                     band_name);
      continue; // Skip this band
    }

    // Calculate average r_look for entire image (r_look is the angle between the NADIR line
    // and a line point directly north, the 'look angle' of the platform.)
    double r_look = asf_r_look(imd);
    double phi_diff = wind_dir - r_look;

    // Pre-populate incidence angles (as a function of sample) and get min/max incidence angle
    // as well
    int line, sample;
    double *incids = (double *)MALLOC(img->sample_count * sizeof(double));
    double min_incid = DBL_MAX;
    double max_incid = DBL_MIN;
    for (sample = 0; sample < img->sample_count; sample++) {
      incids[sample] = R2D * meta_incid(imd, img->line_count / 2, sample);
      min_incid = (incids[sample] < min_incid) ? incids[sample] : min_incid;
      max_incid = (incids[sample] > max_incid) ? incids[sample] : max_incid;
    }

    // Get min/max radar cross-sections
    asfPrintStatus("\nFinding min/max radar cross-sections...\n\n");
    double rcs_min = DBL_MAX;
    double rcs_max = DBL_MIN;
    for (line = 0; line < img->line_count; line++) {
      // Get a line
      get_float_line(in, imd, line+offset, data);
      for (sample = 0; sample < img->sample_count; sample++) {
        if (meta_is_valid_double(data[sample]) && data[sample] >= 0.0) {
          rcs_min = (data[sample] < rcs_min) ? data[sample] : rcs_min;
          rcs_max = (data[sample] > rcs_max) ? data[sample] : rcs_max;
        }
      }
      asfLineMeter(line, img->line_count);
    }

    // FIXME: Generate 2D array of windspeeds here.  One dimension is incidence angle and
    // the other is radar cross-section.  The values in the table are wind speed as a function
    // of incidence angle and radar cross-section (given the provided wind direction.)  The idea
    // is to more-quickly populate a grid of results and then to interpolate results for each
    // pixel of the image rather then perform the full calculation (very sloooow)

    double windspeed1 = 0.0, windspeed2 = 0.0;
    for (line = 0; line < img->line_count; line++) {
      // Get a line
      get_float_line(in, imd, line+offset, data);
      for (sample = 0; sample < img->sample_count; sample++) {
        // FIXME: Here is where we should apply a land mask ...in this if-statement expression
        if (meta_is_valid_double(data[sample]) && data[sample] >= 0.0) {
          // Calculate windspeed
          // FIXME: This returns the angle, at the target pixel location, between straight up
          // and the line to the satellite.  Make sure Frank's code doesn't assume the angle
          // between the line to the satellite and a horizontal line, i.e. 90 degrees minus
          // this angle.
          double incidence_angle = incids[sample];
          switch (platform_type) {
            case p_RSAT1:
              if (!cmod4) {
                // Use CMOD5 to calculate windspeeds
                double hh = alpha;
                ws_inv_cmod5((double)data[sample], phi_diff, incidence_angle,
                             &windspeed1, &windspeed2,
                             (double)MIN_CMOD5_WINDSPEED, (double)MAX_CMOD5_WINDSPEED, 25,
                             hh);
                data[sample] = windspeed1; // When 2 answers exist, take the lower (per Frank Monaldo)
              }
              else {
                // Use CMOD4 to calculate windspeeds
                asfPrintError("The CMOD4 algorithm is not yet supported.  Avoid the -cmod4\n"
                    "option for now and let %s default to using the CMOD5 algorithm\n"
                    "instead.\n");
              }
              break;
            case p_PALSAR:
            case p_TERRASARX:
            case p_ERS1:
            case p_ERS2:
            default:
              asfPrintError("Found a platform type (%s) that is not yet supported.\n",
                            (platform_type == p_PALSAR)    ? "PALSAR" :
                            (platform_type == p_TERRASARX) ? "TerraSAR-X" :
                            (platform_type == p_ERS1)      ? "ERS-1" :
                            (platform_type == p_ERS2)      ? "ERS-2" : "UNKNOWN PLATFORM");
          }
        }
      }
      put_float_line(out, omd, line+offset, data);
      asfLineMeter(line, img->line_count);
    }
  } // end for (each band)
  FREE(data);

  // Insert colormap into metadata

  meta_write(omd, outMetaName);
  meta_free(imd);
  meta_free(omd);

  asfPrintStatus("Windspeed calculation complete.\n\n");

  return EXIT_SUCCESS;
}
示例#10
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;
}
示例#11
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;
}
示例#12
0
// Main program body.
int
main (int argc, char *argv[])
{
  int currArg = 1;
  int NUM_ARGS = 2;

  handle_license_and_version_args(argc, argv, ASF_NAME_STRING);
  asfSplashScreen(argc, argv);

  if (argc<2)
      usage(ASF_NAME_STRING);
  else if (strmatches(argv[1],"-help","--help",NULL))
      print_help();

  while (currArg < (argc-NUM_ARGS)) {
    char *key = argv[currArg++];
    if (strmatches(key,"-help","--help",NULL)) {
        print_help(); // doesn't return
    }
    else if (strmatches(key,"-log","--log",NULL)) {
      CHECK_ARG(1);
      strcpy(logFile,GET_ARG(1));
      fLog = FOPEN(logFile, "a");
      logflag = TRUE;
    }
    else if (strmatches(key,"-quiet","--quiet","-q",NULL)) {
      quietflag = TRUE;
    }
    else {
      --currArg;
      break;
    }
  }

  if ((argc-currArg) < NUM_ARGS) {
    printf("Insufficient arguments.  Expected %d, got %d.\n",
           NUM_ARGS, argc-currArg);
    usage(argv[0]);
  } else if ((argc-currArg) > NUM_ARGS) {
    printf("Unknown argument: %s\n", argv[currArg]);
    usage(argv[0]);
  }

  char *in_file = argv[currArg];
  char *out_file = argv[currArg+1];

  char *in_img = appendExt(in_file, ".img");
  char *out_img = appendExt(out_file, ".img");
  char *in_meta = appendExt(in_file, ".meta");
  char *out_meta = appendExt(out_file, ".meta");

  meta_parameters *meta = meta_read(in_meta);
  if (!meta) asfPrintError("Failed to read metadata for: %s\n", in_file);

  FILE *ifp = FOPEN(in_img, "r");
  FILE *ofp = FOPEN(out_img, "w");
  float *buf = MALLOC(sizeof(float)*meta->general->sample_count);

  int ii,jj;
  for (ii=0; ii<meta->general->line_count; ++ii) {
    get_float_line(ifp, meta, ii, buf);
    for (jj=0; jj<meta->general->sample_count; ++jj) {
      if (buf[jj] < 0) {
        buf[jj] = 0;
      } else {
        buf[jj] = sqrt(buf[jj]);
      }
    }
    put_float_line(ofp, meta, ii, buf);
    asfLineMeter(ii,meta->general->line_count);
  }

  FCLOSE(ifp);
  FCLOSE(ofp);
  FREE(buf);

  if (meta->stats) { 
    FREE(meta->stats);
    meta->stats = NULL;
  }
 
  meta_write(meta, out_meta);
  meta_free(meta);

  FREE(in_img);
  FREE(out_img);
  FREE(in_meta);
  FREE(out_meta);

  asfPrintStatus("Done.\n");
  return EXIT_SUCCESS;
}
示例#13
0
int multilook(char *inFile, char *outFile, char *metaFile, char *overlay)
{
  meta_parameters *metaIn, *metaOut;
  char inAmp[255], inPhase[255], outAmp[255], outPhase[255], outRGB[255];
  FILE *fpAmpIn, *fpPhaseIn, *fpAmpOut, *fpPhaseOut, *fpRGB, *fpOverlay;
  int look_line, look_sample, step_line, step_sample, i,line, sample, row, col;
  long long nitems, newitems, in_sample_count, in_line_count, out_sample_count;
  long long out_line_count, ds;
  register float *ampIn, *phaseIn, ampScale;
  float *ampOut, *phaseOut, *rgb, *scaleIn, Sin[256],Cos[256], scale;
  complexFloat z;
  register float tmp,zImag,zReal,ampI;
  register int index,offset;
  const float convers=256.0/(2*3.14159265358979);
  
  // Create filenames and open files for reading
  create_name(inAmp, inFile, "_amp.img");
  create_name(inPhase, inFile, "_phase.img");
  metaIn = meta_read(inPhase);
  metaOut = meta_read(inPhase);
  // FIXME: Should write out two-banded file. Too much to fix in the rest of
  //        the unwrapping code. Leaving that for clean up after the course.
  create_name(outAmp, outFile, "_amp.img");
  create_name(outPhase, outFile, "_phase.img");
  create_name(outRGB, outFile, "_phase_rgb.img");
  metaIn = meta_read(inFile);
  metaOut = meta_read(inFile);

  // Create new metadata file for the amplitude and phase.
  look_sample = step_sample = 1;
  look_line = step_line = metaOut->sar->look_count;  
  in_sample_count = metaIn->general->sample_count;
  in_line_count = metaIn->general->line_count;
  metaOut->general->sample_count /= step_sample;
  metaOut->general->line_count /= step_line;
  out_sample_count = metaOut->general->sample_count;
  out_line_count = metaOut->general->line_count;
  metaOut->sar->multilook = 1;
  metaOut->sar->line_increment = 1;
  metaOut->sar->sample_increment = 1;
  metaOut->sar->azimuth_time_per_pixel *= step_line;
  metaOut->general->x_pixel_size *= step_sample;
  metaOut->general->y_pixel_size *= step_line;
  meta_write(metaOut, outAmp);
  meta_write(metaOut, outPhase);
  //meta_write(metaOut, outFile);
  meta_write(metaOut, outRGB);
  
  // Open the files
  fpAmpIn = fopenImage(inAmp, "rb");
  fpPhaseIn = fopenImage(inPhase, "rb");
  fpAmpOut = fopenImage(outAmp, "wb");
  fpPhaseOut = fopenImage(outPhase, "wb");
  //FILE *fpIn = fopenImage(inFile, "rb");
  //FILE *fpOut = fopenImage(outFile, "wb");
  fpRGB = fopenImage(outRGB, "wb");
  if (overlay)
    fpOverlay = fopenImage(overlay, "rb");
  
  for (i=0;i<256;i++) {
    float phas=((float)i)/256.0*(2*3.14159265358979);
    Sin[i]=sin(phas);
    Cos[i]=cos(phas);
  }
  
  // Set data variables
  ampScale = 1.0/(look_line*look_sample);
  nitems   = (look_line-step_line)*in_sample_count;
  newitems = step_line*in_sample_count;
  
  ds       = sizeof(float);
  ampIn    = (float *)MALLOC(ds*(newitems+nitems+look_sample));
  phaseIn  = (float *)MALLOC(ds*(newitems+nitems+look_sample));
  if (overlay)
    scaleIn  = (float *)MALLOC(ds*(newitems+nitems+look_sample));
  ampOut   = (float *)MALLOC(ds*out_sample_count);
  rgb      = (float *)MALLOC(ds*out_sample_count);
  phaseOut = (float *)MALLOC(ds*out_sample_count);
  
  // Let the user know what's happening  
  asfPrintStatus("Input is %lld lines by %lld samples\n",
		 in_line_count, in_sample_count);
  asfPrintStatus("Ouput is %lld lines by %lld samples\n\n",
		 out_line_count,out_sample_count);
  
  // Get to work
  for(line=0; line<out_line_count; line++) {
    
    get_float_lines(fpAmpIn, metaIn, line*step_line, look_line, ampIn);
    get_float_lines(fpPhaseIn, metaIn, line*step_line, look_line, phaseIn);
    //get_band_float_lines(fpIn, metaIn, 0, line*step_line, look_line, ampIn);
    //get_band_float_lines(fpIn, metaIn, 1, line*step_line, look_line, 
    //			 phaseIn);
    if (overlay)
      get_float_lines(fpOverlay, metaOut, line, 1, scaleIn);
    
    // Begin adding data
    for (sample=0; sample<out_sample_count; sample++) { 
      tmp = 0.0, zReal=0.0, zImag=0.0;
      // Add up looking area
      for (col=0; col<look_sample; col++) {
	offset=sample*step_sample+col;
	for (row=0; row<look_line; row++) {
	  ampI = ampIn[offset];
	  index = 0xFF&((int)(phaseIn[offset]*convers));
	  tmp += ampI * ampI;
	  zReal += ampI * Cos[index];
	  zImag += ampI * Sin[index];
	  offset += in_sample_count;
	}
      }
      
      // Get phase from complex values
      z.real = zReal;
      z.imag = zImag;

      ampOut[sample] = Cabs(z)*ampScale; 
      phaseOut[sample] = Cphase(z);
      if (overlay)
	scale = scaleIn[sample];
      else
	scale = 1.0;
      if (phaseOut[sample] < 0.0)
	rgb[sample] = (phaseOut[sample] + M_PI) * scale;
      else
	rgb[sample] = phaseOut[sample] * scale;
    }
    
    // Write out data to file
    //put_band_float_line(fpOut, metaOut, 0, line, ampOut);
    //put_band_float_line(fpOut, metaOut, 1, line, phaseOut);
    put_float_line(fpAmpOut, metaOut, line, ampOut);
    put_float_line(fpPhaseOut, metaOut, line, phaseOut);
    put_float_line(fpRGB, metaOut, line, rgb);
    
    asfLineMeter(line, out_line_count);
        
    // Reposition data for next read
    for (i=0;i<nitems;i++) {
      ampIn[i] = ampIn[i + newitems];
      phaseIn[i] = phaseIn[i + newitems];
    }
  }
  
  // Clean up
  FREE(ampIn);
  FREE(phaseIn);
  FREE(ampOut);
  FREE(rgb);
  FREE(phaseOut);
  if (overlay) {
    FREE(scaleIn);
    FCLOSE(fpOverlay);
  }
  FCLOSE(fpAmpIn);
  FCLOSE(fpPhaseIn);
  FCLOSE(fpAmpOut);
  FCLOSE(fpPhaseOut);
  //FCLOSE(fpIn);
  //FCLOSE(fpOut);
  FCLOSE(fpRGB);
  
  meta_free(metaIn);
  meta_free(metaOut);

  // Export a color version of the interferogram to JPEG
  create_name(outPhase, outFile, "_phase_rgb");
  check_return(asf_export_with_lut(JPEG, SIGMA, "interferogram.lut", 
				   outPhase, outPhase),
	       "colorized interferogram (asf_export)");

  return 0;
}
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);
}
示例#15
0
int dem2phase(char *demFile, char *baseFile, char *phaseFile)
{
  int x, y, start_sample, start_line, line_count, sample_count;
  double k, *phase2elevBase, *sinFlat, *cosFlat, xScale, yScale;
  baseline base;
  meta_parameters *meta;
  FILE *fpDem, *fpPhase;
  float *phase,*dem;
  
  meta = meta_read(demFile);
  start_sample = meta->general->start_sample;
  start_line = meta->general->start_line;
  xScale = meta->sar->sample_increment;
  yScale = meta->sar->line_increment;
  line_count = meta->general->line_count;
  sample_count = meta->general->sample_count;
  
  meta_write(meta, phaseFile);
  
  // Allocate some memory
  phase = (float *)MALLOC(sizeof(float)*sample_count);
  dem =(float *)MALLOC(sizeof(float)*sample_count);
 
  // Get wavenumber
  k = meta_get_k(meta);
  
  // Read in baseline values
  base = read_baseline(baseFile);

  // Open files  
  fpDem = fopenImage(demFile, "rb");
  fpPhase = fopenImage(phaseFile,"wb");
  
  /* calculate the sine of the incidence angle across cols*/
  sinFlat = (double *)MALLOC(sizeof(double)*sample_count);
  cosFlat = (double *)MALLOC(sizeof(double)*sample_count);
  phase2elevBase = (double *)MALLOC(sizeof(double)*sample_count);
  for (x=0; x<sample_count; x++) {
    int img_x = x*xScale + start_sample;
    double incid = meta_incid(meta, 0.0, (float)img_x);
    double flat = meta_flat(meta, 0.0, (float)img_x);
    sinFlat[x] = sin(flat);
    cosFlat[x] = cos(flat);
    phase2elevBase[x] = 
      meta_get_slant(meta, 0.0, (float)img_x) * sin(incid)/(2.0*k);
  }
  
  
  // Loop through each row and calculate height
  for (y=0;y<line_count;y++) {
    double Bn_y, Bp_y;
    
    // Read in data 
    get_float_line(fpDem, meta, y, dem);
    
    // Calculate baseline for this row
    meta_interp_baseline(meta, base, y*(int)yScale+start_line, &Bn_y, &Bp_y);
    
    // Step through each pixel in row
    for (x=0; x<sample_count; x++)
      phase[x] = dem[x]/phase2elevBase[x]*(-Bp_y*sinFlat[x]-Bn_y*cosFlat[x]);
    put_float_line(fpPhase, meta, y, phase);
    asfLineMeter(y, line_count);
  }
  asfPrintStatus("Wrote %d lines of simulated phase data.\n\n", line_count);
  
  // Clean up
  FREE(phase);
  FREE(dem);
  FCLOSE(fpPhase);
  FCLOSE(fpDem);

  return(0);
}
示例#16
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);
}
示例#17
0
static int save_as_asf(ImageInfo *ii,
                       const char *out_file, int what_to_save,
                       int strict_boundary, int load)
{
    // See if we can open the output file up front
    FILE *outFp = fopen(out_file, "wb");
    if (!outFp) {
        // failed to open the output file!
        char errbuf[1024];
        snprintf(errbuf, 1024, "Failed to open %s: %s", out_file,
            strerror(errno));
        message_box(errbuf);
        strcat(errbuf, "\n");
        printf("%s", errbuf);
        return FALSE; // failure
    }

    assert (g_poly->n > 0);
    assert (crosshair_line > 0 && crosshair_samp > 0);

    meta_parameters *meta = ii->meta;

    // figure out where to chop
    int line_min, line_max, samp_min, samp_max, nl, ns;
    compute_extent(meta, &line_min, &line_max, &samp_min, &samp_max,
        &nl, &ns);

    // generate metadata
    char *out_metaname = appendExt(out_file, ".meta");
    printf("Generating %s...\n", out_metaname);

    // data will be saved as floating point, except scaled pixel values,
    // which we can make bytes.
    data_type_t data_type = REAL32;
    if (what_to_save == SCALED_PIXEL_VALUE)
      data_type = ASF_BYTE;

    meta_parameters *out_meta =
      build_metadata(meta, out_file, nl, ns, line_min, samp_min, data_type,
                     what_to_save);

    // put_float_line() will always dump BYTE data if the optical block
    // is present... we want to be in control of the data type, so we must
    // wipe out this block
    if (out_meta->optical) {
      FREE(out_meta->optical);
      out_meta->optical=NULL;
    }

    if (what_to_save == LAT_LON_2_BAND) {
      out_meta->general->band_count = 2;
      strcpy(out_meta->general->bands, "LAT,LON");
    }

    // define clipping region, if necessary
    double xp[MAX_POLY_LEN+2], yp[MAX_POLY_LEN+2];
    int i,j,n=0;

    if (strict_boundary)
        define_clipping_region(meta, &n, xp, yp);

    float ndv = 0;
    if (meta_is_valid_double(out_meta->general->no_data))
        ndv = out_meta->general->no_data;
    else if (strict_boundary) // need to set a no data value in this case
        out_meta->general->no_data = 0.;

    meta_write(out_meta, out_metaname);

    // now actually write the data
    printf("Generating %s...\n", out_file);

    if (what_to_save == LAT_LON_2_BAND) {
      // dump a 2-band image, lat & lon data
      float *lats = MALLOC(sizeof(float)*ns);
      float *lons = MALLOC(sizeof(float)*ns);
      for (i=0; i<nl; ++i) {
        int l = line_min+i;
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                double lat, lon;
                meta_get_latLon(meta, l, s, 0, &lat, &lon);
                lats[j] = (float)lat;
                lons[j] = (float)lon;
            }
            else {
                lats[j] = ndv;
                lons[j] = ndv;
            }
        }
        put_band_float_line(outFp, out_meta, 0, i, lats);
        put_band_float_line(outFp, out_meta, 1, i, lons);
        asfLineMeter(i,nl);
      }
      free(lats);
      free(lons);
    }
    else {
      // normal case
      float *buf = MALLOC(sizeof(float)*ns);
      for (i=0; i<nl; ++i) {
        int l = line_min+i;
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            float val;
            if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                val = get_data(ii, what_to_save, l, s);
            }
            else {
                val = ndv;
            }
            buf[j] = val;
        }
        put_float_line(outFp, out_meta, i, buf);
        asfLineMeter(i,nl);
      }
      free(buf);
    }
    fclose(outFp);
    meta_free(out_meta);

    // load the generated file if we were told to
    if (load)
        load_file(out_file);

    return TRUE;
}
示例#18
0
int geoid_adjust(const char *input_filename, const char *output_filename)
{
  char *input_img = appendExt(input_filename, ".img");
  char *input_meta = appendExt(input_filename, ".meta");

  char *output_img = appendExt(output_filename, ".img");
  char *output_meta = appendExt(output_filename, ".meta");

  if (!fileExists(input_img))
    asfPrintError("File not found: %s\n", input_img);
  if (!fileExists(input_meta))
    asfPrintError("File not found: %s\n", input_meta);

  meta_parameters *meta = meta_read(input_meta);
  int nl = meta->general->line_count;
  int ns = meta->general->sample_count;
  int ii, jj;

  FILE *fpIn = FOPEN(input_img, "rb");
  FILE *fpOut = FOPEN(output_img, "wb");
  float *buf;

  // Two ways we can do this:
  //   1) call meta_get_latLon at every point
  //   2) call meta_get_latLon at certain points and interpolate between
  // We will use the first when we have a lat/lon image, and the second for
  // everything else.
  int latlon_image = meta->projection &&
                     meta->projection->type == LAT_LONG_PSEUDO_PROJECTION;

  double avg = 0.0;
  int num=0;

  asfPrintStatus("Performing geoid correction.\n");
  asfPrintStatus(" Input file: %s\n", input_filename);
  asfPrintStatus(" Output file: %s\n", output_filename);

  if (latlon_image) {
    asfPrintStatus("Lat/Lon image, not using mapping interpolation.\n");
    buf = MALLOC(sizeof(float)*ns);
    for (ii=0; ii<nl; ++ii) {
      get_float_line(fpIn, meta, ii, buf);
      for (jj=0; jj<ns; ++jj) {
        double lat, lon;
        meta_get_latLon(meta, ii, jj, 0, &lat, &lon);
        if (buf[jj] > -900 && buf[jj] != meta->general->no_data)
        {
          float ht = get_geoid_height(lat,lon);
          buf[jj] += ht;
          avg += ht;
          ++num;
        }
      }
      put_float_line(fpOut, meta, ii, buf);
      asfLineMeter(ii,nl);
    }
  }
  else {
    asfPrintStatus("Not a Lat/Lon image, using mapping interpolation.\n");
    double tol = .0001;
    int size = find_grid_size(meta, 512, .1*tol);

    int test_mode = 1;
    buf = MALLOC(sizeof(float)*ns*size);

    // these are for tracking the quality of the bilinear interp
    // not used if test_mode is false
    int num_out_of_tol = 0;
    int num_checked = 0;
    int num_bad = 0;
    double max_err = 0;
    double avg_err = 0;

    for (ii=0; ii<nl; ii += size) {
      int line_lo = ii;
      int line_hi = ii + size;

      if (ii+size >= nl)
        size = nl-ii;

      get_float_lines(fpIn, meta, ii, size, buf);

      for (jj=0; jj<ns; jj += size) {
        double lats[4], lons[4];

        int samp_lo = jj;
        int samp_hi = jj + size;

        get_interp_params(meta, line_lo, line_hi, samp_lo, samp_hi, lats, lons);

        int iii, jjj;
        for (iii=0; iii<size; ++iii) {
          for (jjj=0; jjj<size && jj+jjj<ns; ++jjj) {
            int kkk = iii*ns + jj + jjj;
            assert(kkk < ns*size);

            double lat, lon;
            xy_interp(ii+iii, jj+jjj, line_lo, line_hi, samp_lo, samp_hi, lats, lons,
                      &lat, &lon);

            // random checking of the quality of our interpolations
            if (test_mode && iii%11==0 && jjj%13==0) {
              double real_lat, real_lon;
              img_to_latlon(meta, ii+iii, jj+jjj, &real_lat, &real_lon);
              double err = hypot(real_lat - lat, real_lon - lon);

              avg_err += err;
              if (err > max_err)
                max_err = err;

              if (err > .1*tol) {
                asfPrintStatus("Out of tolerance at %d,%d: (%f,%f) vs (%f,%f) -> %f\n",
                               ii+iii, jj+jjj, lat, lon, real_lat, real_lon,
                               err);
                ++num_out_of_tol;
              }
              if (err > tol) {
                asfPrintStatus("Error is larger than %f!\n", .01*tol);
                ++num_bad;
              }
              ++num_checked;
            }

            if (buf[kkk] > -900 && buf[kkk] != meta->general->no_data)
            {
              float ht = get_geoid_height(lat,lon);
              buf[kkk] += ht;
              avg += ht;
              ++num;
            }
          }  
        }
      }
      put_float_lines(fpOut, meta, ii, size, buf);
      asfPrintStatus("Completed %.1f%%  \r", 100.*ii/(double)nl);
    }
    asfPrintStatus("Completed 100%%   \n");
  }

  avg /= (double)(num);
  asfPrintStatus("Average correction: %f\n", avg);

  meta_write(meta, output_meta);
  meta_free(meta);

  FCLOSE(fpIn);
  FCLOSE(fpOut);

  FREE(buf);
  FREE(input_img);
  FREE(input_meta);
  FREE(output_img);
  FREE(output_meta);

  // success
  return 0;
}
void asf_airsar_import(char *inFile, char *outFile, int insar, int polar)
{
  airsar_header *header = NULL;
  meta_parameters *metaIn = NULL, *metaOut = NULL;
  FILE *fpIn, *fpOut;
  float *floatBuf;
  char dataName[1024], *airsar_basename=NULL;
  int ii, kk, create=TRUE, line_count;
  int dem=FALSE, amp=FALSE, coh=FALSE;
  long line_offset;

  // First check for the existence of the input file. In this case we ingest
  // a single AirSAR file and ignore any other option that is passed in.
  if (fileExists(inFile) && strstr(inFile, "_meta.airsar") == NULL) {

    // Check what kind of data it is
    if (strstr(inFile, ".demi2"))
      dem = TRUE;
    else if (strstr(inFile, ".vvi2"))
      amp = TRUE;
    else if (strstr(inFile, ".corgr"))
      coh = TRUE;
    // FIX ME: Does not deal with polarimetric data yet

    header = read_airsar_header(inFile);
    metaIn = import_airsar_meta(inFile, airsar_basename, TRUE);
    line_offset = header->first_data_offset/metaIn->general->sample_count/2;
    metaIn->general->line_count += line_offset;
    metaOut = import_airsar_meta(inFile, airsar_basename, TRUE);

    // Assign appropriate data type
    if (dem || amp)
      metaIn->general->data_type = INTEGER16;
    else 
      metaIn->general->data_type = ASF_BYTE;

    metaOut->general->data_type = REAL32;
    floatBuf = (float *) MALLOC(sizeof(float)*metaIn->general->sample_count);
    fpIn = FOPEN(inFile, "rb");
    append_ext_if_needed(outFile, ".img", NULL);
    fpOut = FOPEN(outFile, "wb");
    for (ii=0; ii<metaOut->general->line_count; ii++) {

      // Interferometric data can be read using get_float_line
      if (dem || amp || coh)
	get_float_line(fpIn, metaIn, ii+line_offset, floatBuf);

      // DEM needs some additional treatment      
      if (dem) {
	for (kk=0; kk<metaIn->general->sample_count; kk++)
	  floatBuf[kk] = floatBuf[kk]*metaIn->airsar->elevation_increment +
	    metaIn->airsar->elevation_offset;
      }

      // Writing away should work the same way
      put_float_line(fpOut, metaOut, ii, floatBuf);
      asfLineMeter(ii, metaOut->general->line_count);
    }
    FCLOSE(fpIn);
    FCLOSE(fpOut);
    if (dem) {
      metaOut->general->image_data_type = DEM;
      strcpy(metaOut->general->bands, "DEM");
    }
    else if (amp) {
      metaOut->general->image_data_type = AMPLITUDE_IMAGE;
      strcpy(metaOut->general->bands, "AMPLITUDE");
    }
    else if (coh) {
      metaOut->general->image_data_type = COHERENCE_IMAGE;
      strcpy(metaOut->general->bands, "COHERENCE");
    }
    meta_write(metaOut, outFile);
  }
  // Take care of interferometric layer stack
  else if (insar) {

    // Check for DEM
    sprintf(dataName, "%s.demi2", inFile);
    if (!fileExists(dataName))
      asfPrintError("Could not find DEM (%s)\nDEM is required for reliable"
		    "geometry and geolocation\n", dataName);
    else {
      printf("Ingesting DEM (%s) ...\n", dataName);
      metaIn = import_airsar_meta(dataName, inFile, TRUE);
      line_count = metaIn->general->line_count;
      ingest_insar_data(dataName, inFile, "DEM", sizeof(short), line_count,
			outFile, create);
      create = FALSE;
    }

    // Check for amplitude image
    sprintf(dataName, "%s.vvi2", inFile);
    if (!fileExists(dataName))
      asfPrintWarning("Could not find amplitude image (%s)\n", dataName);
    else {
      printf("Ingesting amplitude image (%s) ...\n", dataName);
      ingest_insar_data(dataName, inFile, "AMPLITUDE", sizeof(short), 
			line_count, outFile, create);
      create = FALSE;
    }

    // Check for coherence image
    sprintf(dataName, "%s.corgr", inFile);
    if (!fileExists(dataName))
      asfPrintWarning("Could not find coherence image (%s)\n", dataName);
    else {
      printf("Ingesting coherence image (%s) ...\n", dataName);
      ingest_insar_data(dataName, inFile, "COHERENCE", sizeof(char), 
			line_count, outFile, create);
      create = FALSE;
    }    
  }
  // Take care of polarimetric layer stack
  // We will just put all available power images into a multiband image
  else if (polar) {

    // Check for C-band data
    sprintf(dataName, "%s_c.datgr", inFile);
    if (!fileExists(dataName))
      sprintf(dataName, "%s_c.dat", inFile);
    if (!fileExists(dataName))
      asfPrintWarning("Could not find polarimetric data set (%s)\n",
		      dataName);
    else {
      printf("Ingesting C band data (%s) ...\n", dataName);
      ingest_polarimetry_data(dataName, inFile, outFile, 'C', create);
      create = FALSE;
    }

    // Check for L-band data
    sprintf(dataName, "%s_l.datgr", inFile);
    if (!fileExists(dataName))
      sprintf(dataName, "%s_l.dat", inFile);
    if (!fileExists(dataName))
      asfPrintWarning("Could not find polarimetric data set (%s)\n",
		      dataName);
    else {
      printf("Ingesting L band data (%s) ...\n", dataName);
      ingest_polarimetry_data(dataName, inFile, outFile, 'L', create);
      create = FALSE;
    }

    // Check for P-band data
    sprintf(dataName, "%s_p.datgr", inFile);
    if (!fileExists(dataName))
      sprintf(dataName, "%s_p.dat", inFile);
    if (!fileExists(dataName))
      asfPrintWarning("Could not find polarimetric data set (%s)\n",
		      dataName);
    else {
      printf("Ingesting P band data (%s) ...\n", dataName);
      ingest_polarimetry_data(dataName, inFile, outFile, 'P', create);
      create = FALSE;
    }    
  }
  // Regular ingest
  else 
    import_airsar(inFile, r_AMP, outFile);

  // Clean up time
  if (metaIn)
    meta_free(metaIn);
  if (metaOut)
    meta_free(metaOut);
}
示例#20
0
int main(int argc, char *argv[])
{
    if (argc != 8) usage();

    int type = 0; // 0=?, 1=sinc, 2=pole, 3=pyr

    char *in = argv[6];
    char *out = argv[7];

    int line = atoi(argv[2]);
    int samp = atoi(argv[3]);
    int radius = atoi(argv[4]);
    float height = atof(argv[5]);

    if (strcmp(argv[1], "-sinc")==0) type=1;
    if (strcmp(argv[1], "-pole")==0) type=2;
    if (strcmp(argv[1], "-pyr")==0) type=3;
    if (type==0) { printf("Unknown pole type.\n"); usage(); }

    printf("Adding a pole:\n");
    printf("  Center point: (%d,%d)\n", line, samp);
    printf("  Radius: %d\n", radius);
    printf("  Height: %f\n", height);
    if (type!=2)
        printf("    Note that the height value is **added** to the existing "
               "terrain height.\n\n");

    printf("  Input file: %s\n", in);
    printf("  Output file: %s\n", out);

    printf("  Pole type: %s\n", argv[1]+1);

    meta_parameters *meta = meta_read(in);
    int ns = meta->general->sample_count;
    int nl = meta->general->line_count;

    FILE *inDEM = fopenImage(in, "rb");
    FILE *outDEM = fopenImage (out, "wb");

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

    int i,l;
    for (l = 0; l < nl; ++l) {
        get_float_line(inDEM, meta, l, demLine);
        for (i = 0; i < ns; ++i) {
            double x;

            // sinc and pole use circular posts, real distance
            // pyr uses distance measured along the gridlines
            if (type==1 || type==2)
                x = hypot(i-samp, l-line);
            else if (type == 3)
                x = dmax(fabs(i-samp),fabs(l-line));

            if (x < (double)radius) {
                if (type==1) { // sinc
                    if (i==samp && l==line)
                        demLine[i] = height;
                    else {
                        x *= M_PI/radius;
                        demLine[i] += height * sin(x)/x;
                    }
                } else if (type==2) { // pole
                    demLine[i] = height;
                } else if (type==3) { // pyr
                    demLine[i] += height * (radius-x)/radius;
                } else {
                    printf("Impossible: type=%d\n", type);
                    exit(1);
                }
            }
        }
        put_float_line(outDEM, meta, l, demLine);
        asfLineMeter(l,nl);
    }

    meta_write(meta, out);
    fclose(inDEM);
    fclose(outDEM);
    return 0;
}
static void ingest_insar_data(char *inFile, char *inBaseName, char *band,
			      int size, int line_count, char *outFile, 
			      int create)
{
  airsar_header *header;
  meta_parameters *metaIn = NULL, *metaOut = NULL;
  FILE *fpIn, *fpOut;
  int ii, kk, line_offset;
  float *floatBuf;
  char tmp[10];
  
  fpIn = FOPEN(inFile, "rb");
  append_ext_if_needed(outFile, ".img", NULL);
  if (create)
    fpOut = FOPEN(outFile, "wb");
  else
    fpOut = FOPEN(outFile, "ab");

  if (create) {
    metaOut = import_airsar_meta(inFile, inBaseName, TRUE);
    metaOut->general->data_type = REAL32;
    metaOut->general->band_count = 1;
    sprintf(metaOut->general->bands, "%s", band);
    metaOut->general->image_data_type = IMAGE_LAYER_STACK;
  }
  else {
    metaOut = meta_read(outFile);
    metaOut->general->band_count += 1;
    sprintf(tmp, ",%s", band);
    strcat(metaOut->general->bands, tmp);
  }      

  header = read_airsar_header(inFile);
  metaIn = import_airsar_meta(inFile, inBaseName, TRUE);
  line_offset = header->first_data_offset/metaIn->general->sample_count/size;
  metaIn->general->line_count = line_count + line_offset;
  if (size == 2)
    metaIn->general->data_type = INTEGER16;
  else if (size == 1)
    metaIn->general->data_type = ASF_BYTE;
  floatBuf = (float *) MALLOC(sizeof(float)*metaIn->general->sample_count);
  for (ii=0; ii<line_count; ii++) {
    get_float_line(fpIn, metaIn, ii+line_offset, floatBuf);
    if (strcmp_case(band, "DEM") == 0) {
      for (kk=0; kk<metaIn->general->sample_count; kk++)
	floatBuf[kk] = floatBuf[kk]*metaIn->airsar->elevation_increment +
	  metaIn->airsar->elevation_offset;
    }
    put_float_line(fpOut, metaOut, ii, floatBuf);
    asfLineMeter(ii, line_count);
  }
  FCLOSE(fpIn);
  FCLOSE(fpOut);
  meta_write(metaOut, outFile);

  if (floatBuf)
    FREE(floatBuf);
  if (metaIn)
    meta_free(metaIn);
  if (metaOut)
    meta_free(metaOut);
}
void
banded_float_image_export_as_jpeg(BandedFloatImage *self, const char *output_name)
{
  struct jpeg_compress_struct cinfo;
  struct jpeg_error_mgr jerr;
  int i;

  assert(self->nbands >= 1);

  float *min, *max, *mean, *stddev, *lin_min, *lin_max;
  min = MALLOC(sizeof(float)*self->nbands);
  max = MALLOC(sizeof(float)*self->nbands);
  mean = MALLOC(sizeof(float)*self->nbands);
  stddev = MALLOC(sizeof(float)*self->nbands);

  for (i=0; i<self->nbands; ++i) {
      float_image_statistics(self->images[i], &min[i], &max[i], &mean[i], &stddev[i], -999);
      lin_min[i] = mean[i] - 2 * stddev[i];
      lin_max[i] = mean[i] + 2 * stddev[i];
  }

  cinfo.err = jpeg_std_error (&jerr);
  jpeg_create_compress (&cinfo);

  FILE *ofp = fopen (output_name, "wb");
  if ( ofp == NULL ) {
    asfPrintError("Open of %s for writing failed: %s",
                  output_name, strerror(errno));
  }

  jpeg_stdio_dest (&cinfo, ofp);

  int nl = banded_float_image_get_size_y(self);
  int ns = banded_float_image_get_size_x(self);

  cinfo.image_width = ns;
  cinfo.image_height = nl;

  cinfo.input_components = 3;
  cinfo.in_color_space = JCS_RGB;

  jpeg_set_defaults (&cinfo);
  jpeg_start_compress (&cinfo, TRUE);

  JSAMPLE *jsample_row = MALLOC(sizeof(JSAMPLE)*ns*3);
  JSAMPROW *row_pointer = MALLOC(sizeof(JSAMPROW));

  while (cinfo.next_scanline < cinfo.image_height) {
      for (i=0; i<ns; ++i) {
          int band = 0;
          int r = scale_to_byte(lin_min[band], lin_max[band],
              banded_float_image_get_pixel(self, band, cinfo.next_scanline, i));

          if (band < self->nbands-1) ++band;
          int g = scale_to_byte(lin_min[band], lin_max[band],
              banded_float_image_get_pixel(self, band, cinfo.next_scanline, i));

          if (band < self->nbands-1) ++band;
          int b = scale_to_byte(lin_min[band], lin_max[band],
              banded_float_image_get_pixel(self, band, cinfo.next_scanline, i));

          jsample_row[i*3+0] = (JSAMPLE) r;
          jsample_row[i*3+1] = (JSAMPLE) g;
          jsample_row[i*3+2] = (JSAMPLE) b;
      }
      row_pointer[0] = jsample_row;
      int written = jpeg_write_scanlines(&cinfo, row_pointer, 1);
      if (written != 1)
          asfPrintError("Failed to write the correct number of lines.\n");
      asfLineMeter(cinfo.next_scanline, cinfo.image_height);
  }

  FREE(row_pointer);
  FREE(jsample_row);
  jpeg_finish_compress (&cinfo);
  FCLOSE (ofp);
  jpeg_destroy_compress (&cinfo);
}
示例#23
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;
}
示例#24
0
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;
}
示例#25
0
static void add_to_stack(char *out, int band, char *file,
                         int size_x, int size_y,
                         double start_x, double start_y,
                         double per_x, double per_y, int multiband)
{
    meta_parameters *metaIn = meta_read(file);
    meta_parameters *metaOut = meta_read(out);
    char *base = (char *) MALLOC(sizeof(char)*512);
    int start_line, start_sample;

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

    int ns = metaIn->general->sample_count;
    int nl = metaIn->general->line_count;

    asfPrintStatus("  Location in stacked image is S:%d-%d, L:%d-%d\n",
        start_sample, start_sample + size_x,
        start_line, start_line + size_y);

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

    FILE *fpIn = FOPEN(file, "rb");
    FILE *fpOut;
    char *metaFile = appendExt(out, ".meta");
    if (band > 0 || !multiband) {
      fpOut = FOPEN(out, "ab");
      sprintf(base, ",%s", get_basename(file));
      strcat(metaOut->general->bands, base);
    }
    else {
      fpOut = FOPEN(out, "wb");
      sprintf(base, "%s", get_basename(file));
      strcpy(metaOut->general->bands, base);
    }
    if (multiband)
      metaOut->general->band_count = band + 1;
    else
      metaOut->general->band_count = 1;
    meta_write(metaOut, metaFile);
    float *line = MALLOC(sizeof(float)*size_x);

    int y;
    for (y=start_line; y<start_line+size_y; ++y) {
      get_partial_float_line(fpIn, metaIn, y, start_sample, size_x, line);
      if (multiband) 
	put_band_float_line(fpOut, metaOut, band, y-start_line, line); 
      else
	put_float_line(fpOut, metaOut, y-start_line, line); 
      asfLineMeter(y, start_line+size_y);
    }

    FCLOSE(fpIn);
    FCLOSE(fpOut);
    FREE(line);
    FREE(metaFile);
    FREE(base);
    meta_free(metaIn);
    meta_free(metaOut);
}
示例#26
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
}
示例#27
0
static int save_as_csv(ImageInfo *ii, 
                       const char *out_file, int what_to_save,
                       int strict_boundary, int load)
{
    int i,j;

    assert (g_poly->n > 0);
    assert (crosshair_line > 0 && crosshair_samp > 0);

    meta_parameters *meta = ii->meta;

    int line_min, line_max, samp_min, samp_max, nl, ns;
    compute_extent(meta, &line_min, &line_max, &samp_min, &samp_max,
        &nl, &ns);

    if (nl>500 || ns>500) {
        // too big for csv -- Excel etc. will choke
        char errbuf[1024];
        snprintf(errbuf, 1024,
             "\nRegion is too large (%dx%d) to export as CSV (500x500 max)\n\n",
             nl, ns);
        message_box(errbuf);
        printf("%s", errbuf);
        return FALSE; // failure
    }

    FILE *outFp = fopen(out_file, "w");
    if (!outFp) {
        // failed to open the output file!
        char errbuf[1024];
        snprintf(errbuf, 1024, "Failed to open %s: %s", out_file,
            strerror(errno));
        message_box(errbuf);
        strcat(errbuf, "\n");
        printf("%s", errbuf);
        return FALSE; // failure
    }

    printf("Generating %s...\n", out_file);

    // define clipping region, if necessary
    double xp[MAX_POLY_LEN+2], yp[MAX_POLY_LEN+2];
    int n=0;

    if (strict_boundary)
        define_clipping_region(meta, &n, xp, yp);

    // generate csv
    fprintf(outFp, ",");
    for (j=0; j<ns; ++j) {
      if (what_to_save==LAT_LON_2_BAND)        
        fprintf(outFp, "%d,%s", samp_min+j, j==ns-1 ? "\n" : ",");
      else
        fprintf(outFp, "%d%s", samp_min+j, j==ns-1 ? "\n" : ",");
    }
    if (what_to_save==LAT_LON_2_BAND) {
      fprintf(outFp, ",");
      for (j=0; j<ns; ++j) {
        fprintf(outFp, "Lat,Lon%s", j==ns-1 ? "\n" : ",");
      }
    }
    for (i=0; i<nl; ++i) {
        int l = line_min+i;
        fprintf(outFp, "%d,", l);
        for (j=0; j<ns; ++j) {
            int s = samp_min+j;
            if (what_to_save==LAT_LON_2_BAND) {
              float lat, lon;
              if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                double dlat, dlon;
                meta_get_latLon(meta, l, s, 0, &dlat, &dlon);
                lat = (float)dlat;
                lon = (float)dlon;
              } else {
                lat = lon = 0.;
              }
              fprintf(outFp, "%f,%f%s", lat, lon, j==ns-1 ? "\n" : ",");
            }
            else {
              float val;
              if (!strict_boundary || pnpoly(n, xp, yp, s, l)) {
                val = get_data(ii, what_to_save, l, s);
              } else {
                val = 0;
              }
              fprintf(outFp, "%f%s", val, j==ns-1 ? "\n" : ",");
            }
        }
        asfLineMeter(i,nl);
    }

    fclose(outFp);

    // if requested, open up the csv with an external viewer
    if (load)
        open_csv(out_file);

    return TRUE;
}
示例#28
0
int asf_elevation(char *unwrapped_phase, char *phase_mask, 
		  char *baseFile, char *seeds, char *slant_elevation,
		  char *slant_elevation_error, char *slant_amplitude, 
		  char *slant_coherence, char *ground_elevation, 
		  char *ground_elevation_error, char *ground_amplitude, 
		  char *ground_coherence)
{

  int x, y, ss, sl, nrows, ncols;
  double xScale, yScale, k, *phase2elevBase, *sinFlat, *cosFlat;
  meta_parameters *meta;
  baseline base;
  FILE *fphase, *felev, *feleverr, *fseed, *fmask, *fcoh;
  float *uwp, *coh, *elev, *eleverr;
  unsigned char *mask;
  double delta_phase, delta_height;
  double seed_phase, seed_height;

  printf("\nGenerating slant range elevation and elevation error ...\n\n");

  /* Get input scene size and windowing info. Get datafile values*/
  meta = meta_read(unwrapped_phase);
  nrows  = meta->general->line_count;
  ncols  = meta->general->sample_count;
  sl     = meta->general->start_line;
  ss     = meta->general->start_sample;
  yScale = meta->sar->look_count;
  xScale = meta->sar->sample_increment;
  
  // Write metadata files for temporary slant range images
  //  meta->general->image_data_type = DEM;
  meta_write(meta, slant_elevation);
  meta_write(meta, slant_elevation_error);
  
  /* Allocate space for vectors and matricies*/
  uwp = (float *) MALLOC(sizeof(float)*ncols);
  coh = (float *) MALLOC(sizeof(float)*ncols);
  elev = (float *) MALLOC(sizeof(float)*ncols);
  eleverr = (float *) MALLOC(sizeof(float)*ncols);
  mask = (unsigned char *) MALLOC(sizeof(unsigned char)*ncols);

  // Wavenumber K
  k = meta_get_k(meta);

  // Read in baseline values
  base = read_baseline(baseFile);
  
  // Open input files
  fphase = fopenImage(unwrapped_phase, "rb");
  fseed = FOPEN(seeds, "r");
  fmask = fopenImage(phase_mask, "rb");
  fcoh = fopenImage(slant_coherence, "rb");
  
  /*Use least-squares fit to determine the optimal seed_phase and seed_height.*/
  {
    double x,xSum=0,xSqrSum=0,hSum=0,hxSum=0,pxSum=0,pxSqrSum=0;
    double a,b,c,d,e,f,det;
    int npts=0;
    float *phase_line;
    
    phase_line = (float *) MALLOC(sizeof(float)*meta->general->sample_count);
    
    while (1)
      {
	float seed_x,seed_y,height,phase;
	int seek_x,seek_y;
	/*Read in each seed point*/
	if (3!=fscanf(fseed,"%f%f%f",&seed_x,&seed_y,&height))
	  break;/*Break out when no more points.*/
	seek_x=(int)((seed_x-ss)/xScale);
	seek_y=(int)((seed_y-sl)/yScale);
	get_float_line(fphase, meta, seek_y, phase_line);
	phase = phase_line[seek_y];
	if (phase==0)
	  continue;/*Escher couldn't unwrap this tie point.*/
	
	// Calculate that seed point's impact on fit.
	x         = meta_phase_rate(meta,base,seed_y,seed_x);
	xSum     += x;
	xSqrSum  += x * x;
	hSum     += height;
	hxSum    += height * x;
	pxSum    += phase * x;
	pxSqrSum += phase * x * x;
	npts++;
      }
    if (!quietflag)
      printf("   Read %d seed points\n",npts);
    /* The least-squares fit above leaves us with a matrix equation
     *	[ a  b ]   [ seed_phase  ]   [ e ]
     *	[      ] * [             ] = [   ]
     *	[ c  d ]   [ seed_height ]   [ f ]
     *
     *	which has the solution
     *
     *	[ d  -b ]   [ e ]    1    [ seed_phase  ]
     *	[       ] * [   ] * --- = [             ]
     *	[ -c  a ]   [ f ]   det   [ seed_height ]
     */
    a = -xSqrSum;
    b = xSum;
    c = -xSum;
    d = npts;
    e = hxSum-pxSqrSum;
    f = hSum-pxSum;
    det = a*d-b*c;
    seed_phase  = (e*d-f*b)/det;
    seed_height = (e*(-c)+f*a)/det;
  }
  
  if (!quietflag) 
    printf("   Seed Phase: %f\n   Elevation: %f\n\n",seed_phase,seed_height);
  
  /* calculate the sine of the incidence angle across cols*/
  sinFlat = (double *)MALLOC(sizeof(double)*ncols);
  cosFlat = (double *)MALLOC(sizeof(double)*ncols);
  phase2elevBase = (double *)MALLOC(sizeof(double)*ncols);
  for (x=0;x<ncols;x++)
    {
      int img_x = x*xScale + ss;
      double incid = meta_incid(meta, 0, img_x);
      double flat = meta_flat(meta, 0, img_x);
      sinFlat[x] = sin(flat);
      cosFlat[x] = cos(flat);
      phase2elevBase[x] = meta_get_slant(meta, 0, img_x)*sin(incid)/(2.0*k);
    }
  
  // Open intermediate output files
  felev = fopenImage(slant_elevation, "wb");
  feleverr = fopenImage(slant_elevation_error, "wb");
  
  /* loop through each row & calculate height*/
  /*Note:
    To make this faster, we don't call 
    delta_height=delta_phase * meta_phase_rate(ceos,base,y*yScale+sl,x*xScale+ss).
    Instead, we use the annoying temporary arrays
    allocated above to calculate the same thing, quicker.
  */
  for (y=0; y<nrows; y++) {
    double Bn_y,Bp_y;

    // Read in data
    FREAD(mask, sizeof(unsigned char), ncols, fmask);
    get_float_line(fphase, meta, y, uwp);
    get_float_line(fcoh, meta, y, coh);
    
    // Calculate baseline for this row
    meta_interp_baseline(meta, base, y*yScale+sl+1, &Bn_y, &Bp_y);
    
    // Step through each pixel in row
    for (x=0; x<ncols; x++) {
      // Calculate elevation
      if (uwp[x] != 0.0) {
	delta_phase = (double) uwp[x] - seed_phase;
	delta_height = delta_phase * phase2elevBase[x]/
	  (-Bp_y*sinFlat[x] - Bn_y*cosFlat[x]);
	elev[x] = delta_height + seed_height;
      }
      else 
	elev[x] = 0.0;
      // Calculate elevation error
      if (mask[x] == 0x10) {
	double coh_factor, base_height, sigma_height;
	coh_factor = (FLOAT_EQUALS_ZERO(coh[x])) ? 0.0 : sqrt((1-coh[x])/coh[x]);
	base_height = phase2elevBase[x]/(-Bp_y*sinFlat[x] - Bn_y*cosFlat[x]);
	sigma_height = base_height * coh_factor;
	eleverr[x] = (float) fabs(base_height*coh_factor);
      }
      else
	eleverr[x] = -1.0;
    }
    
    put_float_line(felev, meta, y, elev);
    put_float_line(feleverr, meta, y, eleverr);

    asfLineMeter(y, nrows);
  }
  
  // Free memory and close files
  FREE(uwp);
  FREE(mask);
  FREE(coh);
  FREE(elev);
  FREE(eleverr);
  FREE(sinFlat);
  FREE(cosFlat);
  FREE(phase2elevBase);
  FCLOSE(felev);
  FCLOSE(feleverr);
  FCLOSE(fphase);
  FCLOSE(fseed);
  FCLOSE(fmask);


  int fill_value=-1;
  // Transform all the slant range products into ground range
  printf("\nGenerating ground range elevation ...\n");
  deskew_dem(slant_elevation, NULL, ground_elevation, NULL, 0, NULL, NULL, TRUE,
             fill_value, 0);
  printf("\nGenerating ground range amplitude image ...\n");
  deskew_dem(slant_elevation, NULL, ground_amplitude, slant_amplitude, 1, NULL, NULL,
             TRUE, fill_value, 0);
  printf("\nGenerating ground range elevation error ...\n");
  deskew_dem(slant_elevation, NULL, ground_elevation_error, slant_elevation_error, 1,
             NULL, NULL, TRUE, fill_value, 0);
  printf("\nGenerating ground range coherence image ...\n\n");
  deskew_dem(slant_elevation, NULL, ground_coherence, slant_coherence, 0, NULL, NULL,
             TRUE, fill_value, 0);

  //meta_free(meta);
  return 0;
}