[gimp] app: GimpBuffer: same preview colorspace fixes as below for images/layers
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: GimpBuffer: same preview colorspace fixes as below for images/layers
- Date: Fri, 15 Apr 2016 17:18:14 +0000 (UTC)
commit 0a5ba05e454285338095272e7de6c79e46781373
Author: Michael Natterer <mitch gimp org>
Date: Fri Apr 15 18:16:15 2016 +0100
app: GimpBuffer: same preview colorspace fixes as below for images/layers
Plus, implement GimpColorManaged so the view renderer can ask the
buffer for its profile.
This also fixes colors in cross-application copy & paste when GIMP
is the source.
app/core/gimpbuffer.c | 244 +++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 214 insertions(+), 30 deletions(-)
---
diff --git a/app/core/gimpbuffer.c b/app/core/gimpbuffer.c
index 787437b..cd2ef8f 100644
--- a/app/core/gimpbuffer.c
+++ b/app/core/gimpbuffer.c
@@ -26,6 +26,7 @@
#include "core-types.h"
#include "gegl/gimp-babl.h"
+#include "gegl/gimp-gegl-loops.h"
#include "gimp-memsize.h"
#include "gimpbuffer.h"
@@ -33,35 +34,51 @@
#include "gimptempbuf.h"
-static void gimp_buffer_finalize (GObject *object);
-
-static gint64 gimp_buffer_get_memsize (GimpObject *object,
- gint64 *gui_size);
-
-static gboolean gimp_buffer_get_size (GimpViewable *viewable,
- gint *width,
- gint *height);
-static void gimp_buffer_get_preview_size (GimpViewable *viewable,
- gint size,
- gboolean is_popup,
- gboolean dot_for_dot,
- gint *popup_width,
- gint *popup_height);
-static gboolean gimp_buffer_get_popup_size (GimpViewable *viewable,
- gint width,
- gint height,
- gboolean dot_for_dot,
- gint *popup_width,
- gint *popup_height);
-static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable,
- GimpContext *context,
- gint width,
- gint height);
-static gchar * gimp_buffer_get_description (GimpViewable *viewable,
- gchar **tooltip);
-
-
-G_DEFINE_TYPE (GimpBuffer, gimp_buffer, GIMP_TYPE_VIEWABLE)
+static void gimp_color_managed_iface_init (GimpColorManagedInterface *iface);
+
+static void gimp_buffer_finalize (GObject *object);
+
+static gint64 gimp_buffer_get_memsize (GimpObject *object,
+ gint64 *gui_size);
+
+static gboolean gimp_buffer_get_size (GimpViewable *viewable,
+ gint *width,
+ gint *height);
+static void gimp_buffer_get_preview_size (GimpViewable *viewable,
+ gint size,
+ gboolean is_popup,
+ gboolean dot_for_dot,
+ gint *popup_width,
+ gint *popup_height);
+static gboolean gimp_buffer_get_popup_size (GimpViewable *viewable,
+ gint width,
+ gint height,
+ gboolean dot_for_dot,
+ gint *popup_width,
+ gint *popup_height);
+static GimpTempBuf * gimp_buffer_get_new_preview (GimpViewable *viewable,
+ GimpContext *context,
+ gint width,
+ gint height);
+static GdkPixbuf * gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
+ GimpContext *context,
+ gint width,
+ gint height);
+static gchar * gimp_buffer_get_description (GimpViewable *viewable,
+ gchar **tooltip);
+
+static const guint8 *
+ gimp_buffer_color_managed_get_icc_profile (GimpColorManaged *managed,
+ gsize *len);
+static GimpColorProfile *
+ gimp_buffer_color_managed_get_color_profile (GimpColorManaged *managed);
+static void
+ gimp_buffer_color_managed_profile_changed (GimpColorManaged *managed);
+
+
+G_DEFINE_TYPE_WITH_CODE (GimpBuffer, gimp_buffer, GIMP_TYPE_VIEWABLE,
+ G_IMPLEMENT_INTERFACE (GIMP_TYPE_COLOR_MANAGED,
+ gimp_color_managed_iface_init))
#define parent_class gimp_buffer_parent_class
@@ -82,10 +99,19 @@ gimp_buffer_class_init (GimpBufferClass *klass)
viewable_class->get_preview_size = gimp_buffer_get_preview_size;
viewable_class->get_popup_size = gimp_buffer_get_popup_size;
viewable_class->get_new_preview = gimp_buffer_get_new_preview;
+ viewable_class->get_new_pixbuf = gimp_buffer_get_new_pixbuf;
viewable_class->get_description = gimp_buffer_get_description;
}
static void
+gimp_color_managed_iface_init (GimpColorManagedInterface *iface)
+{
+ iface->get_icc_profile = gimp_buffer_color_managed_get_icc_profile;
+ iface->get_color_profile = gimp_buffer_color_managed_get_color_profile;
+ iface->profile_changed = gimp_buffer_color_managed_profile_changed;
+}
+
+static void
gimp_buffer_init (GimpBuffer *buffer)
{
}
@@ -209,7 +235,8 @@ gimp_buffer_get_new_preview (GimpViewable *viewable,
babl_format_has_alpha (format));
else
format = gimp_babl_format (gimp_babl_format_get_base_type (format),
- GIMP_PRECISION_U8_GAMMA,
+ gimp_babl_precision (GIMP_COMPONENT_TYPE_U8,
+ gimp_babl_format_get_linear (format)),
babl_format_has_alpha (format));
preview = gimp_temp_buf_new (width, height, format);
@@ -224,6 +251,75 @@ gimp_buffer_get_new_preview (GimpViewable *viewable,
return preview;
}
+static GdkPixbuf *
+gimp_buffer_get_new_pixbuf (GimpViewable *viewable,
+ GimpContext *context,
+ gint width,
+ gint height)
+{
+ GimpBuffer *buffer = GIMP_BUFFER (viewable);
+ GdkPixbuf *pixbuf;
+ gdouble scale;
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
+ width, height);
+
+ scale = MIN ((gdouble) width / (gdouble) gimp_buffer_get_width (buffer),
+ (gdouble) height / (gdouble) gimp_buffer_get_height (buffer));
+
+ if (buffer->color_profile)
+ {
+ GimpColorProfile *srgb_profile;
+ GimpTempBuf *temp_buf;
+ GeglBuffer *src_buf;
+ GeglBuffer *dest_buf;
+
+ srgb_profile = gimp_color_profile_new_rgb_srgb ();
+
+ temp_buf = gimp_temp_buf_new (width, height,
+ gimp_buffer_get_format (buffer));
+
+ gegl_buffer_get (buffer->buffer,
+ GEGL_RECTANGLE (0, 0, width, height),
+ scale,
+ gimp_temp_buf_get_format (temp_buf),
+ gimp_temp_buf_get_data (temp_buf),
+ GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_CLAMP);
+
+ src_buf = gimp_temp_buf_create_buffer (temp_buf);
+ dest_buf = gimp_pixbuf_create_buffer (pixbuf);
+
+ gimp_temp_buf_unref (temp_buf);
+
+ gimp_gegl_convert_color_profile (src_buf,
+ GEGL_RECTANGLE (0, 0, width, height),
+ buffer->color_profile,
+ dest_buf,
+ GEGL_RECTANGLE (0, 0, 0, 0),
+ srgb_profile,
+ GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
+ TRUE,
+ NULL);
+
+ g_object_unref (src_buf);
+ g_object_unref (dest_buf);
+
+ g_object_unref (srgb_profile);
+ }
+ else
+ {
+ gegl_buffer_get (buffer->buffer,
+ GEGL_RECTANGLE (0, 0, width, height),
+ scale,
+ gimp_pixbuf_get_format (pixbuf),
+ gdk_pixbuf_get_pixels (pixbuf),
+ gdk_pixbuf_get_rowstride (pixbuf),
+ GEGL_ABYSS_CLAMP);
+ }
+
+ return pixbuf;
+}
+
static gchar *
gimp_buffer_get_description (GimpViewable *viewable,
gchar **tooltip)
@@ -236,6 +332,94 @@ gimp_buffer_get_description (GimpViewable *viewable,
gimp_buffer_get_height (buffer));
}
+static const guint8 *
+gimp_buffer_color_managed_get_icc_profile (GimpColorManaged *managed,
+ gsize *len)
+{
+ GimpBuffer *buffer = GIMP_BUFFER (managed);
+
+ if (buffer->color_profile)
+ return gimp_color_profile_get_icc_profile (buffer->color_profile, len);
+
+ return NULL;
+}
+
+static GimpColorProfile *
+gimp_buffer_color_managed_get_color_profile (GimpColorManaged *managed)
+{
+ GimpBuffer *buffer = GIMP_BUFFER (managed);
+ static GimpColorProfile *srgb_profile = NULL;
+ static GimpColorProfile *linear_rgb_profile = NULL;
+ static GimpColorProfile *gray_profile = NULL;
+ static GimpColorProfile *linear_gray_profile = NULL;
+ const Babl *format;
+
+ if (buffer->color_profile)
+ return buffer->color_profile;
+
+ format = gimp_buffer_get_format (buffer);
+
+ if (gimp_babl_format_get_base_type (format) == GIMP_GRAY)
+ {
+ if (gimp_babl_format_get_linear (format))
+ {
+ if (! linear_gray_profile)
+ {
+ linear_gray_profile = gimp_color_profile_new_d65_gray_linear ();
+ g_object_add_weak_pointer (G_OBJECT (linear_gray_profile),
+ (gpointer) &linear_gray_profile);
+ }
+
+ return linear_gray_profile;
+ }
+ else
+ {
+ if (! gray_profile)
+ {
+ gray_profile = gimp_color_profile_new_d65_gray_srgb_trc ();
+ g_object_add_weak_pointer (G_OBJECT (gray_profile),
+ (gpointer) &gray_profile);
+ }
+
+ return gray_profile;
+ }
+ }
+ else
+ {
+ if (gimp_babl_format_get_linear (format))
+ {
+ if (! linear_rgb_profile)
+ {
+ linear_rgb_profile = gimp_color_profile_new_rgb_srgb_linear ();
+ g_object_add_weak_pointer (G_OBJECT (linear_rgb_profile),
+ (gpointer) &linear_rgb_profile);
+ }
+
+ return linear_rgb_profile;
+ }
+ else
+ {
+ if (! srgb_profile)
+ {
+ srgb_profile = gimp_color_profile_new_rgb_srgb ();
+ g_object_add_weak_pointer (G_OBJECT (srgb_profile),
+ (gpointer) &srgb_profile);
+ }
+
+ return srgb_profile;
+ }
+ }
+}
+
+static void
+gimp_buffer_color_managed_profile_changed (GimpColorManaged *managed)
+{
+ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (managed));
+}
+
+
+/* public functions */
+
GimpBuffer *
gimp_buffer_new (GeglBuffer *buffer,
const gchar *name,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]