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; }
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; }
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); }
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 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; }
void c2p_ext(const char *inDataName, const char *inMetaName, const char *outfile, int multilook, int banded) { meta_parameters *in_meta = meta_read(inMetaName); int data_type = in_meta->general->data_type; // the old code did this, but why?? in_meta->general->data_type = meta_polar2complex(data_type); // some sanity checks switch (data_type) { case COMPLEX_BYTE: case COMPLEX_INTEGER16: case COMPLEX_INTEGER32: case COMPLEX_REAL32: case COMPLEX_REAL64: break; default: asfPrintError("c2p: %s is not a complex image.\n", inDataName); } if (in_meta->general->band_count != 1) asfPrintError("c2p: %s is not a single-band image.\n", inDataName); if (!in_meta->sar) asfPrintError("c2p: %s is missing a SAR block.\n", inDataName); asfPrintStatus("Converting complex image to amplitude/phase...\n"); int nl = in_meta->general->line_count; int ns = in_meta->general->sample_count; // process 1 line at a time when not multilooking, otherwise grab nlooks int nlooks = multilook ? in_meta->sar->look_count : 1; if (nlooks == 1 && multilook) { asfPrintStatus("Not multilooking, look_count is 1.\n"); multilook = FALSE; } if (multilook) asfPrintStatus("Multilooking with %d looks.\n", nlooks); meta_parameters *out_meta = meta_read(inMetaName); out_meta->general->data_type = meta_complex2polar(data_type); // set up input/output files FILE *fin = fopenImage(inDataName, "rb"); // we either have 1 or 2 output files, per the "banded" flag. char *outfile_img = appendExt(outfile, ".img"); char *amp_name=NULL, *phase_name=NULL; FILE *fout_banded=NULL, *fout_amp=NULL, *fout_phase=NULL; if (banded) { asfPrintStatus("Output is 2-band image: %s\n", outfile_img); fout_banded = fopenImage(outfile_img, "wb"); } else { amp_name = appendToBasename(outfile_img, "_amp"); phase_name = appendToBasename(outfile_img, "_phase"); asfPrintStatus("Output amplitude file: %s\n", amp_name); asfPrintStatus("Output phase file: %s\n", phase_name); fout_amp = fopenImage(amp_name, "wb"); fout_phase = fopenImage(phase_name, "wb"); } if (banded) assert(fout_banded && !fout_amp && !fout_phase); else assert(!fout_banded && fout_amp && fout_phase); // get the metadata band_count correct, needed in the put_* calls if (banded) { out_meta->general->band_count = 2; strcpy(out_meta->general->bands, "AMP,PHASE"); } // input buffer complexFloat *cpx = MALLOC(sizeof(complexFloat)*ns*nlooks); // output buffers float *amp = MALLOC(sizeof(float)*ns*nlooks); float *phase = MALLOC(sizeof(float)*ns*nlooks); int line_in; // line in the input image int line_out=0; // line in the output image int samp; // sample #, loop index int l; // line loop index, iterates over the lines in the block out_meta->general->line_count = (int)ceil((double)nl/(double)nlooks); for (line_in=0; line_in<nl; line_in+=nlooks) { // lc = "line count" -- how many lines to read. normally we will read // nlooks lines, but near eof we might have to read fewer int lc = nlooks; if (line_in + lc > nl) lc = nl - line_in; // read "nlooks" (or possibly fewer, if near eof) lines of data int blockSize = get_complexFloat_lines(fin,in_meta,line_in,lc,cpx); if (blockSize != lc*ns) asfPrintError("bad blockSize: bs=%d nlooks=%d ns=%d\n", blockSize, nlooks, ns); // first, compute the power/phase for (l=0; l<lc; ++l) { for (samp=0; samp<ns; ++samp) { int k = l*ns + samp; // index into the block float re = cpx[k].real; float im = cpx[k].imag; if (re != 0.0 || im != 0.0) { amp[k] = re*re + im*im; phase[k] = atan2(im, re); } else { amp[k] = phase[k] = 0.0; } } } // now multilook, if requested if (multilook) { // put the multilooked data in the first "row" of amp,phase for (samp=0; samp<ns; ++samp) { float value = 0.0; for (l=0; l<lc; ++l) value += amp[l*ns + samp]; amp[samp] = sqrt(value/(float)lc); value = 0.0; for (l=0; l<lc; ++l) value += phase[l*ns + samp]; phase[samp] = value/(float)lc; } } else { for (samp=0; samp<ns*lc; ++samp) amp[samp] = sqrt(amp[samp]); } // write out a line (multilooked) or a bunch of lines (not multi) if (multilook) { if (banded) { put_band_float_line(fout_banded, out_meta, 0, line_out, amp); put_band_float_line(fout_banded, out_meta, 1, line_out, phase); } else { put_float_line(fout_amp, out_meta, line_out, amp); put_float_line(fout_phase, out_meta, line_out, phase); } ++line_out; } else { for (l=0; l<lc; ++l) { if (banded) { put_band_float_line(fout_banded, out_meta, 0, line_in+l, amp); put_band_float_line(fout_banded, out_meta, 1, line_in+l, phase); } else { put_float_line(fout_amp, out_meta, line_in+l, amp); put_float_line(fout_phase, out_meta, line_in+l, phase); } ++line_out; } } asfPercentMeter((float)line_in/(float)(nl)); } asfPercentMeter(1.0); fclose(fin); if (fout_banded) fclose(fout_banded); if (fout_amp) fclose(fout_amp); if (fout_phase) fclose(fout_phase); if (multilook) { if (out_meta->general->line_count != line_out) asfPrintError("Line counts don't match: %d != %d\n", out_meta->general->line_count, line_out); out_meta->general->y_pixel_size *= nlooks; out_meta->sar->azimuth_time_per_pixel *= nlooks; out_meta->sar->multilook = TRUE; } else assert(line_out == nl); // write out the metadata, different whether multi-banded or not if (banded) { assert(!amp_name && !phase_name); meta_write(out_meta, outfile); } else { assert(amp_name && phase_name); out_meta->general->image_data_type = AMPLITUDE_IMAGE; meta_write(out_meta, amp_name); out_meta->general->image_data_type = PHASE_IMAGE; meta_write(out_meta, phase_name); } if (multilook) asfPrintStatus("Original line count: %d, after multilooking: %d " "(%d looks)\n", nl, line_out, nlooks); meta_free(in_meta); meta_free(out_meta); FREE(amp); FREE(phase); FREE(cpx); FREE(outfile_img); FREE(amp_name); FREE(phase_name); }
int asf_calibrate(const char *inFile, const char *outFile, radiometry_t outRadiometry, int wh_scaleFlag) { meta_parameters *metaIn = meta_read(inFile); meta_parameters *metaOut = meta_read(inFile); if (!metaIn->calibration) { asfPrintError("This data cannot be calibrated, missing calibration block.\n"); } // Check for valid output radiometry if (outRadiometry == r_AMP || outRadiometry == r_POWER) asfPrintError("Invalid radiometry (%s) passed into calibration function!\n", radiometry2str(outRadiometry)); // Check whether output radiometry fits with Woods Hole scaling flag if (wh_scaleFlag && outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA) outRadiometry += 3; // This can only work if the image is in some SAR geometry if (metaIn->projection && metaIn->projection->type != SCANSAR_PROJECTION) asfPrintError("Can't apply calibration factors to map projected images\n" "(Amplitude or Power only)\n"); radiometry_t inRadiometry = metaIn->general->radiometry; asfPrintStatus("Calibrating %s image to %s image\n\n", radiometry2str(inRadiometry), radiometry2str(outRadiometry)); // FIXME: This function should be able to remap between different // radiometry projections. if (metaIn->general->radiometry != r_AMP) asfPrintError("Currently only AMPLITUDE as radiometry is supported!\n"); metaOut->general->radiometry = outRadiometry; int dbFlag = FALSE; if (outRadiometry >= r_SIGMA && outRadiometry <= r_GAMMA) metaOut->general->no_data = 0.0001; if (outRadiometry >= r_SIGMA_DB && outRadiometry <= r_GAMMA_DB) { metaOut->general->no_data = -40.0; dbFlag = TRUE; } if (metaIn->general->image_data_type != POLARIMETRIC_IMAGE) { if (outRadiometry == r_SIGMA || outRadiometry == r_SIGMA_DB) metaOut->general->image_data_type = SIGMA_IMAGE; else if (outRadiometry == r_BETA || outRadiometry == r_BETA_DB) metaOut->general->image_data_type = BETA_IMAGE; else if (outRadiometry == r_GAMMA || outRadiometry == r_GAMMA_DB) metaOut->general->image_data_type = GAMMA_IMAGE; } if (wh_scaleFlag) metaOut->general->data_type = ASF_BYTE; char *input = appendExt(inFile, ".img"); char *output = appendExt(outFile, ".img"); FILE *fpIn = FOPEN(input, "rb"); FILE *fpOut = FOPEN(output, "wb"); int dualpol = strncmp_case(metaIn->general->mode, "FBD", 3) == 0 ? 1 : 0; int band_count = metaIn->general->band_count; int sample_count = metaIn->general->sample_count; int line_count = metaIn->general->line_count; char **bands = extract_band_names(metaIn->general->bands, band_count); float *bufIn = (float *) MALLOC(sizeof(float)*sample_count); float *bufOut = (float *) MALLOC(sizeof(float)*sample_count); float *bufIn2 = NULL, *bufOut2 = NULL, *bufOut3 = NULL; if (dualpol && wh_scaleFlag) { bufIn2 = (float *) MALLOC(sizeof(float)*sample_count); bufOut2 = (float *) MALLOC(sizeof(float)*sample_count); bufOut3 = (float *) MALLOC(sizeof(float)*sample_count); metaOut->general->band_count = 3; sprintf(metaOut->general->bands, "%s,%s,%s-%s", bands[0], bands[1], bands[0], bands[1]); } int ii, jj, kk; float cal_dn, cal_dn2; double incid; if (dualpol && wh_scaleFlag) { metaOut->general->image_data_type = RGB_STACK; for (ii=0; ii<line_count; ii++) { get_band_float_line(fpIn, metaIn, 0, ii, bufIn); get_band_float_line(fpIn, metaIn, 1, ii, bufIn2); for (jj=0; jj<sample_count; jj++) { // Taking the remapping of other radiometries out for the moment //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB) //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]); incid = meta_incid(metaIn, ii, jj); cal_dn = get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[0], dbFlag); cal_dn2 = get_cal_dn(metaOut, incid, jj, bufIn2[jj], bands[1], dbFlag); if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data) || cal_dn == cal_dn2) { bufOut[jj] = 0; bufOut2[jj] = 0; bufOut3[jj] = 0; } else { bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5; bufOut2[jj] = (cal_dn2 + 31) / 0.15 + 1.5; bufOut3[jj] = bufOut[jj] - bufOut2[jj]; } } put_band_float_line(fpOut, metaOut, 0, ii, bufOut); put_band_float_line(fpOut, metaOut, 1, ii, bufOut2); put_band_float_line(fpOut, metaOut, 2, ii, bufOut3); asfLineMeter(ii, line_count); } } else { for (kk=0; kk<band_count; kk++) { for (ii=0; ii<line_count; ii++) { get_band_float_line(fpIn, metaIn, kk, ii, bufIn); for (jj=0; jj<sample_count; jj++) { // Taking the remapping of other radiometries out for the moment //if (inRadiometry >= r_SIGMA && inRadiometry <= r_BETA_DB) //bufIn[jj] = cal2amp(metaIn, incid, jj, bands[kk], bufIn[jj]); if (strstr(bands[kk], "PHASE") == NULL) { incid = meta_incid(metaIn, ii, jj); cal_dn = get_cal_dn(metaOut, incid, jj, bufIn[jj], bands[kk], dbFlag); if (wh_scaleFlag) { if (FLOAT_EQUIVALENT(cal_dn, metaIn->general->no_data)) bufOut[jj] = 0; else bufOut[jj] = (cal_dn + 31) / 0.15 + 1.5; } else bufOut[jj] = cal_dn; } else // PHASE band, do nothing bufOut[jj] = bufIn[jj]; } put_band_float_line(fpOut, metaOut, kk, ii, bufOut); asfLineMeter(ii, line_count); } if (kk==0) sprintf(metaOut->general->bands, "%s-%s", radiometry2str(outRadiometry), bands[kk]); else { char tmp[255]; sprintf(tmp, ",%s-%s", radiometry2str(outRadiometry), bands[kk]); strcat(metaOut->general->bands, tmp); } } } meta_write(metaOut, outFile); meta_free(metaIn); meta_free(metaOut); FREE(bufIn); FREE(bufOut); if (dualpol) { FREE(bufIn2); FREE(bufOut2); FREE(bufOut3); } for (kk=0; kk<band_count; ++kk) FREE(bands[kk]); FREE(bands); FCLOSE(fpIn); FCLOSE(fpOut); FREE(input); FREE(output); return FALSE; }
void import_radarsat2(const char *inBaseName, radiometry_t radiometry, const char *outBaseName, int ampOnly) { FILE *fp; radarsat2_meta *radarsat2; meta_parameters *meta; char **inDataNames=NULL, inDataName[1024], *inMetaName=NULL; char *outDataName=NULL, str[512]; float *amp = NULL, *phase = NULL, *tmp = NULL, re, im; int band, sample; // Check radiometry if (radiometry != r_AMP) { asfPrintWarning("Radiometry other than AMPLITUDE is currently not " "supported.\n"); radiometry = r_AMP; } if (!fileExists(inBaseName)) inMetaName = appendExt(inBaseName, ".xml"); else { inMetaName = (char *) MALLOC(sizeof(char)*1024); strcpy(inMetaName, inBaseName); } outDataName = appendExt(outBaseName, ".img"); radarsat2 = read_radarsat2_meta(inMetaName); asfPrintStatus(" DataType: %s, ProductType: %s\n", radarsat2->dataType, radarsat2->productType); if (strcmp_case(radarsat2->dataType, "COMPLEX") != 0) asfPrintError("Currently only complex data supported!\n"); meta = radarsat2meta(radarsat2); meta_write(meta, outDataName); // Let's check the GeoTIFF data. // Unfortunately, there is no identifier in the GeoTIFF that would identify // the data as Radarsat-2 data. // // The only thing that we can actually do is to look whether the data in the // GeoTIFF file fit the general bill. We can the image dimensions. The data // needs to have 2 bands (I and Q) and 16 bit. The citation geokey needs to // be the really non-descriptive "Uncorrected Satellite Data". TIFF *tiff = NULL; GTIF *gtif = NULL; data_type_t data_type; short sample_format, bits_per_sample, planar_config; short num_bands; int is_scanline_format, is_palette_color_tiff, wrong=FALSE; char *error_message = (char *) MALLOC(sizeof(char)*2048); inDataNames = extract_band_names(meta->general->basename, meta->general->band_count); fp = FOPEN(outDataName, "wb"); int band_count = radarsat2->band_count; if (ampOnly) { strcpy(meta->general->bands, "AMP"); meta->general->band_count = 1; band_count = 1; } for (band=0; band<band_count; band++) { // path from the xml (metadata) file char *path = get_dirname(inBaseName); if (strlen(path)>0) { strcpy(inDataName, path); if (inDataName[strlen(inDataName)-1] != '/') strcat(inDataName, "/"); } else strcpy(inDataName, ""); free(path); strcat(inDataName, inDataNames[band]); tiff = XTIFFOpen(inDataName, "r"); if (!tiff) asfPrintError("Could not open data file (%s)\n", inDataName); gtif = GTIFNew(tiff); if (!gtif) asfPrintError("Could not read GeoTIFF keys from data file (%s)\n", inDataName); // Check image dimensions uint32 tif_sample_count; uint32 tif_line_count; TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &tif_line_count); TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &tif_sample_count); if ((meta->general->sample_count != tif_sample_count) || (meta->general->line_count != tif_line_count)) asfPrintError(error_message, "Problem with image dimensions. Was looking for %d lines " "and %d samples.\nFound %ld lines and %ld samples instead!" "\n", meta->general->line_count, meta->general->sample_count, tif_line_count, tif_sample_count); // Check general TIFF tags get_tiff_data_config(tiff, &sample_format, &bits_per_sample, &planar_config, &data_type, &num_bands, &is_scanline_format, &is_palette_color_tiff, REPORT_LEVEL_WARNING); // The specs say the data is supposed to be unsigned but it is not. // Let is pass as long as we are talking about integer data here strcpy(error_message, ""); if (sample_format != SAMPLEFORMAT_UINT && sample_format != SAMPLEFORMAT_INT) { strcat(error_message, "Problem with sampling format. Was looking for integer, "); if (sample_format == SAMPLEFORMAT_COMPLEXIEEEFP) strcat(error_message, "found complex floating point instead!\n"); else if (sample_format == SAMPLEFORMAT_COMPLEXINT) strcat(error_message, "found complex integer instead!\n"); else if (sample_format == SAMPLEFORMAT_IEEEFP) strcat(error_message, "found floating point instead!\n"); else if (sample_format == SAMPLEFORMAT_VOID) strcat(error_message, "found void instead!\n"); wrong = TRUE; } if (bits_per_sample != 16) { sprintf(str, "Problem with bits per sample. Was looking for 16, found %d " "instead!\n", bits_per_sample); strcat(error_message, str); wrong = TRUE; } if (data_type != INTEGER16) { strcat(error_message, "Problem with data type. Was looking INTEGER16, "); if (data_type == ASF_BYTE) strcat(error_message, "found BYTE instead!\n"); else if (data_type == INTEGER32) strcat(error_message, "found INTEGER32 instead!\n"); else if (data_type == REAL32) strcat(error_message, "found REAL32 instead!\n"); else if (data_type == REAL64) strcat(error_message, "found REAL64 instead!\n"); else if (data_type == COMPLEX_BYTE) strcat(error_message, "found COMPLEX_BYTE instead!\n"); else if (data_type == COMPLEX_INTEGER16) strcat(error_message, "found COMPLEX_INTEGER16 instead!\n"); else if (data_type == COMPLEX_INTEGER32) strcat(error_message, "found COMPLEX_INTEGER32 instead!\n"); else if (data_type == COMPLEX_REAL32) strcat(error_message, "found COMPLEX_REAL32 instead!\n"); else if (data_type == COMPLEX_REAL64) strcat(error_message, "found COMPLEX_REAL64 instead!\n"); wrong = TRUE; } if (num_bands != 2) { sprintf(str, "Problem with number of bands. Was looking for 2, " "found %d instead!\n", num_bands); strcat(error_message, str); wrong = TRUE; } if (wrong) asfPrintError(error_message); // Check GTCitationGeoKey char *citation = NULL; int citation_length, typeSize; tagtype_t citation_type; citation_length = GTIFKeyInfo(gtif, GTCitationGeoKey, &typeSize, &citation_type); if (citation_length > 0) { citation = (char *) MALLOC(citation_length * typeSize); GTIFKeyGet(gtif, GTCitationGeoKey, citation, 0, citation_length); if (citation && strcmp_case(citation, "UNCORRECTED SATELLITE DATA") != 0) { asfPrintError("Problem with GTCitationGeoKey. Was looking for " "'Uncorrected Satellite Data',\nfound '%s' instead!\n", citation); } } else asfPrintError("Problem with GTCitationGeoKey. Was looking for " "'Uncorrected Satellite Data',\ndid not find any key!\n"); tiff_type_t tiffInfo; get_tiff_type(tiff, &tiffInfo); if (tiffInfo.format != SCANLINE_TIFF && tiffInfo.format != STRIP_TIFF && tiffInfo.format != TILED_TIFF) asfPrintError("Can't read the GeoTIFF file (%s). Unrecognized TIFF " "type!\n", inDataNames[band]); // If we made it here, we are reasonably sure that we have the file that // we are looking for. asfPrintStatus("\n Importing %s ...\n", inDataNames[band]); uint32 scanlineSize = TIFFScanlineSize(tiff); tdata_t *tiff_real_buf = _TIFFmalloc(scanlineSize); tdata_t *tiff_imag_buf = _TIFFmalloc(scanlineSize); if (!tiff_real_buf || !tiff_imag_buf) asfPrintError("Can't allocate buffer for reading TIFF lines!\n"); amp = (float *) MALLOC(sizeof(float)*meta->general->sample_count); phase = (float *) MALLOC(sizeof(float)*meta->general->sample_count); // Check whether we need to flip the image in any fashion int flip_vertical = FALSE; if (strcmp_case(radarsat2->lineTimeOrdering, "DECREASING") == 0) { asfPrintStatus(" Data will be flipped vertically while ingesting!\n"); flip_vertical = TRUE; } int flip_horizontal = FALSE; if (strcmp_case(radarsat2->pixelTimeOrdering, "DECREASING") == 0) { asfPrintStatus(" Data will be flipped horizontally while ingesting!\n"); flip_horizontal = TRUE; } if (flip_horizontal) tmp = (float *) MALLOC(sizeof(float)*meta->general->sample_count); // FIXME: still need to implement flipping vertically // Read file line by line uint32 row; int sample_count = meta->general->sample_count; int line_count = meta->general->line_count; for (row=0; row<(uint32)meta->general->line_count; row++) { asfLineMeter(row, meta->general->line_count); if (flip_vertical) { switch (tiffInfo.format) { case SCANLINE_TIFF: TIFFReadScanline(tiff, tiff_real_buf, line_count-row-1, 0); TIFFReadScanline(tiff, tiff_imag_buf, line_count-row-1, 1); break; case STRIP_TIFF: ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, line_count-row-1, 0); ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, line_count-row-1, 1); break; case TILED_TIFF: ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, line_count-row-1, 0); ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, line_count-row-1, 1); break; default: asfPrintError("Can't read this TIFF format!\n"); break; } } else { switch (tiffInfo.format) { case SCANLINE_TIFF: TIFFReadScanline(tiff, tiff_real_buf, row, 0); TIFFReadScanline(tiff, tiff_imag_buf, row, 1); break; case STRIP_TIFF: ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, row, 0); ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, row, 1); break; case TILED_TIFF: ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, row, 0); ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, row, 1); break; default: asfPrintError("Can't read this TIFF format!\n"); break; } } for (sample=0; sample<sample_count; sample++) { switch (sample_format) { case SAMPLEFORMAT_UINT: re = (float)(((uint16*)tiff_real_buf)[sample]); im = (float)(((uint16*)tiff_imag_buf)[sample]); break; case SAMPLEFORMAT_INT: re = (float)(((int16*)tiff_real_buf)[sample]); im = (float)(((int16*)tiff_imag_buf)[sample]); break; } amp[sample] = sqrt(re*re + im*im); phase[sample] = atan2(im, re); } if (flip_horizontal) { for (sample=0; sample<sample_count; sample++) tmp[sample] = amp[sample]; for (sample=0; sample<sample_count; sample++) amp[sample] = tmp[sample_count-sample-1]; } put_band_float_line(fp, meta, band*2, (int)row, amp); if (!ampOnly) put_band_float_line(fp, meta, band*2+1, (int)row, phase); } FREE(amp); FREE(phase); if (tmp) FREE(tmp); _TIFFfree(tiff_real_buf); _TIFFfree(tiff_imag_buf); GTIFFree(gtif); XTIFFClose(tiff); } // update the name field with directory name char *path = get_dirname(inBaseName); if (strlen(path)<=0) path = g_get_current_dir(); char *p = path, *q = path; while (q) { if ((q = strchr(p, DIR_SEPARATOR)) != NULL) p = q+1; } sprintf(meta->general->basename, "%s", p); FREE(path); meta_write(meta, outDataName); meta_free(meta); FREE(radarsat2); FCLOSE(fp); }