コード例 #1
0
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);
}
コード例 #2
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;
}
コード例 #3
0
ファイル: asf_export.c プロジェクト: khogenso/ASF_MapReady
int asf_export_bands(output_format_t format, scale_t sample_mapping, int rgb,
                     int true_color, int false_color,
                     char *look_up_table_name, int use_pixel_is_point,
                     char *in_base_name,
                     char *output_name, char **band_name,
                     int *noutputs, char ***output_names)
{
  char *in_meta_name=NULL, *in_data_name=NULL, *out_name=NULL;

  asfPrintStatus("Exporting ...\n");

  meta_parameters *md = NULL;
  int i, nouts = 0, is_polsarpro = 0, is_matrix = 0;
  char **outs = NULL;

  if (format != HDF && format != NC) {
    in_data_name = appendExt(in_base_name, ".img");
    in_meta_name = appendExt(in_base_name, ".meta");
    md = meta_read(in_meta_name);
    is_polsarpro = 
      (md->general->image_data_type == POLARIMETRIC_SEGMENTATION) ? 1 : 0;
    is_matrix =
      ((md->general->image_data_type >= POLARIMETRIC_C2_MATRIX &&
        md->general->image_data_type <= POLARIMETRIC_STOKES_MATRIX) ||
        md->general->image_data_type == POLARIMETRIC_DECOMPOSITION) ? 1 : 0;
    if (md->general->image_data_type == RGB_STACK)
      rgb = TRUE;
  }

  // Do that exporting magic!
  if ( format == ENVI ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = appendExt(output_name, ".bsq");
      export_as_envi (in_meta_name, in_data_name, out_name);
  }
  else if ( format == ESRI ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = appendExt(output_name, ".esri");
      export_as_esri (in_meta_name, in_data_name, out_name);
  }
  else if ( format == TIF ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".tif", ".tiff");
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, TIF, 0,
                        &nouts, &outs);

  }
  else if ( format == GEOTIFF ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".tif", ".tiff");
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, GEOTIFF, use_pixel_is_point,
                        &nouts, &outs);
      
  }
  else if ( format == JPEG ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".jpg", ".jpeg");
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, JPEG, 0,
                        &nouts, &outs);
  }
  else if ( format == PNG ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".png", NULL);
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, PNG, 0,
                        &nouts, &outs);
  }
  else if ( format == PNG_ALPHA ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".png", NULL);
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, PNG_ALPHA, 0,
                        &nouts, &outs);
  }
  else if ( format == PNG_GE ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".png", NULL);
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, PNG_GE, 0,
                        &nouts, &outs);
  }
  else if ( format == PGM ) {
      //in_data_name = appendExt(in_base_name, ".img");
      //in_meta_name = appendExt(in_base_name, ".meta");
      if (rgb || true_color || false_color || is_polsarpro) {
          asfPrintWarning(
            "Greyscale PGM output is not compatible with color options:\n"
            "(RGB, True Color, False Color, color look-up tables, PolSARpro\n"
            "classifications, etc)  ...\n"
            "Defaulting to producing separate greyscale PGM files for "
            "available bands.\n");
        rgb = 0;
        true_color = 0;
        false_color = 0;
      }
      out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
      strcpy(out_name, output_name);
      if (!is_matrix)
	append_ext_if_needed(out_name, ".pgm", NULL);
      export_band_image(in_meta_name, in_data_name, out_name,
                        sample_mapping, band_name, rgb,
                        true_color, false_color,
                        look_up_table_name, 0, PGM,
                        &nouts, &outs);
  }
  else if ( format == POLSARPRO_HDR ) {
    out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
    strcpy(out_name, output_name);
    export_polsarpro(in_meta_name, in_data_name, out_name, &nouts, &outs);
  }
  else if ( format == HDF ) {
    out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
    strcpy(out_name, output_name);
    export_hdf(in_base_name, out_name, &nouts, &outs);
  }
  else if ( format == NC ) {
    out_name = MALLOC(sizeof(char)*(strlen(output_name)+32));
    strcpy(out_name, output_name);
    export_netcdf(in_base_name, out_name, &nouts, &outs);
  }

  if (format != HDF && format != NC) {
    if (should_write_insar_rgb(md->general->bands)) {
        write_insar_rgb(format, in_meta_name, in_data_name, out_name);
    }

    if (should_write_insar_xml_meta(md)) {
      char *xml_meta = get_insar_xml_string(md, FALSE);
        char *xml_output_file_name = 
            (char *) MALLOC(sizeof(char)*(strlen(out_name)+10));
        sprintf(xml_output_file_name, "%s.xml", stripExt(out_name));

        write_insar_xml_to_file(xml_output_file_name, xml_meta);
        FREE(xml_meta);
        FREE(xml_output_file_name);
    }
    else if (should_write_dem_xml_meta(md)) {
      char *xml_meta = get_dem_xml_string(md, FALSE);
      char *xml_output_file_name =
        (char *) MALLOC(sizeof(char)*(strlen(out_name)+10));
      sprintf(xml_output_file_name, "%s.xml", stripExt(out_name));
      write_dem_xml_to_file(xml_output_file_name, xml_meta);
      FREE(xml_meta);
      FREE(xml_output_file_name);
    }
  }

  if (noutputs && output_names) {
    asfPrintStatus("\n\nExport complete.\nGenerated %d output file%s:\n",
                 nouts, nouts==1?"":"s");
    for (i=0; i<nouts; ++i)
      asfPrintStatus("  %s\n", outs[i]);
    asfPrintStatus("\n");

    *noutputs = nouts;
    *output_names = outs;
  }
  else {
    for (i=0; i<nouts; ++i)
      FREE(outs[i]);
    FREE(outs);
  }

  if (in_data_name)
    FREE(in_data_name);
  if (in_meta_name)
    FREE(in_meta_name);
  if (out_name)
    FREE(out_name);
  if (md)
    meta_free(md);

  asfPrintStatus("Export successful!\n\n");
  return (EXIT_SUCCESS);
}
コード例 #4
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);
}
コード例 #5
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);
}