summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Shaw <jshaw@netsurf-browser.org>2007-11-29 11:30:43 (GMT)
committer James Shaw <jshaw@netsurf-browser.org>2007-11-29 11:30:43 (GMT)
commitaf7f28efd7bacd461d9b9a9bcd319ddf067677b0 (patch)
tree8c2df5c49cbe34822238a36d31c22cfc870b0d07
parent359c5eb9e6c06413b8b8a11e8fcbbc457028fdde (diff)
downloadlibrosprite-af7f28efd7bacd461d9b9a9bcd319ddf067677b0.tar.gz
librosprite-af7f28efd7bacd461d9b9a9bcd319ddf067677b0.tar.bz2
Fix 8bpp alpha in pixel data
svn path=/import/jshaw/libsprite/; revision=10002
-rw-r--r--trunk/libsprite.c34
-rw-r--r--trunk/libsprite.h6
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 */