Simplified image conversion code even more. The alpha channel is a goner...
authorSam Lantinga <slouken@libsdl.org>
Tue, 10 Nov 2009 07:39:07 +0000
changeset 239950b63dc92d6
parent 238 ffe1f112ca0c
child 240 2fdb3e90ede0
Simplified image conversion code even more. The alpha channel is a goner...
IMG_ImageIO.c
IMG_UIImage.m
     1.1 --- a/IMG_ImageIO.c	Tue Nov 10 06:16:45 2009 +0000
     1.2 +++ b/IMG_ImageIO.c	Tue Nov 10 07:39:07 2009 +0000
     1.3 @@ -227,70 +227,63 @@
     1.4  	 * All this code should be scrutinized.
     1.5  	 */
     1.6  
     1.7 -	size_t the_width = CGImageGetWidth(image_ref);
     1.8 -	size_t the_height = CGImageGetHeight(image_ref);
     1.9 -	CGRect the_rect = {{0, 0}, {the_width, the_height}};
    1.10 +	size_t w = CGImageGetWidth(image_ref);
    1.11 +	size_t h = CGImageGetHeight(image_ref);
    1.12 +	CGRect rect = {{0, 0}, {w, h}};
    1.13  
    1.14 +	CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image_ref);
    1.15  	size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref);
    1.16  	size_t bits_per_component = 8;
    1.17  
    1.18 -	SDL_Surface* sdl_surface = NULL;
    1.19 +	SDL_Surface* surface;
    1.20 +	Uint32 Amask;
    1.21  	Uint32 Rmask;
    1.22  	Uint32 Gmask;
    1.23  	Uint32 Bmask;
    1.24 -	Uint32 Amask;
    1.25  
    1.26 -	CGContextRef bitmap_context = NULL;
    1.27 -	CGColorSpaceRef color_space = NULL;
    1.28 -	CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref);
    1.29 +	CGContextRef bitmap_context;
    1.30 +	CGBitmapInfo bitmap_info;
    1.31 +	CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
    1.32  
    1.33 -	switch (bits_per_pixel)
    1.34 -	{
    1.35 -		case 32:
    1.36 -		{
    1.37 -			color_space = CGColorSpaceCreateDeviceRGB();
    1.38 -			//bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */
    1.39 -			bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */
    1.40 -
    1.41 -			Amask = 0xFF000000;
    1.42 -			Rmask = 0x00FF0000;
    1.43 -			Gmask = 0x0000FF00;
    1.44 -			Bmask = 0x000000FF;
    1.45 -
    1.46 -			sdl_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, the_width, the_height, 32, Rmask, Gmask, Bmask, Amask);
    1.47 -			break;
    1.48 -		}
    1.49 -		default:
    1.50 -		{
    1.51 -			color_space = CGColorSpaceCreateDeviceRGB();
    1.52 -			bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */
    1.53 -			Amask = 0x00000000;
    1.54 -			Rmask = 0x00FF0000;
    1.55 -			Gmask = 0x0000FF00;
    1.56 -			Bmask = 0x000000FF;
    1.57 -
    1.58 -			sdl_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, the_width, the_height, 32, Rmask, Gmask, Bmask, Amask);
    1.59 -			break;
    1.60 -		}
    1.61 +	if (alpha == kCGImageAlphaNone ||
    1.62 +	    alpha == kCGImageAlphaNoneSkipFirst ||
    1.63 +	    alpha == kCGImageAlphaNoneSkipLast) {
    1.64 +		bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */
    1.65 +		Amask = 0x00000000;
    1.66 +	} else {
    1.67 +		/* kCGImageAlphaFirst isn't supported */
    1.68 +		//bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */
    1.69 +		bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */
    1.70 +		Amask = 0xFF000000;
    1.71  	}
    1.72  
    1.73 -	if (sdl_surface)
    1.74 +	Rmask = 0x00FF0000;
    1.75 +	Gmask = 0x0000FF00;
    1.76 +	Bmask = 0x000000FF;
    1.77 +
    1.78 +	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask);
    1.79 +	if (surface)
    1.80  	{
    1.81 -		// Sets up a context to be drawn to with sdl_surface->pixels as the area to be drawn to
    1.82 +		// Sets up a context to be drawn to with surface->pixels as the area to be drawn to
    1.83  		bitmap_context = CGBitmapContextCreate(
    1.84 -															sdl_surface->pixels,
    1.85 -															the_width,
    1.86 -															the_height,
    1.87 +															surface->pixels,
    1.88 +															surface->w,
    1.89 +															surface->h,
    1.90  															bits_per_component,
    1.91 -															sdl_surface->pitch,
    1.92 +															surface->pitch,
    1.93  															color_space,
    1.94  															bitmap_info
    1.95  															);
    1.96  
    1.97  		// Draws the image into the context's image_data
    1.98 -		CGContextDrawImage(bitmap_context, the_rect, image_ref);
    1.99 +		CGContextDrawImage(bitmap_context, rect, image_ref);
   1.100  
   1.101  		CGContextRelease(bitmap_context);
   1.102 +
   1.103 +		// FIXME: Reverse the premultiplied alpha
   1.104 +		if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) {
   1.105 +			// Errr, alpha premultiplication is lossy...
   1.106 +		}
   1.107  	}
   1.108  
   1.109  	if (color_space)
   1.110 @@ -298,7 +291,7 @@
   1.111  		CGColorSpaceRelease(color_space);			
   1.112  	}
   1.113  
   1.114 -	return sdl_surface;
   1.115 +	return surface;
   1.116  }
   1.117  
   1.118  
     2.1 --- a/IMG_UIImage.m	Tue Nov 10 06:16:45 2009 +0000
     2.2 +++ b/IMG_UIImage.m	Tue Nov 10 07:39:07 2009 +0000
     2.3 @@ -22,70 +22,63 @@
     2.4  	 * All this code should be scrutinized.
     2.5  	 */
     2.6  
     2.7 -	size_t the_width = CGImageGetWidth(image_ref);
     2.8 -	size_t the_height = CGImageGetHeight(image_ref);
     2.9 -	CGRect the_rect = {{0, 0}, {the_width, the_height}};
    2.10 +	size_t w = CGImageGetWidth(image_ref);
    2.11 +	size_t h = CGImageGetHeight(image_ref);
    2.12 +	CGRect rect = {{0, 0}, {w, h}};
    2.13  
    2.14 +	CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image_ref);
    2.15  	size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref);
    2.16  	size_t bits_per_component = 8;
    2.17  
    2.18 -	SDL_Surface* sdl_surface = NULL;
    2.19 +	SDL_Surface* surface;
    2.20 +	Uint32 Amask;
    2.21  	Uint32 Rmask;
    2.22  	Uint32 Gmask;
    2.23  	Uint32 Bmask;
    2.24 -	Uint32 Amask;
    2.25  
    2.26 -	CGContextRef bitmap_context = NULL;
    2.27 -	CGColorSpaceRef color_space = NULL;
    2.28 -	CGBitmapInfo bitmap_info = CGImageGetBitmapInfo(image_ref);
    2.29 +	CGContextRef bitmap_context;
    2.30 +	CGBitmapInfo bitmap_info;
    2.31 +	CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
    2.32  
    2.33 -	switch (bits_per_pixel)
    2.34 -	{
    2.35 -		case 32:
    2.36 -		{
    2.37 -			color_space = CGColorSpaceCreateDeviceRGB();
    2.38 -			//bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */
    2.39 -			bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */
    2.40 -
    2.41 -			Amask = 0xFF000000;
    2.42 -			Rmask = 0x00FF0000;
    2.43 -			Gmask = 0x0000FF00;
    2.44 -			Bmask = 0x000000FF;
    2.45 -
    2.46 -			sdl_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, the_width, the_height, 32, Rmask, Gmask, Bmask, Amask);
    2.47 -			break;
    2.48 -		}
    2.49 -		default:
    2.50 -		{
    2.51 -			color_space = CGColorSpaceCreateDeviceRGB();
    2.52 -			bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */
    2.53 -			Amask = 0x00000000;
    2.54 -			Rmask = 0x00FF0000;
    2.55 -			Gmask = 0x0000FF00;
    2.56 -			Bmask = 0x000000FF;
    2.57 -
    2.58 -			sdl_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, the_width, the_height, 32, Rmask, Gmask, Bmask, Amask);
    2.59 -			break;
    2.60 -		}
    2.61 +	if (alpha == kCGImageAlphaNone ||
    2.62 +	    alpha == kCGImageAlphaNoneSkipFirst ||
    2.63 +	    alpha == kCGImageAlphaNoneSkipLast) {
    2.64 +		bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */
    2.65 +		Amask = 0x00000000;
    2.66 +	} else {
    2.67 +		/* kCGImageAlphaFirst isn't supported */
    2.68 +		//bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */
    2.69 +		bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */
    2.70 +		Amask = 0xFF000000;
    2.71  	}
    2.72  
    2.73 -	if (sdl_surface)
    2.74 +	Rmask = 0x00FF0000;
    2.75 +	Gmask = 0x0000FF00;
    2.76 +	Bmask = 0x000000FF;
    2.77 +
    2.78 +	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask);
    2.79 +	if (surface)
    2.80  	{
    2.81 -		// Sets up a context to be drawn to with sdl_surface->pixels as the area to be drawn to
    2.82 +		// Sets up a context to be drawn to with surface->pixels as the area to be drawn to
    2.83  		bitmap_context = CGBitmapContextCreate(
    2.84 -															sdl_surface->pixels,
    2.85 -															the_width,
    2.86 -															the_height,
    2.87 +															surface->pixels,
    2.88 +															surface->w,
    2.89 +															surface->h,
    2.90  															bits_per_component,
    2.91 -															sdl_surface->pitch,
    2.92 +															surface->pitch,
    2.93  															color_space,
    2.94  															bitmap_info
    2.95  															);
    2.96  
    2.97  		// Draws the image into the context's image_data
    2.98 -		CGContextDrawImage(bitmap_context, the_rect, image_ref);
    2.99 +		CGContextDrawImage(bitmap_context, rect, image_ref);
   2.100  
   2.101  		CGContextRelease(bitmap_context);
   2.102 +
   2.103 +		// FIXME: Reverse the premultiplied alpha
   2.104 +		if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) {
   2.105 +			// Errr, alpha premultiplication is lossy...
   2.106 +		}
   2.107  	}
   2.108  
   2.109  	if (color_space)
   2.110 @@ -93,7 +86,7 @@
   2.111  		CGColorSpaceRelease(color_space);			
   2.112  	}
   2.113  
   2.114 -	return sdl_surface;
   2.115 +	return surface;
   2.116  }
   2.117  
   2.118  static SDL_Surface* LoadImageFromRWops(SDL_RWops* rw_ops, CFStringRef uti_string_hint)