63#define exposure2white(x) exp2f(-(x))
116 const int new_version)
118 if(old_version == 1 && new_version == 2)
120 typedef struct dt_iop_basicadj_params_v1_t
132 } dt_iop_basicadj_params_v1_t;
134 const dt_iop_basicadj_params_v1_t *old = old_params;
138 new->exposure = old->exposure;
139 new->hlcompr = old->hlcompr;
140 new->hlcomprthresh = old->hlcomprthresh;
141 new->contrast = old->contrast;
142 new->preserve_colors = old->preserve_colors;
143 new->middle_grey = old->middle_grey;
144 new->brightness = old->brightness;
145 new->saturation = old->saturation;
146 new->clip = old->clip;
155 return _(
"this module is deprecated. please use the quick access panel instead.");
160 return _(
"basic adjustments");
167 _(
"linear, RGB, scene-referred"),
168 _(
"non-linear, RGB"),
169 _(
"non-linear, RGB, scene-referred"));
192 g->button_down =
g->draw_selected_region = 0;
193 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->bt_select_region),
g->draw_selected_region);
222 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off), 1);
229 if(
g->call_auto_exposure == 0)
231 g->box_cood[0] =
g->box_cood[1] =
g->box_cood[2] =
g->box_cood[3] = 0.f;
232 g->call_auto_exposure = 1;
248 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
off), 1);
255 if(gtk_toggle_button_get_active(togglebutton))
257 g->draw_selected_region = 1;
260 g->draw_selected_region = 0;
262 g->posx_from =
g->posx_to =
g->posy_from =
g->posy_to = 0;
277 if(
g->call_auto_exposure == 2)
279 g->call_auto_exposure = -1;
287 g->call_auto_exposure = 0;
314 const float def_middle_grey
315 = (work_profile) ? (dt_ioppr_get_profile_info_middle_grey(work_profile) * 100.f) : 18.42f;
339 float point[2] = { (float)
x, (
float)y };
360 if(fabsf(
g->posx_from -
g->posx_to) > 1 && fabsf(
g->posy_from -
g->posy_to) > 1)
362 g->box_cood[0] =
g->posx_from;
363 g->box_cood[1] =
g->posy_from;
364 g->box_cood[2] =
g->posx_to;
365 g->box_cood[3] =
g->posy_to;
369 g->call_auto_exposure = 1;
389 if((which == 3) || (which == 1 &&
type == GDK_2BUTTON_PRESS))
397 float point[2] = { (float)
x, (
float)y };
401 g->posx_from =
g->posx_to =
point[0];
402 g->posy_from =
g->posy_to =
point[1];
418 if(!
g->draw_selected_region || !
g->button_down)
return;
419 if(
g->posx_from ==
g->posx_to &&
g->posy_from ==
g->posy_to)
return;
426 const float posx_from = fmin(
g->posx_from,
g->posx_to);
427 const float posx_to = fmax(
g->posx_from,
g->posx_to);
428 const float posy_from = fmin(
g->posy_from,
g->posy_to);
429 const float posy_to = fmax(
g->posy_from,
g->posy_to);
432 cairo_set_line_width(cr, 1.0 / zoom_scale);
433 cairo_set_source_rgb(cr, .2, .2, .2);
440 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
442 cairo_rectangle(cr, posx_from, posy_from, (posx_to - posx_from), (posy_to - posy_from));
444 cairo_translate(cr, 1.0 / zoom_scale, 1.0 / zoom_scale);
445 cairo_set_source_rgb(cr, .8, .8, .8);
446 cairo_rectangle(cr, posx_from + 1.0 / zoom_scale, posy_from, (posx_to - posx_from) - 3. / zoom_scale,
447 (posy_to - posy_from) - 2. / zoom_scale);
462 p->middle_grey = (work_profile) ? (dt_ioppr_get_rgb_matrix_luminance(self->
picked_color,
465 work_profile->unbounded_coeffs_in,
477static inline float get_gamma(
const float x,
const float gamma)
479 return powf(
x, gamma);
484 return (
x > 1.f) ?
get_gamma(
x, gamma) :
lut[CLAMP((
int)(
x * 0x10000ul), 0, 0xffff)];
487static inline float get_contrast(
const float x,
const float contrast,
const float middle_grey,
488 const float inv_middle_grey)
490 return powf(
x * inv_middle_grey, contrast) * middle_grey;
493static inline float get_lut_contrast(
const float x,
const float contrast,
const float middle_grey,
494 const float inv_middle_grey,
const float *
const lut)
496 return (
x > 1.f) ?
get_contrast(
x, contrast, middle_grey, inv_middle_grey)
497 :
lut[CLAMP((
int)(
x * 0x10000ul), 0, 0xffff)];
522 const float brightness =
p->brightness * 2.f;
523 const float gamma = (brightness >= 0.0f) ? 1.0f / (1.0f + brightness) : (1.0f - brightness);
524 const float contrast =
p->contrast + 1.0f;
525 const float middle_grey = (
p->middle_grey > 0.f) ? (
p->middle_grey / 100.f) : 0.1842f;
526 const float inv_middle_grey = 1.f / middle_grey;
528 const int process_gamma = (
p->brightness != 0.f);
529 const int plain_contrast = (!
p->preserve_colors &&
p->contrast != 0.f);
532 if(process_gamma || plain_contrast)
534 for(
unsigned int i = 0;
i < 0x10000;
i++)
536 const float percentage = (float)
i / (
float)0x10000ul;
537 if(process_gamma)
d->lut_gamma[
i] =
get_gamma(percentage, gamma);
538 if(plain_contrast)
d->lut_contrast[
i] =
get_contrast(percentage, contrast, middle_grey, inv_middle_grey);
559 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->bt_select_region),
g->draw_selected_region);
571 g->call_auto_exposure = 0;
572 g->draw_selected_region = 0;
573 g->posx_from =
g->posx_to =
g->posy_from =
g->posy_to = 0.f;
574 g->box_cood[0] =
g->box_cood[1] =
g->box_cood[2] =
g->box_cood[3] = 0.f;
589 gtk_widget_set_tooltip_text(
g->sl_black_point, _(
"adjust the black level to unclip negative RGB values.\n"
590 "you should never use it to add more density in blacks!\n"
591 "if poorly set, it will clip near-black colors out of gamut\n"
592 "by pushing RGB values into negatives"));
597 gtk_widget_set_tooltip_text(
g->sl_exposure, _(
"adjust the exposure correction"));
601 gtk_widget_set_tooltip_text(
g->sl_hlcompr, _(
"highlight compression adjustment"));
605 gtk_widget_set_tooltip_text(
g->sl_contrast, _(
"contrast adjustment"));
608 gtk_widget_set_tooltip_text(
g->cmb_preserve_colors, _(
"method to preserve colors when applying contrast"));
613 gtk_widget_set_tooltip_text(
g->sl_middle_grey, _(
"middle gray adjustment"));
618 gtk_widget_set_tooltip_text(
g->sl_brightness,_(
"brightness adjustment"));
621 gtk_widget_set_tooltip_text(
g->sl_saturation,_(
"saturation adjustment"));
624 gtk_widget_set_tooltip_text(
g->sl_vibrance, _(
"vibrance adjustment"));
630 gtk_box_pack_start(GTK_BOX(autolevels_box),
g->bt_auto_levels,
TRUE,
TRUE, 0);
634 gtk_widget_set_tooltip_text(
g->bt_select_region,
635 _(
"apply auto exposure based on a region defined by the user\n"
636 "click and drag to draw the area\n"
637 "right click to cancel"));
639 gtk_box_pack_start(GTK_BOX(autolevels_box),
g->bt_select_region,
TRUE,
TRUE, 0);
641 gtk_box_pack_start(GTK_BOX(self->
widget), autolevels_box,
TRUE,
TRUE, 0);
645 gtk_widget_set_tooltip_text(
g->sl_clip, _(
"adjusts clipping value for auto exposure calculation"));
685 const int m =
d < 4.9090934652977266E-91;
686 d =
m ? 2.037035976334486E90 *
d :
d;
688 q =
m ? q - (300 + 0x03fe) : q - 0x03fe;
693static inline double ldexpk(
double x, int32_t q)
695 int32_t
m = q < 0 ? -1 : 0;
696 m = (((
m + q) >> 9) -
m) << 7;
711 double x = (
m - 1) / (
m + 1);
712 const double x2 =
x *
x;
714 double t = 0.148197055177935105296783;
715 t = fma(
t, x2, 0.153108178020442575739679);
716 t = fma(
t, x2, 0.181837339521549679055568);
717 t = fma(
t, x2, 0.22222194152736701733275);
718 t = fma(
t, x2, 0.285714288030134544449368);
719 t = fma(
t, x2, 0.399999999989941956712869);
720 t = fma(
t, x2, 0.666666666666685503450651);
723 x =
x *
t + 0.693147180559945286226764 * e;
725 if(!isfinite(
d))
x = INFINITY;
727 if(
d == 0)
x = -INFINITY;
734 const double sRGBGammaCurve = 2.4;
735 return (
x <= 0.00304) ? (
x * 12.92) : (1.055 * exp(log(
x) / sRGBGammaCurve) - 0.055);
740 const double sRGBGammaCurve = 2.4;
741 return (
x <= 0.03928) ? (
x / 12.92) : (exp(log((
x + 0.055) / 1.055) * sRGBGammaCurve));
746 uint32_t **_histogram,
unsigned int *_hist_size,
int *_histcompr)
750 const int histcompr = 3;
751 const unsigned int hist_size = 65536 >> histcompr;
752 uint32_t *histogram = NULL;
753 const float mul = hist_size;
756 sizeof(uint32_t) * hist_size,
764 memset(histogram, 0,
sizeof(uint32_t) * hist_size);
766 if(box_area[2] > box_area[0] && box_area[3] > box_area[1])
768 for(
int y = box_area[1]; y <= box_area[3]; y++)
770 const float *
const in = img + (size_t)
ch *
width * y;
771 for(
int x = box_area[0];
x <= box_area[2];
x++)
773 const float *
const pixel = in +
x *
ch;
775 for(
int c = 0; c < 3; c++)
781 else if(pixel[c] >= 1.f)
783 histogram[hist_size - 1]++;
787 const uint32_t
R = (uint32_t)(pixel[c] * mul);
798 const float *
const pixel = img +
i;
800 for(
int c = 0; c < 3; c++)
806 else if(pixel[c] >= 1.f)
808 histogram[hist_size - 1]++;
812 const uint32_t
R = (uint32_t)(pixel[c] * mul);
820 *_histogram = histogram;
821 *_hist_size = hist_size;
822 *_histcompr = histcompr;
827static void _get_sum_and_average(
const uint32_t *
const histogram,
const int hist_size,
float *_sum,
float *_avg)
832 for(
int i = 0;
i < hist_size;
i++)
834 float val = histogram[
i];
845static inline float hlcurve(
const float level,
const float hlcomp,
const float hlrange)
849 float val = level + (hlrange - 1.f);
857 float Y = val / hlrange;
866 float R = hlrange / (val * hlcomp);
867 return log1pf(Y) *
R;
876static void _get_auto_exp(
const uint32_t *
const histogram,
const unsigned int hist_size,
const int histcompr,
877 const float defgain,
const float clip,
const float midgray,
float *_expcomp,
878 float *_bright,
float *_contr,
float *_black,
float *_hlcompr,
float *_hlcomprthresh)
885 float hlcomprthresh = 0.f;
887 float scale = 65536.0f;
889 const int imax = 65536 >> histcompr;
891 float sum = 0.f, hisum = 0.f, losum = 0.f;
898 int median = 0, count = histogram[0];
900 while(count < sum / 2)
903 count += histogram[
median];
906 if(
median == 0 || ave < 1.f)
919 float octile[8] = { 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f }, ospread = 0.f;
924 for(;
i <
MIN((
int)ave, imax);
i++)
928 octile[count] += histogram[
i];
930 if(octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f))
932 octile[count] =
xlog(1. + (
float)
i) / log(2.f);
937 losum += histogram[
i];
944 octile[count] += histogram[
i];
946 if(octile[count] > sum / 8.f || (count == 7 && octile[count] > sum / 16.f))
948 octile[count] =
xlog(1.f + (
float)
i) / log(2.f);
953 hisum += histogram[
i];
957 if(losum == 0.f || hisum == 0.f)
969 if(octile[6] > log1pf((
float)imax) / log2(2.f))
971 octile[6] = 1.5f * octile[5] - 0.5f * octile[4];
976 if(octile[7] > log1pf((
float)imax) / log2(2.f))
978 octile[7] = 1.5f * octile[6] - 0.5f * octile[5];
989 for(
int ii = 1; ii < 8; ii++)
991 if(octile[ii] == 0.0f)
993 octile[ii] = octile[ii - 1];
999 for(
int ii = 1; ii < 6; ii++)
1001 ospread += (octile[ii + 1] - octile[ii])
1002 /
MAX(0.5f, (ii > 2 ? (octile[ii + 1] - octile[3]) : (octile[3] - octile[ii])));
1015 hlcomprthresh = 0.f;
1020 unsigned int clipped = 0;
1021 int rawmax = (imax)-1;
1023 while(histogram[rawmax] + clipped <= 0 && rawmax > 1)
1025 clipped += histogram[rawmax];
1030 unsigned int clippable = (int)(sum * clip);
1032 int whiteclip = (imax)-1;
1034 while(whiteclip > 1 && (histogram[whiteclip] + clipped) <= clippable)
1036 clipped += histogram[whiteclip];
1044 while(shc < whiteclip - 1 && histogram[shc] + clipped <= clippable)
1046 clipped += histogram[shc];
1051 rawmax <<= histcompr;
1052 whiteclip <<= histcompr;
1053 ave = ave * (1 << histcompr);
1060 const float expcomp1 = (logf(midgray * scale / (ave - shc + midgray * shc))) /
DT_M_LN2f;
1065 expcomp2 = 0.5f * ((15.5f - histcompr - (2.f * oct7 - oct6)) + logf(scale / rawmax) /
DT_M_LN2f);
1069 expcomp2 = 0.5f * ((15.5f - histcompr - (2.f * octile[7] - octile[6])) + logf(scale / rawmax) /
DT_M_LN2f);
1072 if(fabsf(expcomp1) - fabsf(expcomp2) > 1.f)
1074 expcomp = (expcomp1 * fabsf(expcomp2) + expcomp2 * fabsf(expcomp1)) / (fabsf(expcomp1) + fabsf(expcomp2));
1078 expcomp = 0.5 * (
double)expcomp1 + 0.5 * (
double)expcomp2;
1081 const float gain = expf(expcomp *
DT_M_LN2f);
1083 const float corr = sqrtf(gain * scale / rawmax);
1087 hlcomprthresh = 0.f;
1090 const float comp = (gain * ((float)whiteclip) / scale - 1.f) * 2.3f;
1091 hlcompr = (comp / (fmaxf(0.0f, expcomp) + 1.0f));
1092 hlcompr = fmaxf(0.f, fminf(100.f, hlcompr));
1096 const float midtmp = gain * sqrtf(
median * ave) / scale;
1100 bright = (midgray - midtmp) * 15.0f / (midtmp);
1104 bright = (midgray - midtmp) * 15.0f / (0.10833 - 0.0833f * midtmp);
1107 bright = 0.25f *
MAX(0.f, bright);
1110 contr = (midgray * 100.f) * (1.1f - ospread);
1111 contr =
MAX(0.f,
MIN(100.f, contr));
1113 double whiteclipg =
gamma2(whiteclip * corr);
1118 const float increment = corr * (1 << histcompr);
1120 for(
int ii = 0; ii<65536>> histcompr; ii++)
1123 gavg += histogram[ii] *
gamma2(val);
1131 const int maxwhiteclip = (gavg - black) * 4 / 3
1134 if(whiteclipg < maxwhiteclip)
1136 whiteclipg = maxwhiteclip;
1144 black = (black / whiteclipg);
1146 expcomp = CLAMP(expcomp, -5.0f, 12.0f);
1148 bright =
MAX(-100.f,
MIN(bright, 100.f));
1158 fprintf(stderr,
"[_get_auto_exp] expcomp is NaN!!!\n");
1163 fprintf(stderr,
"[_get_auto_exp] black is NaN!!!\n");
1168 fprintf(stderr,
"[_get_auto_exp] bright is NaN!!!\n");
1173 fprintf(stderr,
"[_get_auto_exp] contr is NaN!!!\n");
1178 fprintf(stderr,
"[_get_auto_exp] hlcompr is NaN!!!\n");
1180 if(isnan(hlcomprthresh))
1182 hlcomprthresh = 0.f;
1183 fprintf(stderr,
"[_get_auto_exp] hlcomprthresh is NaN!!!\n");
1186 *_expcomp = expcomp;
1190 *_hlcompr = hlcompr;
1191 *_hlcomprthresh = hlcomprthresh;
1194static inline __attribute__((always_inline))
int _auto_exposure(
const float *
const img,
const int width,
const int height,
int *box_area,
1195 const float clip,
const float midgray,
float *_expcomp,
float *_bright,
float *_contr,
1196 float *_black,
float *_hlcompr,
float *_hlcomprthresh)
1198 uint32_t *histogram = NULL;
1199 unsigned int hist_size = 0;
1202 const float defGain = 0.0f;
1209 _get_auto_exp(histogram, hist_size, histcompr, defGain, clip, midgray, _expcomp, _bright, _contr, _black,
1210 _hlcompr, _hlcomprthresh);
1221 box_out[0] = box_out[1] = box_out[2] = box_out[3] = 0;
1227 dt_boundingbox_t box_cood = {
g->box_cood[0],
g->box_cood[1],
g->box_cood[2],
g->box_cood[3] };
1229 box_cood[0] *= pipe->
iwidth;
1231 box_cood[2] *= pipe->
iwidth;
1237 box_cood[0] *= roi_in->
scale;
1238 box_cood[1] *= roi_in->
scale;
1239 box_cood[2] *= roi_in->
scale;
1240 box_cood[3] *= roi_in->
scale;
1242 box_cood[0] -= roi_in->
x;
1243 box_cood[1] -= roi_in->
y;
1244 box_cood[2] -= roi_in->
x;
1245 box_cood[3] -= roi_in->
y;
1250 box[0] = fminf(box_cood[0], box_cood[2]);
1251 box[1] = fminf(box_cood[1], box_cood[3]);
1252 box[2] = fmaxf(box_cood[0], box_cood[2]);
1253 box[3] = fmaxf(box_cood[1], box_cood[3]);
1256 if(!(box[0] >=
width || box[1] >=
height || box[2] < 0 || box[3] < 0))
1263 if(!(box[2] - box[0] < 1 || box[3] - box[1] < 1))
1265 box_out[0] = box[0];
1266 box_out[1] = box[1];
1267 box_out[2] = box[2];
1268 box_out[3] = box[3];
1293 g->call_auto_exposure = -1;
1300 if(_auto_exposure((
const float *
const)ivoid, roi_in->
width, roi_in->
height, box,
g->params.clip,
1301 g->params.middle_grey / 100.f, &
g->params.exposure, &
g->params.brightness,
1302 &
g->params.contrast, &
g->params.black_point, &
g->params.hlcompr, &
g->params.hlcomprthresh))
1308 g->call_auto_exposure = 2;
1317 const float black_point =
p->black_point;
1318 const float hlcompr =
p->hlcompr;
1319 const float hlcomprthresh =
p->hlcomprthresh;
1320 const float saturation =
p->saturation + 1.0f;
1321 const float vibrance =
p->vibrance / 1.4f;
1322 const float contrast =
p->contrast + 1.0f;
1324 const float scale = 1.0f / (white -
p->black_point);
1325 const float middle_grey = (
p->middle_grey > 0.f) ? (
p->middle_grey / 100.f) : 0.1842f;
1326 const float inv_middle_grey = 1.f / middle_grey;
1327 const float brightness =
p->brightness * 2.f;
1328 const float gamma = (brightness >= 0.0f) ? 1.0f / (1.0f + brightness) : (1.0f - brightness);
1330 const float hlcomp = hlcompr / 100.0f;
1331 const float shoulder = ((hlcomprthresh / 100.f) / 8.0f) + 0.1f;
1332 const float hlrange = 1.0f - shoulder;
1334 const int plain_contrast = (!
p->preserve_colors &&
p->contrast != 0.f);
1335 const int preserve_colors = (
p->contrast != 0.f) ?
p->preserve_colors : 0;
1336 const int process_gamma = (
p->brightness != 0.f);
1337 const int process_saturation_vibrance = (
p->saturation != 0.f)||(
p->vibrance != 0.f);
1338 const int process_hlcompr = (
p->hlcompr > 0.f);
1340 const float *
const in = (
const float *
const)ivoid;
1341 float *
const out = (
float *
const)
ovoid;
1342 const size_t stride = (size_t)roi_out->
height * roi_out->
width *
ch;
1344 for(
size_t k = 0;
k < stride;
k +=
ch)
1346 for(
size_t c = 0; c < 3; c++)
1349 out[
k + c] = (in[
k + c] - black_point) * scale;
1355 const float lum = (work_profile) ? dt_ioppr_get_rgb_matrix_luminance(
out +
k,
1358 work_profile->unbounded_coeffs_in,
1364 const float ratio =
hlcurve(lum, hlcomp, hlrange);
1366 for(
size_t c = 0; c < 3; c++)
1373 for(
size_t c = 0; c < 3; c++)
1379 if(plain_contrast &&
out[
k + c] > 0.f)
1387 const float lum =
dt_rgb_norm(
out +
k, preserve_colors, work_profile);
1390 const float contrast_lum = powf(lum * inv_middle_grey, contrast) * middle_grey;
1391 ratio = contrast_lum / lum;
1394 for(
size_t c = 0; c < 3; c++)
1401 if(process_saturation_vibrance)
1403 const float average = (
out[
k] +
out[
k+1] +
out[
k+2]) / 3;
1405 const float P = vibrance * (1 - powf(
delta, fabsf(vibrance)));
1407 for(
size_t c = 0; c < 3; c++)
1409 out[
k + c] = average + (saturation +
P) * (
out[
k+c] - average);
1413 out[
k + 3] = in[
k + 3];
1418#undef exposure2white
void cleanup(dt_imageio_module_format_t *self)
static float get_lut_gamma(const float x, const float gamma, const float *const lut)
const char ** description(struct dt_iop_module_t *self)
__DT_CLONE_TARGETS__ int process(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
static __DT_CLONE_TARGETS__ void _get_sum_and_average(const uint32_t *const histogram, const int hist_size, float *_sum, float *_avg)
static __DT_CLONE_TARGETS__ void _get_auto_exp(const uint32_t *const histogram, const unsigned int hist_size, const int histcompr, const float defgain, const float clip, const float midgray, float *_expcomp, float *_bright, float *_contr, float *_black, float *_hlcompr, float *_hlcomprthresh)
static void _auto_levels_callback(GtkButton *button, dt_iop_module_t *self)
static double longBitsToDouble(int64_t i)
static float get_gamma(const float x, const float gamma)
static int ilogbp1(double d)
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *params, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
#define exposure2white(x)
void gui_focus(struct dt_iop_module_t *self, gboolean in)
static float get_contrast(const float x, const float contrast, const float middle_grey, const float inv_middle_grey)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static void _signal_profile_user_changed(gpointer instance, uint8_t profile_type, gpointer user_data)
static double xlog(double d)
void gui_update(struct dt_iop_module_t *self)
static float get_lut_contrast(const float x, const float contrast, const float middle_grey, const float inv_middle_grey, const float *const lut)
void change_image(struct dt_iop_module_t *self)
static void _select_region_toggled_callback(GtkToggleButton *togglebutton, dt_iop_module_t *self)
void gui_init(struct dt_iop_module_t *self)
int button_pressed(struct dt_iop_module_t *self, double x, double y, double pressure, int which, int type, uint32_t state)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
static __DT_CLONE_TARGETS__ int _get_auto_exp_histogram(const float *const img, const int width, const int height, int *box_area, uint32_t **_histogram, unsigned int *_hist_size, int *_histcompr)
static double igamma2(double x)
int button_released(struct dt_iop_module_t *self, double x, double y, int which, uint32_t state)
static void _turn_selregion_picker_off(struct dt_iop_module_t *self)
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
static __DT_CLONE_TARGETS__ void _get_selected_area(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, dt_iop_basicadj_gui_data_t *g, const dt_iop_roi_t *const roi_in, int *box_out)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static int64_t doubleToRawLongBits(double d)
static double gamma2(double x)
void gui_post_expose(struct dt_iop_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx, int32_t pointery)
static void _turn_select_region_off(struct dt_iop_module_t *self)
void gui_cleanup(struct dt_iop_module_t *self)
static void _develop_ui_pipe_finished_callback(gpointer instance, gpointer user_data)
static void _color_picker_callback(GtkWidget *button, dt_iop_module_t *self)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
const char * deprecated_msg()
int mouse_moved(struct dt_iop_module_t *self, double x, double y, double pressure, int which)
static double ldexpk(double x, int32_t q)
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
static float hlcurve(const float level, const float hlcomp, const float hlrange)
void dt_bauhaus_slider_set_soft_range(GtkWidget *widget, float soft_min, float soft_max)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
void dt_bauhaus_slider_set_soft_max(GtkWidget *widget, float val)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
static float dt_camera_rgb_luminance(const float4 rgb)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w)
@ DT_COLORSPACES_PROFILE_TYPE_WORK
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_control_queue_redraw_center()
request redraw of center window. This redraws the center view within a gdk critical section to preven...
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
float dt_boundingbox_t[4]
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define dt_pixelpipe_cache_free_align(mem)
#define __DT_CLONE_TARGETS__
#define __OMP_PARALLEL_FOR__(...)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static float dt_rgb_norm(const float4 in, const int norm, const int work_profile, constant dt_colorspaces_iccprofile_info_cl_t *profile_info, read_only image2d_t lut)
#define dt_dev_add_history_item(dev, module, enable, redraw)
#define dt_dev_pixelpipe_update_history_all(dev)
int dt_dev_distort_transform_plus(const dt_dev_pixelpipe_t *pipe, const double iop_order, const int transf_direction, float *points, size_t points_count)
float dt_dev_get_overlay_scale(dt_develop_t *dev)
Get the overlay scale factor in GUI logical coordinates.
void dt_dev_coordinates_image_norm_to_preview_abs(dt_develop_t *dev, float *points, size_t num_points)
gboolean dt_dev_rescale_roi(dt_develop_t *dev, cairo_t *cr, int32_t width, int32_t height)
Scale the ROI to fit within given width/height, centered.
gboolean dt_dev_pixelpipe_has_preview_output(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
void dt_dev_coordinates_widget_to_image_norm(dt_develop_t *dev, float *points, size_t num_points)
Coordinate conversion helpers between widget, normalized image, and absolute image spaces.
void dt_dev_coordinates_image_abs_to_raw_norm(dt_develop_t *dev, float *points, size_t num_points)
@ DT_DEV_TRANSFORM_DIR_BACK_INCL
void dtgtk_cairo_paint_colorpicker(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
#define DT_GUI_BOX_SPACING
#define DT_PIXEL_APPLY_DPI(value)
void dt_iop_request_focus(dt_iop_module_t *module)
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
static void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module) ACQUIRE(&module -> gui_lock)
@ IOP_FLAGS_SUPPORTS_BLENDING
static void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module) RELEASE(&module -> gui_lock)
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_pipe_current_profile_info(dt_iop_module_t *module, const struct dt_dev_pixelpipe_t *pipe)
dt_iop_order_iccprofile_info_t * dt_ioppr_get_iop_work_profile_info(struct dt_iop_module_t *module, GList *iop_list)
GtkWidget * dt_action_button_new(dt_lib_module_t *self, const gchar *label, gpointer callback, gpointer data, const gchar *tooltip, guint accel_key, GdkModifierType mods)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_CONTROL_PROFILE_USER_CHANGED
This signal is raised when a profile is changed by the user 1 uint32_t : the profile type that has ch...
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
const float uint32_t state[4]
struct dt_gui_gtk_t * gui
struct dt_control_signal_t * signals
struct dt_develop_t * develop
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
float lut_contrast[0x10000]
dt_iop_basicadj_params_t params
GtkWidget * cmb_preserve_colors
GtkWidget * sl_saturation
GtkWidget * sl_black_point
GtkWidget * sl_brightness
GtkWidget * bt_auto_levels
dt_boundingbox_t box_cood
GtkWidget * sl_middle_grey
dt_iop_basicadj_params_t params
GtkWidget * bt_select_region
dt_iop_rgb_norms_t preserve_colors
GtkDarktableToggleButton * off
dt_iop_params_t * default_params
struct dt_develop_t * dev
dt_iop_gui_data_t * gui_data
dt_aligned_pixel_t picked_color
dt_colormatrix_t matrix_in
Region of interest passed through the pixelpipe.
typedef double((*spd)(unsigned long int wavelength, double TempK))