gtk-utils.c revision 14b11b2b
16ba797d6Smrg#include <gtk/gtk.h>
214b11b2bSmrg#ifdef HAVE_CONFIG_H
314b11b2bSmrg#include <pixman-config.h>
414b11b2bSmrg#endif
514b11b2bSmrg#include "utils.h"
66ba797d6Smrg#include "gtk-utils.h"
76ba797d6Smrg
8f4f78bb6Smrgpixman_image_t *
9f4f78bb6Smrgpixman_image_from_file (const char *filename, pixman_format_code_t format)
10f4f78bb6Smrg{
11f4f78bb6Smrg    GdkPixbuf *pixbuf;
12f4f78bb6Smrg    pixman_image_t *image;
13f4f78bb6Smrg    int width, height;
14f4f78bb6Smrg    uint32_t *data, *d;
15f4f78bb6Smrg    uint8_t *gdk_data;
16f4f78bb6Smrg    int n_channels;
17f4f78bb6Smrg    int j, i;
18f4f78bb6Smrg    int stride;
19f4f78bb6Smrg
20f4f78bb6Smrg    if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
21f4f78bb6Smrg	return NULL;
22f4f78bb6Smrg
23f4f78bb6Smrg    image = NULL;
24f4f78bb6Smrg
25f4f78bb6Smrg    width = gdk_pixbuf_get_width (pixbuf);
26f4f78bb6Smrg    height = gdk_pixbuf_get_height (pixbuf);
27f4f78bb6Smrg    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
28f4f78bb6Smrg    gdk_data = gdk_pixbuf_get_pixels (pixbuf);
29f4f78bb6Smrg    stride = gdk_pixbuf_get_rowstride (pixbuf);
30f4f78bb6Smrg
31f4f78bb6Smrg    if (!(data = malloc (width * height * sizeof (uint32_t))))
32f4f78bb6Smrg	goto out;
33f4f78bb6Smrg
34f4f78bb6Smrg    d = data;
35f4f78bb6Smrg    for (j = 0; j < height; ++j)
36f4f78bb6Smrg    {
37f4f78bb6Smrg	uint8_t *gdk_line = gdk_data;
38f4f78bb6Smrg
39f4f78bb6Smrg	for (i = 0; i < width; ++i)
40f4f78bb6Smrg	{
41f4f78bb6Smrg	    int r, g, b, a;
42f4f78bb6Smrg	    uint32_t pixel;
43f4f78bb6Smrg
44f4f78bb6Smrg	    r = gdk_line[0];
45f4f78bb6Smrg	    g = gdk_line[1];
46f4f78bb6Smrg	    b = gdk_line[2];
47f4f78bb6Smrg
48f4f78bb6Smrg	    if (n_channels == 4)
49f4f78bb6Smrg		a = gdk_line[3];
50f4f78bb6Smrg	    else
51f4f78bb6Smrg		a = 0xff;
52f4f78bb6Smrg
53f4f78bb6Smrg	    r = (r * a + 127) / 255;
54f4f78bb6Smrg	    g = (g * a + 127) / 255;
55f4f78bb6Smrg	    b = (b * a + 127) / 255;
56f4f78bb6Smrg
57f4f78bb6Smrg	    pixel = (a << 24) | (r << 16) | (g << 8) | b;
58f4f78bb6Smrg
59f4f78bb6Smrg	    *d++ = pixel;
60f4f78bb6Smrg	    gdk_line += n_channels;
61f4f78bb6Smrg	}
62f4f78bb6Smrg
63f4f78bb6Smrg	gdk_data += stride;
64f4f78bb6Smrg    }
65f4f78bb6Smrg
66f4f78bb6Smrg    image = pixman_image_create_bits (
67f4f78bb6Smrg	format, width, height, data, width * 4);
68f4f78bb6Smrg
69f4f78bb6Smrgout:
70f4f78bb6Smrg    g_object_unref (pixbuf);
71f4f78bb6Smrg    return image;
72f4f78bb6Smrg}
73f4f78bb6Smrg
746ba797d6SmrgGdkPixbuf *
756ba797d6Smrgpixbuf_from_argb32 (uint32_t *bits,
766ba797d6Smrg		    int width,
776ba797d6Smrg		    int height,
786ba797d6Smrg		    int stride)
796ba797d6Smrg{
806ba797d6Smrg    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
816ba797d6Smrg					8, width, height);
826ba797d6Smrg    int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
836ba797d6Smrg    guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
849ad247e8Sjmcneill    int i;
856ba797d6Smrg
869ad247e8Sjmcneill    for (i = 0; i < height; ++i)
879ad247e8Sjmcneill    {
889ad247e8Sjmcneill	uint32_t *src_row = &bits[i * (stride / 4)];
899ad247e8Sjmcneill	uint32_t *dst_row = p_bits + i * (p_stride / 4);
906ba797d6Smrg
919ad247e8Sjmcneill	a8r8g8b8_to_rgba_np (dst_row, src_row, width);
926ba797d6Smrg    }
939ad247e8Sjmcneill
946ba797d6Smrg    return pixbuf;
956ba797d6Smrg}
966ba797d6Smrg
976ba797d6Smrgstatic gboolean
9814b11b2bSmrgon_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data)
996ba797d6Smrg{
10014b11b2bSmrg    pixman_image_t *pimage = user_data;
101f4f78bb6Smrg    int width = pixman_image_get_width (pimage);
102f4f78bb6Smrg    int height = pixman_image_get_height (pimage);
103f4f78bb6Smrg    int stride = pixman_image_get_stride (pimage);
104f4f78bb6Smrg    cairo_surface_t *cimage;
105f4f78bb6Smrg    cairo_format_t format;
106f4f78bb6Smrg
107f4f78bb6Smrg    if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8)
108f4f78bb6Smrg	format = CAIRO_FORMAT_RGB24;
109f4f78bb6Smrg    else
110f4f78bb6Smrg	format = CAIRO_FORMAT_ARGB32;
111f4f78bb6Smrg
112f4f78bb6Smrg    cimage = cairo_image_surface_create_for_data (
113f4f78bb6Smrg	(uint8_t *)pixman_image_get_data (pimage),
114f4f78bb6Smrg	format, width, height, stride);
115f4f78bb6Smrg
116f4f78bb6Smrg    cairo_rectangle (cr, 0, 0, width, height);
117f4f78bb6Smrg    cairo_set_source_surface (cr, cimage, 0, 0);
118f4f78bb6Smrg    cairo_fill (cr);
119f4f78bb6Smrg
120f4f78bb6Smrg    cairo_surface_destroy (cimage);
1216ba797d6Smrg
1226ba797d6Smrg    return TRUE;
1236ba797d6Smrg}
1246ba797d6Smrg
1256ba797d6Smrgvoid
1266ba797d6Smrgshow_image (pixman_image_t *image)
1276ba797d6Smrg{
1286ba797d6Smrg    GtkWidget *window;
1299ad247e8Sjmcneill    int width, height;
1306ba797d6Smrg    int argc;
1316ba797d6Smrg    char **argv;
1326ba797d6Smrg    char *arg0 = g_strdup ("pixman-test-program");
1336ba797d6Smrg    pixman_format_code_t format;
1349ad247e8Sjmcneill    pixman_image_t *copy;
1356ba797d6Smrg
1366ba797d6Smrg    argc = 1;
1376ba797d6Smrg    argv = (char **)&arg0;
1386ba797d6Smrg
1396ba797d6Smrg    gtk_init (&argc, &argv);
1406ba797d6Smrg
1416ba797d6Smrg    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1426ba797d6Smrg    width = pixman_image_get_width (image);
1436ba797d6Smrg    height = pixman_image_get_height (image);
1446ba797d6Smrg
1456ba797d6Smrg    gtk_window_set_default_size (GTK_WINDOW (window), width, height);
1469ad247e8Sjmcneill
1479ad247e8Sjmcneill    format = pixman_image_get_format (image);
1489ad247e8Sjmcneill
149f4f78bb6Smrg    /* We always display the image as if it contains sRGB data. That
150f4f78bb6Smrg     * means that no conversion should take place when the image
151f4f78bb6Smrg     * has the a8r8g8b8_sRGB format.
1529ad247e8Sjmcneill     */
1539ad247e8Sjmcneill    switch (format)
1549ad247e8Sjmcneill    {
1559ad247e8Sjmcneill    case PIXMAN_a8r8g8b8_sRGB:
1569ad247e8Sjmcneill    case PIXMAN_a8r8g8b8:
157f4f78bb6Smrg    case PIXMAN_x8r8g8b8:
1589ad247e8Sjmcneill	copy = pixman_image_ref (image);
1599ad247e8Sjmcneill	break;
1609ad247e8Sjmcneill
1619ad247e8Sjmcneill    default:
1629ad247e8Sjmcneill	copy = pixman_image_create_bits (PIXMAN_a8r8g8b8,
1639ad247e8Sjmcneill					 width, height, NULL, -1);
1649ad247e8Sjmcneill	pixman_image_composite32 (PIXMAN_OP_SRC,
1659ad247e8Sjmcneill				  image, NULL, copy,
1669ad247e8Sjmcneill				  0, 0, 0, 0, 0, 0,
1679ad247e8Sjmcneill				  width, height);
1689ad247e8Sjmcneill	break;
1699ad247e8Sjmcneill    }
1709ad247e8Sjmcneill
17114b11b2bSmrg    g_signal_connect (window, "draw", G_CALLBACK (on_draw), copy);
1726ba797d6Smrg    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
1736ba797d6Smrg
1746ba797d6Smrg    gtk_widget_show (window);
1756ba797d6Smrg
1766ba797d6Smrg    gtk_main ();
1776ba797d6Smrg}
178