Re: gdk_pixbuf_flip() and eog metafiles
- From: Ole Aamot <Ole Aamot nr no>
- To: Federico Mena Quintero <federico ximian com>
- Cc: eog-list gnome org
- Subject: Re: gdk_pixbuf_flip() and eog metafiles
- Date: 02 May 2001 16:14:12 +0200
Federico Mena Quintero <federico ximian com> writes:
| Ole Aamot nr no writes:
| > I read about gdk_pixbuf_flip() in the list archive.
| I don't think that function exists yet. Should be a 5-minute thing to
| write.
I'll try to finish both (horizontal flipping should work), unless there are
any objections to the appended, premature patch.
2001-05-02 Ole Aamot <oka perceptron nr no>
* gdk-pixbuf/gdk-pixbuf-orient.[ch] (gdk_pixbuf_flip): Horizontal
flipping basicly works, but vertical flipping is not yet
implemented.
* gdk-pixbuf/testpixbuf-orient.c: Test for gdk_pixbuf_flip()
* gdk-pixbuf/Makefile.am: Adding the files above.
I don't think it was so simple, but perhaps you know more efficient ways
to do this?
| > Sometimes orientation correction is necessary before
| > the image is displayed.
|
| NO! NO! NO! What we need to do is to fire-bomb the factories of all
| digital camera manufacturers who are to cheap to put a goddamn mercury
| sensor in their stupid cameras. I paid nearly USD 1000 for my stupid
| camera and it sucks to have to rotate images by hand :)
Oh, this explains why there is a tag named "Orientation"
in the EXIF standard.
| > Is there work on meta files for archiving under way?
|
| Meta files of what?
Meta files would be a way to get eog display an image "correctly" without
modifying the actual images. Anyway, perhaps that is a bad idea for eog.
The ``GNOME Photo collector'' (http://gpc.sourceforge.net) saves various
meta information about images into a postgresql database. Rather useful.
-- Ole
This patch lives at http://www.nr.no/~oka/2001-05-02-gdk_pixbuf_flip.patch
diff --exclude=CVS -ruN gdk-pixbuf/ChangeLog gdk-pixbuf.oka/ChangeLog
--- gdk-pixbuf/ChangeLog Fri Apr 27 02:03:21 2001
+++ gdk-pixbuf.oka/ChangeLog Wed May 2 15:07:25 2001
@@ -1,3 +1,10 @@
+2001-05-02 Ole Aamot <oka perceptron nr no>
+
+ * gdk-pixbuf/gdk-pixbuf-orient.[ch] (gdk_pixbuf_flip): Horizontal
+ flipping basicly works, but vertical flipping is not yet implemented.
+ * gdk-pixbuf/testpixbuf-orient.c: Test for gdk_pixbuf_flip()
+ * gdk-pixbuf/Makefile.am: Adding the files above.
+
2001-04-26 Federico Mena Quintero <federico ximian com>
Released 0.11.0.
diff --exclude=CVS -ruN gdk-pixbuf/gdk-pixbuf/Makefile.am gdk-pixbuf.oka/gdk-pixbuf/Makefile.am
--- gdk-pixbuf/gdk-pixbuf/Makefile.am Thu Mar 1 21:16:28 2001
+++ gdk-pixbuf.oka/gdk-pixbuf/Makefile.am Wed May 2 14:44:33 2001
@@ -150,7 +150,8 @@
builtin_libraries =
endif
-noinst_PROGRAMS = test-gdk-pixbuf testpixbuf testpixbuf-drawable testanimation testpixbuf-scale
+noinst_PROGRAMS = test-gdk-pixbuf testpixbuf testpixbuf-drawable \
+ testanimation testpixbuf-scale testpixbuf-orient
TESTS = test-gdk-pixbuf
DEPS = libgdk_pixbuf.la
@@ -168,12 +169,14 @@
testpixbuf_LDADD = $(LDADDS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS)
testpixbuf_scale_LDADD = $(LDADDS)
+testpixbuf_orient_LDADD = $(LDADDS)
testanimation_LDADD = $(LDADDS) -lgmodule
else
test_gdk_pixbuf_LDADD = $(LDADDS) $(GNOME_LIBS) -lgmodule
testpixbuf_LDADD = $(LDADDS) $(GNOME_LIBS) -lgmodule
testpixbuf_drawable_LDADD = $(LDADDS) $(GNOME_LIBS)
testpixbuf_scale_LDADD = $(LDADDS) $(GNOME_LIBS)
+testpixbuf_orient_LDADD = $(LDADDS) $(GNOME_LIBS)
testanimation_LDADD = $(LDADDS) $(GNOME_LIBS) -lgmodule
endif
@@ -193,6 +196,7 @@
gdk-pixbuf-drawable.c \
gdk-pixbuf-io.c \
gdk-pixbuf-loader.c \
+ gdk-pixbuf-orient.c \
gdk-pixbuf-render.c \
gdk-pixbuf-scale.c \
gdk-pixbuf-util.c \
@@ -228,6 +232,7 @@
gdk-pixbuf.h \
gdk-pixbuf-loader.h \
gdk-pixbuf-features.h \
+ gdk-pixbuf-orient.h \
gdk-pixbuf-xlib.h \
gdk-pixbuf-xlibrgb.h \
$(CANVAS_PIXBUF_HEADERFILES)
diff --exclude=CVS -ruN gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-orient.c gdk-pixbuf.oka/gdk-pixbuf/gdk-pixbuf-orient.c
--- gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-orient.c Thu Jan 1 01:00:00 1970
+++ gdk-pixbuf.oka/gdk-pixbuf/gdk-pixbuf-orient.c Wed May 2 15:00:32 2001
@@ -0,0 +1,166 @@
+/* GdkPixbuf library - Orientation functions.
+ *
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gdk-pixbuf-private.h"
+
+
+
+/**
+ * gdk_pixbuf_flip:
+ * @pixbuf: a #GdkPixbuf
+ * @horizontal: Whether to flip in horizontal direction. If @horizontal is
+ * #TRUE, then flip around in horizontal direction.
+ * @vertical: Whether to flip in vertical direction. If @vertical is #TRUE,
+ * then flip in vertical direction. (NOT IMPLEMENTED YET!)
+ * @in_place: If in_place is #TRUE, the original @pixbuf is modified.
+ *
+ * Flips @pixbuf around horizontally and/or vertically.
+ *
+ * Return value: The original @pixbuf is modified and returned, if
+ * in_place is #TRUE. If in_place is #FALSE, a newly created pixbuf
+ * with a reference count of 1 is returned.
+ **/
+GdkPixbuf *
+gdk_pixbuf_flip (GdkPixbuf *pixbuf,
+ gboolean horizontal,
+ gboolean vertical,
+ gboolean in_place)
+{
+ GdkPixbuf *dest;
+ gint src_has_alpha;
+ gint width, height, src_rs;
+ gint dst_rs;
+
+ guchar *src_pix, *src_p;
+ guchar *dst_pix, *dst_p;
+
+ gint i, j;
+ gint alpha;
+
+ g_warning ("%s is not finished.\n", __PRETTY_FUNCTION__);
+
+ g_return_if_fail (pixbuf != NULL);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ src_has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+
+ alpha = src_has_alpha ? 4 : 3;
+
+ src_rs = gdk_pixbuf_get_rowstride (pixbuf);
+ src_pix = gdk_pixbuf_get_pixels (pixbuf);
+
+ if (in_place==TRUE) {
+ dest = pixbuf;
+ dst_rs = gdk_pixbuf_get_rowstride (pixbuf);
+ dst_pix = gdk_pixbuf_get_pixels (pixbuf);
+ } else {
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src_has_alpha, 8, width, height);
+ dst_rs = gdk_pixbuf_get_rowstride (dest);
+ dst_pix = gdk_pixbuf_get_pixels (dest);
+ }
+
+ if (horizontal==TRUE) {
+ for (i = 0; i < height; i++) {
+ src_p = src_pix + (src_rs * i);
+ dst_p = dst_pix + (dst_rs * i);
+
+ for (j = 0; j < width; j++) {
+ *(dst_p++) = *(src_p++);
+ *(dst_p++) = *(src_p++);
+ *(dst_p++) = *(src_p++);
+ if (src_has_alpha)
+ *(dst_p) = *(src_p++);
+ dst_p = dst_p - (alpha + 3);
+ }
+ }
+ }
+
+ return dest;
+}
+
+
+
+/**
+ * gdk_pixbuf_rotate:
+ * @pixbuf: a #GdkPixbuf
+ * @angle: angle modulo 90-degree (ie 90, 180, 270 degrees angle)
+ * @in_place: If in_place is #TRUE, the original data is modified
+ * and the same value as @pixbuf is returned.
+ *
+ * Rotates @pixbuf by 90-degree multiples in the counter-clockwise
+ * direction.
+ *
+ * Return value: The original @pixbuf is modified and returned, if
+ * in_place is #TRUE.
+ * If in_place is false, we try to allocate a new #GdkPixbuf and return
+ * NULL on failure; on success we write the flipped data there.
+ **/
+
+GdkPixbuf *
+gdk_pixbuf_rotate (GdkPixbuf *pixbuf,
+ gint angle,
+ gboolean in_place)
+{
+ GdkPixbuf *dest;
+ gint src_has_alpha;
+
+ gint src_w, src_h, src_rs;
+ gint dst_w, dst_h, dst_rs;
+
+ guchar *src_pix, *src_p;
+ guchar *dst_pix, *dst_p;
+
+ gint i, j;
+ gint alpha;
+
+ g_warning ("%s is not finished.\n", __PRETTY_FUNCTION__);
+
+ g_return_val_if_fail (pixbuf != NULL, NULL);
+ g_return_val_if_fail (angle % 90 == 0, NULL);
+
+ src_w = gdk_pixbuf_get_width (pixbuf);
+ src_h = gdk_pixbuf_get_height (pixbuf);
+
+ src_has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ src_rs = gdk_pixbuf_get_rowstride (pixbuf);
+ src_pix = gdk_pixbuf_get_pixels (pixbuf);
+
+ alpha = (src_has_alpha ? 4 : 3);
+
+ /* NOT FINISHED! */
+
+ if (in_place==TRUE) {
+ dest = pixbuf;
+ dst_rs = gdk_pixbuf_get_rowstride (pixbuf);
+ dst_pix = gdk_pixbuf_get_pixels (pixbuf);
+ } else {
+ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src_has_alpha, 8, dst_w, dst_h);
+ dst_rs = gdk_pixbuf_get_rowstride (dest);
+ dst_pix = gdk_pixbuf_get_pixels (dest);
+ }
+ return dest;
+}
+
+
+
+
+
diff --exclude=CVS -ruN gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-orient.h gdk-pixbuf.oka/gdk-pixbuf/gdk-pixbuf-orient.h
--- gdk-pixbuf/gdk-pixbuf/gdk-pixbuf-orient.h Thu Jan 1 01:00:00 1970
+++ gdk-pixbuf.oka/gdk-pixbuf/gdk-pixbuf-orient.h Wed May 2 14:43:53 2001
@@ -0,0 +1,37 @@
+/* GdkPixbuf library - Orientation functions.
+ *
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GDK_PIXBUF_ORIENT_H
+#define GDK_PIXBUF_ORIENT_H
+
+#include "gdk-pixbuf.h"
+
+GdkPixbuf *gdk_pixbuf_flip (GdkPixbuf *pixbuf,
+ gboolean horizontal,
+ gboolean vertical,
+ gboolean in_place);
+
+GdkPixbuf *gdk_pixbuf_rotate (GdkPixbuf *pixbuf,
+ int angle,
+ gboolean in_place);
+
+#endif /* GDK_PIXBUF_ORIENT_H */
+
+
diff --exclude=CVS -ruN gdk-pixbuf/gdk-pixbuf/testpixbuf-orient.c gdk-pixbuf.oka/gdk-pixbuf/testpixbuf-orient.c
--- gdk-pixbuf/gdk-pixbuf/testpixbuf-orient.c Thu Jan 1 01:00:00 1970
+++ gdk-pixbuf.oka/gdk-pixbuf/testpixbuf-orient.c Wed May 2 14:53:34 2001
@@ -0,0 +1,165 @@
+/* testpix-orient.c -- Testing orientation functions
+ *
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * 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.
+ */
+
+
+#include <stdio.h>
+#include <png.h>
+
+#include "gdk-pixbuf.h"
+#include "gdk-pixbuf-orient.h"
+
+#define FLIPH TRUE
+#define FLIPV TRUE
+
+gboolean
+save_pixbuf_to_file_as_png (GdkPixbuf *pixbuf, char *filename)
+{
+ FILE *handle;
+ char *buffer;
+ gboolean has_alpha;
+ int width, height, depth, rowstride;
+ guchar *pixels;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_text text[2];
+ int i;
+
+ g_return_val_if_fail (pixbuf != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (filename[0] != '\0', FALSE);
+
+ handle = fopen (filename, "wb");
+ if (handle == NULL)
+ return FALSE;
+
+ png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (png_ptr == NULL) {
+ fclose (handle);
+ return FALSE;
+ }
+
+ info_ptr = png_create_info_struct (png_ptr);
+ if (info_ptr == NULL) {
+ png_destroy_write_struct (&png_ptr, (png_infopp)NULL);
+ fclose (handle);
+ return FALSE;
+ }
+
+ if (setjmp (png_ptr->jmpbuf)) {
+ png_destroy_write_struct (&png_ptr, &info_ptr);
+ fclose (handle);
+ return FALSE;
+ }
+
+ png_init_io (png_ptr, handle);
+
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ depth = gdk_pixbuf_get_bits_per_sample (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ png_set_IHDR (png_ptr, info_ptr, width, height,
+ depth, PNG_COLOR_TYPE_RGB_ALPHA,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ /* Some text to go with the png image */
+ text[0].key = "Title";
+ text[0].text = filename;
+ text[0].compression = PNG_TEXT_COMPRESSION_NONE;
+ text[1].key = "Software";
+ text[1].text = "testpixbuf-orient (gdk-pixbuf)";
+ text[1].compression = PNG_TEXT_COMPRESSION_NONE;
+ png_set_text (png_ptr, info_ptr, text, 2);
+
+ /* Write header data */
+ png_write_info (png_ptr, info_ptr);
+
+ /* if there is no alpha in the data, allocate buffer to expand into */
+ if (has_alpha)
+ buffer = NULL;
+ else
+ buffer = g_malloc(4 * width);
+
+ /* pump the raster data into libpng, one scan line at a time */
+ for (i = 0; i < height; i++) {
+ if (has_alpha) {
+ png_bytep row_pointer = pixels;
+ png_write_row (png_ptr, row_pointer);
+ } else {
+ /* expand RGB to RGBA using an opaque alpha value */
+ int x;
+ char *buffer_ptr = buffer;
+ char *source_ptr = pixels;
+ for (x = 0; x < width; x++) {
+ *buffer_ptr++ = *source_ptr++;
+ *buffer_ptr++ = *source_ptr++;
+ *buffer_ptr++ = *source_ptr++;
+ *buffer_ptr++ = 255;
+ }
+ png_write_row (png_ptr, (png_bytep) buffer);
+ }
+ pixels += rowstride;
+ }
+
+ png_write_end (png_ptr, info_ptr);
+ png_destroy_write_struct (&png_ptr, &info_ptr);
+
+ g_free (buffer);
+
+ fclose (handle);
+ return TRUE;
+}
+
+
+
+int
+main(int argc, char **argv)
+{
+ GdkPixbuf *pixbuf, *flippedout_h, *flippedout_v, *flippedout_hv;
+
+ int angle;
+
+ gtk_init (&argc, &argv);
+ gdk_rgb_init ();
+
+ if (argc != 2) {
+ fprintf (stderr, "Usage: testpixbuf-orient FILE\n");
+ exit (1);
+ }
+
+ pixbuf = gdk_pixbuf_new_from_file (argv[1]);
+
+ if (!pixbuf) {
+ fprintf (stderr, "Cannot load %s\n", argv[1]);
+ exit(1);
+ }
+
+ flippedout_h = gdk_pixbuf_flip(pixbuf, TRUE, FALSE, FALSE);
+/* flippedout_v = gdk_pixbuf_flip(pixbuf, FALSE, TRUE, FALSE); */
+
+ save_pixbuf_to_file_as_png (pixbuf,"testorient-unflipped-original.png");
+ save_pixbuf_to_file_as_png (flippedout_h,"testorient-flipped-horizontal.png");
+/* save_pixbuf_to_file_as_png (flippedout_v,"testorient-flipped-vertical.png"); */
+
+ exit(0);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]