diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-06-04 00:43:01 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-06-04 00:43:01 -0400 |
commit | f3b24d38bbe217bbfe7f19772dc7808edda8af85 (patch) | |
tree | b2c2228d7cabc8c4db6819b428d2fc6111170d69 | |
parent | 7ef52eb259b73e56350efe9b3abae6c5dfd31034 (diff) |
upscale demo
-rw-r--r-- | demos/Makefile.am | 4 | ||||
-rw-r--r-- | demos/upscale.c | 164 |
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; +} |