Skip to content

Commit

Permalink
Darkroom: paint background using color management
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
aurelienpierre committed Jan 15, 2025
1 parent 39ca7b3 commit f8e5daa
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 30 deletions.
14 changes: 14 additions & 0 deletions src/common/colorspaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/common/colorspaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 4 additions & 0 deletions src/develop/develop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
50 changes: 21 additions & 29 deletions src/views/darkroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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:
Expand Down Expand Up @@ -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?
Expand All @@ -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)
{
Expand Down Expand Up @@ -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<<closeup, 1);

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);

if(dev->iso_12646.enabled)
{
// draw the white frame around picture
Expand Down

0 comments on commit f8e5daa

Please sign in to comment.