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