355 for(
int i=0;
i<padding;
i++) out2[
i] = out2[padding];
356 for(
int i=w-padding;
i<w;
i++) out2[
i] = out2[w-padding-1];
362 const float *
const input,
368 const float highlights,
373 if(wd <= 1 || ht <= 1)
return 0;
394 if(num_levels < 2)
return 0;
396 int last_level = num_levels-1;
397 if(b &&
b->mode == 2)
398 last_level = num_levels > 4 ? 4 : num_levels-1;
399 const int max_supp = 1<<last_level;
410 if(b &&
b->mode == 2)
411 padded[0] =
ll_pad_input(input, wd, ht, max_supp, &w, &h, b);
413 padded[0] =
ll_pad_input(input, wd, ht, max_supp, &w, &h, 0);
414 if(padded[0] == NULL)
421 for(
int l=1;l<=last_level;l++)
424 if(padded[l] == NULL)
432 for(
int l=0;l<=last_level;l++)
435 if(output[l] == NULL)
443 for(
int l=1;l<last_level;l++)
445 gauss_reduce(padded[last_level-1], output[last_level],
dl(w,last_level-1),
dl(h,last_level-1));
453 for(
int k=0;
k<
num_gamma;
k++)
for(
int l=0;l<=last_level;l++)
456 if(buf[
k][l] == NULL)
468 apply_curve(buf[
k][0], padded[0], w, h, max_supp, gamma[
k],
sigma, shadows, highlights, clarity);
471 for(
int l=1;l<=last_level;l++)
478 if(b &&
b->mode == 2)
480 const float isize = powf(2.0f, last_level) /
b->roi->scale;
481 const float psize = isize /
b->buf->width *
b->wd;
482 const float pl = log2f(psize);
483 const int pl0 = CLAMP((
int)pl, 0,
b->num_levels-1), pl1 = CLAMP((
int)(pl+1), 0,
b->num_levels-1);
484 const float weight = CLAMP(pl-pl0, 0, 1);
485 const float mul0 = 1.0/powf(2.0f, pl0);
486 const float mul1 = 1.0/powf(2.0f, pl1);
487 const float mul = powf(2.0f, last_level);
488 const int pw =
dl(w,last_level), ph =
dl(h,last_level);
489 const int pw0 =
dl(
b->pwd, pl0), ph0 =
dl(
b->pht, pl0);
490 const int pw1 =
dl(
b->pwd, pl1), ph1 =
dl(
b->pht, pl1);
494#pragma omp parallel for collapse(2) default(shared)
496 for(
int j=0;j<ph;j++)
for(
int i=0;
i<pw;
i++)
499 float ix = ((
i*mul - max_supp) +
b->roi->x)/
b->roi->scale;
500 float iy = ((j*mul - max_supp) +
b->roi->y)/
b->roi->scale;
502 float px = CLAMP(ix / (
float)
b->buf->width *
b->wd + (
b->pwd-
b->wd)/2.0f, 0,
b->pwd);
503 float py = CLAMP(iy / (
float)
b->buf->height *
b->ht + (
b->pht-
b->ht)/2.0f, 0,
b->pht);
505 int px0 = CLAMP(px*mul0, 0, pw0-1);
506 int py0 = CLAMP(py*mul0, 0, ph0-1);
507 int px1 = CLAMP(px*mul1, 0, pw1-1);
508 int py1 = CLAMP(py*mul1, 0, ph1-1);
510 float f0x = CLAMP(px*mul0 - px0, 0.0f, 1.0f);
511 float f0y = CLAMP(py*mul0 - py0, 0.0f, 1.0f);
512 float f1x = CLAMP(px*mul1 - px1, 0.0f, 1.0f);
513 float f1y = CLAMP(py*mul1 - py1, 0.0f, 1.0f);
515 (1.0f-f0x)*(1.0f-f0y)*
b->output[pl0][CLAMP(py0 , 0, ph0-1)*pw0 + CLAMP(px0 , 0, pw0-1)]+
516 ( f0x)*(1.0f-f0y)*
b->output[pl0][CLAMP(py0 , 0, ph0-1)*pw0 + CLAMP(px0+1, 0, pw0-1)]+
517 (1.0f-f0x)*( f0y)*
b->output[pl0][CLAMP(py0+1, 0, ph0-1)*pw0 + CLAMP(px0 , 0, pw0-1)]+
518 ( f0x)*( f0y)*
b->output[pl0][CLAMP(py0+1, 0, ph0-1)*pw0 + CLAMP(px0+1, 0, pw0-1)];
520 (1.0f-f1x)*(1.0f-f1y)*
b->output[pl1][CLAMP(py1 , 0, ph1-1)*pw1 + CLAMP(px1 , 0, pw1-1)]+
521 ( f1x)*(1.0f-f1y)*
b->output[pl1][CLAMP(py1 , 0, ph1-1)*pw1 + CLAMP(px1+1, 0, pw1-1)]+
522 (1.0f-f1x)*( f1y)*
b->output[pl1][CLAMP(py1+1, 0, ph1-1)*pw1 + CLAMP(px1 , 0, pw1-1)]+
523 ( f1x)*( f1y)*
b->output[pl1][CLAMP(py1+1, 0, ph1-1)*pw1 + CLAMP(px1+1, 0, pw1-1)];
525 float c0 =
b->output[pl0][py0*pw0 + px0];
526 float c1 =
b->output[pl1][py1*pw1 + px1];
534 for(
int l=last_level-1;l >= 0; l--)
536 const int pw =
dl(w,l), ph =
dl(h,l);
541 for(
int j=0;j<ph;j++)
for(
int i=0;
i<pw;
i++)
543 const float v = padded[l][j*pw+
i];
547 const float a =
CLAMPS((
v - gamma[lo])/(gamma[hi]-gamma[lo]), 0.0f, 1.0f);
548 const float l0 =
ll_laplacian(buf[lo][l+1], buf[lo][l],
i, j, pw, ph);
550 output[l][j*pw+
i] += l0 * (1.0f-
a) +
l1 * a;
559 for(
int j=0;j<ht;j++)
for(
int i=0;
i<wd;
i++)
561 out[4*(j*wd+
i)+0] = 100.0f * output[0][(j+max_supp)*w+max_supp+
i];
562 out[4*(j*wd+
i)+1] = input[4*(j*wd+
i)+1];
563 out[4*(j*wd+
i)+2] = input[4*(j*wd+
i)+2];
565 if(b &&
b->mode == 1)
572 b->num_levels = num_levels;
573 for(
int l=0;l<num_levels;l++)
b->output[l] = output[l];
578 const int keep_preview = (
b &&
b->mode == 1 && err == 0);
581 if(!keep_preview || l)