39#include "irplib_hist.h"
56 return (irplib_hist *)cpl_calloc(1,
sizeof(irplib_hist));
64irplib_hist_delete(irplib_hist *d)
80irplib_hist_init(irplib_hist *hist,
86 cpl_ensure_code(hist != NULL, CPL_ERROR_NULL_INPUT);
87 cpl_ensure_code(nbins > 0, CPL_ERROR_ILLEGAL_INPUT);
88 cpl_ensure_code(range > 0, CPL_ERROR_ILLEGAL_INPUT);
89 cpl_ensure_code(hist->bins == NULL, CPL_ERROR_ILLEGAL_INPUT);
92 hist->bins = (
unsigned long *)cpl_calloc(nbins,
sizeof(
unsigned long));
97 return cpl_error_get_code();
106irplib_hist_get_value(
const irplib_hist *hist,
const unsigned long binpos)
108 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
109 cpl_ensure(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT, 0);
110 cpl_ensure(binpos < hist->nbins, CPL_ERROR_ILLEGAL_INPUT, 0);
112 return hist->bins[binpos];
120irplib_hist_get_nbins(
const irplib_hist *hist)
122 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
132irplib_hist_get_bin_size(
const irplib_hist *hist)
134 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
135 cpl_ensure(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT, 0);
137 return hist->range / (double)(hist->nbins - 2);
145irplib_hist_get_range(
const irplib_hist *hist)
147 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
158irplib_hist_get_start(
const irplib_hist *hist)
160 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
161 cpl_ensure(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT, 0);
173irplib_hist_fill(irplib_hist *hist,
const cpl_image *image)
175 double binwidth = 1.0;
178 const float *data = 0;
179 const cpl_binary *bpm_data = 0;
180 const cpl_mask *bpm = 0;
183 cpl_ensure_code(hist != NULL, CPL_ERROR_NULL_INPUT);
184 cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
186 if (hist->bins == NULL) {
187 const double hstart = cpl_image_get_min(image);
188 const double hrange = cpl_image_get_max(image) - hstart;
189 cpl_error_code error;
197 const unsigned long nbins = (
unsigned long)(hrange / binwidth) + 2;
199 error = irplib_hist_init(hist, nbins, hstart, hrange);
200 cpl_ensure_code(!error, error);
203 cpl_ensure_code(hist->range > 0, CPL_ERROR_ILLEGAL_INPUT);
206 binwidth = hist->range / (double)(hist->nbins - 2);
209 nsamples = cpl_image_get_size_x(image) * cpl_image_get_size_y(image);
210 data = cpl_image_get_data_float_const(image);
211 bpm = cpl_image_get_bpm_const(image);
213 bpm_data = cpl_mask_get_data_const(bpm);
216 for (i = 0; i < nsamples; i++) {
218 if (bpm_data && bpm_data[i] != CPL_BINARY_0) {
221 pos = (int)((data[i] - hist->start) / binwidth);
225 else if ((
unsigned long)pos >= (hist->nbins - 2)) {
226 hist->bins[hist->nbins - 1]++;
229 hist->bins[pos + 1]++;
233 return cpl_error_get_code();
244irplib_hist_get_max(
const irplib_hist *hist,
unsigned long *maxpos)
246 unsigned long max = 0;
249 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, 0);
250 cpl_ensure(maxpos != NULL, CPL_ERROR_NULL_INPUT, 0);
251 cpl_ensure(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT, 0);
253 for (ui = 0; ui < hist->nbins; ui++) {
254 double c_value = irplib_hist_get_value(hist, ui);
269irplib_hist_cast_table(
const irplib_hist *hist)
272 cpl_error_code error;
274 cpl_ensure(hist != NULL, CPL_ERROR_NULL_INPUT, NULL);
275 cpl_ensure(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
277 table = cpl_table_new(hist->nbins);
279 error = cpl_table_new_column(table,
"HIST", CPL_TYPE_INT);
280 cpl_ensure(!error, error, NULL);
282 error = cpl_table_copy_data_int(table,
"HIST", (
int *)(hist->bins));
283 cpl_ensure(!error, error, NULL);
294irplib_hist_collapse(irplib_hist *hist,
unsigned long new_nbins)
296 unsigned long ui, nuj;
297 unsigned long *old_bins;
298 unsigned long old_nbins;
299 double collapse_rate;
300 cpl_error_code error;
303 cpl_ensure_code(hist != NULL, CPL_ERROR_NULL_INPUT);
304 cpl_ensure_code(hist->bins != NULL, CPL_ERROR_ILLEGAL_INPUT);
305 cpl_ensure_code(new_nbins > 0, CPL_ERROR_ILLEGAL_INPUT);
306 cpl_ensure_code(new_nbins <= hist->nbins, CPL_ERROR_ILLEGAL_INPUT);
308 old_bins = hist->bins;
309 old_nbins = hist->nbins;
312 error = irplib_hist_init(hist, new_nbins, hist->start, hist->range);
313 cpl_ensure_code(!error, error);
315 collapse_rate = (double)(old_nbins - 2) / (double)(new_nbins - 2);
318 hist->bins[0] = old_bins[0];
319 hist->bins[new_nbins - 1] = old_bins[old_nbins - 1];
324 for (ui = 1; ui < new_nbins - 1; ui++) {
326 const double up = collapse_rate * ui;
328 hist->bins[ui] += rest;
330 for (uj = nuj; uj < (
unsigned long)up + 1; uj++)
331 hist->bins[ui] += old_bins[uj];
333 rest = (
unsigned long)(up - (
unsigned long)up) * old_bins[uj];
334 hist->bins[ui] += rest;
336 rest = old_bins[uj] - rest;
342 return cpl_error_get_code();