void floats_to_bytes_from_file_ext(const char *inFile, const char *outFile, char *band, float mask, scale_t scaling, float scale_factor) { FILE *fp; meta_parameters *meta; float *float_data; unsigned char *byte_data; int ii, band_number; long long pixel_count; long offset; meta = meta_read(inFile); band_number = (!band || strlen(band) == 0 || strcmp(band, "???")==0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); pixel_count = meta->general->line_count * meta->general->sample_count; offset = meta->general->line_count * band_number; float_data = (float *) MALLOC(sizeof(float) * pixel_count); fp = FOPEN(inFile, "rb"); get_float_lines(fp, meta, offset, meta->general->line_count, float_data); FCLOSE(fp); byte_data = floats_to_bytes_ext(float_data, pixel_count, mask, scaling, scale_factor); for (ii=0; ii<pixel_count; ii++) float_data[ii] = (float) byte_data[ii]; meta->general->data_type = ASF_BYTE; meta_write(meta, outFile); fp = FOPEN(outFile, "wb"); put_float_lines(fp, meta, offset, meta->general->line_count, float_data); FCLOSE(fp); FREE(float_data); FREE(byte_data); meta_free(meta); }
int find_band(meta_parameters *meta, char *name, int *ok) { const char *rad_name = get_cal_band_name(meta, name); int band_num = get_band_number(meta->general->bands, meta->general->band_count, rad_name); if (band_num < 0) { asfPrintStatus("Band '%s' not found.\n", name); *ok = FALSE; } return band_num; }
int open_asf_data(const char *filename, const char *band, int multilook, meta_parameters *meta, ClientInterface *client) { ReadAsfClientInfo *info = MALLOC(sizeof(ReadAsfClientInfo)); info->is_rgb = FALSE; info->band_gs = info->band_r = info->band_g = info->band_b = 0; info->ml = multilook; // special hack for Avnir data! if (!band && strcmp_case(meta->general->sensor_name, "AVNIR") == 0 && meta->general->band_count >= 3) { // no band was specifed -- show true color (3,2,1) asfPrintStatus("Avnir data: defaulting to TRUE color -- " "Red=3, Green=2, Blue=1\n"); band = "03,02,01"; } if (band) { char *r, *b, *g; if (split3(band, &r, &g, &b, ',')) { // Looks like we were given 3 bands -- so, we are doing rgb info->band_r = get_band_number(meta->general->bands, meta->general->band_count, r); if (info->band_r < 0) asfPrintWarning("Red band '%s' not found.\n", r); else asfPrintStatus("Red band is band #%d: %s\n", info->band_r+1, r); info->band_g = get_band_number(meta->general->bands, meta->general->band_count, g); if (info->band_g < 0) asfPrintWarning("Green band '%s' not found.\n", g); else asfPrintStatus("Green band is band #%d: %s\n", info->band_g+1, g); info->band_b = get_band_number(meta->general->bands, meta->general->band_count, b); if (info->band_b < 0) asfPrintWarning("Blue band '%s' not found.\n", b); else asfPrintStatus("Blue band is band #%d: %s\n", info->band_b+1, b); if (info->band_r < 0 && info->band_g < 0 && info->band_b < 0) { // none of the bands were found return FALSE; } info->is_rgb = TRUE; FREE(r); FREE(g); FREE(b); set_bands_rgb(info->band_r, info->band_g, info->band_b); } else { // Single band name given info->band_gs = get_band_number(meta->general->bands, meta->general->band_count, (char*)band); if (info->band_gs < 0) { asfPrintWarning("Band '%s' not found.\n", band); return FALSE; } else { asfPrintStatus("Reading band #%d: %s\n", info->band_gs+1, band); } set_bands_greyscale(info->band_gs); } } info->fp = fopen(filename, "rb"); if (!info->fp) { asfPrintWarning("Failed to open ASF Internal file %s: %s\n", filename, strerror(errno)); return FALSE; } client->read_client_info = info; client->read_fn = read_asf_client; client->thumb_fn = get_asf_thumbnail_data; client->free_fn = free_asf_client_info; if (meta->general->data_type == ASF_BYTE) client->data_type = info->is_rgb ? RGB_BYTE : GREYSCALE_BYTE; else client->data_type = info->is_rgb ? RGB_FLOAT : GREYSCALE_FLOAT; return TRUE; }
void calc_minmax_median(const char *inFile, char *band, double mask, double *min, double *max) { long long ii, jj; float logeps = 10.0 * log10(EPSILON); float median, median0; meta_parameters *meta = meta_read(inFile); int band_number = (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); long sample_count = meta->general->sample_count; long line_count = meta->general->line_count; long pixel_count = sample_count*line_count; long offset = line_count * band_number; float *data_line = MALLOC(sizeof(float) * sample_count); float *data = MALLOC(sizeof(float) * pixel_count); float *data2 = MALLOC(sizeof(float) * pixel_count); // Culling invalid pixels FILE *fp = FOPEN(inFile, "rb"); long valid_pixel_count = 0; asfPrintStatus("\nCalculating min and max using median...\n"); for (ii=0; ii<line_count; ++ii) { get_float_line(fp, meta, ii + offset, data_line); asfPercentMeter(((double)ii/(double)line_count)); for (jj=0; jj<sample_count; ++jj) { if (!FLOAT_EQUIVALENT(data_line[jj], -9999.99) || !FLOAT_EQUIVALENT(data_line[jj], logeps) || ISNAN(mask)) { data[valid_pixel_count] = data_line[jj]; valid_pixel_count++; } } } asfPercentMeter(1.0); FCLOSE(fp); FREE(data_line); // Determine initial min and max *min = INIT_MINMAX; *max = -INIT_MINMAX; float minmin = INIT_MINMAX; float maxmax = -INIT_MINMAX; for (ii=0; ii<valid_pixel_count; ++ii) { data2[ii] = data[ii]; if (data[ii] < minmin) minmin = data[ii]; if (data[ii] > maxmax) maxmax = data[ii]; } median0 = median_value(data, valid_pixel_count); // Determine minimum median = median0; *min = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == minmin) { if (data[jj] <= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] < median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == minmin) median = *min; *min = median; } // Determine maximum median = median0; *max = median0; for (ii=0; ii<3; ii++) { pixel_count = -1; for (jj=0; jj<valid_pixel_count; ++jj) if (median0 == maxmax) { if (data[jj] >= median) { pixel_count++; data2[pixel_count] = data[jj]; } } else { if (data[jj] > median) { pixel_count++; data2[pixel_count] = data[jj]; } } median = median_value(data2, pixel_count); if (median == maxmax) median = *max; *max = median; } FREE(data); FREE(data2); }
void calc_stats_rmse_from_file(const char *inFile, char *band, double mask, double *min, double *max, double *mean, double *stdDev, double *rmse, gsl_histogram **histogram) { double se; int ii,jj; *min = 999999; *max = -999999; *mean = 0.0; meta_parameters *meta = meta_read(inFile); int band_number = (!band || strlen(band) == 0 || strcmp(band, "???") == 0) ? 0 : get_band_number(meta->general->bands, meta->general->band_count, band); long offset = meta->general->line_count * band_number; float *data = MALLOC(sizeof(float) * meta->general->sample_count); // pass 1 -- calculate mean, min & max FILE *fp = FOPEN(inFile, "rb"); long long pixel_count=0; asfPrintStatus("\nCalculating min, max, and mean...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter(((double)ii/(double)meta->general->line_count)); get_float_line(fp, meta, ii + offset, data); for (jj=0; jj<meta->general->sample_count; ++jj) { if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) { if (data[jj] < *min) *min = data[jj]; if (data[jj] > *max) *max = data[jj]; *mean += data[jj]; ++pixel_count; } } } asfPercentMeter(1.0); FCLOSE(fp); *mean /= pixel_count; // Guard against weird data if(!(*min<*max)) *max = *min + 1; // Initialize the histogram. const int num_bins = 256; gsl_histogram *hist = gsl_histogram_alloc (num_bins); gsl_histogram_set_ranges_uniform (hist, *min, *max); *stdDev = 0.0; // pass 2 -- update histogram, calculate standard deviation fp = FOPEN(inFile, "rb"); asfPrintStatus("\nCalculating standard deviation, rmse, and histogram...\n"); se = 0.0; for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter(((double)ii/(double)meta->general->line_count)); get_float_line(fp, meta, ii + offset, data); for (jj=0; jj<meta->general->sample_count; ++jj) { if (ISNAN(mask) || !FLOAT_EQUIVALENT(data[jj], mask)) { *stdDev += (data[jj] - *mean) * (data[jj] - *mean); gsl_histogram_increment (hist, data[jj]); se += (data[jj] - *mean) * (data[jj] - *mean); } } } asfPercentMeter(1.0); FCLOSE(fp); *stdDev = sqrt(*stdDev/(pixel_count - 1)); *rmse = sqrt(se/(pixel_count - 1)); FREE(data); *histogram = hist; }
void calc_stats_from_file_with_formula(const char *inFile, char *bands, calc_stats_formula_t formula_callback, double mask, double *min, double *max, double *mean, double *stdDev, gsl_histogram **histogram) { int ii,jj,kk; const int N=MAX_BANDS; *min = 999999; *max = -999999; *mean = 0.0; meta_parameters *meta = meta_read(inFile); int band_numbers[N]; for (ii=0; ii<N; ++ii) band_numbers[ii] = -1; int band_count = 0; if (bands) { char *s = STRDUP(bands); // a copy we can fiddle with char *q, *p = s; do { q = strchr(p, ','); if (q) *q = '\0'; if (strlen(p) > 0 && strcmp(p, "???") != 0) { band_numbers[band_count] = get_band_number(meta->general->bands, meta->general->band_count, p); //printf("%s -> %d\n", p, band_numbers[band_count]); ++band_count; } if (q) p = q+1; } while (q); FREE(s); } long band_offsets[N]; float *band_data[N]; for (ii=0; ii<N; ++ii) { if (band_numbers[ii] >= 0) { band_offsets[ii] = meta->general->line_count * band_numbers[ii]; band_data[ii] = MALLOC(sizeof(float)*meta->general->sample_count); } else { band_offsets[ii] = -1; band_data[ii] = NULL; } } // pass 1 -- calculate mean, min & max FILE *fp = FOPEN(inFile, "rb"); long long pixel_count=0; asfPrintStatus("\nCalculating min, max, and mean...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter((double)ii/(double)meta->general->line_count); for (kk=0; kk<N; ++kk) { if (band_data[kk]) { assert(band_offsets[kk] >= 0); get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]); } } for (jj=0; jj<meta->general->sample_count; ++jj) { int is_masked = FALSE; if (ISNAN(mask)) { for (kk=0; kk<N; ++kk) if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask)) is_masked = TRUE; } if (!is_masked) { double data_arr[N]; int ll; for (ll=0, kk=0; kk<N; ++kk) if (band_data[kk]) data_arr[ll++] = band_data[kk][jj]; assert(ll==band_count); double val = formula_callback(data_arr, mask); if (val < *min) *min = val; if (val > *max) *max = val; *mean += val; ++pixel_count; } } } asfPercentMeter(1.0); FCLOSE(fp); *mean /= pixel_count; // Guard against weird data if(!(*min<*max)) *max = *min + 1; // Initialize the histogram. const int num_bins = 256; gsl_histogram *hist = gsl_histogram_alloc (num_bins); gsl_histogram_set_ranges_uniform (hist, *min, *max); *stdDev = 0.0; // pass 2 -- update histogram, calculate standard deviation fp = FOPEN(inFile, "rb"); asfPrintStatus("\nCalculating standard deviation and histogram...\n"); for (ii=0; ii<meta->general->line_count; ++ii) { asfPercentMeter((double)ii/(double)meta->general->line_count); for (kk=0; kk<N; ++kk) { if (band_data[kk]) { assert(band_offsets[kk] >= 0); get_float_line(fp, meta, ii + band_offsets[kk], band_data[kk]); } } for (jj=0; jj<meta->general->sample_count; ++jj) { int is_masked = FALSE; if (ISNAN(mask)) { for (kk=0; kk<N; ++kk) if (band_data[kk] && FLOAT_EQUIVALENT(band_data[kk][jj], mask)) is_masked = TRUE; } if (!is_masked) { double data_arr[N]; int ll; for (ll=0, kk=0; kk<N; ++kk) if (band_data[kk]) data_arr[ll++] = band_data[kk][jj]; assert(ll==band_count); double val = formula_callback(data_arr, mask); *stdDev += (val - *mean) * (val - *mean); gsl_histogram_increment (hist, val); } } } asfPercentMeter(1.0); FCLOSE(fp); *stdDev = sqrt(*stdDev/(pixel_count - 1)); for (ii=0; ii<N; ++ii) if (band_data[ii]) FREE(band_data[ii]); *histogram = hist; }
int open_asf_data(const char *filename, const char *band, int multilook, meta_parameters *meta, ClientInterface *client) { ReadAsfClientInfo *info = MALLOC(sizeof(ReadAsfClientInfo)); info->is_rgb = FALSE; info->band_gs = info->band_r = info->band_g = info->band_b = 0; info->ml = multilook; // special hack for Avnir data! if (!band && strcmp_case(meta->general->sensor_name, "AVNIR") == 0 && meta->general->band_count >= 3) { // no band was specifed -- show true color (3,2,1) asfPrintStatus("Avnir data: defaulting to TRUE color -- " "Red=3, Green=2, Blue=1\n"); band = "03,02,01"; } if (band) { char *r, *b, *g; if (split3(band, &r, &g, &b, ',')) { // Looks like we were given 3 bands -- so, we are doing rgb info->band_r = get_band_number(meta->general->bands, meta->general->band_count, r); if (info->band_r < 0) asfPrintWarning("Red band '%s' not found.\n", r); else asfPrintStatus("Red band is band #%d: %s\n", info->band_r+1, r); info->band_g = get_band_number(meta->general->bands, meta->general->band_count, g); if (info->band_g < 0) asfPrintWarning("Green band '%s' not found.\n", g); else asfPrintStatus("Green band is band #%d: %s\n", info->band_g+1, g); info->band_b = get_band_number(meta->general->bands, meta->general->band_count, b); if (info->band_b < 0) asfPrintWarning("Blue band '%s' not found.\n", b); else asfPrintStatus("Blue band is band #%d: %s\n", info->band_b+1, b); if (info->band_r < 0 && info->band_g < 0 && info->band_b < 0) { // none of the bands were found return FALSE; } info->is_rgb = TRUE; FREE(r); FREE(g); FREE(b); set_bands_rgb(info->band_r, info->band_g, info->band_b); } else { // Single band name given info->band_gs = get_band_number(meta->general->bands, meta->general->band_count, (char*)band); if (info->band_gs < 0) { asfPrintWarning("Band '%s' not found.\n", band); return FALSE; } else { asfPrintStatus("Reading band #%d: %s\n", info->band_gs+1, band); } set_bands_greyscale(info->band_gs); } } info->fp = fopen(filename, "rb"); if (!info->fp) { asfPrintWarning("Failed to open ASF Internal file %s: %s\n", filename, strerror(errno)); return FALSE; } client->read_client_info = info; client->read_fn = read_asf_client; client->thumb_fn = get_asf_thumbnail_data; client->free_fn = free_asf_client_info; if (meta->general->data_type == ASF_BYTE) client->data_type = info->is_rgb ? RGB_BYTE : GREYSCALE_BYTE; else client->data_type = info->is_rgb ? RGB_FLOAT : GREYSCALE_FLOAT; // special sanity checks for ASF data if (meta->general->line_count == 0 || meta->general->sample_count == 0) { asfPrintStatus("Line count: %d\n", meta->general->line_count); asfPrintStatus("Sample count: %d\n", meta->general->sample_count); asfPrintWarning("Line count or sample count is 0.\n"); return FALSE; } long long sz = fileSize(filename); int mult = (info->is_rgb ? 3 : 1) * (meta->general->data_type == ASF_BYTE ? 1 : 4); long long expected_sz = meta->general->line_count * meta->general->sample_count * mult; if (sz < expected_sz) { asfPrintWarning("File is too short! Truncating lines...\n"); int orig = meta->general->line_count; asfPrintStatus("Original line count: %d\n", orig); meta->general->line_count = sz / mult / meta->general->sample_count; asfPrintStatus("Truncated line count (calculated from file size): %d\n", meta->general->line_count); asfPrintWarning("Truncated %d lines!\n", orig - meta->general->line_count); } return TRUE; }