103#define DT_IOP_COLOR_ICC_LEN 512
105#define LUT_SAMPLES 0x10000
169 return _(
"input color profile");
175 "using color profiles to remap RGB values"),
177 _(
"linear or non-linear, RGB, scene-referred"),
178 _(
"defined by profile"),
179 _(
"linear, RGB, scene-referred"));
233 "[colorin] profile `%s' not suitable for work profile. it has been replaced by linear Rec2020 RGB!\n",
236 work_filename[0] =
'\0';
240 void *new_params,
const int new_version)
242#define DT_IOP_COLOR_ICC_LEN_V5 100
244 if(old_version == 1 && new_version == 7)
254 memset(
new, 0,
sizeof(*
new));
262 else if(!strcmp(old->
iccprofile,
"darktable"))
266 else if(!strcmp(old->
iccprofile,
"alternate"))
272 else if(!strcmp(old->
iccprofile,
"linear_rec709_rgb") || !strcmp(old->
iccprofile,
"linear_rgb"))
274 else if(!strcmp(old->
iccprofile,
"linear_rec2020_rgb"))
285 g_strlcpy(new->filename, old->
iccprofile,
sizeof(new->filename));
288 new->intent = old->
intent;
290 new->blue_mapping = 1;
292 new->filename_work[0] =
'\0';
295 if(old_version == 2 && new_version == 7)
297 typedef struct dt_iop_colorin_params_v2_t
302 } dt_iop_colorin_params_v2_t;
304 const dt_iop_colorin_params_v2_t *old = (dt_iop_colorin_params_v2_t *)old_params;
306 memset(
new, 0,
sizeof(*
new));
308 if(!strcmp(old->iccprofile,
"eprofile"))
310 else if(!strcmp(old->iccprofile,
"ematrix"))
312 else if(!strcmp(old->iccprofile,
"cmatrix"))
314 else if(!strcmp(old->iccprofile,
"darktable"))
316 else if(!strcmp(old->iccprofile,
"vendor"))
318 else if(!strcmp(old->iccprofile,
"alternate"))
320 else if(!strcmp(old->iccprofile,
"sRGB"))
322 else if(!strcmp(old->iccprofile,
"adobergb"))
324 else if(!strcmp(old->iccprofile,
"linear_rec709_rgb") || !strcmp(old->iccprofile,
"linear_rgb"))
326 else if(!strcmp(old->iccprofile,
"linear_rec2020_rgb"))
328 else if(!strcmp(old->iccprofile,
"infrared"))
330 else if(!strcmp(old->iccprofile,
"XYZ"))
332 else if(!strcmp(old->iccprofile,
"Lab"))
337 g_strlcpy(new->filename, old->iccprofile,
sizeof(new->filename));
340 new->intent = old->intent;
341 new->normalize = old->normalize;
342 new->blue_mapping = 1;
344 new->filename_work[0] =
'\0';
347 if(old_version == 3 && new_version == 7)
349 typedef struct dt_iop_colorin_params_v3_t
355 } dt_iop_colorin_params_v3_t;
357 const dt_iop_colorin_params_v3_t *old = (dt_iop_colorin_params_v3_t *)old_params;
359 memset(
new, 0,
sizeof(*
new));
361 if(!strcmp(old->iccprofile,
"eprofile"))
363 else if(!strcmp(old->iccprofile,
"ematrix"))
365 else if(!strcmp(old->iccprofile,
"cmatrix"))
367 else if(!strcmp(old->iccprofile,
"darktable"))
369 else if(!strcmp(old->iccprofile,
"vendor"))
371 else if(!strcmp(old->iccprofile,
"alternate"))
373 else if(!strcmp(old->iccprofile,
"sRGB"))
375 else if(!strcmp(old->iccprofile,
"adobergb"))
377 else if(!strcmp(old->iccprofile,
"linear_rec709_rgb") || !strcmp(old->iccprofile,
"linear_rgb"))
379 else if(!strcmp(old->iccprofile,
"linear_rec2020_rgb"))
381 else if(!strcmp(old->iccprofile,
"infrared"))
383 else if(!strcmp(old->iccprofile,
"XYZ"))
385 else if(!strcmp(old->iccprofile,
"Lab"))
390 g_strlcpy(new->filename, old->iccprofile,
sizeof(new->filename));
393 new->intent = old->intent;
394 new->normalize = old->normalize;
395 new->blue_mapping = old->blue_mapping;
397 new->filename_work[0] =
'\0';
401 if(old_version == 4 && new_version == 7)
403 typedef struct dt_iop_colorin_params_v4_t
410 } dt_iop_colorin_params_v4_t;
412 const dt_iop_colorin_params_v4_t *old = (dt_iop_colorin_params_v4_t *)old_params;
414 memset(
new, 0,
sizeof(*
new));
416 new->type = old->type;
417 g_strlcpy(new->filename, old->filename,
sizeof(new->filename));
418 new->intent = old->intent;
419 new->normalize = old->normalize;
420 new->blue_mapping = old->blue_mapping;
422 new->filename_work[0] =
'\0';
426 if(old_version == 5 && new_version == 7)
428 typedef struct dt_iop_colorin_params_v5_t
438 } dt_iop_colorin_params_v5_t;
440 const dt_iop_colorin_params_v5_t *old = (dt_iop_colorin_params_v5_t *)old_params;
442 memset(
new, 0,
sizeof(*
new));
444 new->type = old->type;
445 g_strlcpy(new->filename, old->filename,
sizeof(new->filename));
446 new->intent = old->intent;
447 new->normalize = old->normalize;
448 new->blue_mapping = old->blue_mapping;
449 new->type_work = old->type_work;
450 g_strlcpy(new->filename_work, old->filename_work,
sizeof(new->filename_work));
455 if(old_version == 6 && new_version == 7)
459 typedef struct dt_iop_colorin_params_v6_t
469 } dt_iop_colorin_params_v6_t;
471 const dt_iop_colorin_params_v6_t *old = (dt_iop_colorin_params_v6_t *)old_params;
473 memcpy(
new, old,
sizeof(*
new));
479#undef DT_IOP_COLOR_ICC_LEN_V5
484 const int program = 2;
501static void intent_changed (
GtkWidget *widget, gpointer user_data)
520 if(pos < g->n_image_profiles)
521 prof =
g->image_profiles;
525 pos -=
g->n_image_profiles;
527 for(; prof; prof = g_list_next(prof))
533 memcpy(
p->filename, pp->
filename,
sizeof(
p->filename));
562 type_work = pp->
type;
563 g_strlcpy(filename_work, pp->
filename,
sizeof(filename_work));
570 p->type_work = type_work;
571 g_strlcpy(
p->filename_work, filename_work,
sizeof(
p->filename_work));
577 "[colorin] can't extract matrix from colorspace `%s', it will be replaced by Rec2020 RGB!\n",
579 dt_control_log(_(
"can't extract matrix from colorspace `%s', it will be replaced by Rec2020 RGB!"),
p->filename_work);
603 cl_mem dev_m = NULL, dev_l = NULL, dev_r = NULL, dev_g = NULL, dev_b = NULL, dev_coeffs = NULL;
606 float cmat[12], lmat[12];
623 const int devid = pipe->
devid;
629 size_t origin[] = { 0, 0, 0 };
630 size_t region[] = { roi_in->
width, roi_in->
height, 1 };
632 if(err != CL_SUCCESS)
goto error;
662 if(err != CL_SUCCESS)
goto error;
690 const float YY =
out[0] +
out[1] +
out[2];
693 const float zz =
out[2] / YY;
694 const float bound_z = 0.5f, bound_Y = 0.5f;
695 const float amount = 0.11f;
698 const float t = (zz - bound_z) / (1.0f - bound_z) * fminf(1.0, YY / bound_Y);
699 out[1] +=
t * amount;
700 out[2] -=
t * amount;
705static inline __attribute__((always_inline)) dt_aligned_pixel_simd_t _colorin_clamp_rgb01_vec4(
706 dt_aligned_pixel_simd_t in)
708 in[0] = CLAMP(in[0], 0.0f, 1.0f);
709 in[1] = CLAMP(in[1], 0.0f, 1.0f);
710 in[2] = CLAMP(in[2], 0.0f, 1.0f);
730 const dt_aligned_pixel_simd_t cm0 = dt_colormatrix_row_to_simd(cmatrix, 0);
731 const dt_aligned_pixel_simd_t cm1 = dt_colormatrix_row_to_simd(cmatrix, 1);
732 const dt_aligned_pixel_simd_t cm2 = dt_colormatrix_row_to_simd(cmatrix, 2);
733 const dt_aligned_pixel_simd_t nm0 = dt_colormatrix_row_to_simd(nmatrix, 0);
734 const dt_aligned_pixel_simd_t nm1 = dt_colormatrix_row_to_simd(nmatrix, 1);
735 const dt_aligned_pixel_simd_t nm2 = dt_colormatrix_row_to_simd(nmatrix, 2);
736 const dt_aligned_pixel_simd_t lm0 = dt_colormatrix_row_to_simd(lmatrix, 0);
737 const dt_aligned_pixel_simd_t lm1 = dt_colormatrix_row_to_simd(lmatrix, 1);
738 const dt_aligned_pixel_simd_t lm2 = dt_colormatrix_row_to_simd(lmatrix, 2);
743 for(
int j = 0; j < roi_out->
height; j++)
745 const float *in = (
const float *)ivoid + (
size_t)
ch * j * roi_out->
width;
749 for(
int i = 0;
i < roi_out->
width;
i++)
751 const float *
const in_pixel = in + (size_t)
ch *
i;
752 float *
const out_pixel =
out + (size_t)
ch *
i;
756 for(
int c = 0; c < 3; c++)
757 cam[c] = (
d->lut[c][0] >= 0.0f) ? dt_ioppr_eval_trc(in_pixel[c],
d->lut[c],
d->unbounded_coeffs[c],
LUT_SAMPLES)
762 const dt_aligned_pixel_simd_t cam_v = dt_load_simd_aligned(cam);
766 dt_store_simd_nontemporal(out_pixel, dt_mat3x4_mul_vec4(cam_v, cm0, cm1, cm2));
770 const dt_aligned_pixel_simd_t nRGB = dt_mat3x4_mul_vec4(cam_v, nm0, nm1, nm2);
771 const dt_aligned_pixel_simd_t cRGB = _colorin_clamp_rgb01_vec4(nRGB);
772 dt_store_simd_nontemporal(out_pixel, dt_mat3x4_mul_vec4(cRGB, lm0, lm1, lm2));
781 const void *
const ivoid,
void *
const ovoid,
785 const size_t npixels = (size_t)roi_out->
width * roi_out->
height;
792 const dt_aligned_pixel_simd_t cm0 = dt_colormatrix_row_to_simd(cmatrix, 0);
793 const dt_aligned_pixel_simd_t cm1 = dt_colormatrix_row_to_simd(cmatrix, 1);
794 const dt_aligned_pixel_simd_t cm2 = dt_colormatrix_row_to_simd(cmatrix, 2);
799 for(
size_t k = 0;
k < npixels;
k++)
801 const size_t idx = 4 *
k;
802 const dt_aligned_pixel_simd_t vin = dt_load_simd_aligned(in + idx);
803 dt_store_simd_nontemporal(
out + idx, dt_mat3x4_mul_vec4(vin, cm0, cm1, cm2));
810 const void *
const ivoid,
void *
const ovoid,
814 const size_t npixels = (size_t)roi_out->
width * roi_out->
height;
822 const dt_aligned_pixel_simd_t nm0 = dt_colormatrix_row_to_simd(nmatrix, 0);
823 const dt_aligned_pixel_simd_t nm1 = dt_colormatrix_row_to_simd(nmatrix, 1);
824 const dt_aligned_pixel_simd_t nm2 = dt_colormatrix_row_to_simd(nmatrix, 2);
825 const dt_aligned_pixel_simd_t lm0 = dt_colormatrix_row_to_simd(lmatrix, 0);
826 const dt_aligned_pixel_simd_t lm1 = dt_colormatrix_row_to_simd(lmatrix, 1);
827 const dt_aligned_pixel_simd_t lm2 = dt_colormatrix_row_to_simd(lmatrix, 2);
832 for(
size_t k = 0;
k < npixels;
k++)
834 const size_t idx = 4 *
k;
835 const dt_aligned_pixel_simd_t vin = dt_load_simd_aligned(in + idx);
836 const dt_aligned_pixel_simd_t nRGB = dt_mat3x4_mul_vec4(vin, nm0, nm1, nm2);
837 const dt_aligned_pixel_simd_t cRGB = _colorin_clamp_rgb01_vec4(nRGB);
838 dt_store_simd_nontemporal(
out + idx, dt_mat3x4_mul_vec4(cRGB, lm0, lm1, lm2));
867 const size_t npixels = (size_t)roi_out->
width * roi_out->
height;
875 const dt_aligned_pixel_simd_t cm0 = dt_colormatrix_row_to_simd(cmatrix, 0);
876 const dt_aligned_pixel_simd_t cm1 = dt_colormatrix_row_to_simd(cmatrix, 1);
877 const dt_aligned_pixel_simd_t cm2 = dt_colormatrix_row_to_simd(cmatrix, 2);
878 const dt_aligned_pixel_simd_t nm0 = dt_colormatrix_row_to_simd(nmatrix, 0);
879 const dt_aligned_pixel_simd_t nm1 = dt_colormatrix_row_to_simd(nmatrix, 1);
880 const dt_aligned_pixel_simd_t nm2 = dt_colormatrix_row_to_simd(nmatrix, 2);
881 const dt_aligned_pixel_simd_t lm0 = dt_colormatrix_row_to_simd(lmatrix, 0);
882 const dt_aligned_pixel_simd_t lm1 = dt_colormatrix_row_to_simd(lmatrix, 1);
883 const dt_aligned_pixel_simd_t lm2 = dt_colormatrix_row_to_simd(lmatrix, 2);
888 for(
size_t k = 0;
k < npixels;
k++)
890 const float *in = (
const float *)ivoid + 4 *
k;
897 for(
int c = 0; c < 3; c++)
898 cam[c] = (
d->lut[c][0] >= 0.0f) ? dt_ioppr_eval_trc(in[c],
d->lut[c],
d->unbounded_coeffs[c],
LUT_SAMPLES)
901 const dt_aligned_pixel_simd_t cam_v = dt_load_simd_aligned(cam);
905 dt_store_simd_nontemporal(
out, dt_mat3x4_mul_vec4(cam_v, cm0, cm1, cm2));
909 const dt_aligned_pixel_simd_t nRGB = dt_mat3x4_mul_vec4(cam_v, nm0, nm1, nm2);
910 const dt_aligned_pixel_simd_t cRGB = _colorin_clamp_rgb01_vec4(nRGB);
911 dt_store_simd_nontemporal(
out, dt_mat3x4_mul_vec4(cRGB, lm0, lm1, lm2));
924 if(!blue_mapping &&
d->nonlinearlut == 0)
926 process_cmatrix_fastpath(self, piece, ivoid,
ovoid, roi_in, roi_out);
928 else if(blue_mapping)
946 const cmsHTRANSFORM xform_cam_lab =
d->xform_cam_Lab;
947 const cmsHTRANSFORM xform_cam_nrgb =
d->xform_cam_nrgb;
948 const cmsHTRANSFORM xform_nrgb_lab =
d->xform_nrgb_Lab;
955 const float *in = (
const float *)ivoid + (
size_t)
ch *
k * roi_out->
width;
958 float *camptr = (
float *)
out;
959 for(
int j = 0; j < roi_out->
width; j++)
961 float *
const pixel = camptr + 4 * j;
975 float *rgbptr = (
float *)
out;
977 for(
int j = 0; j < roi_out->
width; j++)
979 float *
const pixel = rgbptr + 4 * j;
980 for(
int c = 0; c < 3; c++) pixel[c] = CLAMP(pixel[c], 0.0f, 1.0f);
997 const cmsHTRANSFORM xform_cam_lab =
d->xform_cam_Lab;
998 const cmsHTRANSFORM xform_cam_nrgb =
d->xform_cam_nrgb;
999 const cmsHTRANSFORM xform_nrgb_lab =
d->xform_nrgb_Lab;
1005 for(
int k = 0;
k < roi_out->
height;
k++)
1007 const float *in = (
const float *)ivoid + (
size_t)
ch *
k * roi_out->
width;
1019 float *rgbptr = (
float *)
out;
1021 for(
int j = 0; j < roi_out->
width; j++)
1023 float *
const pixel = rgbptr + 4 * j;
1024 for(
int c = 0; c < 3; c++) pixel[c] = CLAMP(pixel[c], 0.0f, 1.0f);
1061 else if(!isnan(
d->cmatrix[0][0]))
1063 process_cmatrix(self, pipe, piece, ivoid,
ovoid, roi_in, roi_out);
1067 process_lcms2(self, pipe, piece, ivoid,
ovoid, roi_in, roi_out);
1076 if(
d->xform_cam_Lab)
1078 cmsDeleteTransform(
d->xform_cam_Lab);
1079 d->xform_cam_Lab = NULL;
1081 if(
d->xform_cam_nrgb)
1083 cmsDeleteTransform(
d->xform_cam_nrgb);
1084 d->xform_cam_nrgb = NULL;
1086 if(
d->xform_nrgb_Lab)
1088 cmsDeleteTransform(
d->xform_nrgb_Lab);
1089 d->xform_nrgb_Lab = NULL;
1095 d->cmatrix[0][0] =
d->nmatrix[0][0] =
d->lmatrix[0][0] = NAN;
1096 d->lut[0][0] = -1.0f;
1097 d->lut[1][0] = -1.0f;
1098 d->lut[2][0] = -1.0f;
1099 d->nonlinearlut = 0;
1105 switch(
p->normalize)
1136 else d->clear_input = 1;
1142 else d->clear_input = 1;
1148 else d->clear_input = 1;
1155 gboolean new_profile =
FALSE;
1156 cmsHPROFILE profile = NULL;
1161 d->clear_input = new_profile;
1202 g_strlcpy(
d->filename,
p->filename,
sizeof(
d->filename));
1204 d->filename[0] =
'\0';
1212 d->type_work =
p->type_work;
1213 g_strlcpy(
d->filename_work,
p->filename_work,
sizeof(
d->filename_work));
1221 d->blue_mapping =
p->blue_mapping;
1229 if(work_profile_info)
1231 d->type_work = work_profile_info->
type;
1232 g_strlcpy(
d->filename_work, work_profile_info->
filename,
sizeof(
d->filename_work));
1237 const cmsHPROFILE work = work_profile ? work_profile->
profile : NULL;
1238 const gboolean can_use_work_matrix = (work_profile_info
1240 && !isnan(work_profile_info->
matrix_out[0][0]));
1253 dt_iop_fmt_log(self,
"commit: class=%s matrix_supported=%d requested_input=%d resolved_input=%d blue_mapping=%d",
1256 requested_input_type,
type,
d->blue_mapping);
1269 cmsColorSpaceSignature input_color_space = cmsGetColorSpace(
d->input);
1271 switch(input_color_space)
1283 (
char)(input_color_space>>24),
1284 (
char)(input_color_space>>16),
1285 (
char)(input_color_space>>8),
1286 (
char)(input_color_space));
1290 gboolean use_matrix =
FALSE;
1299 && can_use_work_matrix)
1301 float lutr[1], lutg[1], lutb[1];
1317 d->cmatrix[0][0] = NAN;
1318 d->xform_cam_Lab = work ? cmsCreateTransform(
d->input,
input_format, work, TYPE_RGBA_FLT,
p->intent, 0) : NULL;
1319 d->xform_cam_nrgb = cmsCreateTransform(
d->input,
input_format,
d->nrgb, TYPE_RGBA_FLT,
p->intent, 0);
1320 d->xform_nrgb_Lab = work ? cmsCreateTransform(
d->nrgb, TYPE_RGBA_FLT, work, TYPE_RGBA_FLT,
p->intent, 0) : NULL;
1328 && can_use_work_matrix)
1337 d->cmatrix[0][0] = NAN;
1338 d->xform_cam_Lab = work ? cmsCreateTransform(
d->input,
input_format, work, TYPE_RGBA_FLT,
p->intent, 0) : NULL;
1343 if(
d->nrgb && ((
IS_NULL_PTR(
d->xform_cam_nrgb) && isnan(
d->nmatrix[0][0])) || (
IS_NULL_PTR(
d->xform_nrgb_Lab) && isnan(
d->lmatrix[0][0]))))
1345 if(
d->xform_cam_nrgb)
1347 cmsDeleteTransform(
d->xform_cam_nrgb);
1348 d->xform_cam_nrgb = NULL;
1350 if(
d->xform_nrgb_Lab)
1352 cmsDeleteTransform(
d->xform_nrgb_Lab);
1353 d->xform_nrgb_Lab = NULL;
1359 if(
IS_NULL_PTR(
d->xform_cam_Lab) && isnan(
d->cmatrix[0][0]))
1363 "[colorin] unsupported input profile `%s' has been replaced by linear Rec709 RGB!\n",
1367 dt_control_log(_(
"unsupported input profile has been replaced by linear Rec709 RGB!"));
1375 && can_use_work_matrix)
1384 d->cmatrix[0][0] = NAN;
1385 d->xform_cam_Lab = work ? cmsCreateTransform(
d->input, TYPE_RGBA_FLT, work, TYPE_RGBA_FLT,
p->intent, 0) : NULL;
1389 d->nonlinearlut = 0;
1395 for(
int k = 0;
k < 3;
k++)
1398 if(
d->lut[
k][0] >= 0.0f)
1402 const float x[4] = { 0.7f, 0.8f, 0.9f, 1.0f };
1403 const float y[4] = { extrapolate_lut(
d->lut[
k],
x[0],
LUT_SAMPLES),
1410 d->unbounded_coeffs[
k][0] = -1.0f;
1419 input_matrix_for_pipe);
1432 if(
d->xform_cam_Lab)
1434 cmsDeleteTransform(
d->xform_cam_Lab);
1435 d->xform_cam_Lab = NULL;
1437 if(
d->xform_cam_nrgb)
1439 cmsDeleteTransform(
d->xform_cam_nrgb);
1440 d->xform_cam_nrgb = NULL;
1442 if(
d->xform_nrgb_Lab)
1444 cmsDeleteTransform(
d->xform_nrgb_Lab);
1445 d->xform_nrgb_Lab = NULL;
1465 && pp->
type ==
p->type_work
1481 for(
const GList *prof =
g->image_profiles; prof; prof = g_list_next(prof))
1484 if(pp->
type ==
p->type
1496 && pp->
type ==
p->type
1521 module->default_enabled = 1;
1522 module->hide_enable_button = 1;
1525 gboolean new_profile;
1527 dt_iop_fmt_log(module,
"reload_defaults: class=%s matrix_supported=%d -> default_input_profile=%d new_profile=%d",
1541 g->image_profiles = NULL;
1542 g->n_image_profiles = 0;
1554 g->image_profiles = g_list_append(
g->image_profiles, prof);
1565 g->image_profiles = g_list_append(
g->image_profiles, prof);
1576 g->image_profiles = g_list_append(
g->image_profiles, prof);
1589 g->image_profiles = g_list_append(
g->image_profiles, prof);
1604 g->image_profiles = g_list_append(
g->image_profiles, prof);
1619 g->image_profiles = g_list_append(
g->image_profiles, prof);
1625 g->n_image_profiles = pos + 1;
1630 for(GList *l =
g->image_profiles; l; l = g_list_next(l))
1635 gboolean input_system_profile_separator_added =
FALSE;
1636 gboolean input_file_profile_separator_added =
FALSE;
1642 if(
g->n_image_profiles > 0 && !input_system_profile_separator_added)
1645 input_system_profile_separator_added =
TRUE;
1650 input_file_profile_separator_added =
TRUE;
1662 gboolean work_file_profile_separator_added =
FALSE;
1671 work_file_profile_separator_added =
TRUE;
1686 g->image_profiles = NULL;
1697 gtk_box_pack_start(GTK_BOX(self->
widget),
g->profile_combobox,
TRUE,
TRUE, 0);
1701 gtk_box_pack_start(GTK_BOX(self->
widget),
g->work_combobox,
TRUE,
TRUE, 0);
1705 char *system_profile_dir = g_build_filename(datadir,
"color",
"in", NULL);
1706 char *user_profile_dir = g_build_filename(confdir,
"color",
"in", NULL);
1707 char *
tooltip = g_strdup_printf(_(
"ICC profiles in %s or %s"), user_profile_dir, system_profile_dir);
1708 gtk_widget_set_tooltip_text(
g->profile_combobox,
tooltip);
1716 char *system_profile_dir = g_build_filename(datadir,
"color",
"out", NULL);
1717 char *user_profile_dir = g_build_filename(confdir,
"color",
"out", NULL);
1718 char *
tooltip = g_strdup_printf(_(
"ICC profiles in %s or %s"), user_profile_dir, system_profile_dir);
1719 gtk_widget_set_tooltip_text(
g->work_combobox,
tooltip);
1725 g_signal_connect(G_OBJECT(
g->profile_combobox),
"value-changed", G_CALLBACK(
profile_changed), (gpointer)self);
1726 g_signal_connect(G_OBJECT(
g->work_combobox),
"value-changed", G_CALLBACK(
workicc_changed), (gpointer)self);
1729 gtk_widget_set_tooltip_text(
g->clipping_combobox, _(
"confine Lab values to gamut of RGB color space"));
1735 while(
g->image_profiles)
1738 g->image_profiles = g_list_delete_link(
g->image_profiles,
g->image_profiles);
static void error(char *msg)
void dt_bauhaus_combobox_clear(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_combobox_add_separator(GtkWidget *widget)
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_combobox_add(GtkWidget *widget, const char *text)
void dt_bauhaus_combobox_add_with_tooltip(GtkWidget *widget, const char *text, const char *tooltip)
static __DT_CLONE_TARGETS__ void normalize(float *const buffer, const size_t width, const size_t height, const float norm)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
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 __DT_CLONE_TARGETS__ void process_cmatrix_fastpath_clipping(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
const char ** description(struct dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ void process_cmatrix_proper(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
void reload_defaults(dt_iop_module_t *module)
static dt_colorspaces_color_profile_type_t _resolve_input_profile(const dt_iop_colorin_params_t *p, dt_dev_pixelpipe_t *pipe, dt_iop_colorin_data_t *d)
static void profile_changed(GtkWidget *widget, gpointer user_data)
static void apply_blue_mapping(const float *const in, float *const out)
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
@ DT_NORMALIZE_LINEAR_REC2020_RGB
@ DT_NORMALIZE_LINEAR_REC709_RGB
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)
#define DT_IOP_COLOR_ICC_LEN
void gui_update(struct dt_iop_module_t *self)
void gui_init(struct dt_iop_module_t *self)
static void _reset_input_transforms(dt_iop_colorin_data_t *d)
static dt_iop_colorspace_type_t _colorin_format_cst(dt_iop_module_t *self)
#define DT_IOP_COLOR_ICC_LEN_V5
void cleanup_global(dt_iop_module_so_t *module)
static void update_profile_list(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)
void input_format(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece, dt_iop_buffer_dsc_t *dsc)
static __DT_CLONE_TARGETS__ void process_lcms2_proper(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
void gui_cleanup(struct dt_iop_module_t *self)
static void _resolve_work_profile(dt_colorspaces_color_profile_type_t *work_type, char *work_filename)
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)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static __DT_CLONE_TARGETS__ void process_cmatrix_fastpath_simple(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
static void _select_normalization_profile(const dt_iop_colorin_params_t *p, dt_iop_colorin_data_t *d)
static __DT_CLONE_TARGETS__ void process_cmatrix_bm(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
static __DT_CLONE_TARGETS__ void process_lcms2_bm(struct dt_iop_module_t *self, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
void init_global(dt_iop_module_so_t *module)
static void workicc_changed(GtkWidget *widget, gpointer user_data)
static void _set_input_profile_metadata(dt_iop_colorin_data_t *d, const dt_iop_colorin_params_t *p, const dt_colorspaces_color_profile_type_t type)
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 _reset_processing_state(dt_iop_colorin_data_t *d, 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 dt_profiled_colormatrix_t dt_profiled_colormatrices[]
static dt_profiled_colormatrix_t dt_vendor_colormatrices[]
static dt_profiled_colormatrix_t dt_alternate_colormatrices[]
static const int dt_vendor_colormatrix_cnt
static const int dt_alternate_colormatrix_cnt
static const int dt_profiled_colormatrix_cnt
const dt_colorspaces_color_profile_t * dt_colorspaces_get_profile(dt_colorspaces_color_profile_type_t type, const char *filename, dt_colorspaces_profile_direction_t direction)
dt_colorspaces_color_profile_type_t dt_colorspaces_get_input_profile_from_image(int32_t imgid, dt_colorspaces_color_profile_type_t requested, cmsHPROFILE *output, gboolean *new_profile)
Resolve an embedded/matrix input profile for a given image, honoring the requested type when possible...
int dt_colorspaces_get_matrix_from_output_profile(cmsHPROFILE prof, dt_colormatrix_t matrix, float *lutr, float *lutg, float *lutb, const int lutsize)
cmsHPROFILE dt_colorspaces_create_vendor_profile(const char *makermodel)
int dt_colorspaces_get_matrix_from_input_profile(cmsHPROFILE prof, dt_colormatrix_t matrix, float *lutr, float *lutg, float *lutb, const int lutsize)
cmsHPROFILE dt_colorspaces_create_darktable_profile(const char *makermodel)
void dt_colorspaces_cleanup_profile(cmsHPROFILE p)
dt_colorspaces_color_profile_type_t dt_image_find_best_color_profile(int32_t imgid, cmsHPROFILE *output, gboolean *new_profile)
Best effort to find a suitable (input) color profile for a given image, using embedded ICC or EXIF wh...
const char * dt_colorspaces_get_name(dt_colorspaces_color_profile_type_t type, const char *filename)
cmsHPROFILE dt_colorspaces_create_alternate_profile(const char *makermodel)
gboolean dt_colorspaces_is_profile_equal(const char *fullname, const char *filename)
void dt_colorspaces_transform_rgba_float_row(const cmsHTRANSFORM transform, const float *in, float *out, const int width)
#define DT_IOP_COLOR_ICC_LEN
dt_colorspaces_color_profile_type_t
@ DT_COLORSPACE_EMBEDDED_MATRIX
@ DT_COLORSPACE_EMBEDDED_ICC
@ DT_COLORSPACE_ENHANCED_MATRIX
@ DT_COLORSPACE_LIN_REC2020
@ DT_COLORSPACE_STANDARD_MATRIX
@ DT_COLORSPACE_VENDOR_MATRIX
@ DT_COLORSPACE_LIN_REC709
@ DT_COLORSPACE_ALTERNATE_MATRIX
@ DT_COLORSPACES_PROFILE_TYPE_INPUT
@ DT_COLORSPACES_PROFILE_TYPE_WORK
@ DT_PROFILE_DIRECTION_IN
@ DT_PROFILE_DIRECTION_ANY
static gboolean dt_colorspaces_is_raw_matrix_profile_type(const dt_colorspaces_color_profile_type_t type)
const dt_colormatrix_t dt_aligned_pixel_t out
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)
void dt_control_log(const char *msg,...)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define __OMP_SIMD__(...)
static void dt_free_gpointer(gpointer ptr)
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_CLONE_TARGETS__
#define __OMP_PARALLEL_FOR__(...)
#define __OMP_PARALLEL_FOR_SIMD__(...)
#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_dev_add_history_item(dev, module, enable, redraw)
#define dt_dev_pixelpipe_rebuild_all(dev)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
#define DT_GUI_BOX_SPACING
void dt_image_cache_read_release(dt_image_cache_t *cache, const dt_image_t *img)
dt_image_t * dt_image_cache_get(dt_image_cache_t *cache, const int32_t imgid, char mode)
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
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)
#define dt_omploop_sfence()
#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)...
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
static void dt_iop_estimate_exp(const float *const x, const float *const y, const int num, float *coeff)
static float kernel(const float *x, const float *y)
dt_iop_order_iccprofile_info_t * dt_ioppr_add_profile_info_to_list(struct dt_develop_t *dev, const dt_colorspaces_color_profile_type_t profile_type, const char *profile_filename, const int intent)
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_work_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent)
dt_iop_order_iccprofile_info_t * dt_ioppr_set_pipe_input_profile_info(struct dt_develop_t *dev, struct dt_dev_pixelpipe_t *pipe, const dt_colorspaces_color_profile_type_t type, const char *filename, const int intent, const dt_colormatrix_t matrix_in)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]
static void transpose_3xSSE(const dt_colormatrix_t input, dt_colormatrix_t output)
static void pack_3xSSE_to_3x4(const dt_colormatrix_t input, float output[12])
static void dt_colormatrix_mul(dt_colormatrix_t dst, const dt_colormatrix_t m1, const dt_colormatrix_t m2)
float dt_aligned_pixel_t[4]
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)
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
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_copy_host_to_device(const int devid, void *host, const int width, const int height, const int bpp)
void dt_opencl_release_mem_object(cl_mem mem)
#define DT_DEBUG_CONTROL_SIGNAL_RAISE(ctlsig, signal,...)
@ 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...
struct _GtkWidget GtkWidget
struct dt_gui_gtk_t * gui
struct dt_colorspaces_t * color_profiles
struct dt_control_signal_t * signals
struct dt_bauhaus_t * bauhaus
struct dt_image_cache_t * image_cache
struct dt_develop_t * develop
dt_colorspaces_color_profile_type_t type
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
struct dt_develop_t * dev
char camera_makermodel[128]
float d65_color_matrix[9]
dt_iop_buffer_type_t datatype
cmsHTRANSFORM * xform_cam_nrgb
cmsHTRANSFORM * xform_nrgb_Lab
dt_colorspaces_color_profile_type_t type
cmsHTRANSFORM * xform_cam_Lab
dt_colorspaces_color_profile_type_t type_work
float unbounded_coeffs[3][3]
int kernel_colorin_unbound
int kernel_colorin_clipping
GtkWidget * clipping_combobox
GtkWidget * profile_combobox
GtkWidget * work_combobox
dt_colorspaces_color_profile_type_t type
dt_iop_color_intent_t intent
dt_colorspaces_color_profile_type_t type_work
dt_iop_color_normalize_t normalize
dt_iop_color_intent_t intent
dt_iop_global_data_t * data
struct dt_develop_t * dev
dt_iop_gui_data_t * gui_data
dt_iop_global_data_t * global_data
dt_colorspaces_color_profile_type_t type
dt_colormatrix_t matrix_out
char filename[DT_IOP_COLOR_ICC_LEN]
dt_colormatrix_t matrix_in
Region of interest passed through the pixelpipe.