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)
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
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->profile_transform ||
|
||||
gimp_display_shell_has_filter (shell))
|
||||
{
|
||||
const Babl *filter_format = babl_format ("R'G'B'A float");
|
||||
/* if there is a profile transform or a display filter, we need
|
||||
* to use temp buffers
|
||||
*/
|
||||
|
||||
if (! shell->filter_buffer)
|
||||
/* 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));
|
||||
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
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user