summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/bitmap.c91
1 files changed, 50 insertions, 41 deletions
diff --git a/gtk/bitmap.c b/gtk/bitmap.c
index 96e9edaee..4474b074f 100644
--- a/gtk/bitmap.c
+++ b/gtk/bitmap.c
@@ -187,48 +187,54 @@ unsigned char *bitmap_get_buffer(void *vbitmap)
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
cairo_surface_flush(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (!gbitmap->converted)
- return (unsigned char *) pixels;
+ return pixels;
fmt = cairo_image_surface_get_format(gbitmap->surface);
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ b = pixels[4 * pixel_loop + 0];
+ r = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 2] = b;
}
} else {
- uint32_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and de-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
- } else {
- r = ((pixel & 0xff0000) >> 8) / t;
- g = ((pixel & 0xff00)) / t;
- b = ((pixel & 0xff) << 8) / t;
+ b = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ r = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = (r << 8) / t;
+ g = (g << 8) / t;
+ b = (b << 8) / t;
r = (r > 255) ? 255 : r;
g = (g > 255) ? 255 : g;
b = (b > 255) ? 255 : b;
-
- pixels[pixel_loop] = (t << 24) |
- (r) | (g << 8) | (b << 16);
+ } else {
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = r;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = b;
+ pixels[4 * pixel_loop + 3] = t;
}
}
@@ -319,8 +325,8 @@ void bitmap_modified(void *vbitmap) {
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
int pixel_loop;
int pixel_count;
- uint32_t *pixels;
- uint32_t pixel;
+ uint8_t *pixels;
+ uint32_t t, r, g, b;
cairo_format_t fmt;
assert(gbitmap);
@@ -329,7 +335,7 @@ void bitmap_modified(void *vbitmap) {
pixel_count = cairo_image_surface_get_width(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
- pixels = (uint32_t *)cairo_image_surface_get_data(gbitmap->surface);
+ pixels = cairo_image_surface_get_data(gbitmap->surface);
if (gbitmap->converted) {
cairo_surface_mark_dirty(gbitmap->surface);
@@ -337,30 +343,33 @@ void bitmap_modified(void *vbitmap) {
}
if (fmt == CAIRO_FORMAT_RGB24) {
+ /* Opaque image: simply swap R & B channels */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- pixels[pixel_loop] = (pixel & 0xff00ff00) |
- ((pixel & 0xff) << 16) |
- ((pixel & 0xff0000) >> 16);
+ r = pixels[4 * pixel_loop + 0];
+ b = pixels[4 * pixel_loop + 2];
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 2] = r;
}
} else {
- uint8_t t, r, g, b;
+ /* Alpha image: swap R & B channels, and pre-multiply alpha */
for (pixel_loop=0; pixel_loop < pixel_count; pixel_loop++) {
- pixel = pixels[pixel_loop];
- t = (pixel & 0xff000000) >> 24;
- if (t == 0) {
- pixels[pixel_loop] = 0;
+ r = pixels[4 * pixel_loop + 0];
+ g = pixels[4 * pixel_loop + 1];
+ b = pixels[4 * pixel_loop + 2];
+ t = pixels[4 * pixel_loop + 3];
+
+ if (t != 0) {
+ r = ((r * t) >> 8) & 0xff;
+ g = ((g * t) >> 8) & 0xff;
+ b = ((b * t) >> 8) & 0xff;
} else {
- r = (pixel & 0xff0000) >> 16;
- g = (pixel & 0xff00) >> 8;
- b = pixel & 0xff;
-
- pixels[pixel_loop] = (t << 24) |
- ((r * t) >> 8) |
- ((g * t) >> 8) << 8 |
- ((b * t) >> 8) << 16;
-
+ r = g = b = 0;
}
+
+ pixels[4 * pixel_loop + 0] = b;
+ pixels[4 * pixel_loop + 1] = g;
+ pixels[4 * pixel_loop + 2] = r;
+ pixels[4 * pixel_loop + 3] = t;
}
}