From 9787fd5948f915e76d5a1a89aa403f7e2e28c1f2 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 10 Nov 2009 08:26:52 +0000 Subject: [PATCH] Fixed bug #868 Premultiplied alpha is not entirely lossy, as it turns out. Also fixed building with SDL_IMAGE_USE_COMMON_BACKEND --- IMG_ImageIO.c | 25 ++++++++++++++++++++++++- IMG_UIImage.m | 21 ++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/IMG_ImageIO.c b/IMG_ImageIO.c index 2b2c5c41..37c58af3 100644 --- a/IMG_ImageIO.c +++ b/IMG_ImageIO.c @@ -6,6 +6,9 @@ * Copyright 2009 __MyCompanyName__. All rights reserved. * */ + +#if defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) + #include "SDL_image.h" // For ImageIO framework and also LaunchServices framework (for UTIs) @@ -282,7 +285,26 @@ static SDL_Surface* Create_SDL_Surface_From_CGImage(CGImageRef image_ref) // FIXME: Reverse the premultiplied alpha if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { - // Errr, alpha premultiplication is lossy... + int i, j; + Uint8 *p = (Uint8 *)surface->pixels; + for (i = surface->h * surface->pitch/4; i--; ) { +#if __LITTLE_ENDIAN__ + Uint8 A = p[3]; + if (A) { + for (j = 0; j < 3; ++j) { + p[j] = (p[j] * 255) / A; + } + } +#else + Uint8 A = p[0]; + if (A) { + for (j = 1; i < 4; ++j) { + p[j] = (p[j] * 255) / A; + } + } +#endif /* ENDIAN */ + p += 4; + } } } @@ -487,3 +509,4 @@ SDL_Surface* IMG_Load(const char *file) return sdl_surface; } +#endif /* defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) */ diff --git a/IMG_UIImage.m b/IMG_UIImage.m index 40299249..851d87e1 100644 --- a/IMG_UIImage.m +++ b/IMG_UIImage.m @@ -77,7 +77,26 @@ // FIXME: Reverse the premultiplied alpha if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { - // Errr, alpha premultiplication is lossy... + int i, j; + Uint8 *p = (Uint8 *)surface->pixels; + for (i = surface->h * surface->pitch/4; i--; ) { +#if __LITTLE_ENDIAN__ + Uint8 A = p[3]; + if (A) { + for (j = 0; j < 3; ++j) { + p[j] = (p[j] * 255) / A; + } + } +#else + Uint8 A = p[0]; + if (A) { + for (j = 1; i < 4; ++j) { + p[j] = (p[j] * 255) / A; + } + } +#endif /* ENDIAN */ + p += 4; + } } }