From f8e5daadfa028ad4c7e420a7ea7ebbbfacebb356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20PIERRE?= Date: Wed, 15 Jan 2025 23:31:32 +0100 Subject: [PATCH] =?UTF-8?q?Darkroom:=C2=A0paint=20background=20using=20col?= =?UTF-8?q?or=20management?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use display profile to get the right color. It's not so much for actual color rather than to use proper display gamma on grey. Use LCMS2 there to suport every display profile. --- src/common/colorspaces.c | 14 +++++++++++ src/common/colorspaces.h | 2 +- src/develop/develop.h | 4 ++++ src/views/darkroom.c | 50 +++++++++++++++++----------------------- 4 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/common/colorspaces.c b/src/common/colorspaces.c index a3e6c7326111..8ea6243936b9 100644 --- a/src/common/colorspaces.c +++ b/src/common/colorspaces.c @@ -1423,6 +1423,9 @@ static void _update_display_transforms(dt_colorspaces_t *self) if(self->transform_adobe_rgb_to_display) cmsDeleteTransform(self->transform_adobe_rgb_to_display); self->transform_adobe_rgb_to_display = NULL; + if(self->transform_xyz_to_display) cmsDeleteTransform(self->transform_xyz_to_display); + self->transform_xyz_to_display = NULL; + const dt_colorspaces_color_profile_t *display_dt_profile = _get_profile(self, self->display_type, self->display_filename, DT_PROFILE_DIRECTION_DISPLAY); @@ -1438,6 +1441,14 @@ static void _update_display_transforms(dt_colorspaces_t *self) self->display_intent, 0); + self->transform_xyz_to_display = cmsCreateTransform(_get_profile(self, DT_COLORSPACE_XYZ, "", + DT_PROFILE_DIRECTION_IN)->profile, + TYPE_XYZA_FLT, + display_profile, + TYPE_RGBA_FLT, + self->display_intent, + 0); + self->transform_adobe_rgb_to_display = cmsCreateTransform(_get_profile(self, DT_COLORSPACE_ADOBERGB, "", DT_PROFILE_DIRECTION_DISPLAY)->profile, TYPE_RGBA_8, @@ -1775,6 +1786,9 @@ void dt_colorspaces_cleanup(dt_colorspaces_t *self) if(self->transform_adobe_rgb_to_display) cmsDeleteTransform(self->transform_adobe_rgb_to_display); self->transform_adobe_rgb_to_display = NULL; + if(self->transform_xyz_to_display) cmsDeleteTransform(self->transform_xyz_to_display); + self->transform_xyz_to_display = NULL; + for(GList *iter = self->profiles; iter; iter = g_list_next(iter)) { dt_colorspaces_color_profile_t *p = (dt_colorspaces_color_profile_t *)iter->data; diff --git a/src/common/colorspaces.h b/src/common/colorspaces.h index 9d04b95202f2..046c3ec3ca9a 100644 --- a/src/common/colorspaces.h +++ b/src/common/colorspaces.h @@ -163,7 +163,7 @@ typedef struct dt_colorspaces_t dt_colorspaces_color_mode_t mode; - cmsHTRANSFORM transform_srgb_to_display, transform_adobe_rgb_to_display; + cmsHTRANSFORM transform_srgb_to_display, transform_adobe_rgb_to_display, transform_xyz_to_display; } dt_colorspaces_t; diff --git a/src/develop/develop.h b/src/develop/develop.h index f6cf65593d37..25b122589fe2 100644 --- a/src/develop/develop.h +++ b/src/develop/develop.h @@ -213,6 +213,10 @@ typedef struct dt_develop_t // darkroom border size int32_t border_size; + + // Those are the darkroom main widget size, aka max available size to paint stuff. + // They are set by Gtk from the window size minus all panels. + // The actual image size has to be smaller or equal. int32_t orig_width, orig_height; dt_backbuf_t raw_histogram; // backbuf to prepare the raw histogram (before white balance) diff --git a/src/views/darkroom.c b/src/views/darkroom.c index ff280cb3b067..b4d13f802b20 100644 --- a/src/views/darkroom.c +++ b/src/views/darkroom.c @@ -322,6 +322,16 @@ static void _darkroom_pickers_draw(dt_view_t *self, cairo_t *cri, cairo_restore(cri); } + +void _colormanage_ui_color(const float L, const float a, const float b, dt_aligned_pixel_t RGB) +{ + dt_aligned_pixel_t Lab = { L, a, b, 1.f }; + dt_aligned_pixel_t XYZ = { 0.f, 0.f, 0.f, 1.f }; + dt_Lab_to_XYZ(Lab, XYZ); + cmsDoTransform(darktable.color_profiles->transform_xyz_to_display, XYZ, RGB, 1); +} + + void expose( dt_view_t *self, cairo_t *cri, @@ -330,14 +340,8 @@ void expose( int32_t pointerx, int32_t pointery) { - cairo_set_source_rgb(cri, .2, .2, .2); cairo_save(cri); - // user param is Lab lightness/brightness (roughly, cubic root of Y). - // Convert that to typical gamma 2.2 - double user_bg_rgb = ((double)dt_conf_get_int("display/brightness")) / 100.; - user_bg_rgb = pow(user_bg_rgb, 3.0 - 2.2); - dt_develop_t *dev = (dt_develop_t *)self->data; const int32_t tb = dev->border_size; // account for border, make it transparent for other modules called below: @@ -368,6 +372,17 @@ void expose( cairo_surface_t *surface; cairo_t *cr = cairo_create(image_surface); + // user param is Lab lightness/brightness (which is they same for greys) + dt_aligned_pixel_t bg_color; + if(dev->iso_12646.enabled) + _colormanage_ui_color(50., 0., 0., bg_color); + else + _colormanage_ui_color((float)dt_conf_get_int("display/brightness"), 0., 0., bg_color); + + // Paint background color + cairo_set_source_rgb(cr, bg_color[0], bg_color[1], bg_color[2]); + cairo_paint(cr); + if(dev->pipe->output_backbuf && // do we have an image? dev->pipe->output_imgid == dev->image_storage.id && // is the right image? dev->pipe->backbuf_scale == backbuf_scale && // is this the zoom scale we want to display? @@ -383,17 +398,6 @@ void expose( wd /= darktable.gui->ppd; ht /= darktable.gui->ppd; - if(dev->iso_12646.enabled) - { - // force middle grey in background - cairo_set_source_rgb(cr, 0.4663, 0.4663, 0.4663); - } - else - { - cairo_set_source_rgb(cr, user_bg_rgb, user_bg_rgb, user_bg_rgb); - } - cairo_paint(cr); - cairo_translate(cr, ceilf(.5f * (width - wd)), ceilf(.5f * (height - ht))); if(closeup) { @@ -439,18 +443,6 @@ void expose( const float ht = dev->preview_pipe->output_backbuf_height; const float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, 1<iso_12646.enabled) - { - // force middle grey in background - cairo_set_source_rgb(cr, 0.4663, 0.4663, 0.4663); - } - else - { - cairo_set_source_rgb(cr, user_bg_rgb, user_bg_rgb, user_bg_rgb); - } - - cairo_paint(cr); - if(dev->iso_12646.enabled) { // draw the white frame around picture