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); }
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); }
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); }
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; }
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; }
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; }
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; }
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; }
// 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; }
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); }
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); }
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); }
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; }
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); }
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); }
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; }
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; }
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); }
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 }
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; }
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; }