[gimp] app: apply display filters in sRGB, not monitor profile
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: apply display filters in sRGB, not monitor profile
- Date: Fri, 3 Nov 2017 08:29:42 +0000 (UTC)
commit 9cd8e7f9c6ce01adda07d0c25fc18f43b3f56fda
Author: Ell <ell_se yahoo com>
Date: Fri Nov 3 03:59:06 2017 -0400
app: apply display filters in sRGB, not monitor profile
When we have display filters, break the color profile transform in
two: first, convert from the image profile to sRGB, then apply the
filters, then convert from sRGB to the monitor profile.
app/display/gimpdisplayshell-profile.c | 54 ++++++++++++---
app/display/gimpdisplayshell-render.c | 121 +++++++++++++++++++++----------
app/display/gimpdisplayshell.h | 11 ++--
3 files changed, 133 insertions(+), 53 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-profile.c b/app/display/gimpdisplayshell-profile.c
index b035bf4..23a580d 100644
--- a/app/display/gimpdisplayshell-profile.c
+++ b/app/display/gimpdisplayshell-profile.c
@@ -87,6 +87,8 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
GimpImage *image;
GimpColorProfile *src_profile;
const Babl *src_format;
+ GimpColorProfile *filter_profile;
+ const Babl *filter_format;
const Babl *dest_format;
gimp_display_shell_profile_free (shell);
@@ -103,8 +105,18 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
src_format = gimp_projectable_get_format (GIMP_PROJECTABLE (image));
- if (gimp_display_shell_has_filter (shell) ||
- ! gimp_display_shell_profile_can_convert_to_u8 (shell))
+ if (gimp_display_shell_has_filter (shell))
+ {
+ filter_format = shell->filter_format;
+ filter_profile = gimp_babl_format_get_color_profile (filter_format);
+ }
+ else
+ {
+ filter_format = src_format;
+ filter_profile = src_profile;
+ }
+
+ if (! gimp_display_shell_profile_can_convert_to_u8 (shell))
{
dest_format = shell->filter_format;
}
@@ -114,22 +126,38 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
}
#if 0
- g_printerr ("src_profile: %s\n"
- "src_format: %s\n"
- "dest_format: %s\n",
+ g_printerr ("src_profile: %s\n"
+ "src_format: %s\n"
+ "filter_profile: %s\n"
+ "filter_format: %s\n"
+ "dest_format: %s\n",
gimp_color_profile_get_label (src_profile),
babl_get_name (src_format),
+ gimp_color_profile_get_label (filter_profile),
+ babl_get_name (filter_format),
babl_get_name (dest_format));
#endif
+ if (! gimp_color_transform_can_gegl_copy (src_profile, filter_profile))
+ {
+ shell->filter_transform =
+ gimp_color_transform_new (src_profile,
+ src_format,
+ filter_profile,
+ filter_format,
+ GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
+ GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION |
+ GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE);
+ }
+
shell->profile_transform =
gimp_widget_get_color_transform (gtk_widget_get_toplevel (GTK_WIDGET (shell)),
gimp_display_shell_get_color_config (shell),
- src_profile,
- src_format,
+ filter_profile,
+ filter_format,
dest_format);
- if (shell->profile_transform)
+ if (shell->filter_transform || shell->profile_transform)
{
gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE;
gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE;
@@ -157,7 +185,14 @@ gimp_display_shell_profile_can_convert_to_u8 (GimpDisplayShell *shell)
if (image)
{
- switch (gimp_image_get_component_type (image))
+ GimpComponentType component_type;
+
+ if (! gimp_display_shell_has_filter (shell))
+ component_type = gimp_image_get_component_type (image);
+ else
+ component_type = gimp_babl_format_get_component_type (shell->filter_format);
+
+ switch (component_type)
{
case GIMP_COMPONENT_TYPE_U8:
#if 0
@@ -184,6 +219,7 @@ static void
gimp_display_shell_profile_free (GimpDisplayShell *shell)
{
g_clear_object (&shell->profile_transform);
+ g_clear_object (&shell->filter_transform);
g_clear_object (&shell->profile_buffer);
shell->profile_data = NULL;
shell->profile_stride = 0;
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index cb36652..21f0cc1 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -171,7 +171,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
can_convert_to_u8 = gimp_display_shell_profile_can_convert_to_u8 (shell);
- /* create the filter buffer if we have filters
+ /* create the filter buffer if we have filters, or can't convert
+ * to u8 directly
*/
if ((gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) &&
! shell->filter_buffer)
@@ -194,10 +195,10 @@ gimp_display_shell_render (GimpDisplayShell *shell,
shell->filter_data);
}
- if (shell->profile_transform)
+ if (! gimp_display_shell_has_filter (shell) || shell->filter_transform)
{
- /* if there is a profile transform, load the projection
- * pixels into the profile_buffer
+ /* if there are no filters, or there is a filter transform,
+ * load the projection pixels into the profile_buffer
*/
#ifndef USE_NODE_BLIT
gegl_buffer_get (buffer,
@@ -216,42 +217,10 @@ gimp_display_shell_render (GimpDisplayShell *shell,
shell->profile_data, shell->profile_stride,
GEGL_BLIT_CACHE);
#endif
-
- if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8)
- {
- /* if there are filters, convert the pixels from the
- * profile_buffer to the filter_buffer
- */
- gimp_color_transform_process_buffer (shell->profile_transform,
- shell->profile_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height),
- shell->filter_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height));
- }
- else
- {
- /* otherwise, convert the profile_buffer directly into
- * the cairo_buffer
- */
- gimp_color_transform_process_buffer (shell->profile_transform,
- shell->profile_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height),
- cairo_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height));
- }
}
else
{
- /* otherwise, load the projection pixels directly into the
- * filter_buffer
+ /* otherwise, load the pixels directly into the filter_buffer
*/
#ifndef USE_NODE_BLIT
gegl_buffer_get (buffer,
@@ -272,10 +241,32 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#endif
}
+ /* if there is a filter transform, convert the pixels from
+ * the profile_buffer to the filter_buffer
+ */
+ if (shell->filter_transform)
+ {
+ gimp_color_transform_process_buffer (shell->filter_transform,
+ shell->profile_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height));
+ }
+
+ /* if there are filters, apply them
+ */
if (gimp_display_shell_has_filter (shell))
{
GeglBuffer *filter_buffer;
+ /* shift the filter_buffer so that the area passed to
+ * the filters is the real render area, allowing for
+ * position-dependent filters
+ */
filter_buffer = g_object_new (GEGL_TYPE_BUFFER,
"source", shell->filter_buffer,
"shift-x", -scaled_x,
@@ -293,10 +284,62 @@ gimp_display_shell_render (GimpDisplayShell *shell,
g_object_unref (filter_buffer);
}
+ /* if there is a profile transform...
+ */
+ if (shell->profile_transform)
+ {
+ if (gimp_display_shell_has_filter (shell))
+ {
+ /* if we have filters, convert the pixels in the filter_buffer
+ * in-place
+ */
+ gimp_color_transform_process_buffer (shell->profile_transform,
+ shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height));
+ }
+ else if (! can_convert_to_u8)
+ {
+ /* otherwise, if we can't convert to u8 directly, convert
+ * the pixels from the profile_buffer to the filter_buffer
+ */
+ gimp_color_transform_process_buffer (shell->profile_transform,
+ shell->profile_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height));
+ }
+ else
+ {
+ /* otherwise, convert the profile_buffer directly into
+ * the cairo_buffer
+ */
+ gimp_color_transform_process_buffer (shell->profile_transform,
+ shell->profile_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ cairo_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height));
+ }
+ }
+
+ /* finally, copy the filter buffer to the cairo-ARGB32 buffer,
+ * if necessary
+ */
if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8)
{
- /* finally, copy the filter buffer to the cairo-ARGB32 buffer
- */
gegl_buffer_get (shell->filter_buffer,
GEGL_RECTANGLE (0, 0,
scaled_width,
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 565edb8..9c5cb19 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -157,13 +157,14 @@ struct _GimpDisplayShell
guchar *profile_data; /* profile_buffer's pixels */
gint profile_stride; /* profile_buffer's stride */
- GimpColorDisplayStack *filter_stack; /* color display conversion stuff */
+ GimpColorDisplayStack *filter_stack; /* color display conversion stuff */
guint filter_idle_id;
- const Babl *filter_format; /* filter_buffer's format */
- GeglBuffer *filter_buffer; /* buffer for display filters */
- guchar *filter_data; /* filter_buffer's pixels */
- gint filter_stride; /* filter_buffer's stride */
+ GimpColorTransform *filter_transform;
+ const Babl *filter_format; /* filter_buffer's format */
+ GeglBuffer *filter_buffer; /* buffer for display filters */
+ guchar *filter_data; /* filter_buffer's pixels */
+ gint filter_stride; /* filter_buffer's stride */
GimpDisplayXfer *xfer; /* manages image buffer transfers */
cairo_surface_t *mask_surface; /* buffer for rendering the mask */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]