[gimp] Bug 723392 - Pasting an image replaces color profile with default one
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Bug 723392 - Pasting an image replaces color profile with default one
- Date: Fri, 14 Aug 2015 16:05:33 +0000 (UTC)
commit 875314dd19c977782babe93da504b8269612528c
Author: Michael Natterer <mitch gimp org>
Date: Fri Aug 14 18:03:31 2015 +0200
Bug 723392 - Pasting an image replaces color profile with default one
gimp_layer_new_convert_profile(): if there is a profile, always use
lcms to copy between the buffers, to avoid the additional gamma
conversion gegl_buffer_copy/get() would do in some cases. This should
fix copying between linear and gamma images.
app/core/gimplayer-new.c | 104 ++++++++++++++++++++++++++++-----------------
1 files changed, 65 insertions(+), 39 deletions(-)
---
diff --git a/app/core/gimplayer-new.c b/app/core/gimplayer-new.c
index bd3f1e5..781e2ef 100644
--- a/app/core/gimplayer-new.c
+++ b/app/core/gimplayer-new.c
@@ -30,6 +30,8 @@
#include "config/gimpcoreconfig.h"
+#include "gegl/gimp-babl.h"
+
#include "gimp.h"
#include "gimpbuffer.h"
#include "gimpimage.h"
@@ -40,6 +42,7 @@
/* local function prototypes */
static gboolean gimp_layer_new_convert_profile (GimpLayer *layer,
+ GeglBuffer *src_buffer,
const guint8 *icc_data,
gsize icc_length,
GError **error);
@@ -139,8 +142,7 @@ gimp_layer_new_from_gegl_buffer (GeglBuffer *buffer,
const guint8 *buffer_icc_data,
gsize buffer_icc_length)
{
- GimpLayer *layer;
- GeglBuffer *dest;
+ GimpLayer *layer;
g_return_val_if_fail (GEGL_IS_BUFFER (buffer), NULL);
g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
@@ -156,12 +158,17 @@ gimp_layer_new_from_gegl_buffer (GeglBuffer *buffer,
format,
name, opacity, mode);
- dest = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
- gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, dest, NULL);
-
if (buffer_icc_data)
- gimp_layer_new_convert_profile (layer, buffer_icc_data, buffer_icc_length,
- NULL);
+ {
+ gimp_layer_new_convert_profile (layer, buffer,
+ buffer_icc_data, buffer_icc_length,
+ NULL);
+ }
+ else
+ {
+ gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)), NULL);
+ }
return layer;
}
@@ -189,10 +196,8 @@ gimp_layer_new_from_pixbuf (GdkPixbuf *pixbuf,
gdouble opacity,
GimpLayerModeEffects mode)
{
- GeglBuffer *buffer;
GimpLayer *layer;
- gint width;
- gint height;
+ GeglBuffer *buffer;
guint8 *icc_data;
gsize icc_len;
@@ -200,25 +205,27 @@ gimp_layer_new_from_pixbuf (GdkPixbuf *pixbuf,
g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
g_return_val_if_fail (format != NULL, NULL);
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
-
- layer = gimp_layer_new (dest_image, width, height,
+ layer = gimp_layer_new (dest_image,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
format, name, opacity, mode);
- buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (layer));
-
- gegl_buffer_set (buffer, GEGL_RECTANGLE (0, 0, width, height), 0,
- gimp_pixbuf_get_format (pixbuf),
- gdk_pixbuf_get_pixels (pixbuf),
- gdk_pixbuf_get_rowstride (pixbuf));
+ buffer = gimp_pixbuf_create_buffer (pixbuf);
icc_data = gimp_pixbuf_get_icc_profile (pixbuf, &icc_len);
+
if (icc_data)
{
- gimp_layer_new_convert_profile (layer, icc_data, icc_len, NULL);
+ gimp_layer_new_convert_profile (layer, buffer, icc_data, icc_len, NULL);
g_free (icc_data);
}
+ else
+ {
+ gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE,
+ gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)), NULL);
+ }
+
+ g_object_unref (buffer);
return layer;
}
@@ -228,27 +235,44 @@ gimp_layer_new_from_pixbuf (GdkPixbuf *pixbuf,
static gboolean
gimp_layer_new_convert_profile (GimpLayer *layer,
+ GeglBuffer *src_buffer,
const guint8 *icc_data,
gsize icc_length,
GError **error)
{
- GimpDrawable *drawable = GIMP_DRAWABLE (layer);
- GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
- GimpColorConfig *config = image->gimp->config->color_management;
+ GimpDrawable *drawable = GIMP_DRAWABLE (layer);
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
+ GimpColorConfig *config = image->gimp->config->color_management;
+ GeglBuffer *dest_buffer = gimp_drawable_get_buffer (drawable);
GimpColorProfile *src_profile;
GimpColorProfile *dest_profile;
+ const Babl *src_format;
+ const Babl *dest_format;
cmsHPROFILE src_lcms;
cmsHPROFILE dest_lcms;
- const Babl *iter_format;
- cmsUInt32Number lcms_format;
+ cmsUInt32Number lcms_src_format;
+ cmsUInt32Number lcms_dest_format;
cmsHTRANSFORM transform;
- if (! gimp_drawable_is_rgb (drawable))
- return TRUE;
+ /* FIXME: we need the unconditional full copy only in two cases:
+ * - if we return without doing anything
+ * - if there is an alpha channel, because lcms doesn't copy it
+ */
+ gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);
+ /* FIXME: this is the wrong check, need something like file import
+ * conversion config
+ */
if (config->mode == GIMP_COLOR_MANAGEMENT_OFF)
return TRUE;
+ src_format = gegl_buffer_get_format (src_buffer);
+ dest_format = gegl_buffer_get_format (dest_buffer);
+
+ if ((gimp_babl_format_get_base_type (src_format) != GIMP_RGB) ||
+ (gimp_babl_format_get_base_type (dest_format) != GIMP_RGB))
+ return TRUE;
+
src_profile = gimp_color_profile_new_from_icc_profile (icc_data, icc_length,
error);
if (! src_profile)
@@ -260,36 +284,38 @@ gimp_layer_new_convert_profile (GimpLayer *layer,
{
g_object_unref (src_profile);
g_object_unref (dest_profile);
-
return TRUE;
}
src_lcms = gimp_color_profile_get_lcms_profile (src_profile);
dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);
- iter_format =
- gimp_color_profile_get_format (gimp_drawable_get_format (drawable),
- &lcms_format);
+ src_format = gimp_color_profile_get_format (src_format, &lcms_src_format);
+ dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format);
- transform = cmsCreateTransform (src_lcms, lcms_format,
- dest_lcms, lcms_format,
+ transform = cmsCreateTransform (src_lcms, lcms_src_format,
+ dest_lcms, lcms_dest_format,
GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
cmsFLAGS_NOOPTIMIZE);
if (transform)
{
- GeglBuffer *buffer = gimp_drawable_get_buffer (drawable);
GeglBufferIterator *iter;
- iter = gegl_buffer_iterator_new (buffer, NULL, 0,
- iter_format,
- GEGL_ACCESS_READWRITE,
+ iter = gegl_buffer_iterator_new (src_buffer, NULL, 0,
+ src_format,
+ GEGL_ACCESS_READ,
GEGL_ABYSS_NONE);
+ gegl_buffer_iterator_add (iter, dest_buffer, NULL, 0,
+ dest_format,
+ GEGL_ACCESS_WRITE,
+ GEGL_ABYSS_NONE);
+
while (gegl_buffer_iterator_next (iter))
{
cmsDoTransform (transform,
- iter->data[0], iter->data[0], iter->length);
+ iter->data[0], iter->data[1], iter->length);
}
cmsDeleteTransform (transform);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]