26#include <glib/gstdio.h>
31#define ELEM_SWAP(a,b) { elem_type t=(a);(a)=(b);(b)=t; }
62 while (a[2*
i+1]<
x)
i++ ;
63 while (
x<a[2*j+1]) j-- ;
75#define median(a,n) kth_smallest(a,n,(((n)&1)?((n)/2):(((n)/2)-1)))
82 FILE *
f = g_fopen(filename,
"rb");
84 fscanf(
f,
"PF\n%d %d\n%*[^\n]", wd, ht);
87 float *
p = (
float *)malloc(
sizeof(
float)*3*(*wd)*(*ht));
88 fread(
p,
sizeof(
float)*3, (*wd)*(*ht),
f);
89 for(
int k=0;
k<3*(*wd)*(*ht);
k++)
p[
k] = fmaxf(0.0f,
p[
k]);
98 FILE *
f = g_fopen(filename,
"rb");
103 fscanf(
f,
"%*f %*f %*f %*f %*f %*f %*f %*f %*f %*f\n");
106 fseek(
f, 0, SEEK_SET);
108 float *hist = (
float *)malloc(
sizeof(
float) * 3 * (*bins));
112 fscanf(
f,
"%*f %*f %*f %*f %*f %*f %*f %f %f %f\n", hist + 3*
k, hist+3*
k+1, hist+3*
k+2);
122 const float *
const hist,
123 float *
const inv_hist,
130 for(
int i=last+1;
i<bins;
i++)
132 for(
int k=last;
k<bins;
k++)
134 if(hist[3*
k+c] >=
i/(
float)bins)
137 inv_hist[3*
i+c] =
k/(float)bins;
147write_pfm(
const char *filename,
float *buf,
int wd,
int ht)
149 FILE *
f = g_fopen(filename,
"wb");
151 fprintf(
f,
"PF\n%d %d\n-1.0\n", wd, ht);
152 fwrite(buf,
sizeof(
float)*3, wd*ht,
f);
163 return fmaxf(fminf(
f,
M),
m);
168 return (
int)
clamp(((
float *)a)[0]*
N, 0,
N-1) - (int)
clamp(((
float *)b)[0]*
N, 0,
N-1);
175 fprintf(stderr,
"usage: %s input.pfm [-c a1 b1]\n", arg[0]);
179 float *input =
read_pfm(arg[1], &wd, &ht);
185 if(argc >= 9 && !strcmp(arg[2],
"-c"))
201 float x =
k/(
N-1.0f)/a[c];
202 const float d = fmaxf(0.0f,
x + 3./8. + (b[c]/a[c])*(b[c]/a[c]));
204 fprintf(stderr,
"%f ",
x);
206 fprintf(stderr,
"\n");
209 for(
int k=0;
k<wd*ht;
k++)
214 input[3*
k+c] = input[3*
k+c] / a[c];
215 const float d = fmaxf(0.0f, input[3*
k+c] + 3./8. + (b[c]/a[c])*(b[c]/a[c]));
216 input[3*
k+c] = 2.0f*sqrtf(
d);
217 max = fmaxf(
max, input[3*
k+c]);
220 for(
int k=0;
k<3*wd*ht;
k++) input[
k] /=
max;
222 else if(argc >= 4 && !strcmp(arg[2],
"-h"))
226 float *inv_hist = (
float *)malloc(
sizeof(
float) * 3 * bins);
230 for(
int k=0;
k<bins;
k++)
232 fprintf(stderr,
"%f %f %f\n", inv_hist[3*
k], inv_hist[3*
k+1], inv_hist[3*
k+2]);
235 for(
int k=0;
k<wd*ht;
k++)
239 float f =
clamp(input[3*
k+c]*bins, 0, bins-2);
240 const int bin = (int)
f;
242 input[3*
k+c] = (1.0f-
f)*inv_hist[3*bin+c] +
f*inv_hist[3*(bin+1)+c];
247 float std[
N][3] = {{0.0f}};
248 float cnt[
N][3] = {{0.0f}};
251 for(
int j=0;j<ht;j++)
253 for(
int i=0;
i<wd-1;
i+=2)
255 float *buf = input + 3*(wd*j +
i);
265 for(
int i=0;
i<wd;
i++)
267 for(
int j=0;j<ht-1;j+=2)
269 float *buf = input + 3*(wd*j +
i);
272 buf[c] += buf[3*wd+c];
274 buf[3*wd+c] -= buf[c];
284 float *
out = (
float *)malloc(
sizeof(
float)*3*wd/2*ht/2);
285 for(
int j=0;j<ht-1;j+=2)
287 for(
int i=0;
i<wd-1;
i+=2)
291 out[3*((wd/2)*(j/2)+(
i/2))+c] = input[3*(wd*j+
i)+c];
300 float *llhh = (
float *)malloc(
sizeof(
float)*wd*ht/2);
304 for(
int j=0;j<ht-1;j+=2)
306 for(
int i=0;
i<wd-1;
i+=2)
308 llhh[2*
k] = input[3*(wd*j+
i)+c];
309 llhh[2*
k+1] = fabsf(input[3*(wd*(j+1)+(
i+1))+c]);
315 for(
int begin=0;begin<
k;)
318 const int bin = (int)
clamp(llhh[2*begin]*
N, 0,
N-1);
320 while((end <
k) && ((int)
clamp(llhh[2*end]*
N, 0,
N-1) == bin))
322 assert(end >=
k || bin <= (
int)
clamp(llhh[2*end]*
N, 0,
N-1));
329 std[bin][c] +=
median(llhh+2*begin, end-begin)/0.6745;
330 cnt[bin][c] = end - begin;
338 for(
int k=0;
k<wd*ht;
k++)
342 const int i =
clamp(ref[3*
k+c]*
N, 0,
N-1);
344 const float diff = input[3*
k+c] - ref[3*
k+c];
346 var[
i][c] += diff*diff;
356 std[
i][c] /= cnt[
i][c];
364 for(
int k=0;
k<3;
k++) std[
i][
k] *=
max;
369 for(
int k=0;
k<3;
k++) sum[
k] += std[
i][
k];
373 fprintf(stdout,
"%f %f %f %f %f %f %f %f %f %f\n",
i/(
float)
N, std[
i][0], std[
i][1], std[
i][2],
374 cnt[
i][0], cnt[
i][1], cnt[
i][2],
375 cdf[0]/sum[0], cdf[1]/sum[1], cdf[2]/sum[2]);
377 for(
int k=0;
k<3;
k++) cdf[
k] += std[
i][
k];
void write_pfm(const char *filename, int width, int height, float *data)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
static const dt_colormatrix_t M
float *const restrict const size_t k
static float * read_histogram(const char *filename, int *bins)
int compare_llhh(const void *a, const void *b)
static float clamp(float f, float m, float M)
float dt_aligned_pixel_t[4]
static elem_type kth_smallest(elem_type a[], int n, int k)
static float * read_pfm(const char *filename, int *wd, int *ht)
static void invert_histogram(const float *const hist, float *const inv_hist, const int bins)