Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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);
}
Beispiel #4
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;
}
Beispiel #5
0
int clip(char *inFile, char *maskFile, char *outFile)
{
  meta_parameters *metaIn, *metaMask;
  metaIn = meta_read(inFile);
  metaMask = meta_read(maskFile);

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

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

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

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

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

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

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

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

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

  return 0;
}
Beispiel #6
0
void c2p_ext(const char *inDataName, const char *inMetaName,
             const char *outfile, int multilook, int banded)
{
    meta_parameters *in_meta = meta_read(inMetaName);
    int data_type = in_meta->general->data_type;
    // the old code did this, but why??
    in_meta->general->data_type = meta_polar2complex(data_type);

    // some sanity checks
    switch (data_type) {
      case COMPLEX_BYTE:
      case COMPLEX_INTEGER16:
      case COMPLEX_INTEGER32:
      case COMPLEX_REAL32:
      case COMPLEX_REAL64:
          break;
      default:
          asfPrintError("c2p: %s is not a complex image.\n", inDataName);
    }

    if (in_meta->general->band_count != 1)
        asfPrintError("c2p: %s is not a single-band image.\n", inDataName);

    if (!in_meta->sar)
        asfPrintError("c2p: %s is missing a SAR block.\n", inDataName);

    asfPrintStatus("Converting complex image to amplitude/phase...\n");

    int nl = in_meta->general->line_count;
    int ns = in_meta->general->sample_count;
    // process 1 line at a time when not multilooking, otherwise grab nlooks
    int nlooks = multilook ? in_meta->sar->look_count : 1;

    if (nlooks == 1 && multilook) {
        asfPrintStatus("Not multilooking, look_count is 1.\n");
        multilook = FALSE;
    }

    if (multilook)
        asfPrintStatus("Multilooking with %d looks.\n", nlooks);

    meta_parameters *out_meta = meta_read(inMetaName);
    out_meta->general->data_type = meta_complex2polar(data_type);

    // set up input/output files
    FILE *fin = fopenImage(inDataName, "rb");

    // we either have 1 or 2 output files, per the "banded" flag.
    char *outfile_img = appendExt(outfile, ".img");
    char *amp_name=NULL, *phase_name=NULL;
    FILE *fout_banded=NULL, *fout_amp=NULL, *fout_phase=NULL;
    if (banded) {
        asfPrintStatus("Output is 2-band image: %s\n", outfile_img);
        fout_banded = fopenImage(outfile_img, "wb");
    } else {
        amp_name = appendToBasename(outfile_img, "_amp");
        phase_name = appendToBasename(outfile_img, "_phase");
        asfPrintStatus("Output amplitude file: %s\n", amp_name);
        asfPrintStatus("Output phase file: %s\n", phase_name);
        fout_amp = fopenImage(amp_name, "wb");
        fout_phase = fopenImage(phase_name, "wb");
    }
    if (banded)
        assert(fout_banded && !fout_amp && !fout_phase);
    else
        assert(!fout_banded && fout_amp && fout_phase);

    // get the metadata band_count correct, needed in the put_* calls
    if (banded) {
        out_meta->general->band_count = 2;
        strcpy(out_meta->general->bands, "AMP,PHASE");
    }

    // input buffer
    complexFloat *cpx = MALLOC(sizeof(complexFloat)*ns*nlooks);

    // output buffers
    float *amp = MALLOC(sizeof(float)*ns*nlooks);
    float *phase = MALLOC(sizeof(float)*ns*nlooks);

    int line_in;    // line in the input image
    int line_out=0; // line in the output image
    int samp;       // sample #, loop index
    int l;          // line loop index, iterates over the lines in the block

    out_meta->general->line_count = (int)ceil((double)nl/(double)nlooks);

    for (line_in=0; line_in<nl; line_in+=nlooks)
    {
        // lc = "line count" -- how many lines to read. normally we will read
        // nlooks lines, but near eof we might have to read fewer
        int lc = nlooks; 
        if (line_in + lc > nl)
            lc = nl - line_in;

        // read "nlooks" (or possibly fewer, if near eof) lines of data
        int blockSize = get_complexFloat_lines(fin,in_meta,line_in,lc,cpx);
        if (blockSize != lc*ns)
            asfPrintError("bad blockSize: bs=%d nlooks=%d ns=%d\n", 
			  blockSize, nlooks, ns);

        // first, compute the power/phase
        for (l=0; l<lc; ++l) {
            for (samp=0; samp<ns; ++samp) {
                int k = l*ns + samp; // index into the block
                float re = cpx[k].real;
                float im = cpx[k].imag;
                if (re != 0.0 || im != 0.0) {
                    amp[k] = re*re + im*im;
                    phase[k] = atan2(im, re);
                } else {
                    amp[k] = phase[k] = 0.0;
                }
            }
        }

        // now multilook, if requested
        if (multilook) {
            // put the multilooked data in the first "row" of amp,phase
            for (samp=0; samp<ns; ++samp) {
                float value = 0.0;
                for (l=0; l<lc; ++l)
                    value += amp[l*ns + samp];
                amp[samp] = sqrt(value/(float)lc);

                value = 0.0;
                for (l=0; l<lc; ++l)
                    value += phase[l*ns + samp];
                phase[samp] = value/(float)lc;
            }
        }
        else {
            for (samp=0; samp<ns*lc; ++samp)
                amp[samp] = sqrt(amp[samp]);
        }

        // write out a line (multilooked) or a bunch of lines (not multi)
        if (multilook) {
            if (banded) {
                put_band_float_line(fout_banded, out_meta, 0, line_out, amp);
                put_band_float_line(fout_banded, out_meta, 1, line_out, phase);
            } else {
                put_float_line(fout_amp, out_meta, line_out, amp);
                put_float_line(fout_phase, out_meta, line_out, phase);
            }
            ++line_out;
        } else {
            for (l=0; l<lc; ++l) {
                if (banded) {
                    put_band_float_line(fout_banded, out_meta, 0, line_in+l, amp);
                    put_band_float_line(fout_banded, out_meta, 1, line_in+l, phase);
                } else {
                    put_float_line(fout_amp, out_meta, line_in+l, amp);
                    put_float_line(fout_phase, out_meta, line_in+l, phase);
                }
                ++line_out;
            }
        }

        asfPercentMeter((float)line_in/(float)(nl));
    }
    asfPercentMeter(1.0);

    fclose(fin);
    if (fout_banded) fclose(fout_banded);
    if (fout_amp) fclose(fout_amp);
    if (fout_phase) fclose(fout_phase);

    if (multilook) {
        if (out_meta->general->line_count != line_out)
            asfPrintError("Line counts don't match: %d != %d\n",
                out_meta->general->line_count, line_out);
        out_meta->general->y_pixel_size *= nlooks;
        out_meta->sar->azimuth_time_per_pixel *= nlooks;
        out_meta->sar->multilook = TRUE;
    } else
        assert(line_out == nl);

    // write out the metadata, different whether multi-banded or not
    if (banded) {
        assert(!amp_name && !phase_name);
        meta_write(out_meta, outfile);
    } else {
        assert(amp_name && phase_name);
        
        out_meta->general->image_data_type = AMPLITUDE_IMAGE;
        meta_write(out_meta, amp_name);
        
        out_meta->general->image_data_type = PHASE_IMAGE;
        meta_write(out_meta, phase_name);
    }

    if (multilook)
        asfPrintStatus("Original line count: %d, after multilooking: %d "
            "(%d looks)\n", nl, line_out, nlooks);

    meta_free(in_meta);
    meta_free(out_meta);

    FREE(amp);
    FREE(phase);
    FREE(cpx);

    FREE(outfile_img);

    FREE(amp_name);
    FREE(phase_name);
}
Beispiel #7
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;
}
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);
}