gtk-utils.c revision f4f78bb6
16ba797d6Smrg#include <gtk/gtk.h>
26ba797d6Smrg#include <config.h>
39ad247e8Sjmcneill#include "../test/utils.h"
46ba797d6Smrg#include "gtk-utils.h"
56ba797d6Smrg
6f4f78bb6Smrgpixman_image_t *
7f4f78bb6Smrgpixman_image_from_file (const char *filename, pixman_format_code_t format)
8f4f78bb6Smrg{
9f4f78bb6Smrg    GdkPixbuf *pixbuf;
10f4f78bb6Smrg    pixman_image_t *image;
11f4f78bb6Smrg    int width, height;
12f4f78bb6Smrg    uint32_t *data, *d;
13f4f78bb6Smrg    uint8_t *gdk_data;
14f4f78bb6Smrg    int n_channels;
15f4f78bb6Smrg    int j, i;
16f4f78bb6Smrg    int stride;
17f4f78bb6Smrg
18f4f78bb6Smrg    if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
19f4f78bb6Smrg	return NULL;
20f4f78bb6Smrg
21f4f78bb6Smrg    image = NULL;
22f4f78bb6Smrg
23f4f78bb6Smrg    width = gdk_pixbuf_get_width (pixbuf);
24f4f78bb6Smrg    height = gdk_pixbuf_get_height (pixbuf);
25f4f78bb6Smrg    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
26f4f78bb6Smrg    gdk_data = gdk_pixbuf_get_pixels (pixbuf);
27f4f78bb6Smrg    stride = gdk_pixbuf_get_rowstride (pixbuf);
28f4f78bb6Smrg
29f4f78bb6Smrg    if (!(data = malloc (width * height * sizeof (uint32_t))))
30f4f78bb6Smrg	goto out;
31f4f78bb6Smrg
32f4f78bb6Smrg    d = data;
33f4f78bb6Smrg    for (j = 0; j < height; ++j)
34f4f78bb6Smrg    {
35f4f78bb6Smrg	uint8_t *gdk_line = gdk_data;
36f4f78bb6Smrg
37f4f78bb6Smrg	for (i = 0; i < width; ++i)
38f4f78bb6Smrg	{
39f4f78bb6Smrg	    int r, g, b, a;
40f4f78bb6Smrg	    uint32_t pixel;
41f4f78bb6Smrg
42f4f78bb6Smrg	    r = gdk_line[0];
43f4f78bb6Smrg	    g = gdk_line[1];
44f4f78bb6Smrg	    b = gdk_line[2];
45f4f78bb6Smrg
46f4f78bb6Smrg	    if (n_channels == 4)
47f4f78bb6Smrg		a = gdk_line[3];
48f4f78bb6Smrg	    else
49f4f78bb6Smrg		a = 0xff;
50f4f78bb6Smrg
51f4f78bb6Smrg	    r = (r * a + 127) / 255;
52f4f78bb6Smrg	    g = (g * a + 127) / 255;
53f4f78bb6Smrg	    b = (b * a + 127) / 255;
54f4f78bb6Smrg
55f4f78bb6Smrg	    pixel = (a << 24) | (r << 16) | (g << 8) | b;
56f4f78bb6Smrg
57f4f78bb6Smrg	    *d++ = pixel;
58f4f78bb6Smrg	    gdk_line += n_channels;
59f4f78bb6Smrg	}
60f4f78bb6Smrg
61f4f78bb6Smrg	gdk_data += stride;
62f4f78bb6Smrg    }
63f4f78bb6Smrg
64f4f78bb6Smrg    image = pixman_image_create_bits (
65f4f78bb6Smrg	format, width, height, data, width * 4);
66f4f78bb6Smrg
67f4f78bb6Smrgout:
68f4f78bb6Smrg    g_object_unref (pixbuf);
69f4f78bb6Smrg    return image;
70f4f78bb6Smrg}
71f4f78bb6Smrg
726ba797d6SmrgGdkPixbuf *
736ba797d6Smrgpixbuf_from_argb32 (uint32_t *bits,
746ba797d6Smrg		    int width,
756ba797d6Smrg		    int height,
766ba797d6Smrg		    int stride)
776ba797d6Smrg{
786ba797d6Smrg    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
796ba797d6Smrg					8, width, height);
806ba797d6Smrg    int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
816ba797d6Smrg    guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
829ad247e8Sjmcneill    int i;
836ba797d6Smrg
849ad247e8Sjmcneill    for (i = 0; i < height; ++i)
859ad247e8Sjmcneill    {
869ad247e8Sjmcneill	uint32_t *src_row = &bits[i * (stride / 4)];
879ad247e8Sjmcneill	uint32_t *dst_row = p_bits + i * (p_stride / 4);
886ba797d6Smrg
899ad247e8Sjmcneill	a8r8g8b8_to_rgba_np (dst_row, src_row, width);
906ba797d6Smrg    }
919ad247e8Sjmcneill
926ba797d6Smrg    return pixbuf;
936ba797d6Smrg}
946ba797d6Smrg
956ba797d6Smrgstatic gboolean
966ba797d6Smrgon_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data)
976ba797d6Smrg{
98f4f78bb6Smrg    pixman_image_t *pimage = data;
99f4f78bb6Smrg    int width = pixman_image_get_width (pimage);
100f4f78bb6Smrg    int height = pixman_image_get_height (pimage);
101f4f78bb6Smrg    int stride = pixman_image_get_stride (pimage);
102f4f78bb6Smrg    cairo_surface_t *cimage;
103f4f78bb6Smrg    cairo_format_t format;
104f4f78bb6Smrg    cairo_t *cr;
105f4f78bb6Smrg
106f4f78bb6Smrg    if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8)
107f4f78bb6Smrg	format = CAIRO_FORMAT_RGB24;
108f4f78bb6Smrg    else
109f4f78bb6Smrg	format = CAIRO_FORMAT_ARGB32;
110f4f78bb6Smrg
111f4f78bb6Smrg    cimage = cairo_image_surface_create_for_data (
112f4f78bb6Smrg	(uint8_t *)pixman_image_get_data (pimage),
113f4f78bb6Smrg	format, width, height, stride);
1146ba797d6Smrg
115f4f78bb6Smrg    cr = gdk_cairo_create (widget->window);
116f4f78bb6Smrg
117f4f78bb6Smrg    cairo_rectangle (cr, 0, 0, width, height);
118f4f78bb6Smrg    cairo_set_source_surface (cr, cimage, 0, 0);
119f4f78bb6Smrg    cairo_fill (cr);
120f4f78bb6Smrg
121f4f78bb6Smrg    cairo_destroy (cr);
122f4f78bb6Smrg    cairo_surface_destroy (cimage);
1236ba797d6Smrg
1246ba797d6Smrg    return TRUE;
1256ba797d6Smrg}
1266ba797d6Smrg
1276ba797d6Smrgvoid
1286ba797d6Smrgshow_image (pixman_image_t *image)
1296ba797d6Smrg{
1306ba797d6Smrg    GtkWidget *window;
1319ad247e8Sjmcneill    int width, height;
1326ba797d6Smrg    int argc;
1336ba797d6Smrg    char **argv;
1346ba797d6Smrg    char *arg0 = g_strdup ("pixman-test-program");
1356ba797d6Smrg    pixman_format_code_t format;
1369ad247e8Sjmcneill    pixman_image_t *copy;
1376ba797d6Smrg
1386ba797d6Smrg    argc = 1;
1396ba797d6Smrg    argv = (char **)&arg0;
1406ba797d6Smrg
1416ba797d6Smrg    gtk_init (&argc, &argv);
1426ba797d6Smrg
1436ba797d6Smrg    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1446ba797d6Smrg    width = pixman_image_get_width (image);
1456ba797d6Smrg    height = pixman_image_get_height (image);
1466ba797d6Smrg
1476ba797d6Smrg    gtk_window_set_default_size (GTK_WINDOW (window), width, height);
1489ad247e8Sjmcneill
1499ad247e8Sjmcneill    format = pixman_image_get_format (image);
1509ad247e8Sjmcneill
151f4f78bb6Smrg    /* We always display the image as if it contains sRGB data. That
152f4f78bb6Smrg     * means that no conversion should take place when the image
153f4f78bb6Smrg     * has the a8r8g8b8_sRGB format.
1549ad247e8Sjmcneill     */
1559ad247e8Sjmcneill    switch (format)
1569ad247e8Sjmcneill    {
1579ad247e8Sjmcneill    case PIXMAN_a8r8g8b8_sRGB:
1589ad247e8Sjmcneill    case PIXMAN_a8r8g8b8:
159f4f78bb6Smrg    case PIXMAN_x8r8g8b8:
1609ad247e8Sjmcneill	copy = pixman_image_ref (image);
1619ad247e8Sjmcneill	break;
1629ad247e8Sjmcneill
1639ad247e8Sjmcneill    default:
1649ad247e8Sjmcneill	copy = pixman_image_create_bits (PIXMAN_a8r8g8b8,
1659ad247e8Sjmcneill					 width, height, NULL, -1);
1669ad247e8Sjmcneill	pixman_image_composite32 (PIXMAN_OP_SRC,
1679ad247e8Sjmcneill				  image, NULL, copy,
1689ad247e8Sjmcneill				  0, 0, 0, 0, 0, 0,
1699ad247e8Sjmcneill				  width, height);
1709ad247e8Sjmcneill	break;
1719ad247e8Sjmcneill    }
1729ad247e8Sjmcneill
173f4f78bb6Smrg    g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), copy);
1746ba797d6Smrg    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
1756ba797d6Smrg
1766ba797d6Smrg    gtk_widget_show (window);
1776ba797d6Smrg
1786ba797d6Smrg    gtk_main ();
1796ba797d6Smrg}
180