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