Changeset 47689 in webkit
- Timestamp:
- Aug 23, 2009 12:18:17 AM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r47688 r47689 1 2009-08-22 Martin Robinson <martin.james.robinson@gmail.com> 2 3 Reviewed by Xan Lopez. 4 5 [GTK] BitmapImage::getGdkPixbuf does not handle alpha channels properly 6 https://bugs.webkit.org/show_bug.cgi?id=28345 7 8 When doing the conversion between cairo_surface_t* and GdkPixbuf* 9 account for the differences in the respective formats' in-memory 10 image format. 11 12 * platform/graphics/gtk/ImageGtk.cpp: 13 (WebCore::getCairoSurfacePixel): 14 (WebCore::getGdkPixbufPixel): 15 (WebCore::BitmapImage::getGdkPixbuf): 16 1 17 2009-08-22 Darin Adler <darin@apple.com> 2 18 -
trunk/WebCore/platform/graphics/gtk/ImageGtk.cpp
r43955 r47689 89 89 } 90 90 91 static inline unsigned char* getCairoSurfacePixel(unsigned char* data, uint x, uint y, uint rowStride) 92 { 93 return data + (y * rowStride) + x * 4; 94 } 95 96 static inline guchar* getGdkPixbufPixel(guchar* data, uint x, uint y, uint rowStride) 97 { 98 return data + (y * rowStride) + x * 4; 99 } 100 91 101 GdkPixbuf* BitmapImage::getGdkPixbuf() 92 102 { 93 103 int width = cairo_image_surface_get_width(frameAtIndex(currentFrame())); 94 104 int height = cairo_image_surface_get_height(frameAtIndex(currentFrame())); 105 unsigned char* surfaceData = cairo_image_surface_get_data(frameAtIndex(currentFrame())); 106 int surfaceRowStride = cairo_image_surface_get_stride(frameAtIndex(currentFrame())); 95 107 96 int bestDepth = gdk_visual_get_best_depth(); 97 GdkColormap* cmap = gdk_colormap_new(gdk_visual_get_best_with_depth(bestDepth), true); 108 GdkPixbuf* dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); 109 if (!dest) 110 return 0; 98 111 99 GdkPixmap* pixmap = gdk_pixmap_new(0, width, height, bestDepth); 100 gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), cmap); 101 cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(pixmap)); 102 cairo_set_source_surface(cr, frameAtIndex(currentFrame()), 0, 0); 103 cairo_paint(cr); 104 cairo_destroy(cr); 112 guchar* pixbufData = gdk_pixbuf_get_pixels(dest); 113 int pixbufRowStride = gdk_pixbuf_get_rowstride(dest); 105 114 106 GdkPixbuf* pixbuf = gdk_pixbuf_get_from_drawable(0, GDK_DRAWABLE(pixmap), 0, 0, 0, 0, 0, width, height); 107 g_object_unref(pixmap); 108 g_object_unref(cmap); 115 /* From: http://cairographics.org/manual/cairo-image-surface.html#cairo-format-t 116 * "CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with alpha in 117 * the upper 8 bits, then red, then green, then blue. The 32-bit 118 * quantities are stored native-endian. Pre-multiplied alpha is used. 119 * (That is, 50% transparent red is 0x80800000, not 0x80ff0000.)" 120 * 121 * See http://developer.gimp.org/api/2.0/gdk-pixbuf/gdk-pixbuf-gdk-pixbuf.html#GdkPixbuf 122 * for information on the structure of GdkPixbufs stored with GDK_COLORSPACE_RGB. 123 * 124 * RGB color channels in CAIRO_FORMAT_ARGB32 are stored based on the 125 * endianness of the machine and are also multiplied by the alpha channel. 126 * To properly transfer the data from the Cairo surface we must divide each 127 * of the RGB channels by the alpha channel and then reorder all channels 128 * if this machine is little-endian. 129 */ 130 for (int y = 0; y < height; y++) { 131 for (int x = 0; x < height; x++) { 132 unsigned char* source = getCairoSurfacePixel(surfaceData, x, y, surfaceRowStride); 133 guchar* dest = getGdkPixbufPixel(pixbufData, x, y, pixbufRowStride); 109 134 110 return pixbuf; 135 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 136 guchar alpha = source[3]; 137 dest[0] = alpha ? ((source[2] * 255) / alpha) : 0; 138 dest[1] = alpha ? ((source[1] * 255) / alpha) : 0; 139 dest[2] = alpha ? ((source[0] * 255) / alpha) : 0; 140 dest[3] = alpha; 141 #else 142 guchar alpha = source[0]; 143 dest[0] = alpha ? ((source[1] * 255) / alpha) : 0; 144 dest[1] = alpha ? ((source[2] * 255) / alpha) : 0; 145 dest[2] = alpha ? ((source[3] * 255) / alpha) : 0; 146 dest[3] = alpha; 147 #endif 148 } 149 } 150 151 return dest; 111 152 } 112 153
Note: See TracChangeset
for help on using the changeset viewer.