gtk-utils.c revision 101944cf
1#include <gtk/gtk.h>
2#include <config.h>
3#include "../test/utils.h"
4#include "gtk-utils.h"
5
6pixman_image_t *
7pixman_image_from_file (const char *filename, pixman_format_code_t format)
8{
9    GdkPixbuf *pixbuf;
10    pixman_image_t *image;
11    int width, height;
12    uint32_t *data, *d;
13    uint8_t *gdk_data;
14    int n_channels;
15    int j, i;
16    int stride;
17
18    if (!(pixbuf = gdk_pixbuf_new_from_file (filename, NULL)))
19	return NULL;
20
21    image = NULL;
22
23    width = gdk_pixbuf_get_width (pixbuf);
24    height = gdk_pixbuf_get_height (pixbuf);
25    n_channels = gdk_pixbuf_get_n_channels (pixbuf);
26    gdk_data = gdk_pixbuf_get_pixels (pixbuf);
27    stride = gdk_pixbuf_get_rowstride (pixbuf);
28
29    if (!(data = malloc (width * height * sizeof (uint32_t))))
30	goto out;
31
32    d = data;
33    for (j = 0; j < height; ++j)
34    {
35	uint8_t *gdk_line = gdk_data;
36
37	for (i = 0; i < width; ++i)
38	{
39	    int r, g, b, a;
40	    uint32_t pixel;
41
42	    r = gdk_line[0];
43	    g = gdk_line[1];
44	    b = gdk_line[2];
45
46	    if (n_channels == 4)
47		a = gdk_line[3];
48	    else
49		a = 0xff;
50
51	    r = (r * a + 127) / 255;
52	    g = (g * a + 127) / 255;
53	    b = (b * a + 127) / 255;
54
55	    pixel = (a << 24) | (r << 16) | (g << 8) | b;
56
57	    *d++ = pixel;
58	    gdk_line += n_channels;
59	}
60
61	gdk_data += stride;
62    }
63
64    image = pixman_image_create_bits (
65	format, width, height, data, width * 4);
66
67out:
68    g_object_unref (pixbuf);
69    return image;
70}
71
72GdkPixbuf *
73pixbuf_from_argb32 (uint32_t *bits,
74		    int width,
75		    int height,
76		    int stride)
77{
78    GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE,
79					8, width, height);
80    int p_stride = gdk_pixbuf_get_rowstride (pixbuf);
81    guint32 *p_bits = (guint32 *)gdk_pixbuf_get_pixels (pixbuf);
82    int i;
83
84    for (i = 0; i < height; ++i)
85    {
86	uint32_t *src_row = &bits[i * (stride / 4)];
87	uint32_t *dst_row = p_bits + i * (p_stride / 4);
88
89	a8r8g8b8_to_rgba_np (dst_row, src_row, width);
90    }
91
92    return pixbuf;
93}
94
95static gboolean
96on_expose (GtkWidget *widget, GdkEventExpose *expose, gpointer data)
97{
98    pixman_image_t *pimage = data;
99    int width = pixman_image_get_width (pimage);
100    int height = pixman_image_get_height (pimage);
101    int stride = pixman_image_get_stride (pimage);
102    cairo_surface_t *cimage;
103    cairo_format_t format;
104    cairo_t *cr;
105
106    if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8)
107	format = CAIRO_FORMAT_RGB24;
108    else
109	format = CAIRO_FORMAT_ARGB32;
110
111    cimage = cairo_image_surface_create_for_data (
112	(uint8_t *)pixman_image_get_data (pimage),
113	format, width, height, stride);
114
115    cr = gdk_cairo_create (widget->window);
116
117    cairo_rectangle (cr, 0, 0, width, height);
118    cairo_set_source_surface (cr, cimage, 0, 0);
119    cairo_fill (cr);
120
121    cairo_destroy (cr);
122    cairo_surface_destroy (cimage);
123
124    return TRUE;
125}
126
127void
128show_image (pixman_image_t *image)
129{
130    GtkWidget *window;
131    int width, height;
132    int argc;
133    char **argv;
134    char *arg0 = g_strdup ("pixman-test-program");
135    pixman_format_code_t format;
136    pixman_image_t *copy;
137
138    argc = 1;
139    argv = (char **)&arg0;
140
141    gtk_init (&argc, &argv);
142
143    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
144    width = pixman_image_get_width (image);
145    height = pixman_image_get_height (image);
146
147    gtk_window_set_default_size (GTK_WINDOW (window), width, height);
148
149    format = pixman_image_get_format (image);
150
151    /* We always display the image as if it contains sRGB data. That
152     * means that no conversion should take place when the image
153     * has the a8r8g8b8_sRGB format.
154     */
155    switch (format)
156    {
157    case PIXMAN_a8r8g8b8_sRGB:
158    case PIXMAN_a8r8g8b8:
159    case PIXMAN_x8r8g8b8:
160	copy = pixman_image_ref (image);
161	break;
162
163    default:
164	copy = pixman_image_create_bits (PIXMAN_a8r8g8b8,
165					 width, height, NULL, -1);
166	pixman_image_composite32 (PIXMAN_OP_SRC,
167				  image, NULL, copy,
168				  0, 0, 0, 0, 0, 0,
169				  width, height);
170	break;
171    }
172
173    g_signal_connect (window, "expose_event", G_CALLBACK (on_expose), copy);
174    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
175
176    gtk_widget_show (window);
177
178    gtk_main ();
179}
180