From af7f28efd7bacd461d9b9a9bcd319ddf067677b0 Mon Sep 17 00:00:00 2001 From: James Shaw Date: Thu, 29 Nov 2007 11:30:43 +0000 Subject: Fix 8bpp alpha in pixel data svn path=/import/jshaw/libsprite/; revision=10002 --- trunk/libsprite.c | 34 +++++++++++++++++++++++++++++----- trunk/libsprite.h | 6 +++--- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/trunk/libsprite.c b/trunk/libsprite.c index 464badd..78c5274 100644 --- a/trunk/libsprite.c +++ b/trunk/libsprite.c @@ -311,15 +311,26 @@ uint32_t sprite_cmyk_to_rgb(uint32_t cmyk) } /* TODO: could make static inline? */ -uint32_t sprite_upscale_color(uint32_t pixel, struct sprite_mode* mode) +uint32_t sprite_upscale_color(uint32_t pixel, struct sprite_mode* mode, bool* has_alpha_pixel_data) { switch (mode->colorbpp) { case 32: if (mode->color_model == SPRITE_RGB) { /* swap from 0xAABBGGRR to 0xRRGGBBAA */ - /*uint8_t alpha = pixel & (0xff << 24); - TODO: think about mask/alpha */ - return BSWAP(pixel); + pixel = BSWAP(pixel); + + uint8_t alpha = pixel & 0xff; + if (alpha == 0x00) { + if (!(*has_alpha_pixel_data)) { + pixel = pixel | 0xff; + } + } else { + *has_alpha_pixel_data = true; + /* TODO: if this is the first non 0x00 alpha byte we've seen, + * we need to go through all previous pixels and set them to 0xff + */ + } + return pixel; } else { return sprite_cmyk_to_rgb(pixel); } @@ -353,6 +364,13 @@ uint32_t sprite_upscale_color(uint32_t pixel, struct sprite_mode* mode) } } +void sprite_fix_alpha(uint32_t* image, uint32_t pixels) +{ + for (uint32_t i = 0; i <= pixels; i++) { + image[i] = image[i] & 0xffffff00; + } +} + struct sprite_mask_state* sprite_init_mask_state(struct sprite* sprite, struct sprite_header* header, uint8_t* mask) { struct sprite_mask_state* mask_state = malloc(sizeof(struct sprite_mask_state)); @@ -419,6 +437,8 @@ void sprite_load_high_color(uint8_t* image_in, uint8_t* mask, struct sprite* spr const uint32_t bytesPerPixel = bpp / 8; const uint32_t row_max_bit = header->width_words * 32 - (31 - header->last_used_bit); /* Last used bit in row */ + bool has_alpha_pixel_data = false; + /* Spec says that there must be no left-hand wastage */ assert(header->first_used_bit == 0); @@ -431,7 +451,11 @@ void sprite_load_high_color(uint8_t* image_in, uint8_t* mask, struct sprite* spr pixel = pixel | (b << (j * 8)); } - pixel = sprite_upscale_color(pixel, sprite->mode); + bool old_has_alpha = has_alpha_pixel_data; + pixel = sprite_upscale_color(pixel, sprite->mode, &has_alpha_pixel_data); + if (old_has_alpha != has_alpha_pixel_data) { + sprite_fix_alpha(sprite->image, (y * sprite->width) + x_pixels - 1); + } /* TODO: handle photodesk-style 0xBBGGRRAA sprites */ if (sprite->has_mask) { uint8_t mask_pixel = sprite_next_mask_pixel(mask, mask_state); diff --git a/trunk/libsprite.h b/trunk/libsprite.h index 04724d7..1d8ceb0 100644 --- a/trunk/libsprite.h +++ b/trunk/libsprite.h @@ -17,10 +17,10 @@ struct sprite_area { struct sprite_mode { uint32_t colorbpp; /* maskbpp denotes the amount of alpha bpp used - * while mask_width is the bits used to store the mask. - * Old modes have the same mask_width as their colorbpp, but the value + * while mask_width is the bits used to store the mask. + * Old modes have the same mask_width as their colorbpp, but the value * is always all-zeroes or all-ones. - * New modes can have 1bpp or 8bpp masks + * New modes can have 1bpp or 8bpp masks */ uint32_t maskbpp; uint32_t mask_width; /* in pixels */ -- cgit v1.2.3