[f-spot] Re-add f_pixbuf_to_cairo_surface.



commit fc0a130f2ade576ac0f9d68f0887236b5596108d
Author: Ruben Vermeersch <ruben savanne be>
Date:   Thu Jul 22 16:45:51 2010 +0200

    Re-add f_pixbuf_to_cairo_surface.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=624776

 lib/libfspot/Makefile.am      |    2 +
 lib/libfspot/f-pixbuf-utils.c |  228 +++++++++++++++++++++++++++++++++++++++++
 lib/libfspot/f-pixbuf-utils.h |   41 ++++++++
 3 files changed, 271 insertions(+), 0 deletions(-)
---
diff --git a/lib/libfspot/Makefile.am b/lib/libfspot/Makefile.am
index 008d2e6..a002d13 100644
--- a/lib/libfspot/Makefile.am
+++ b/lib/libfspot/Makefile.am
@@ -18,6 +18,8 @@ libfspot_la_SOURCES =				\
 	f-image-surface.c			\
 	f-image-surface.h			\
 	f-pixbuf-unsharp.c			\
+	f-pixbuf-utils.c			\
+	f-pixbuf-utils.h			\
 	f-screen-utils.c
 
 libfspot_la_LIBADD = 					\
diff --git a/lib/libfspot/f-pixbuf-utils.c b/lib/libfspot/f-pixbuf-utils.c
new file mode 100644
index 0000000..bc5090a
--- /dev/null
+++ b/lib/libfspot/f-pixbuf-utils.c
@@ -0,0 +1,228 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* f-pixbuf-utils.c
+ *
+ * Copyright (C) 2001, 2002, 2003 The Free Software Foundation, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Paolo Bacchilega <paolo bacch tin it>
+ *
+ * Adapted by Ettore Perazzoli <ettore perazzoli org>
+ */
+
+/* Some bits are based upon the GIMP source code, the original copyright
+ * note follows:
+ *
+ * The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ */
+
+
+#include <config.h>
+
+#include "f-pixbuf-utils.h"
+
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+#include <errno.h>
+#include <gdk/gdk.h>
+#include "f-image-surface.h"
+
+/* Public functions.  */
+
+int
+f_pixbuf_get_image_size (GdkPixbuf *pixbuf)
+{
+	int width, height;
+
+	width = gdk_pixbuf_get_width (pixbuf);
+	height = gdk_pixbuf_get_height (pixbuf);
+
+	return MAX (width, height);
+}
+
+int
+f_pixbuf_get_scaled_width (GdkPixbuf *pixbuf,
+			   int size)
+{
+	int orig_width, orig_height;
+
+	orig_width = gdk_pixbuf_get_width (pixbuf);
+	orig_height = gdk_pixbuf_get_height (pixbuf);
+
+	if (orig_width > orig_height)
+		return size;
+	else
+		return size * ((double) orig_width / orig_height);
+}
+
+int
+f_pixbuf_get_scaled_height (GdkPixbuf *pixbuf,
+			    int size)
+{
+	int orig_width, orig_height;
+
+	orig_width = gdk_pixbuf_get_width (pixbuf);
+	orig_height = gdk_pixbuf_get_height (pixbuf);
+
+	if (orig_width > orig_height)
+		return size * ((double) orig_height / orig_width);
+	else
+		return size;
+}
+
+cairo_surface_t *
+f_pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
+{
+  gint width = gdk_pixbuf_get_width (pixbuf);
+  gint height = gdk_pixbuf_get_height (pixbuf);
+  guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+  int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+  int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+  guchar *cairo_pixels;
+  cairo_format_t format;
+  cairo_surface_t *surface;
+  int j;
+
+  if (n_channels == 3)
+    format = CAIRO_FORMAT_RGB24;
+  else
+    format = CAIRO_FORMAT_ARGB32;
+
+  surface = f_image_surface_create (format, width, height);
+  cairo_pixels = (guchar *)f_image_surface_get_data (surface);
+
+  for (j = height; j; j--)
+    {
+      guchar *p = gdk_pixels;
+      guchar *q = cairo_pixels;
+
+      if (n_channels == 3)
+	{
+	  guchar *end = p + 3 * width;
+	  
+	  while (p < end)
+	    {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+	      q[0] = p[2];
+	      q[1] = p[1];
+	      q[2] = p[0];
+#else	  
+	      q[1] = p[0];
+	      q[2] = p[1];
+	      q[3] = p[2];
+#endif
+	      p += 3;
+	      q += 4;
+	    }
+	}
+      else
+	{
+	  guchar *end = p + 4 * width;
+	  guint t1,t2,t3;
+	    
+#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x7f; d = ((t >> 8) + t) >> 8; } G_STMT_END
+
+	  while (p < end)
+	    {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+	      MULT(q[0], p[2], p[3], t1);
+	      MULT(q[1], p[1], p[3], t2);
+	      MULT(q[2], p[0], p[3], t3);
+	      q[3] = p[3];
+#else	  
+	      q[0] = p[3];
+	      MULT(q[1], p[0], p[3], t1);
+	      MULT(q[2], p[1], p[3], t2);
+	      MULT(q[3], p[2], p[3], t3);
+#endif
+	      
+	      p += 4;
+	      q += 4;
+	    }
+	  
+#undef MULT
+	}
+
+      gdk_pixels += gdk_rowstride;
+      cairo_pixels += 4 * width;
+    }
+
+  return surface;
+}
+
+GdkPixbuf *
+f_pixbuf_from_cairo_surface (cairo_surface_t *source)
+{
+  gint width = cairo_image_surface_get_width (source);
+  gint height = cairo_image_surface_get_height (source);
+  GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+				      TRUE,
+				      8,
+				      width,
+				      height);
+
+  guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
+  int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+  int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+  cairo_format_t format;
+  cairo_surface_t *surface;
+  cairo_t *ctx;
+  static const cairo_user_data_key_t key;
+  int j;
+
+  format = f_image_surface_get_format (source);
+  surface = cairo_image_surface_create_for_data (gdk_pixels,
+						 format,
+						 width, height, gdk_rowstride);
+  ctx = cairo_create (surface);
+  cairo_set_source_surface (ctx, source, 0, 0);
+  if (format == CAIRO_FORMAT_ARGB32)
+	  cairo_mask_surface (ctx, source, 0, 0);
+  else
+	  cairo_paint (ctx);
+
+  for (j = height; j; j--)
+    {
+      guchar *p = gdk_pixels;
+      guchar *end = p + 4 * width;
+      guchar tmp;
+
+      while (p < end)
+	{
+	  tmp = p[0];
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+	  p[0] = p[2];
+	  p[2] = tmp;
+#else	  
+	  p[0] = p[1];
+	  p[1] = p[2];
+	  p[2] = p[3];
+	  p[3] = tmp;
+#endif
+	  p += 4;
+	}
+
+      gdk_pixels += gdk_rowstride;
+    }
+
+  cairo_destroy (ctx);
+  cairo_surface_destroy (surface);
+  return pixbuf;
+}
diff --git a/lib/libfspot/f-pixbuf-utils.h b/lib/libfspot/f-pixbuf-utils.h
new file mode 100644
index 0000000..a0ae7dd
--- /dev/null
+++ b/lib/libfspot/f-pixbuf-utils.h
@@ -0,0 +1,41 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* f-pixbuf-utils.h
+ *
+ * Copyright (C) 2003  Ettore Perazzoli
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ettore Perazzoli <ettore ximian com>
+ */
+
+#ifndef _F_PIXBUF_UTILS_H_
+#define _F_PIXBUF_UTILS_H_
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+
+/* Return the largest between height and width of the specified PIXBUF.  */
+int f_pixbuf_get_image_size (GdkPixbuf *pixbuf);
+
+/* Return the normalized width for the specified PIXBUF at the specified
+   thumbnail SIZE.  */
+int f_pixbuf_get_scaled_width (GdkPixbuf *pixbuf, int size);
+
+/* Return the normalized height for the specified PIXBUF at the specified
+   thumbnail SIZE.  */
+int f_pixbuf_get_scaled_height (GdkPixbuf *pixbuf, int size);
+
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]