summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2012-06-04 00:43:01 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-06-04 00:43:01 -0400
commitf3b24d38bbe217bbfe7f19772dc7808edda8af85 (patch)
treeb2c2228d7cabc8c4db6819b428d2fc6111170d69
parent7ef52eb259b73e56350efe9b3abae6c5dfd31034 (diff)
upscale demo
-rw-r--r--demos/Makefile.am4
-rw-r--r--demos/upscale.c164
2 files changed, 167 insertions, 1 deletions
diff --git a/demos/Makefile.am b/demos/Makefile.am
index 9aac1f5e..a87bc34f 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -20,7 +20,8 @@ DEMOS = \
trap-test \
tri-test \
quad2quad \
- checkerboard
+ checkerboard \
+ upscale
EXTRA_DIST = parrot.c parrot.jpg
@@ -35,6 +36,7 @@ convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
radial_test_SOURCES = radial-test.c $(GTK_UTILS)
tri_test_SOURCES = tri-test.c $(GTK_UTILS)
checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
+upscale_SOURCES = upscale.c $(GTK_UTILS)
noinst_PROGRAMS = $(DEMOS)
diff --git a/demos/upscale.c b/demos/upscale.c
new file mode 100644
index 00000000..02d4ec32
--- /dev/null
+++ b/demos/upscale.c
@@ -0,0 +1,164 @@
+/* Copyright (C) 2005, 2008 Red Hat, Inc.
+ * Copyright © 2002 University of Southern California
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 <math.h>
+#include <gtk/gtk.h>
+#include <pixman.h>
+#include <stdlib.h>
+#include "gtk-utils.h"
+
+static pixman_image_t *
+pixman_image_from_file (const char *filename)
+{
+ GdkPixbuf *pixbuf;
+ pixman_image_t *image;
+ int width, height;
+ uint32_t *data, *d;
+ uint8_t *gdk_data;
+ int n_channels;
+ int j, i;
+ int stride;
+
+ if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
+ return NULL;
+
+ image = NULL;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ gdk_data = gdk_pixbuf_get_pixels (pixbuf);
+ stride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ if (!(data = malloc (width * height * sizeof (uint32_t))))
+ goto out;
+
+ d = data;
+ for (j = 0; j < height; ++j)
+ {
+ uint8_t *gdk_line = gdk_data;
+
+ for (i = 0; i < width; ++i)
+ {
+ int r, g, b, a;
+ uint32_t pixel;
+
+ r = gdk_line[0];
+ g = gdk_line[1];
+ b = gdk_line[2];
+
+ if (n_channels == 4)
+ a = gdk_line[3];
+ else
+ a = 0xff;
+
+ r = (r * a + 127) / 255;
+ g = (g * a + 127) / 255;
+ b = (b * a + 127) / 255;
+
+ pixel = (a << 24) | (r << 16) | (g << 8) | b;
+
+ *d++ = pixel;
+ gdk_line += n_channels;
+ }
+
+ gdk_data += stride;
+ }
+
+ image = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, width, height, data, width * 4);
+
+out:
+ g_object_unref (pixbuf);
+ return image;
+}
+
+typedef struct pixman_f_transform pixman_f_transform_t;
+
+static pixman_image_t *
+scale_image (pixman_image_t *image, double scale_factor)
+{
+ pixman_image_t *result;
+ int old_width = pixman_image_get_width (image);
+ int old_height = pixman_image_get_height (image);
+ int new_width = sqrt (0.5 * old_width * scale_factor * 0.5 * old_width * scale_factor +
+ 0.5 * old_height * scale_factor * 0.5 * old_height * scale_factor) * 2;
+ int new_height = new_width;
+ pixman_f_transform_t ftransform;
+ pixman_transform_t transform;
+
+ result = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, new_width, new_height, NULL, -1);
+
+ pixman_f_transform_init_translate (
+ &ftransform, - old_width / 2.0, - old_height / 2.0);
+
+ pixman_f_transform_scale (
+ &ftransform, NULL, scale_factor, scale_factor);
+
+ pixman_f_transform_rotate (
+ &ftransform, NULL, sin (30.0), cos (30.0));
+
+ pixman_f_transform_translate (
+ &ftransform, NULL, 0.5 * new_width, 0.5 * new_height);
+
+ if (!pixman_f_transform_invert (&ftransform, &ftransform))
+ printf ("no invert\n");
+
+ pixman_transform_from_pixman_f_transform (&transform, &ftransform);
+
+ pixman_image_set_transform (image, &transform);
+#if 0
+ pixman_image_set_sampling (image, PIXMAN_SAMPLE_BOX);
+#endif
+
+ pixman_image_composite32 (PIXMAN_OP_SRC, image, NULL, result,
+ 0, 0, 0, 0, 0, 0, new_width, new_height);
+
+ return result;
+}
+
+int
+main (int argc, char **argv)
+{
+ pixman_image_t *image, *result;
+ char *filename;
+
+ gtk_init (&argc, &argv);
+
+ if (argc < 2)
+ {
+ printf ("%s <image file>\n", argv[0]);
+ return -1;
+ }
+
+ filename = argv[1];
+
+ if (!(image = pixman_image_from_file (filename)))
+ {
+ printf ("Could not read %s\n", filename);
+ return -1;
+ }
+
+ result = scale_image (image, 1/4.0);
+
+ show_image (result);
+
+ return 0;
+}