gtk-utils.c revision a156c6bd
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_draw (GtkWidget *widget, cairo_t *cr, gpointer user_data) 97{ 98 pixman_image_t *pimage = user_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 105 if (pixman_image_get_format (pimage) == PIXMAN_x8r8g8b8) 106 format = CAIRO_FORMAT_RGB24; 107 else 108 format = CAIRO_FORMAT_ARGB32; 109 110 cimage = cairo_image_surface_create_for_data ( 111 (uint8_t *)pixman_image_get_data (pimage), 112 format, width, height, stride); 113 114 cairo_rectangle (cr, 0, 0, width, height); 115 cairo_set_source_surface (cr, cimage, 0, 0); 116 cairo_fill (cr); 117 118 cairo_surface_destroy (cimage); 119 120 return TRUE; 121} 122 123void 124show_image (pixman_image_t *image) 125{ 126 GtkWidget *window; 127 int width, height; 128 int argc; 129 char **argv; 130 char *arg0 = g_strdup ("pixman-test-program"); 131 pixman_format_code_t format; 132 pixman_image_t *copy; 133 134 argc = 1; 135 argv = (char **)&arg0; 136 137 gtk_init (&argc, &argv); 138 139 window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 140 width = pixman_image_get_width (image); 141 height = pixman_image_get_height (image); 142 143 gtk_window_set_default_size (GTK_WINDOW (window), width, height); 144 145 format = pixman_image_get_format (image); 146 147 /* We always display the image as if it contains sRGB data. That 148 * means that no conversion should take place when the image 149 * has the a8r8g8b8_sRGB format. 150 */ 151 switch (format) 152 { 153 case PIXMAN_a8r8g8b8_sRGB: 154 case PIXMAN_a8r8g8b8: 155 case PIXMAN_x8r8g8b8: 156 copy = pixman_image_ref (image); 157 break; 158 159 default: 160 copy = pixman_image_create_bits (PIXMAN_a8r8g8b8, 161 width, height, NULL, -1); 162 pixman_image_composite32 (PIXMAN_OP_SRC, 163 image, NULL, copy, 164 0, 0, 0, 0, 0, 0, 165 width, height); 166 break; 167 } 168 169 g_signal_connect (window, "draw", G_CALLBACK (on_draw), copy); 170 g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL); 171 172 gtk_widget_show (window); 173 174 gtk_main (); 175} 176