89#include "external/cie_colorimetric_tables.c"
97#define INITIALBLACKBODYTEMPERATURE 4000
99#define DT_IOP_LOWEST_TEMPERATURE 1901
100#define DT_IOP_HIGHEST_TEMPERATURE 25000
102#define DT_IOP_LOWEST_TINT 0.135
103#define DT_IOP_HIGHEST_TINT 2.326
105#define DT_IOP_NUM_OF_STD_TEMP_PRESETS 4
108#define DT_IOP_TEMP_AS_SHOT 0
109#define DT_IOP_TEMP_SPOT 1
110#define DT_IOP_TEMP_USER 2
111#define DT_IOP_TEMP_D65 3
170 void *new_params,
const int new_version)
172 if(old_version == 2 && new_version == 3)
174 typedef struct dt_iop_temperature_params_v2_t
178 } dt_iop_temperature_params_v2_t;
180 dt_iop_temperature_params_v2_t *o = (dt_iop_temperature_params_v2_t *)old_params;
183 n->
red = o->coeffs[0];
184 n->green = o->coeffs[1];
185 n->blue = o->coeffs[2];
195 p->red = a[0];
p->green = a[1];
p->blue = a[2];
p->g2 = a[3];
200 a[0] =
p->red; a[1] =
p->green; a[2] =
p->blue; a[3] =
p->g2;
207 if(g_str_has_suffix(img->
filename,
"-hdr.dng"))
210 static const char *
const ignored_cameras[] = {
211 "Canon PowerShot A610",
212 "Canon PowerShot S3 IS",
213 "Canon PowerShot A620",
214 "Canon PowerShot A720 IS",
215 "Canon PowerShot A630",
216 "Canon PowerShot A640",
217 "Canon PowerShot A650",
218 "Canon PowerShot SX110 IS",
229 for(
int i=0;
i <
sizeof(ignored_cameras)/
sizeof(ignored_cameras[1]);
i++)
239 return C_(
"modulename",
"white balance");
246 _(
"linear, raw, scene-referred"),
248 _(
"linear, raw, scene-referred"));
280typedef double((*spd)(
unsigned long int wavelength,
double TempK));
289 const long double lambda = (
double)wavelength * 1e-9;
306#define c1 3.7417715246641281639549488324352159753e-16L
307#define c2 0.014387769599838156481252937624049081933L
309 return (
double)(
c1 / (powl(lambda, 5) * (expl(
c2 / (lambda * TempK)) - 1.0L)));
322 cmsCIExyY WhitePoint = { 0.3127, 0.3290, 1.0 };
328 cmsWhitePointFromTemp(&WhitePoint, TempK);
330 const double M = (0.0241 + 0.2562 * WhitePoint.x - 0.7341 * WhitePoint.y),
331 m1 = (-1.3515 - 1.7703 * WhitePoint.x + 5.9114 * WhitePoint.y) /
M,
332 m2 = (0.0300 - 31.4424 * WhitePoint.x + 30.0717 * WhitePoint.y) /
M;
334 const unsigned long int j
335 = ((wavelength - cie_daylight_components[0].wavelength)
336 / (cie_daylight_components[1].wavelength - cie_daylight_components[0].wavelength));
338 return (cie_daylight_components[j].
S[0] + m1 * cie_daylight_components[j].
S[1]
339 + m2 * cie_daylight_components[j].
S[2]);
348 cmsCIEXYZ Source = {.X = 0.0, .Y = 0.0, .Z = 0.0 };
354 for(
size_t i = 0;
i < cie_1931_std_colorimetric_observer_count;
i++)
356 const unsigned long int lambda = cie_1931_std_colorimetric_observer[0].wavelength
357 + (cie_1931_std_colorimetric_observer[1].wavelength
358 - cie_1931_std_colorimetric_observer[0].wavelength) *
i;
359 const double P = I(lambda, TempK);
360 Source.X +=
P * cie_1931_std_colorimetric_observer[
i].xyz.X;
361 Source.Y +=
P * cie_1931_std_colorimetric_observer[
i].xyz.Y;
362 Source.Z +=
P * cie_1931_std_colorimetric_observer[
i].xyz.Z;
366 const double _max = fmax(fmax(Source.X, Source.Y), Source.Z);
407 for(*TempK = (maxtemp + mintemp) / 2.0; (maxtemp - mintemp) > 1.0; *TempK = (maxtemp + mintemp) / 2.0)
410 if(_xyz.Z / _xyz.X >
XYZ.Z /
XYZ.X)
416 *tint = (_xyz.Y / _xyz.X) / (
XYZ.Y /
XYZ.X);
429 double XYZ[3] = { xyz.X, xyz.Y, xyz.Z };
432 for(
int k = 0;
k < 4;
k++)
435 for(
int i = 0;
i < 3;
i++)
437 CAM[
k] +=
g->XYZ_to_CAM[
k][
i] *
XYZ[
i];
441 for(
int k = 0;
k < 4;
k++) mul[
k] = 1.0 / CAM[
k];
466 for(
int k = 0; k < 4; k++) CAM[k] = CAM[k] > 0.0f ? 1.0 / CAM[
k] : 0.0f;
469 for(
int k = 0;
k < 3;
k++)
472 for(
int i = 0;
i < 4;
i++)
474 XYZ[
k] +=
g->CAM_to_XYZ[
k][
i] * CAM[
i];
478 return (cmsCIEXYZ){
XYZ[0],
XYZ[1],
XYZ[2] };
492 const uint8_t(*
const xtrans)[6] = (
const uint8_t(*
const)[6])piece->
dsc_in.
xtrans;
497 const float *
const in = (
const float *
const)ivoid;
498 float *
const out = (
float *
const)
ovoid;
499 const float *
const d_coeffs =
d->coeffs;
504 for(
int j = 0; j <
height; j++)
506 const size_t row_start = (size_t)j *
width;
507 const float coeffs[12] =
509 d_coeffs[
FCxtrans(j, 0, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 1, roi_out, xtrans)],
510 d_coeffs[
FCxtrans(j, 2, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 3, roi_out, xtrans)],
511 d_coeffs[
FCxtrans(j, 4, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 5, roi_out, xtrans)],
512 d_coeffs[
FCxtrans(j, 6, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 7, roi_out, xtrans)],
513 d_coeffs[
FCxtrans(j, 8, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 9, roi_out, xtrans)],
514 d_coeffs[
FCxtrans(j, 10, roi_out, xtrans)], d_coeffs[
FCxtrans(j, 11, roi_out, xtrans)],
521 const size_t p = row_start +
i;
522 out[
p + 0] = in[
p + 0] * coeffs[0];
523 out[
p + 1] = in[
p + 1] * coeffs[1];
524 out[
p + 2] = in[
p + 2] * coeffs[2];
525 out[
p + 3] = in[
p + 3] * coeffs[3];
526 out[
p + 4] = in[
p + 4] * coeffs[4];
527 out[
p + 5] = in[
p + 5] * coeffs[5];
528 out[
p + 6] = in[
p + 6] * coeffs[6];
529 out[
p + 7] = in[
p + 7] * coeffs[7];
530 out[
p + 8] = in[
p + 8] * coeffs[8];
531 out[
p + 9] = in[
p + 9] * coeffs[9];
532 out[
p + 10] = in[
p + 10] * coeffs[10];
533 out[
p + 11] = in[
p + 11] * coeffs[11];
537 const size_t p = row_start +
i;
538 out[
p] = in[
p] * coeffs[
i % 12];
545 const int cfa_x = roi_out->
x & 1;
547 for(
int j = 0; j <
height; j++)
549 const int offset_j = j + roi_out->
y;
550 const size_t row_start = (size_t)j *
width;
551 const int id0 =
FC(offset_j, cfa_x + 0, filters);
552 const int id1 =
FC(offset_j, cfa_x + 1, filters);
553 const float coeff0 = d_coeffs[id0];
554 const float coeff1 = d_coeffs[id1];
559 const size_t p = row_start +
i;
560 out[
p + 0] = in[
p + 0] * coeff0;
561 out[
p + 1] = in[
p + 1] * coeff1;
565 const size_t p = row_start +
i;
566 out[
p] = in[
p] * d_coeffs[
FC(offset_j,
i + roi_out->
x, filters)];
574 const size_t npixels = (size_t)roi_out->
width * roi_out->
height;
579 for(
size_t k = 0;
k < npixels;
k++)
581 const size_t p = 4 *
k;
582 out[
p + 0] = in[
p + 0] *
d->coeffs[0];
583 out[
p + 1] = in[
p + 1] *
d->coeffs[1];
584 out[
p + 2] = in[
p + 2] *
d->coeffs[2];
585 out[
p + 3] = in[
p + 3];
592 for(
size_t k = 0;
k <
ch * npixels;
k +=
ch)
594 for(ptrdiff_t c = 0; c < 3; c++)
596 const size_t p =
k + c;
597 out[
p] = in[
p] *
d->coeffs[c];
618 const int devid = pipe->
devid;
620 cl_mem dev_coeffs = NULL;
621 cl_mem dev_xtrans = NULL;
661 if(err != CL_SUCCESS)
goto error;
683 const gboolean
state = current_state && !mono;
684 dt_iop_fmt_log(self,
"force_enable: class=%s mono=%d current=%d -> %d",
686 mono, current_state,
state);
726 d->coeffs[0] =
p->red;
727 d->coeffs[1] =
p->green;
728 d->coeffs[2] =
p->blue;
733 d->coeffs[3] = g2_usable ?
p->g2 :
p->green;
734 dt_iop_fmt_log(self,
"commit: class=%s matrix_supported=%d coeffs=[%.4f %.4f %.4f %.4f] g2_in=%.4f g2_usable=%d -> enabled=%d",
737 d->coeffs[0],
d->coeffs[1],
d->coeffs[2],
d->coeffs[3],
p->g2, g2_usable, piece->
enabled);
743 for(
int k = 0;
k < 4;
k++)
755 gboolean is_D65 =
TRUE;
756 for(
int c = 0; c < 3; c++)
757 if(
d->coeffs[c] != (
float)
g->daylight_wb[c]) is_D65 =
FALSE;
779 const gboolean color_rgb =
g->colored_sliders &&
791 if(!color_rgb)
return;
810 if(!
g->blackbody_is_confusing)
830 const double white[3] = {
831 1.0/
g->daylight_wb[0],
832 1.0/
g->daylight_wb[1],
833 1.0/
g->daylight_wb[2],
856 if(gtk_widget_get_visible(GTK_WIDGET(
g->scale_r)))
858 gtk_widget_queue_draw(GTK_WIDGET(
g->scale_r));
859 gtk_widget_queue_draw(GTK_WIDGET(
g->scale_g));
860 gtk_widget_queue_draw(GTK_WIDGET(
g->scale_b));
873 if(!
g->colored_sliders)
return;
877 const int blackbody_is_confusing =
g->blackbody_is_confusing;
883 const double dayligh_white[3] = {
884 1.0/
g->daylight_wb[0],
885 1.0/
g->daylight_wb[1],
886 1.0/
g->daylight_wb[2],
889 double cur_coeffs[4] = {0.0};
890 temp2mul(self, cur_temp, 1.0, cur_coeffs);
891 const double cur_white[3] = {
897 if(blackbody_is_confusing)
907 double coeffs_tint[4];
908 temp2mul(self, K, cur_tint, coeffs_K);
909 temp2mul(self, cur_temp, tint, coeffs_tint);
910 coeffs_K[0] /= coeffs_K[1];
911 coeffs_K[2] /= coeffs_K[1];
912 coeffs_K[3] /= coeffs_K[1];
914 coeffs_tint[0] /= coeffs_tint[1];
915 coeffs_tint[2] /= coeffs_tint[1];
916 coeffs_tint[3] /= coeffs_tint[1];
917 coeffs_tint[1] = 1.0;
919 dt_aligned_pixel_t sRGB_K = { dayligh_white[0]*coeffs_K[0], dayligh_white[1]*coeffs_K[1],
920 dayligh_white[2]*coeffs_K[2] };
921 dt_aligned_pixel_t sRGB_tint = {cur_white[0]*coeffs_tint[0], cur_white[1]*coeffs_tint[1],
922 cur_white[2]*coeffs_tint[2]};
923 const float maxsRGB_K = fmaxf(fmaxf(sRGB_K[0], sRGB_K[1]), sRGB_K[2]);
924 const float maxsRGB_tint = fmaxf(fmaxf(sRGB_tint[0], sRGB_tint[1]),sRGB_tint[2]);
930 sRGB_K[
ch] = fmaxf(sRGB_K[
ch] / maxsRGB_K, 0.f);
933 if(maxsRGB_tint > 1.f)
937 sRGB_tint[
ch] = fmaxf(sRGB_tint[
ch] / maxsRGB_tint, 0.f);
960 dt_XYZ_to_Rec709_D65(XYZ_temp, sRGB_temp);
961 dt_XYZ_to_Rec709_D65(XYZ_tint, sRGB_tint);
963 const float maxsRGB_temp = fmaxf(fmaxf(sRGB_temp[0], sRGB_temp[1]), sRGB_temp[2]);
964 const float maxsRGB_tint = fmaxf(fmaxf(sRGB_tint[0], sRGB_tint[1]), sRGB_tint[2]);
966 if(maxsRGB_temp > 1.f)
970 sRGB_temp[
ch] = fmaxf(sRGB_temp[
ch] / maxsRGB_temp, 0.f);
974 if(maxsRGB_tint > 1.f)
978 sRGB_tint[
ch] = fmaxf(sRGB_tint[
ch] / maxsRGB_tint, 0.f);
987 if(gtk_widget_get_visible(GTK_WIDGET(
g->scale_k)))
989 gtk_widget_queue_draw(GTK_WIDGET(
g->scale_k));
990 gtk_widget_queue_draw(GTK_WIDGET(
g->scale_tint));
1028 g->as_shot_wb[0] =
g->as_shot_wb[1] =
g->as_shot_wb[2] =
g->as_shot_wb[3] = 1.f;
1030 g->as_shot_wb[0] /=
g->as_shot_wb[1];
1031 g->as_shot_wb[2] /=
g->as_shot_wb[1];
1032 g->as_shot_wb[3] /=
g->as_shot_wb[1];
1033 g->as_shot_wb[1] = 1.0;
1036 float TempK_def, tint_def;
1037 mul2temp(self,
d, &TempK_def, &tint_def);
1048 memset(
g->preset_num, 0,
sizeof(
g->preset_num));
1066 gboolean found =
FALSE;
1069 if(
p->red ==
g->as_shot_wb[0] &&
p->green ==
g->as_shot_wb[1] &&
p->blue ==
g->as_shot_wb[2])
1077 if((
p->red == (
float)
g->daylight_wb[0]) &&
1078 (
p->green == (
float)
g->daylight_wb[1]) &&
1079 (
p->blue == (
float)
g->daylight_wb[2]))
1089 if (!found || isnan(
g->mod_temp))
1091 g->mod_temp = tempK;
1096 gtk_widget_set_visible(
g->buttonbar,
g->button_bar_visible);
1109 gtk_widget_queue_draw(self->
gui->
widget);
1130 bwb[0] = mul[0] / mul[1];
1131 bwb[2] = mul[2] / mul[1];
1133 bwb[3] = mul[3] / mul[1];
1148 const double RGB_to_XYZ[3][4] = { { 0.4124564, 0.3575761, 0.1804375, 0 },
1149 { 0.2126729, 0.7151522, 0.0721750, 0 },
1150 { 0.0193339, 0.1191920, 0.9503041, 0 } };
1153 const double XYZ_to_RGB[4][3] = { { 3.2404542, -1.5371385, -0.4985314 },
1154 { -0.9692660, 1.8760108, 0.0415560 },
1155 { 0.0556434, -0.2040259, 1.0572252 },
1163 memcpy(
g->XYZ_to_CAM, XYZ_to_RGB,
sizeof(
g->XYZ_to_CAM));
1164 memcpy(
g->CAM_to_XYZ, RGB_to_XYZ,
sizeof(
g->CAM_to_XYZ));
1170 g->XYZ_to_CAM,
g->CAM_to_XYZ))
1172 char *camera =
module->dev->image_storage.camera_makermodel;
1173 fprintf(stderr,
"[temperature] `%s' color matrix not found for image\n", camera);
1174 dt_control_log(_(
"`%s' color matrix not found for image"), camera);
1180 const dt_image_t *img = &
module->dev->image_storage;
1186 for(
int k = 0; ok &&
k < num_coeffs;
k++)
1208 dt_control_log(_(
"failed to read camera white balance information from `%s'!"),
1210 fprintf(stderr,
"[temperature] failed to read camera white balance information from `%s'!\n",
1218 for(
int c = 0; c < 4; c++) coeffs[c] = bwb[c];
1244 const gboolean is_modern =
1247 module->default_enabled = 0;
1248 module->hide_enable_button = 0;
1255 module->hide_enable_button = 1;
1263 module->default_enabled = 1;
1267 double coeffs[4] = { 0 };
1270 d->red = coeffs[0]/coeffs[1];
1271 d->blue = coeffs[2]/coeffs[1];
1272 d->g2 = coeffs[3]/coeffs[1];
1279 d->red = coeffs[0]/coeffs[1];
1280 d->blue = coeffs[2]/coeffs[1];
1281 d->g2 = coeffs[3]/coeffs[1];
1287 dt_iop_fmt_log(module,
"reload_defaults: class=%s matrix_supported=%d mono=%d modern=%d -> default_enabled=%d coeffs=[%.4f %.4f %.4f %.4f]",
1289 is_raw, monochrome, is_modern, module->
default_enabled,
d->red,
d->green,
d->blue,
d->g2);
1308 const int program = 2;
1338 temp2mul(self,
g->mod_temp,
g->mod_tint,
g->mod_coeff);
1341 g->mod_coeff[0] /=
g->mod_coeff[1];
1342 g->mod_coeff[2] /=
g->mod_coeff[1];
1343 g->mod_coeff[3] /=
g->mod_coeff[1];
1344 g->mod_coeff[1] = 1.0;
1381 if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)))
1388 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton),
TRUE);
1405 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->btn_user), pos ==
DT_IOP_TEMP_USER);
1406 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->btn_d65), pos ==
DT_IOP_TEMP_D65);
1416 if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
g->colorpicker)))
1419 g_signal_emit_by_name(G_OBJECT(
g->colorpicker),
"button-press-event", NULL, &ret_val);
1432 if(self->
gui->
off) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->
gui->
off), 1);
1438 TempK =
g->mod_temp;
1476 p->green = grayrgb[1] > 0.001f ? 1.0f / grayrgb[1] : 1.0f;
1477 p->red = fmaxf(0.0f, fminf(8.0f, (grayrgb[0] > 0.001f ? 1.0f / grayrgb[0] : 1.0f) /
p->green));
1478 p->blue = fmaxf(0.0f, fminf(8.0f, (grayrgb[2] > 0.001f ? 1.0f / grayrgb[2] : 1.0f) /
p->green));
1479 p->g2 = fmaxf(0.0f, fminf(8.0f, (grayrgb[3] > 0.001f ? 1.0f / grayrgb[3] : 1.0f) /
p->green));
1510 gtk_widget_set_tooltip_text(
g->scale_r, _(
"green channel coefficient"));
1512 gtk_widget_set_tooltip_text(
g->scale_g, _(
"magenta channel coefficient"));
1514 gtk_widget_set_tooltip_text(
g->scale_b, _(
"cyan channel coefficient"));
1516 gtk_widget_set_tooltip_text(
g->scale_g2, _(
"yellow channel coefficient"));
1518 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_b, 0);
1519 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_g2, 1);
1520 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_g, 2);
1521 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_r, 3);
1526 gtk_widget_set_tooltip_text(
g->scale_r, _(
"red channel coefficient"));
1528 gtk_widget_set_tooltip_text(
g->scale_g, _(
"green channel coefficient"));
1530 gtk_widget_set_tooltip_text(
g->scale_b, _(
"blue channel coefficient"));
1532 gtk_widget_set_tooltip_text(
g->scale_g2, _(
"emerald channel coefficient"));
1534 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_r, 0);
1535 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_g, 1);
1536 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_b, 2);
1537 gtk_box_reorder_child(GTK_BOX(
g->cs.container),
g->scale_g2, 3);
1547 g->colored_sliders =
TRUE;
1548 g->blackbody_is_confusing =
FALSE;
1550 const int feedback =
TRUE;
1551 g->button_bar_visible =
TRUE;
1553 GtkBox *box_enabled = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL,
DT_GUI_BOX_SPACING));
1558 gtk_widget_set_tooltip_text(
g->btn_asshot, _(
"set white balance to as shot"));
1567 gtk_widget_set_tooltip_text(
g->colorpicker, _(
"set white balance to detected from area"));
1572 gtk_widget_set_tooltip_text(
g->btn_user, _(
"set white balance to user modified"));
1578 gtk_widget_set_tooltip_text(
g->btn_d65, _(
"set white balance to camera reference point\nin most cases it should be D65"));
1582 gtk_box_pack_end(GTK_BOX(
g->buttonbar),
g->btn_d65,
TRUE,
TRUE, 0);
1583 gtk_box_pack_end(GTK_BOX(
g->buttonbar),
g->btn_user,
TRUE,
TRUE, 0);
1584 gtk_box_pack_end(GTK_BOX(
g->buttonbar),
g->colorpicker,
TRUE,
TRUE, 0);
1585 gtk_box_pack_end(GTK_BOX(
g->buttonbar),
g->btn_asshot,
TRUE,
TRUE, 0);
1586 gtk_box_pack_start(box_enabled,
g->buttonbar,
TRUE,
TRUE, 0);
1590 gtk_widget_set_tooltip_text(
g->presets, _(
"choose white balance setting"));
1591 gtk_box_pack_start(box_enabled,
g->presets,
TRUE,
TRUE, 0);
1594 for(
int k = 0;
k < 4;
k++)
1596 g->daylight_wb[
k] = 1.0;
1597 g->as_shot_wb[
k] = 1.f;
1600 GtkWidget *temp_label_box = gtk_event_box_new();
1602 gtk_widget_set_tooltip_text(
g->temp_label, _(
"click to cycle color mode on sliders"));
1603 gtk_container_add(GTK_CONTAINER(temp_label_box),
g->temp_label);
1605 gtk_box_pack_start(box_enabled, temp_label_box,
TRUE,
TRUE, 0);
1609 0, 5000.0, 0, feedback);
1612 gtk_widget_set_tooltip_text(
g->scale_k, _(
"color temperature (in Kelvin)"));
1613 gtk_box_pack_start(box_enabled,
g->scale_k,
TRUE,
TRUE, 0);
1616 0, 1.0, 3, feedback);
1618 gtk_widget_set_tooltip_text(
g->scale_tint, _(
"color tint of the image, from magenta (value < 1) to green (value > 1)"));
1619 gtk_box_pack_start(box_enabled,
g->scale_tint,
TRUE,
TRUE, 0);
1623 "plugins/darkroom/temperature/expand_coefficients",
1624 _(
"channel coefficients"),
1625 GTK_BOX(box_enabled), GTK_PACK_END);
1627 self->
gui->
widget = GTK_WIDGET(
g->cs.container);
1638 gtk_widget_set_no_show_all(
g->scale_g2,
TRUE);
1640 g_signal_connect(G_OBJECT(
g->scale_k),
"value-changed", G_CALLBACK(
temp_tint_callback), self);
1641 g_signal_connect(G_OBJECT(
g->scale_tint),
"value-changed", G_CALLBACK(
temp_tint_callback), self);
1649 GtkWidget *label_disabled = gtk_label_new(_(
"white balance disabled for camera"));
1650 gtk_widget_set_halign(label_disabled, GTK_ALIGN_START);
1651 gtk_label_set_ellipsize(GTK_LABEL(label_disabled), PANGO_ELLIPSIZE_END);
1653 gtk_stack_add_named(GTK_STACK(self->
gui->
widget), GTK_WIDGET(box_enabled),
"enabled");
1654 gtk_stack_add_named(GTK_STACK(self->
gui->
widget), label_disabled,
"disabled");
static void error(char *msg)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_combobox_clear(GtkWidget *widget)
void dt_bauhaus_slider_clear_stops(GtkWidget *widget)
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
void dt_bauhaus_slider_set_stop(GtkWidget *widget, float stop, float r, float g, float b)
float dt_bauhaus_slider_get(GtkWidget *widget)
GtkWidget * dt_bauhaus_slider_new_with_range_and_feedback(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits, int feedback)
void dt_bauhaus_slider_set_feedback(GtkWidget *widget, int feedback)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
float dt_bauhaus_slider_get_hard_max(GtkWidget *widget)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
#define DT_BAUHAUS_SLIDER_MAX_STOPS
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_gui_new_collapsible_section(dt_gui_collapsible_section_t *cs, const char *confname, const char *label, GtkBox *parent, GtkPackType pack)
Create a collapsible section and pack it into the parent box.
void dt_gui_update_collapsible_section(dt_gui_collapsible_section_t *cs)
void dt_iop_color_picker_reset(dt_iop_module_t *module, gboolean keep)
GtkWidget * dt_color_picker_new_with_cst(dt_iop_module_t *module, dt_iop_color_picker_kind_t kind, GtkWidget *w, const dt_iop_colorspace_type_t cst)
__DT_CLONE_TARGETS__ int dt_colorspaces_conversion_matrices_rgb(const float *adobe_XYZ_to_CAM, double(*out_RGB_to_CAM)[3], double(*out_CAM_to_RGB)[4], const float *embedded_matrix, double *mul)
Compute the sRGB->camera and camera->sRGB matrices, and the default white balance multipliers.
int dt_colorspaces_conversion_matrices_xyz(const float adobe_XYZ_to_CAM[4][3], float in_XYZ_to_CAM[9], double XYZ_to_CAM[4][3], double CAM_to_XYZ[3][4])
Compute the XYZ->camera and camera->XYZ matrices for an image.
The colour-profile module's API: which profiles exist, and how to apply one.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
static dt_aligned_pixel_t XYZ
const dt_colormatrix_t dt_aligned_pixel_t out
static const dt_colormatrix_t M
gboolean dt_conf_is_equal(const char *name, const char *value)
gboolean dt_image_is_matrix_correction_supported(const dt_image_t *img)
dt_image_pipe_class_t dt_image_pipe_class(const dt_image_t *img)
const char * dt_image_pipe_class_name(const dt_image_pipe_class_t klass)
gboolean dt_image_is_monochrome(const dt_image_t *img)
gboolean dt_image_needs_rawprepare(const dt_image_t *img)
void dt_control_log(const char *msg,...)
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
static int FCxtrans(const int row, const int col, global const unsigned char(*const xtrans)[6])
static int FC(const int row, const int col, const unsigned int filters)
#define dt_dev_add_history_item(dev, module, enable, redraw)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
#define FILTERS_ARE_CYGM(filters)
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)
@ DT_REQUEST_COLORPICK_OFF
#define dt_iop_fmt_log(module, fmt,...)
Debug helper to trace a module's input-format-driven decisions on the -d pipe channel (DT_DEBUG_PIPE)...
GtkWidget * dt_iop_togglebutton_new(dt_iop_module_t *self, const char *section, const gchar *label, const gchar *ctrl_label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, GtkWidget *box)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
static dt_iop_gui_data_t * dt_iop_gui_data(const struct dt_iop_module_t *m)
The module's GUI data blob, NULL-safe for headless callers: IOP process() implementations read it for...
#define IOP_GUI_ALLOC(module)
static float kernel(const float *x, const float *y)
struct dt_iop_tonecurve_params_t preset
GtkWidget * dt_ui_section_label_new(const gchar *str)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free_align(ptr)
Release memory from dt_alloc_align() and set ptr to NULL.
static void * dt_calloc_align(size_t size)
dt_alloc_align() followed by a zero fill.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
DT_MODULE() for a module whose params struct is introspected.
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
int dt_opencl_create_kernel(const int prog, const char *name)
void * dt_opencl_copy_host_to_device_constant(const int devid, const size_t size, void *host)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
void dt_opencl_release_mem_object(cl_mem mem)
#define __OMP_PARALLEL_FOR__(...)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
const float uint32_t state[4]
dt_iop_buffer_dsc_t dsc_out
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
dt_aligned_pixel_t wb_coeffs
struct dt_develop_t::@14 proxy
gboolean camera_missing_sample
char camera_makermodel[128]
float d65_color_matrix[9]
float adobe_XYZ_to_CAM[4][3]
char filename[DT_MAX_FILENAME_LEN]
dt_aligned_pixel_t wb_coeffs
dt_aligned_pixel_t coeffs
dt_aligned_pixel_t processed_maximum
struct dt_iop_buffer_dsc_t::@56 temperature
dt_iop_gui_data_t * gui_data
dt_iop_global_data_t * data
dt_dev_request_colorpick_flags_t request_color_pick
int32_t hide_enable_button
dt_iop_params_t * default_params
struct dt_iop_module_gui_t * gui
struct dt_develop_t * dev
dt_iop_global_data_t * global_data
dt_aligned_pixel_t picked_color_min
dt_aligned_pixel_t picked_color_max
dt_aligned_pixel_t picked_color
Region of interest passed through the pixelpipe.
int kernel_whitebalance_1f_xtrans
int kernel_whitebalance_4f
int kernel_whitebalance_1f
dt_gui_collapsible_section_t cs
GtkWidget * balance_label
int blackbody_is_confusing
gboolean button_bar_visible
#define __DT_CLONE_TARGETS__
#define DT_IOP_HIGHEST_TINT
static cmsCIEXYZ temperature_tint_to_XYZ(double TempK, double tint)
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static double spd_blackbody(unsigned long int wavelength, double TempK)
const char ** description(struct dt_iop_module_t *self)
static cmsCIEXYZ spectrum_to_XYZ(double TempK, spd I)
__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 cmsCIEXYZ mul2xyz(dt_iop_module_t *self, const dt_iop_temperature_params_t *p)
static void _publish_wb_coeffs(dt_iop_module_t *self, const dt_iop_temperature_params_t *p)
void reload_defaults(dt_iop_module_t *module)
static double spd_daylight(unsigned long int wavelength, double TempK)
#define INITIALBLACKBODYTEMPERATURE
static void temp2mul(dt_iop_module_t *self, double TempK, double tint, double mul[4])
#define DT_IOP_LOWEST_TINT
void color_rgb_sliders(struct dt_iop_module_t *self)
static void gui_sliders_update(struct dt_iop_module_t *self)
static void XYZ_to_temperature(cmsCIEXYZ XYZ, float *TempK, float *tint)
#define DT_IOP_LOWEST_TEMPERATURE
static int ignore_missing_wb(dt_image_t *img)
static int calculate_bogus_daylight_wb(dt_iop_module_t *module, double bwb[4])
static cmsCIEXYZ temperature_to_XYZ(double TempK)
static void _temp_array_from_params(double a[4], const dt_iop_temperature_params_t *p)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void output_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
void gui_reset(struct dt_iop_module_t *self)
#define DT_IOP_HIGHEST_TEMPERATURE
static gboolean btn_toggled(GtkWidget *togglebutton, GdkEventButton *event, dt_iop_module_t *self)
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
void gui_init(struct dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
#define DT_IOP_TEMP_AS_SHOT
void cleanup_global(dt_iop_module_so_t *module)
void commit_proxy(dt_iop_module_t *self)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static void _temp_params_from_array(dt_iop_temperature_params_t *p, const double a[4])
static void mul2temp(dt_iop_module_t *self, dt_iop_temperature_params_t *p, float *TempK, float *tint)
static void temp_tint_callback(GtkWidget *slider, dt_iop_module_t *self)
void gui_cleanup(struct dt_iop_module_t *self)
typedef double((*spd)(unsigned long int wavelength, double TempK))
gboolean force_enable(struct dt_iop_module_t *self, const gboolean current_state)
static void find_coeffs(dt_iop_module_t *module, double coeffs[4])
#define DT_IOP_NUM_OF_STD_TEMP_PRESETS
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static void prepare_matrices(dt_iop_module_t *module)
void init_global(dt_iop_module_so_t *module)
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
static void xyz2mul(dt_iop_module_t *self, cmsCIEXYZ xyz, double mul[4])
void color_picker_apply(dt_iop_module_t *self, GtkWidget *picker, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void color_temptint_sliders(struct dt_iop_module_t *self)
static void preset_tune_callback(GtkWidget *widget, dt_iop_module_t *self)
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 int _max(int a, int b)
Telling the user something happened.