mirror of https://github.com/GNOME/gimp.git
Bug 750874 - Displayed colors look clipped after profile conversion...
but they aren't clipped Add gimp_display_shell_profile_can_convert_to_u8() which returns whether the lcms transform can safely write directly into an u8 buffer without destroying out-of-gammut pixel values, which we assume is the case for all integer formats. If the function returns FALSE, always convert via the R'G'B'A float filter_buffer. Also connect to the image's "precision-changed" signal and update the profile transform when it's emitted.
This commit is contained in:
parent
86e88b9b40
commit
c876e281b1
|
@ -117,6 +117,8 @@ static void gimp_display_shell_sample_point_move_handler (GimpImage *i
|
||||||
GimpDisplayShell *shell);
|
GimpDisplayShell *shell);
|
||||||
static void gimp_display_shell_invalidate_preview_handler (GimpImage *image,
|
static void gimp_display_shell_invalidate_preview_handler (GimpImage *image,
|
||||||
GimpDisplayShell *shell);
|
GimpDisplayShell *shell);
|
||||||
|
static void gimp_display_shell_precision_changed_handler (GimpImage *image,
|
||||||
|
GimpDisplayShell *shell);
|
||||||
static void gimp_display_shell_profile_changed_handler (GimpColorManaged *image,
|
static void gimp_display_shell_profile_changed_handler (GimpColorManaged *image,
|
||||||
GimpDisplayShell *shell);
|
GimpDisplayShell *shell);
|
||||||
static void gimp_display_shell_saved_handler (GimpImage *image,
|
static void gimp_display_shell_saved_handler (GimpImage *image,
|
||||||
|
@ -251,9 +253,15 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
|
||||||
g_signal_connect (image, "invalidate-preview",
|
g_signal_connect (image, "invalidate-preview",
|
||||||
G_CALLBACK (gimp_display_shell_invalidate_preview_handler),
|
G_CALLBACK (gimp_display_shell_invalidate_preview_handler),
|
||||||
shell);
|
shell);
|
||||||
|
g_signal_connect (image, "precision-changed",
|
||||||
|
G_CALLBACK (gimp_display_shell_precision_changed_handler),
|
||||||
|
shell);
|
||||||
g_signal_connect (image, "profile-changed",
|
g_signal_connect (image, "profile-changed",
|
||||||
G_CALLBACK (gimp_display_shell_profile_changed_handler),
|
G_CALLBACK (gimp_display_shell_profile_changed_handler),
|
||||||
shell);
|
shell);
|
||||||
|
g_signal_connect (image, "precision-changed",
|
||||||
|
G_CALLBACK (gimp_display_shell_precision_changed_handler),
|
||||||
|
shell);
|
||||||
g_signal_connect (image, "saved",
|
g_signal_connect (image, "saved",
|
||||||
G_CALLBACK (gimp_display_shell_saved_handler),
|
G_CALLBACK (gimp_display_shell_saved_handler),
|
||||||
shell);
|
shell);
|
||||||
|
@ -453,6 +461,9 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
|
||||||
g_signal_handlers_disconnect_by_func (image,
|
g_signal_handlers_disconnect_by_func (image,
|
||||||
gimp_display_shell_profile_changed_handler,
|
gimp_display_shell_profile_changed_handler,
|
||||||
shell);
|
shell);
|
||||||
|
g_signal_handlers_disconnect_by_func (image,
|
||||||
|
gimp_display_shell_precision_changed_handler,
|
||||||
|
shell);
|
||||||
g_signal_handlers_disconnect_by_func (image,
|
g_signal_handlers_disconnect_by_func (image,
|
||||||
gimp_display_shell_invalidate_preview_handler,
|
gimp_display_shell_invalidate_preview_handler,
|
||||||
shell);
|
shell);
|
||||||
|
@ -790,6 +801,13 @@ gimp_display_shell_invalidate_preview_handler (GimpImage *image,
|
||||||
gimp_display_shell_icon_update (shell);
|
gimp_display_shell_icon_update (shell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gimp_display_shell_precision_changed_handler (GimpImage *image,
|
||||||
|
GimpDisplayShell *shell)
|
||||||
|
{
|
||||||
|
gimp_display_shell_profile_update (shell);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_display_shell_profile_changed_handler (GimpColorManaged *image,
|
gimp_display_shell_profile_changed_handler (GimpColorManaged *image,
|
||||||
GimpDisplayShell *shell)
|
GimpDisplayShell *shell)
|
||||||
|
@ -797,7 +815,6 @@ gimp_display_shell_profile_changed_handler (GimpColorManaged *image,
|
||||||
gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (shell));
|
gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (shell));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_display_shell_saved_handler (GimpImage *image,
|
gimp_display_shell_saved_handler (GimpImage *image,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "gegl/gimp-babl.h"
|
#include "gegl/gimp-babl.h"
|
||||||
|
|
||||||
|
#include "core/gimpimage.h"
|
||||||
#include "core/gimppickable.h"
|
#include "core/gimppickable.h"
|
||||||
|
|
||||||
#include "gimpdisplay.h"
|
#include "gimpdisplay.h"
|
||||||
|
@ -92,10 +93,15 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
|
||||||
gimp_image_get_precision (image),
|
gimp_image_get_precision (image),
|
||||||
TRUE);
|
TRUE);
|
||||||
|
|
||||||
if (gimp_display_shell_has_filter (shell))
|
if (gimp_display_shell_has_filter (shell) ||
|
||||||
|
! gimp_display_shell_profile_can_convert_to_u8 (shell))
|
||||||
|
{
|
||||||
dest_format = shell->filter_format;
|
dest_format = shell->filter_format;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
dest_format = babl_format ("R'G'B'A u8");
|
dest_format = babl_format ("R'G'B'A u8");
|
||||||
|
}
|
||||||
|
|
||||||
g_printerr ("src_format: %s\n", babl_get_name (src_format));
|
g_printerr ("src_format: %s\n", babl_get_name (src_format));
|
||||||
g_printerr ("dest_format: %s\n", babl_get_name (dest_format));
|
g_printerr ("dest_format: %s\n", babl_get_name (dest_format));
|
||||||
|
@ -130,6 +136,30 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gimp_display_shell_profile_can_convert_to_u8 (GimpDisplayShell *shell)
|
||||||
|
{
|
||||||
|
GimpImage *image;
|
||||||
|
|
||||||
|
image = gimp_display_get_image (shell->display);
|
||||||
|
|
||||||
|
if (image)
|
||||||
|
{
|
||||||
|
switch (gimp_image_get_component_type (image))
|
||||||
|
{
|
||||||
|
case GIMP_COMPONENT_TYPE_U8:
|
||||||
|
case GIMP_COMPONENT_TYPE_U16:
|
||||||
|
case GIMP_COMPONENT_TYPE_U32:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gimp_display_shell_profile_convert_buffer (GimpDisplayShell *shell,
|
gimp_display_shell_profile_convert_buffer (GimpDisplayShell *shell,
|
||||||
GeglBuffer *src_buffer,
|
GeglBuffer *src_buffer,
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
void gimp_display_shell_profile_dispose (GimpDisplayShell *shell);
|
void gimp_display_shell_profile_dispose (GimpDisplayShell *shell);
|
||||||
void gimp_display_shell_profile_update (GimpDisplayShell *shell);
|
void gimp_display_shell_profile_update (GimpDisplayShell *shell);
|
||||||
|
|
||||||
|
gboolean gimp_display_shell_profile_can_convert_to_u8 (GimpDisplayShell *shell);
|
||||||
|
|
||||||
void gimp_display_shell_profile_convert_buffer (GimpDisplayShell *shell,
|
void gimp_display_shell_profile_convert_buffer (GimpDisplayShell *shell,
|
||||||
GeglBuffer *src_buffer,
|
GeglBuffer *src_buffer,
|
||||||
GeglRectangle *src_area,
|
GeglRectangle *src_area,
|
||||||
|
|
|
@ -163,13 +163,17 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
||||||
if (shell->profile_transform ||
|
if (shell->profile_transform ||
|
||||||
gimp_display_shell_has_filter (shell))
|
gimp_display_shell_has_filter (shell))
|
||||||
{
|
{
|
||||||
|
gboolean can_convert_to_u8;
|
||||||
|
|
||||||
/* if there is a profile transform or a display filter, we need
|
/* if there is a profile transform or a display filter, we need
|
||||||
* to use temp buffers
|
* to use temp buffers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
*/
|
*/
|
||||||
if (gimp_display_shell_has_filter (shell) &&
|
if ((gimp_display_shell_has_filter (shell) || ! can_convert_to_u8) &&
|
||||||
! shell->filter_buffer)
|
! shell->filter_buffer)
|
||||||
{
|
{
|
||||||
gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE;
|
gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE;
|
||||||
|
@ -213,7 +217,7 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
||||||
GEGL_BLIT_CACHE);
|
GEGL_BLIT_CACHE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (gimp_display_shell_has_filter (shell))
|
if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8)
|
||||||
{
|
{
|
||||||
/* if there are filters, convert the pixels from the
|
/* if there are filters, convert the pixels from the
|
||||||
* profile_buffer to the filter_buffer
|
* profile_buffer to the filter_buffer
|
||||||
|
@ -277,7 +281,10 @@ gimp_display_shell_render (GimpDisplayShell *shell,
|
||||||
GEGL_RECTANGLE (0, 0,
|
GEGL_RECTANGLE (0, 0,
|
||||||
scaled_width,
|
scaled_width,
|
||||||
scaled_height));
|
scaled_height));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gimp_display_shell_has_filter (shell) || ! can_convert_to_u8)
|
||||||
|
{
|
||||||
/* finally, copy the filter buffer to the cairo-ARGB32 buffer
|
/* finally, copy the filter buffer to the cairo-ARGB32 buffer
|
||||||
*/
|
*/
|
||||||
gegl_buffer_get (shell->filter_buffer,
|
gegl_buffer_get (shell->filter_buffer,
|
||||||
|
|
Loading…
Reference in New Issue