mirror of https://github.com/GNOME/gimp.git
app: make all GimpViewRenderers color manage themselves
Automatically connect to the global GimpColorConfig unless a different one is set manually (like for previews that belong to a GimpDisplayShell and should follow its color management settings. Add public API for subclasses to get to the renderer's color transform. Automatically color manage rendered pixbufs, just as we already manage temp_bufs.
This commit is contained in:
parent
c0aff6b0f0
commit
a35276ed91
|
@ -93,6 +93,9 @@ static void gimp_view_renderer_size_changed (GimpViewRenderer *rende
|
|||
GimpViewable *viewable);
|
||||
static void gimp_view_renderer_profile_changed (GimpViewRenderer *renderer,
|
||||
GimpViewable *viewable);
|
||||
static void gimp_view_renderer_config_notify (GObject *config,
|
||||
const GParamSpec *pspec,
|
||||
GimpViewRenderer *renderer);
|
||||
|
||||
static void gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
|
@ -110,10 +113,6 @@ static cairo_pattern_t *
|
|||
gimp_view_renderer_create_background (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget);
|
||||
|
||||
static void gimp_view_renderer_transform_create (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
GeglBuffer *src_buffer,
|
||||
GeglBuffer *dest_buffer);
|
||||
static void gimp_view_renderer_transform_free (GimpViewRenderer *renderer);
|
||||
|
||||
|
||||
|
@ -577,15 +576,27 @@ gimp_view_renderer_set_color_config (GimpViewRenderer *renderer,
|
|||
if (color_config != renderer->priv->color_config)
|
||||
{
|
||||
if (renderer->priv->color_config)
|
||||
g_object_unref (renderer->priv->color_config);
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (renderer->priv->color_config,
|
||||
gimp_view_renderer_config_notify,
|
||||
renderer);
|
||||
|
||||
g_object_unref (renderer->priv->color_config);
|
||||
}
|
||||
|
||||
renderer->priv->color_config = color_config;
|
||||
|
||||
if (renderer->priv->color_config)
|
||||
g_object_ref (renderer->priv->color_config);
|
||||
{
|
||||
g_object_ref (renderer->priv->color_config);
|
||||
|
||||
if (renderer->viewable)
|
||||
gimp_view_renderer_profile_changed (renderer, renderer->viewable);
|
||||
g_signal_connect (renderer->priv->color_config, "notify",
|
||||
G_CALLBACK (gimp_view_renderer_config_notify),
|
||||
renderer);
|
||||
}
|
||||
|
||||
gimp_view_renderer_config_notify (G_OBJECT (renderer->priv->color_config),
|
||||
NULL, renderer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -729,12 +740,28 @@ gimp_view_renderer_real_set_context (GimpViewRenderer *renderer,
|
|||
GimpContext *context)
|
||||
{
|
||||
if (renderer->context)
|
||||
g_object_unref (renderer->context);
|
||||
{
|
||||
if (renderer->priv->color_config ==
|
||||
renderer->context->gimp->config->color_management)
|
||||
{
|
||||
gimp_view_renderer_set_color_config (renderer, NULL);
|
||||
}
|
||||
|
||||
g_object_unref (renderer->context);
|
||||
}
|
||||
|
||||
renderer->context = context;
|
||||
|
||||
if (renderer->context)
|
||||
g_object_ref (renderer->context);
|
||||
{
|
||||
g_object_ref (renderer->context);
|
||||
|
||||
if (renderer->priv->color_config == NULL)
|
||||
{
|
||||
gimp_view_renderer_set_color_config (renderer,
|
||||
renderer->context->gimp->config->color_management);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -864,6 +891,15 @@ gimp_view_renderer_profile_changed (GimpViewRenderer *renderer,
|
|||
gimp_view_renderer_invalidate (renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_view_renderer_config_notify (GObject *config,
|
||||
const GParamSpec *pspec,
|
||||
GimpViewRenderer *renderer)
|
||||
{
|
||||
gimp_view_renderer_transform_free (renderer);
|
||||
gimp_view_renderer_invalidate (renderer);
|
||||
}
|
||||
|
||||
|
||||
/* protected functions */
|
||||
|
||||
|
@ -936,18 +972,64 @@ gimp_view_renderer_render_pixbuf (GimpViewRenderer *renderer,
|
|||
GtkWidget *widget,
|
||||
GdkPixbuf *pixbuf)
|
||||
{
|
||||
GimpColorTransform *transform;
|
||||
const Babl *format;
|
||||
|
||||
if (renderer->surface)
|
||||
{
|
||||
cairo_surface_destroy (renderer->surface);
|
||||
renderer->surface = NULL;
|
||||
}
|
||||
|
||||
g_object_ref (pixbuf);
|
||||
format = gimp_pixbuf_get_format (pixbuf);
|
||||
|
||||
if (renderer->priv->pixbuf)
|
||||
g_object_unref (renderer->priv->pixbuf);
|
||||
transform =
|
||||
gimp_view_renderer_get_color_transform (renderer, widget,
|
||||
format, format);
|
||||
|
||||
renderer->priv->pixbuf = pixbuf;
|
||||
if (transform)
|
||||
{
|
||||
GdkPixbuf *new;
|
||||
gint width = gdk_pixbuf_get_width (pixbuf);
|
||||
gint height = gdk_pixbuf_get_height (pixbuf);
|
||||
gsize src_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
guchar *src = gdk_pixbuf_get_pixels (pixbuf);
|
||||
gsize dest_stride;
|
||||
guchar *dest;
|
||||
gint i;
|
||||
|
||||
new = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
|
||||
gdk_pixbuf_get_has_alpha (pixbuf),
|
||||
8, width, height);
|
||||
|
||||
dest_stride = gdk_pixbuf_get_rowstride (new);
|
||||
dest = gdk_pixbuf_get_pixels (new);
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
{
|
||||
gimp_color_transform_process_pixels (transform,
|
||||
format, src,
|
||||
format, dest,
|
||||
width);
|
||||
|
||||
src += src_stride;
|
||||
dest += dest_stride;
|
||||
}
|
||||
|
||||
if (renderer->priv->pixbuf)
|
||||
g_object_unref (renderer->priv->pixbuf);
|
||||
|
||||
renderer->priv->pixbuf = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_object_ref (pixbuf);
|
||||
|
||||
if (renderer->priv->pixbuf)
|
||||
g_object_unref (renderer->priv->pixbuf);
|
||||
|
||||
renderer->priv->pixbuf = pixbuf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1003,6 +1085,57 @@ gimp_view_renderer_render_icon (GimpViewRenderer *renderer,
|
|||
}
|
||||
}
|
||||
|
||||
GimpColorTransform *
|
||||
gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
const Babl *src_format,
|
||||
const Babl *dest_format)
|
||||
{
|
||||
GimpColorProfile *profile;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_VIEW_RENDERER (renderer), NULL);
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (src_format != NULL, NULL);
|
||||
g_return_val_if_fail (dest_format != NULL, NULL);
|
||||
|
||||
if (renderer->priv->profile_transform)
|
||||
return renderer->priv->profile_transform;
|
||||
|
||||
if (! renderer->priv->color_config)
|
||||
{
|
||||
g_printerr ("EEK\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (GIMP_IS_COLOR_MANAGED (renderer->viewable))
|
||||
{
|
||||
GimpColorManaged *managed = GIMP_COLOR_MANAGED (renderer->viewable);
|
||||
|
||||
profile = gimp_color_managed_get_color_profile (managed);
|
||||
}
|
||||
else
|
||||
{
|
||||
static GimpColorProfile *srgb_profile = NULL;
|
||||
|
||||
if (G_UNLIKELY (! srgb_profile))
|
||||
srgb_profile = gimp_color_profile_new_rgb_srgb ();
|
||||
|
||||
profile = srgb_profile;
|
||||
}
|
||||
|
||||
renderer->priv->profile_transform =
|
||||
gimp_widget_get_color_transform (widget,
|
||||
renderer->priv->color_config,
|
||||
profile,
|
||||
src_format,
|
||||
dest_format);
|
||||
|
||||
return renderer->priv->profile_transform;
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static void
|
||||
gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
|
@ -1099,9 +1232,10 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
|
|||
|
||||
if (babl_format_has_alpha (temp_buf_format) && channel == -1)
|
||||
{
|
||||
GeglBuffer *src_buffer;
|
||||
GeglBuffer *dest_buffer;
|
||||
cairo_surface_t *alpha_surface;
|
||||
GimpColorTransform *transform;
|
||||
GeglBuffer *src_buffer;
|
||||
GeglBuffer *dest_buffer;
|
||||
cairo_surface_t *alpha_surface;
|
||||
|
||||
alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
width, height);
|
||||
|
@ -1109,13 +1243,14 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
|
|||
src_buffer = gimp_temp_buf_create_buffer (temp_buf);
|
||||
dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface);
|
||||
|
||||
if (! renderer->priv->profile_transform)
|
||||
gimp_view_renderer_transform_create (renderer, widget,
|
||||
src_buffer, dest_buffer);
|
||||
transform =
|
||||
gimp_view_renderer_get_color_transform (renderer, widget,
|
||||
gegl_buffer_get_format (src_buffer),
|
||||
gegl_buffer_get_format (dest_buffer));
|
||||
|
||||
if (renderer->priv->profile_transform)
|
||||
if (transform)
|
||||
{
|
||||
gimp_color_transform_process_buffer (renderer->priv->profile_transform,
|
||||
gimp_color_transform_process_buffer (transform,
|
||||
src_buffer,
|
||||
GEGL_RECTANGLE (x - temp_buf_x,
|
||||
y - temp_buf_y,
|
||||
|
@ -1148,21 +1283,23 @@ gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
|
|||
}
|
||||
else if (channel == -1)
|
||||
{
|
||||
GeglBuffer *src_buffer;
|
||||
GeglBuffer *dest_buffer;
|
||||
GimpColorTransform *transform;
|
||||
GeglBuffer *src_buffer;
|
||||
GeglBuffer *dest_buffer;
|
||||
|
||||
cairo_surface_flush (surface);
|
||||
|
||||
src_buffer = gimp_temp_buf_create_buffer (temp_buf);
|
||||
dest_buffer = gimp_cairo_surface_create_buffer (surface);
|
||||
|
||||
if (! renderer->priv->profile_transform)
|
||||
gimp_view_renderer_transform_create (renderer, widget,
|
||||
src_buffer, dest_buffer);
|
||||
transform =
|
||||
gimp_view_renderer_get_color_transform (renderer, widget,
|
||||
gegl_buffer_get_format (src_buffer),
|
||||
gegl_buffer_get_format (dest_buffer));
|
||||
|
||||
if (renderer->priv->profile_transform)
|
||||
if (transform)
|
||||
{
|
||||
gimp_color_transform_process_buffer (renderer->priv->profile_transform,
|
||||
gimp_color_transform_process_buffer (transform,
|
||||
src_buffer,
|
||||
GEGL_RECTANGLE (x - temp_buf_x,
|
||||
y - temp_buf_y,
|
||||
|
@ -1277,41 +1414,6 @@ gimp_view_renderer_create_background (GimpViewRenderer *renderer,
|
|||
return pattern;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_view_renderer_transform_create (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
GeglBuffer *src_buffer,
|
||||
GeglBuffer *dest_buffer)
|
||||
{
|
||||
if (GIMP_IS_COLOR_MANAGED (renderer->viewable))
|
||||
{
|
||||
GimpColorManaged *managed = GIMP_COLOR_MANAGED (renderer->viewable);
|
||||
GimpColorProfile *profile;
|
||||
|
||||
if (G_UNLIKELY (renderer->context == NULL))
|
||||
{
|
||||
g_warning ("%s: renderer->context is NULL", G_STRFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
profile = gimp_color_managed_get_color_profile (managed);
|
||||
|
||||
if (profile)
|
||||
{
|
||||
GimpColorConfig *config = renderer->priv->color_config;
|
||||
|
||||
if (! config)
|
||||
config = renderer->context->gimp->config->color_management;
|
||||
|
||||
renderer->priv->profile_transform =
|
||||
gimp_widget_get_color_transform (widget, config,
|
||||
profile,
|
||||
gegl_buffer_get_format (src_buffer),
|
||||
gegl_buffer_get_format (dest_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_view_renderer_transform_free (GimpViewRenderer *renderer)
|
||||
{
|
||||
|
|
|
@ -156,6 +156,11 @@ void gimp_view_renderer_render_pixbuf (GimpViewRenderer *renderer,
|
|||
void gimp_view_renderer_render_icon (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
const gchar *icon_name);
|
||||
GimpColorTransform *
|
||||
gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
|
||||
GtkWidget *widget,
|
||||
const Babl *src_format,
|
||||
const Babl *dest_format);
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue