[gimp] app: switch gimpdisplayshell-render.c to the new profile filter code
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: switch gimpdisplayshell-render.c to the new profile filter code
- Date: Mon, 1 Jun 2015 21:35:49 +0000 (UTC)
commit 08545ad5492f186eca6b111f634cd480ca5a3fd9
Author: Michael Natterer <mitch gimp org>
Date: Mon Jun 1 23:30:03 2015 +0200
app: switch gimpdisplayshell-render.c to the new profile filter code
- disable auto-adding of the lcms display filter module
- change profile convert dest formats to be always R'G'B'A, a display
profile transform outputs something that can be displayed directly,
so no additional gamma transform must happen when the pixels are
copied to a cairo-ARGB32 buffer
- add a medium forest of if() branches to gimpdisplayshell-filter.c
which cover all combinations of profile and display filter
transforms
- all of this is still very broken when changing an image to linear,
because the configured RGB profile from prefs will do horrible
nonsense (things work fine though with a per-image profile that is
for linear data)
app/display/gimpdisplayshell-filter.c | 5 +
app/display/gimpdisplayshell-profile.c | 13 +--
app/display/gimpdisplayshell-render.c | 189 +++++++++++++++++++++++---------
3 files changed, 148 insertions(+), 59 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-filter.c b/app/display/gimpdisplayshell-filter.c
index 773ce75..b1fa583 100644
--- a/app/display/gimpdisplayshell-filter.c
+++ b/app/display/gimpdisplayshell-filter.c
@@ -89,6 +89,10 @@ gimp_display_shell_filter_new (GimpDisplayShell *shell,
g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL);
+#if 0
+ /* disabled because we use gimpdisplayshell-profile now, keep
+ * the code around for reference.
+ */
if (config->display_module)
{
GType type = g_type_from_name (config->display_module);
@@ -111,6 +115,7 @@ gimp_display_shell_filter_new (GimpDisplayShell *shell,
return stack;
}
}
+#endif
return NULL;
}
diff --git a/app/display/gimpdisplayshell-profile.c b/app/display/gimpdisplayshell-profile.c
index c0fc41b..ad070ee 100644
--- a/app/display/gimpdisplayshell-profile.c
+++ b/app/display/gimpdisplayshell-profile.c
@@ -38,6 +38,7 @@
#include "gimpdisplay.h"
#include "gimpdisplayshell.h"
+#include "gimpdisplayshell-filter.h"
#include "gimpdisplayshell-profile.h"
#include "gimpdisplayxfer.h"
@@ -89,16 +90,10 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
src_format = gimp_pickable_get_format (GIMP_PICKABLE (image));
- if (shell->filter_stack && shell->filter_stack->filters)
- dest_format = gimp_babl_format (GIMP_RGB,
- gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT,
- gimp_babl_format_get_linear (src_format)),
- TRUE);
+ if (gimp_display_shell_has_filter (shell))
+ dest_format = babl_format ("R'G'B'A float");
else
- dest_format = gimp_babl_format (GIMP_RGB,
- gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT,
- gimp_babl_format_get_linear (src_format)),
- TRUE);
+ dest_format = babl_format ("R'G'B'A u8");
g_printerr ("src_format: %s\n", babl_get_name (src_format));
g_printerr ("dest_format: %s\n", babl_get_name (dest_format));
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index af63f90..d8f8f1b 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -41,6 +41,7 @@
#include "gimpdisplayshell.h"
#include "gimpdisplayshell-transform.h"
#include "gimpdisplayshell-filter.h"
+#include "gimpdisplayshell-profile.h"
#include "gimpdisplayshell-render.h"
#include "gimpdisplayshell-scroll.h"
#include "gimpdisplayxfer.h"
@@ -62,9 +63,10 @@ gimp_display_shell_render (GimpDisplayShell *shell,
#ifdef USE_NODE_BLIT
GeglNode *node;
#endif
- gdouble scale_x = 1.0;
- gdouble scale_y = 1.0;
- gdouble buffer_scale = 1.0;
+ const Babl *filter_format = babl_format ("R'G'B'A float");
+ gdouble scale_x = 1.0;
+ gdouble scale_y = 1.0;
+ gdouble buffer_scale = 1.0;
gint viewport_offset_x;
gint viewport_offset_y;
gint viewport_width;
@@ -78,8 +80,9 @@ gimp_display_shell_render (GimpDisplayShell *shell,
gint xfer_src_y;
gint mask_src_x = 0;
gint mask_src_y = 0;
- gint stride;
- guchar *data;
+ gint cairo_stride;
+ guchar *cairo_data;
+ GeglBuffer *cairo_buffer;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
g_return_if_fail (cr != NULL);
@@ -146,16 +149,29 @@ gimp_display_shell_render (GimpDisplayShell *shell,
&xfer_src_y);
}
- stride = cairo_image_surface_get_stride (xfer);
- data = cairo_image_surface_get_data (xfer);
- data += xfer_src_y * stride + xfer_src_x * 4;
+ cairo_stride = cairo_image_surface_get_stride (xfer);
+ cairo_data = cairo_image_surface_get_data (xfer) +
+ xfer_src_y * cairo_stride + xfer_src_x * 4;
- /* apply filters to the rendered projection */
- if (shell->filter_stack)
- {
- const Babl *filter_format = babl_format ("R'G'B'A float");
+ cairo_buffer = gegl_buffer_linear_new_from_data (cairo_data,
+ babl_format ("cairo-ARGB32"),
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ cairo_stride,
+ NULL, NULL);
- if (! shell->filter_buffer)
+ if (shell->profile_transform ||
+ gimp_display_shell_has_filter (shell))
+ {
+ /* if there is a profile transform or a display filter, we need
+ * to use temp buffers
+ */
+
+ /* create the filter buffer if we have filters
+ */
+ if (gimp_display_shell_has_filter (shell) &&
+ ! shell->filter_buffer)
{
gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE;
gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE;
@@ -163,7 +179,8 @@ gimp_display_shell_render (GimpDisplayShell *shell,
shell->filter_data =
gegl_malloc (w * h * babl_format_get_bytes_per_pixel (filter_format));
- shell->filter_stride = w * babl_format_get_bytes_per_pixel (filter_format);
+ shell->filter_stride =
+ w * babl_format_get_bytes_per_pixel (filter_format);
shell->filter_buffer =
gegl_buffer_linear_new_from_data (shell->filter_data,
@@ -174,48 +191,118 @@ gimp_display_shell_render (GimpDisplayShell *shell,
shell->filter_data);
}
+ if (shell->profile_transform)
+ {
+ /* if there is a profile transform, load the projection
+ * pixels into the profile_buffer
+ */
#ifndef USE_NODE_BLIT
- gegl_buffer_get (buffer,
- GEGL_RECTANGLE (scaled_x, scaled_y,
- scaled_width, scaled_height),
- buffer_scale,
- filter_format,
- shell->filter_data, shell->filter_stride,
- GEGL_ABYSS_CLAMP);
+ gegl_buffer_get (buffer,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ buffer_scale,
+ shell->profile_src_format,
+ shell->profile_data, shell->profile_stride,
+ GEGL_ABYSS_CLAMP);
#else
- gegl_node_blit (node,
- buffer_scale,
- GEGL_RECTANGLE (scaled_x, scaled_y,
- scaled_width, scaled_height),
- filter_format,
- shell->filter_data, shell->filter_stride,
- GEGL_BLIT_CACHE);
+ gegl_node_blit (node,
+ buffer_scale,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ shell->profile_src_format,
+ shell->profile_data, shell->profile_stride,
+ GEGL_BLIT_CACHE);
#endif
- gimp_color_display_stack_convert_buffer (shell->filter_stack,
- shell->filter_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height));
-
- gegl_buffer_get (shell->filter_buffer,
- GEGL_RECTANGLE (0, 0,
- scaled_width,
- scaled_height),
- 1.0,
- babl_format ("cairo-ARGB32"),
- data, stride,
- GEGL_ABYSS_CLAMP);
+ if (gimp_display_shell_has_filter (shell))
+ {
+ /* if there are filters, convert the pixels from the
+ * profile_buffer to the filter_buffer
+ */
+ gimp_display_shell_profile_convert_buffer (shell,
+ 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_display_shell_profile_convert_buffer (shell,
+ 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
+ */
+#ifndef USE_NODE_BLIT
+ gegl_buffer_get (buffer,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ buffer_scale,
+ filter_format,
+ shell->filter_data, shell->filter_stride,
+ GEGL_ABYSS_CLAMP);
+#else
+ gegl_node_blit (node,
+ buffer_scale,
+ GEGL_RECTANGLE (scaled_x, scaled_y,
+ scaled_width, scaled_height),
+ filter_format,
+ shell->filter_data, shell->filter_stride,
+ GEGL_BLIT_CACHE);
+#endif
+ }
+
+ if (gimp_display_shell_has_filter (shell))
+ {
+ /* convert the filter_buffer in place
+ */
+ gimp_color_display_stack_convert_buffer (shell->filter_stack,
+ shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height));
+
+ /* finally, copy the filter buffer to the cairo-ARGB32 buffer
+ */
+ gegl_buffer_get (shell->filter_buffer,
+ GEGL_RECTANGLE (0, 0,
+ scaled_width,
+ scaled_height),
+ 1.0,
+ babl_format ("cairo-ARGB32"),
+ cairo_data, cairo_stride,
+ GEGL_ABYSS_CLAMP);
+ }
}
else
{
+ /* otherwise we can copy the projection pixels straight to the
+ * cairo-ARGB32 buffer
+ */
#ifndef USE_NODE_BLIT
gegl_buffer_get (buffer,
GEGL_RECTANGLE (scaled_x, scaled_y,
scaled_width, scaled_height),
buffer_scale,
babl_format ("cairo-ARGB32"),
- data, stride,
+ cairo_data, cairo_stride,
GEGL_ABYSS_CLAMP);
#else
gegl_node_blit (node,
@@ -223,11 +310,13 @@ gimp_display_shell_render (GimpDisplayShell *shell,
GEGL_RECTANGLE (scaled_x, scaled_y,
scaled_width, scaled_height),
babl_format ("cairo-ARGB32"),
- data, stride,
+ cairo_data, cairo_stride,
GEGL_BLIT_CACHE);
#endif
}
+ g_object_unref (cairo_buffer);
+
if (shell->mask)
{
if (! shell->mask_surface)
@@ -242,16 +331,16 @@ gimp_display_shell_render (GimpDisplayShell *shell,
cairo_surface_mark_dirty (shell->mask_surface);
- stride = cairo_image_surface_get_stride (shell->mask_surface);
- data = cairo_image_surface_get_data (shell->mask_surface);
- data += mask_src_y * stride + mask_src_x * 4;
+ cairo_stride = cairo_image_surface_get_stride (shell->mask_surface);
+ cairo_data = cairo_image_surface_get_data (shell->mask_surface) +
+ mask_src_y * cairo_stride + mask_src_x * 4;
gegl_buffer_get (shell->mask,
GEGL_RECTANGLE (scaled_x, scaled_y,
scaled_width, scaled_height),
buffer_scale,
babl_format ("Y u8"),
- data, stride,
+ cairo_data, cairo_stride,
GEGL_ABYSS_CLAMP);
if (shell->mask_inverted)
@@ -261,7 +350,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
while (mask_height--)
{
gint mask_width = scaled_width;
- guchar *d = data;
+ guchar *d = cairo_data;
while (mask_width--)
{
@@ -270,7 +359,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
*d++ = inv;
}
- data += stride;
+ cairo_data += cairo_stride;
}
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]