From 0046663e68adcba6d4643a0cd26e99168b2742bc Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 30 Dec 2011 16:14:00 -0500 Subject: [PATCH] SDL_image uses ImageIO for ios4 and osx and UIImage on ios3 Vittorio Giovara >> The second one is a feature request to make it so that when the >> ImageIO framework is not present the library would fallback to the >> UIImage backend; although it would perhaps make backporting a little >> difficult I am sure that there is still a lot of software targeting >> pre-ios 4 that could make use of it. > > It's possible, and not entirely unreasonable, but iOS moves so fast > that I haven't felt it really merited the extra effort to do so. My > experience is that there isn't a lot of interest in 3.x. I have a > 3.1.3 device and there are actually very few apps (that I would be > interested in getting) that support 3.x any more and I have to be very > careful to no upgrade my existing apps because the new versions don't > work on my device any more. I think the percentage of devices 3.x is > less than 10% now. Testing old devices is another difficulty. And if > you need to start weak linking frameworks in the Xcode project, you go > into areas most non Apple developers don't know about. > > -Eric I see your point, iOS is a much faster platform than OSX and a lot of applications are dropping support for 3.* devices, however I feel that as SDL is a compatibility layer between architectures it should be as compatible as possible, until major api change or build system make it impossible/unbearable to keep it updated. Having said that I am proposing a solution that should keep SDL_image compatible with both the newer ImageIO for ios4 and osx and allow us to use uiimage on ios3: what I am linking is a merge of IMG_UIImage.m and IMG_ImageIO.c and the small changes that need to be applied to the related xcode project files). --- IMG_ImageIO.c | 523 ------------- IMG_ImageIO.m | 718 ++++++++++++++++++ Makefile.am | 2 +- Xcode/SDL_image.xcodeproj/project.pbxproj | 23 +- .../showimage.xcodeproj/project.pbxproj | 7 + .../SDL_image.xcodeproj/project.pbxproj | 28 +- configure.in | 3 + 7 files changed, 752 insertions(+), 552 deletions(-) delete mode 100644 IMG_ImageIO.c create mode 100644 IMG_ImageIO.m diff --git a/IMG_ImageIO.c b/IMG_ImageIO.c deleted file mode 100644 index 2dffd7bc..00000000 --- a/IMG_ImageIO.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * IMG_ImageIO.c - * SDL_image - * - * Created by Eric Wing on 1/1/09. - * Copyright 2009 __MyCompanyName__. All rights reserved. - * - */ - -#if defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) - -#include "SDL_image.h" - -// Used because CGDataProviderCreate became deprecated in 10.5 -#include -#include - -#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) -#import // for UTCoreTypes.h -#import -#else -// For ImageIO framework and also LaunchServices framework (for UTIs) -#include -#endif - -/************************************************************** - ***** Begin Callback functions for block reading ************* - **************************************************************/ - -// This callback reads some bytes from an SDL_rwops and copies it -// to a Quartz buffer (supplied by Apple framework). -static size_t MyProviderGetBytesCallback(void* rwops_userdata, void* quartz_buffer, size_t the_count) -{ - return (size_t)SDL_RWread((struct SDL_RWops *)rwops_userdata, quartz_buffer, 1, the_count); -} - -// This callback is triggered when the data provider is released -// so you can clean up any resources. -static void MyProviderReleaseInfoCallback(void* rwops_userdata) -{ - // What should I put here? - // I think the user and SDL_RWops controls closing, so I don't do anything. -} - -static void MyProviderRewindCallback(void* rwops_userdata) -{ - SDL_RWseek((struct SDL_RWops *)rwops_userdata, 0, RW_SEEK_SET); -} - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // CGDataProviderCreateSequential was introduced in 10.5; CGDataProviderCreate is deprecated -off_t MyProviderSkipForwardBytesCallback(void* rwops_userdata, off_t the_count) -{ - off_t start_position = SDL_RWtell((struct SDL_RWops *)rwops_userdata); - SDL_RWseek((struct SDL_RWops *)rwops_userdata, the_count, RW_SEEK_CUR); - off_t end_position = SDL_RWtell((struct SDL_RWops *)rwops_userdata); - return (end_position - start_position); -} -#else // CGDataProviderCreate was deprecated in 10.5 -static void MyProviderSkipBytesCallback(void* rwops_userdata, size_t the_count) -{ - SDL_RWseek((struct SDL_RWops *)rwops_userdata, the_count, RW_SEEK_CUR); -} -#endif - - -/************************************************************** - ***** End Callback functions for block reading *************** - **************************************************************/ - -// This creates a CGImageSourceRef which is a handle to an image that can be used to examine information -// about the image or load the actual image data. -static CGImageSourceRef CreateCGImageSourceFromRWops(SDL_RWops* rw_ops, CFDictionaryRef hints_and_options) -{ - CGImageSourceRef source_ref; - - // Similar to SDL_RWops, Apple has their own callbacks for dealing with data streams. - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // CGDataProviderCreateSequential was introduced in 10.5; CGDataProviderCreate is deprecated - CGDataProviderSequentialCallbacks provider_callbacks = - { - 0, - MyProviderGetBytesCallback, - MyProviderSkipForwardBytesCallback, - MyProviderRewindCallback, - MyProviderReleaseInfoCallback - }; - - CGDataProviderRef data_provider = CGDataProviderCreateSequential(rw_ops, &provider_callbacks); - - -#else // CGDataProviderCreate was deprecated in 10.5 - - CGDataProviderCallbacks provider_callbacks = - { - MyProviderGetBytesCallback, - MyProviderSkipBytesCallback, - MyProviderRewindCallback, - MyProviderReleaseInfoCallback - }; - - CGDataProviderRef data_provider = CGDataProviderCreate(rw_ops, &provider_callbacks); -#endif - // Get the CGImageSourceRef. - // The dictionary can be NULL or contain hints to help ImageIO figure out the image type. - source_ref = CGImageSourceCreateWithDataProvider(data_provider, hints_and_options); - return source_ref; -} - - -/* Create a CGImageSourceRef from a file. */ -/* Remember to CFRelease the created source when done. */ -static CGImageSourceRef CreateCGImageSourceFromFile(const char* the_path) -{ - CFURLRef the_url = NULL; - CGImageSourceRef source_ref = NULL; - CFStringRef cf_string = NULL; - - /* Create a CFString from a C string */ - cf_string = CFStringCreateWithCString( - NULL, - the_path, - kCFStringEncodingUTF8 - ); - if(!cf_string) - { - return NULL; - } - - /* Create a CFURL from a CFString */ - the_url = CFURLCreateWithFileSystemPath( - NULL, - cf_string, - kCFURLPOSIXPathStyle, - false - ); - - /* Don't need the CFString any more (error or not) */ - CFRelease(cf_string); - - if(!the_url) - { - return NULL; - } - - - source_ref = CGImageSourceCreateWithURL(the_url, NULL); - /* Don't need the URL any more (error or not) */ - CFRelease(the_url); - - return source_ref; -} - - - -static CGImageRef CreateCGImageFromCGImageSource(CGImageSourceRef image_source) -{ - CGImageRef image_ref = NULL; - - if(NULL == image_source) - { - return NULL; - } - - // Get the first item in the image source (some image formats may - // contain multiple items). - image_ref = CGImageSourceCreateImageAtIndex(image_source, 0, NULL); - if(NULL == image_ref) - { - IMG_SetError("CGImageSourceCreateImageAtIndex() failed"); - } - return image_ref; -} - -static CFDictionaryRef CreateHintDictionary(CFStringRef uti_string_hint) -{ - CFDictionaryRef hint_dictionary = NULL; - - if(uti_string_hint != NULL) - { - // Do a bunch of work to setup a CFDictionary containing the jpeg compression properties. - CFStringRef the_keys[1]; - CFStringRef the_values[1]; - - the_keys[0] = kCGImageSourceTypeIdentifierHint; - the_values[0] = uti_string_hint; - - // kCFTypeDictionaryKeyCallBacks or kCFCopyStringDictionaryKeyCallBacks? - hint_dictionary = CFDictionaryCreate(NULL, (const void**)&the_keys, (const void**)&the_values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - } - return hint_dictionary; -} - - - - -static int Internal_isType(SDL_RWops* rw_ops, CFStringRef uti_string_to_test) -{ - CGImageSourceRef image_source; - CFStringRef uti_type; - Boolean is_type; - - CFDictionaryRef hint_dictionary = NULL; - - hint_dictionary = CreateHintDictionary(uti_string_to_test); - image_source = CreateCGImageSourceFromRWops(rw_ops, hint_dictionary); - - if(hint_dictionary != NULL) - { - CFRelease(hint_dictionary); - } - - if(NULL == image_source) - { - return 0; - } - - // This will get the UTI of the container, not the image itself. - // Under most cases, this won't be a problem. - // But if a person passes an icon file which contains a bmp, - // the format will be of the icon file. - // But I think the main SDL_image codebase has this same problem so I'm not going to worry about it. - uti_type = CGImageSourceGetType(image_source); - // CFShow(uti_type); - - // Unsure if we really want conformance or equality - is_type = UTTypeConformsTo(uti_string_to_test, uti_type); - - CFRelease(image_source); - - return (int)is_type; -} - -// Once we have our image, we need to get it into an SDL_Surface -static SDL_Surface* Create_SDL_Surface_From_CGImage(CGImageRef image_ref) -{ - /* This code is adapted from Apple's Documentation found here: - * http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/index.html - * Listing 9-4††Using a Quartz image as a texture source. - * Unfortunately, this guide doesn't show what to do about - * non-RGBA image formats so I'm making the rest up. - * All this code should be scrutinized. - */ - - size_t w = CGImageGetWidth(image_ref); - size_t h = CGImageGetHeight(image_ref); - CGRect rect = {{0, 0}, {w, h}}; - - CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image_ref); - //size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref); - size_t bits_per_component = 8; - - SDL_Surface* surface; - Uint32 Amask; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - - CGContextRef bitmap_context; - CGBitmapInfo bitmap_info; - CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); - - if (alpha == kCGImageAlphaNone || - alpha == kCGImageAlphaNoneSkipFirst || - alpha == kCGImageAlphaNoneSkipLast) { - bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */ - Amask = 0x00000000; - } else { - /* kCGImageAlphaFirst isn't supported */ - //bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */ - bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */ - Amask = 0xFF000000; - } - - Rmask = 0x00FF0000; - Gmask = 0x0000FF00; - Bmask = 0x000000FF; - - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask); - if (surface) - { - // Sets up a context to be drawn to with surface->pixels as the area to be drawn to - bitmap_context = CGBitmapContextCreate( - surface->pixels, - surface->w, - surface->h, - bits_per_component, - surface->pitch, - color_space, - bitmap_info - ); - - // Draws the image into the context's image_data - CGContextDrawImage(bitmap_context, rect, image_ref); - - CGContextRelease(bitmap_context); - - // FIXME: Reverse the premultiplied alpha - if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { - 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; j < 4; ++j) { - p[j] = (p[j] * 255) / A; - } - } -#endif /* ENDIAN */ - p += 4; - } - } - } - - if (color_space) - { - CGColorSpaceRelease(color_space); - } - - return surface; -} - - -static SDL_Surface* LoadImageFromRWops(SDL_RWops* rw_ops, CFStringRef uti_string_hint) -{ - SDL_Surface* sdl_surface; - CGImageSourceRef image_source; - CGImageRef image_ref = NULL; - CFDictionaryRef hint_dictionary = NULL; - - hint_dictionary = CreateHintDictionary(uti_string_hint); - image_source = CreateCGImageSourceFromRWops(rw_ops, hint_dictionary); - - if(hint_dictionary != NULL) - { - CFRelease(hint_dictionary); - } - - if(NULL == image_source) - { - return NULL; - } - - image_ref = CreateCGImageFromCGImageSource(image_source); - CFRelease(image_source); - - if(NULL == image_ref) - { - return NULL; - } - - sdl_surface = Create_SDL_Surface_From_CGImage(image_ref); - CFRelease(image_ref); - return sdl_surface; - -} - - - -static SDL_Surface* LoadImageFromFile(const char* file) -{ - SDL_Surface* sdl_surface = NULL; - CGImageSourceRef image_source = NULL; - CGImageRef image_ref = NULL; - - // First ImageIO - image_source = CreateCGImageSourceFromFile(file); - - if(NULL == image_source) - { - return NULL; - } - - image_ref = CreateCGImageFromCGImageSource(image_source); - CFRelease(image_source); - - if(NULL == image_ref) - { - return NULL; - } - - sdl_surface = Create_SDL_Surface_From_CGImage(image_ref); - CFRelease(image_ref); - return sdl_surface; -} - -int IMG_InitJPG() -{ - return 0; -} - -void IMG_QuitJPG() -{ -} - -int IMG_InitPNG() -{ - return 0; -} - -void IMG_QuitPNG() -{ -} - -int IMG_InitTIF() -{ - return 0; -} - -void IMG_QuitTIF() -{ -} - -int IMG_isCUR(SDL_RWops *src) -{ - /* FIXME: Is this a supported type? */ - return Internal_isType(src, CFSTR("com.microsoft.cur")); -} - -int IMG_isICO(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypeICO); -} - -int IMG_isBMP(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypeBMP); -} - -int IMG_isGIF(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypeGIF); -} - -// Note: JPEG 2000 is kUTTypeJPEG2000 -int IMG_isJPG(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypeJPEG); -} - -int IMG_isPNG(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypePNG); -} - -// This isn't a public API function. Apple seems to be able to identify tga's. -int IMG_isTGA(SDL_RWops *src) -{ - return Internal_isType(src, CFSTR("com.truevision.tga-image")); -} - -int IMG_isTIF(SDL_RWops *src) -{ - return Internal_isType(src, kUTTypeTIFF); -} - -SDL_Surface* IMG_LoadCUR_RW(SDL_RWops *src) -{ - /* FIXME: Is this a supported type? */ - return LoadImageFromRWops(src, CFSTR("com.microsoft.cur")); -} -SDL_Surface* IMG_LoadICO_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypeICO); -} -SDL_Surface* IMG_LoadBMP_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypeBMP); -} -SDL_Surface* IMG_LoadGIF_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypeGIF); -} -SDL_Surface* IMG_LoadJPG_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypeJPEG); -} -SDL_Surface* IMG_LoadPNG_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypePNG); -} -SDL_Surface* IMG_LoadTGA_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, CFSTR("com.truevision.tga-image")); -} -SDL_Surface* IMG_LoadTIF_RW(SDL_RWops *src) -{ - return LoadImageFromRWops(src, kUTTypeTIFF); -} - -// Apple provides both stream and file loading functions in ImageIO. -// Potentially, Apple can optimize for either case. -SDL_Surface* IMG_Load(const char *file) -{ - SDL_Surface* sdl_surface = NULL; - - sdl_surface = LoadImageFromFile(file); - if(NULL == sdl_surface) - { - // Either the file doesn't exist or ImageIO doesn't understand the format. - // For the latter case, fallback to the native SDL_image handlers. - SDL_RWops *src = SDL_RWFromFile(file, "rb"); - char *ext = strrchr(file, '.'); - if(ext) { - ext++; - } - if(!src) { - /* The error message has been set in SDL_RWFromFile */ - return NULL; - } - sdl_surface = IMG_LoadTyped_RW(src, 1, ext); - } - return sdl_surface; -} - -#endif /* defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) */ diff --git a/IMG_ImageIO.m b/IMG_ImageIO.m new file mode 100644 index 00000000..54b57805 --- /dev/null +++ b/IMG_ImageIO.m @@ -0,0 +1,718 @@ +/* + * IMG_ImageIO.c + * SDL_image + * + * Created by Eric Wing on 1/1/09. + * Copyright 2009 __MyCompanyName__. All rights reserved. + * + */ + +#if defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) + +#include "SDL_image.h" + +// Used because CGDataProviderCreate became deprecated in 10.5 +#include +#include +#include + +#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) +#ifdef ALLOW_UIIMAGE_FALLBACK +#define USE_UIIMAGE_BACKEND() ([UIImage instancesRespondToSelector:@selector(initWithCGImage:scale:orientation:)] == NO) +#else +#define USE_UIIMAGE_BACKEND() (Internal_checkImageIOisAvailable()) +#endif +#import // for UTCoreTypes.h +#import +#import +#else +// For ImageIO framework and also LaunchServices framework (for UTIs) +#include +#endif + +/************************************************************** + ***** Begin Callback functions for block reading ************* + **************************************************************/ + +// This callback reads some bytes from an SDL_rwops and copies it +// to a Quartz buffer (supplied by Apple framework). +static size_t MyProviderGetBytesCallback(void* rwops_userdata, void* quartz_buffer, size_t the_count) +{ + return (size_t)SDL_RWread((struct SDL_RWops *)rwops_userdata, quartz_buffer, 1, the_count); +} + +// This callback is triggered when the data provider is released +// so you can clean up any resources. +static void MyProviderReleaseInfoCallback(void* rwops_userdata) +{ + // What should I put here? + // I think the user and SDL_RWops controls closing, so I don't do anything. +} + +static void MyProviderRewindCallback(void* rwops_userdata) +{ + SDL_RWseek((struct SDL_RWops *)rwops_userdata, 0, RW_SEEK_SET); +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // CGDataProviderCreateSequential was introduced in 10.5; CGDataProviderCreate is deprecated +off_t MyProviderSkipForwardBytesCallback(void* rwops_userdata, off_t the_count) +{ + off_t start_position = SDL_RWtell((struct SDL_RWops *)rwops_userdata); + SDL_RWseek((struct SDL_RWops *)rwops_userdata, the_count, RW_SEEK_CUR); + off_t end_position = SDL_RWtell((struct SDL_RWops *)rwops_userdata); + return (end_position - start_position); +} +#else // CGDataProviderCreate was deprecated in 10.5 +static void MyProviderSkipBytesCallback(void* rwops_userdata, size_t the_count) +{ + SDL_RWseek((struct SDL_RWops *)rwops_userdata, the_count, RW_SEEK_CUR); +} +#endif + +/************************************************************** + ***** End Callback functions for block reading *************** + **************************************************************/ + +// This creates a CGImageSourceRef which is a handle to an image that can be used to examine information +// about the image or load the actual image data. +static CGImageSourceRef CreateCGImageSourceFromRWops(SDL_RWops* rw_ops, CFDictionaryRef hints_and_options) +{ + CGImageSourceRef source_ref; + + // Similar to SDL_RWops, Apple has their own callbacks for dealing with data streams. + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // CGDataProviderCreateSequential was introduced in 10.5; CGDataProviderCreate is deprecated + CGDataProviderSequentialCallbacks provider_callbacks = + { + 0, + MyProviderGetBytesCallback, + MyProviderSkipForwardBytesCallback, + MyProviderRewindCallback, + MyProviderReleaseInfoCallback + }; + + CGDataProviderRef data_provider = CGDataProviderCreateSequential(rw_ops, &provider_callbacks); + + +#else // CGDataProviderCreate was deprecated in 10.5 + + CGDataProviderCallbacks provider_callbacks = + { + MyProviderGetBytesCallback, + MyProviderSkipBytesCallback, + MyProviderRewindCallback, + MyProviderReleaseInfoCallback + }; + + CGDataProviderRef data_provider = CGDataProviderCreate(rw_ops, &provider_callbacks); +#endif + // Get the CGImageSourceRef. + // The dictionary can be NULL or contain hints to help ImageIO figure out the image type. + source_ref = CGImageSourceCreateWithDataProvider(data_provider, hints_and_options); + return source_ref; +} + +/* Create a CGImageSourceRef from a file. */ +/* Remember to CFRelease the created source when done. */ +static CGImageSourceRef CreateCGImageSourceFromFile(const char* the_path) +{ + CFURLRef the_url = NULL; + CGImageSourceRef source_ref = NULL; + CFStringRef cf_string = NULL; + + /* Create a CFString from a C string */ + cf_string = CFStringCreateWithCString(NULL, the_path, kCFStringEncodingUTF8); + if (!cf_string) { + return NULL; + } + + /* Create a CFURL from a CFString */ + the_url = CFURLCreateWithFileSystemPath(NULL, cf_string, kCFURLPOSIXPathStyle, false); + + /* Don't need the CFString any more (error or not) */ + CFRelease(cf_string); + + if(!the_url) + { + return NULL; + } + + + source_ref = CGImageSourceCreateWithURL(the_url, NULL); + /* Don't need the URL any more (error or not) */ + CFRelease(the_url); + + return source_ref; +} + +static CGImageRef CreateCGImageFromCGImageSource(CGImageSourceRef image_source) +{ + CGImageRef image_ref = NULL; + + if(NULL == image_source) + { + return NULL; + } + + // Get the first item in the image source (some image formats may + // contain multiple items). + image_ref = CGImageSourceCreateImageAtIndex(image_source, 0, NULL); + if(NULL == image_ref) + { + IMG_SetError("CGImageSourceCreateImageAtIndex() failed"); + } + return image_ref; +} + +static CFDictionaryRef CreateHintDictionary(CFStringRef uti_string_hint) +{ + CFDictionaryRef hint_dictionary = NULL; + + if(uti_string_hint != NULL) + { + // Do a bunch of work to setup a CFDictionary containing the jpeg compression properties. + CFStringRef the_keys[1]; + CFStringRef the_values[1]; + + the_keys[0] = kCGImageSourceTypeIdentifierHint; + the_values[0] = uti_string_hint; + + // kCFTypeDictionaryKeyCallBacks or kCFCopyStringDictionaryKeyCallBacks? + hint_dictionary = CFDictionaryCreate(NULL, (const void**)&the_keys, (const void**)&the_values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + return hint_dictionary; +} + + +// Once we have our image, we need to get it into an SDL_Surface +static SDL_Surface* Create_SDL_Surface_From_CGImage(CGImageRef image_ref) +{ + /* This code is adapted from Apple's Documentation found here: + * http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/index.html + * Listing 9-4††Using a Quartz image as a texture source. + * Unfortunately, this guide doesn't show what to do about + * non-RGBA image formats so I'm making the rest up. + * All this code should be scrutinized. + */ + + size_t w = CGImageGetWidth(image_ref); + size_t h = CGImageGetHeight(image_ref); + CGRect rect = {{0, 0}, {w, h}}; + + CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image_ref); + //size_t bits_per_pixel = CGImageGetBitsPerPixel(image_ref); + size_t bits_per_component = 8; + + SDL_Surface* surface; + Uint32 Amask; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + + CGContextRef bitmap_context; + CGBitmapInfo bitmap_info; + CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB(); + + if (alpha == kCGImageAlphaNone || + alpha == kCGImageAlphaNoneSkipFirst || + alpha == kCGImageAlphaNoneSkipLast) { + bitmap_info = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; /* XRGB */ + Amask = 0x00000000; + } else { + /* kCGImageAlphaFirst isn't supported */ + //bitmap_info = kCGImageAlphaFirst | kCGBitmapByteOrder32Host; /* ARGB */ + bitmap_info = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; /* ARGB */ + Amask = 0xFF000000; + } + + Rmask = 0x00FF0000; + Gmask = 0x0000FF00; + Bmask = 0x000000FF; + + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, Rmask, Gmask, Bmask, Amask); + if (surface) + { + // Sets up a context to be drawn to with surface->pixels as the area to be drawn to + bitmap_context = CGBitmapContextCreate( + surface->pixels, + surface->w, + surface->h, + bits_per_component, + surface->pitch, + color_space, + bitmap_info + ); + + // Draws the image into the context's image_data + CGContextDrawImage(bitmap_context, rect, image_ref); + + CGContextRelease(bitmap_context); + + // FIXME: Reverse the premultiplied alpha + if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst) { + 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; j < 4; ++j) { + p[j] = (p[j] * 255) / A; + } + } +#endif /* ENDIAN */ + p += 4; + } + } + } + + if (color_space) + { + CGColorSpaceRelease(color_space); + } + + return surface; +} + + +#pragma mark - +#pragma mark IMG_Init stubs +#if !defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) +static int Internal_checkImageIOisAvailable() { + // just check if we are running on ios 4 or more, else throw exception + if ([UIImage instancesRespondToSelector:@selector(initWithCGImage:scale:orientation:)]) + return 0; + [NSException raise:@"UIImage fallback not enabled at compile time" + format:@"ImageIO is not available on your platform, please recompile SDL_Image with ALLOW_UIIMAGE_FALLBACK."]; + return -1; +} +#endif + +int IMG_InitJPG() +{ + return 0; +} + +void IMG_QuitJPG() +{ +} + +int IMG_InitPNG() +{ + return 0; +} + +void IMG_QuitPNG() +{ +} + +int IMG_InitTIF() +{ + return 0; +} + +void IMG_QuitTIF() +{ +} + +#pragma mark - +#pragma mark Get type of image +static int Internal_isType_UIImage (SDL_RWops *rw_ops, CFStringRef uti_string_to_test) +{ + int is_type = 0; + +#if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) + int start = SDL_RWtell(rw_ops); + if ((0 == CFStringCompare(uti_string_to_test, kUTTypeICO, 0)) || + (0 == CFStringCompare(uti_string_to_test, CFSTR("com.microsoft.cur"), 0))) { + + // The Win32 ICO file header (14 bytes) + Uint16 bfReserved; + Uint16 bfType; + Uint16 bfCount; + int type = (0 == CFStringCompare(uti_string_to_test, kUTTypeICO, 0)) ? 1 : 2; + + bfReserved = SDL_ReadLE16(rw_ops); + bfType = SDL_ReadLE16(rw_ops); + bfCount = SDL_ReadLE16(rw_ops); + if ((bfReserved == 0) && (bfType == type) && (bfCount != 0)) + is_type = 1; + } else if (0 == CFStringCompare(uti_string_to_test, kUTTypeBMP, 0)) { + char magic[2]; + + if ( SDL_RWread(rw_ops, magic, sizeof(magic), 1) ) { + if ( strncmp(magic, "BM", 2) == 0 ) { + is_type = 1; + } + } + } else if (0 == CFStringCompare(uti_string_to_test, kUTTypeGIF, 0)) { + char magic[6]; + + if ( SDL_RWread(rw_ops, magic, sizeof(magic), 1) ) { + if ( (strncmp(magic, "GIF", 3) == 0) && + ((memcmp(magic + 3, "87a", 3) == 0) || + (memcmp(magic + 3, "89a", 3) == 0)) ) { + is_type = 1; + } + } + } else if (0 == CFStringCompare(uti_string_to_test, kUTTypeJPEG, 0)) { + int in_scan = 0; + Uint8 magic[4]; + + // This detection code is by Steaphan Greene + // Blame me, not Sam, if this doesn't work right. */ + // And don't forget to report the problem to the the sdl list too! */ + + if ( SDL_RWread(rw_ops, magic, 2, 1) ) { + if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) { + is_type = 1; + while (is_type == 1) { + if(SDL_RWread(rw_ops, magic, 1, 2) != 2) { + is_type = 0; + } else if( (magic[0] != 0xFF) && (in_scan == 0) ) { + is_type = 0; + } else if( (magic[0] != 0xFF) || (magic[1] == 0xFF) ) { + /* Extra padding in JPEG (legal) */ + /* or this is data and we are scanning */ + SDL_RWseek(rw_ops, -1, SEEK_CUR); + } else if(magic[1] == 0xD9) { + /* Got to end of good JPEG */ + break; + } else if( (in_scan == 1) && (magic[1] == 0x00) ) { + /* This is an encoded 0xFF within the data */ + } else if( (magic[1] >= 0xD0) && (magic[1] < 0xD9) ) { + /* These have nothing else */ + } else if(SDL_RWread(rw_ops, magic+2, 1, 2) != 2) { + is_type = 0; + } else { + /* Yes, it's big-endian */ + Uint32 start; + Uint32 size; + Uint32 end; + start = SDL_RWtell(rw_ops); + size = (magic[2] << 8) + magic[3]; + end = SDL_RWseek(rw_ops, size-2, SEEK_CUR); + if ( end != start + size - 2 ) is_type = 0; + if ( magic[1] == 0xDA ) { + /* Now comes the actual JPEG meat */ +#ifdef FAST_IS_JPEG + /* Ok, I'm convinced. It is a JPEG. */ + break; +#else + /* I'm not convinced. Prove it! */ + in_scan = 1; +#endif + } + } + } + } + } + } else if (0 == CFStringCompare(uti_string_to_test, kUTTypePNG, 0)) { + Uint8 magic[4]; + + if ( SDL_RWread(rw_ops, magic, 1, sizeof(magic)) == sizeof(magic) ) { + if ( magic[0] == 0x89 && + magic[1] == 'P' && + magic[2] == 'N' && + magic[3] == 'G' ) { + is_type = 1; + } + } + } else if (0 == CFStringCompare(uti_string_to_test, CFSTR("com.truevision.tga-image"), 0)) { + //TODO: fill me! + } else if (0 == CFStringCompare(uti_string_to_test, kUTTypeTIFF, 0)) { + Uint8 magic[4]; + + if ( SDL_RWread(rw_ops, magic, 1, sizeof(magic)) == sizeof(magic) ) { + if ( (magic[0] == 'I' && + magic[1] == 'I' && + magic[2] == 0x2a && + magic[3] == 0x00) || + (magic[0] == 'M' && + magic[1] == 'M' && + magic[2] == 0x00 && + magic[3] == 0x2a) ) { + is_type = 1; + } + } + } + + // reset the file descption pointer + SDL_RWseek(rw_ops, start, SEEK_SET); + +#endif /* #if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) */ + return is_type; +} + +static int Internal_isType_ImageIO (SDL_RWops *rw_ops, CFStringRef uti_string_to_test) +{ + int is_type = 0; + + CFDictionaryRef hint_dictionary = CreateHintDictionary(uti_string_to_test); + CGImageSourceRef image_source = CreateCGImageSourceFromRWops(rw_ops, hint_dictionary); + + if (hint_dictionary != NULL) { + CFRelease(hint_dictionary); + } + + if (NULL == image_source) { + return 0; + } + + // This will get the UTI of the container, not the image itself. + // Under most cases, this won't be a problem. + // But if a person passes an icon file which contains a bmp, + // the format will be of the icon file. + // But I think the main SDL_image codebase has this same problem so I'm not going to worry about it. + CFStringRef uti_type = CGImageSourceGetType(image_source); + // CFShow(uti_type); + + // Unsure if we really want conformance or equality + is_type = (int)UTTypeConformsTo(uti_string_to_test, uti_type); + + CFRelease(image_source); + return is_type; +} + +static int Internal_isType (SDL_RWops *rw_ops, CFStringRef uti_string_to_test) +{ + if (rw_ops == NULL) + return 0; + +#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) + if (USE_UIIMAGE_BACKEND()) + return Internal_isType_UIImage(rw_ops, uti_string_to_test); + else +#endif + return Internal_isType_ImageIO(rw_ops, uti_string_to_test); +} + +int IMG_isCUR(SDL_RWops *src) +{ + /* FIXME: Is this a supported type? */ + return Internal_isType(src, CFSTR("com.microsoft.cur")); +} + +int IMG_isICO(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypeICO); +} + +int IMG_isBMP(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypeBMP); +} + +int IMG_isGIF(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypeGIF); +} + +// Note: JPEG 2000 is kUTTypeJPEG2000 +int IMG_isJPG(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypeJPEG); +} + +int IMG_isPNG(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypePNG); +} + +// This isn't a public API function. Apple seems to be able to identify tga's. +int IMG_isTGA(SDL_RWops *src) +{ + return Internal_isType(src, CFSTR("com.truevision.tga-image")); +} + +int IMG_isTIF(SDL_RWops *src) +{ + return Internal_isType(src, kUTTypeTIFF); +} + +#pragma mark - +#pragma mark Load image engine +static SDL_Surface *LoadImageFromRWops_UIImage (SDL_RWops* rw_ops, CFStringRef uti_string_hint) +{ + SDL_Surface *sdl_surface = NULL; + +#if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) + NSAutoreleasePool* autorelease_pool = [[NSAutoreleasePool alloc] init]; + UIImage *ui_image; + int bytes_read = 0; + // I don't know what a good size is. + // Max recommended texture size is 1024x1024 on iPhone so maybe base it on that? + const int block_size = 1024*4; + char temp_buffer[block_size]; + + NSMutableData* ns_data = [[NSMutableData alloc] initWithCapacity:1024*1024*4]; + do { + bytes_read = SDL_RWread(rw_ops, temp_buffer, 1, block_size); + [ns_data appendBytes:temp_buffer length:bytes_read]; + } while (bytes_read > 0); + + ui_image = [[UIImage alloc] initWithData:ns_data]; + if (ui_image != nil) + sdl_surface = Create_SDL_Surface_From_CGImage([ui_image CGImage]); + [ui_image release]; + [ns_data release]; + [autorelease_pool drain]; + +#endif /* #if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) */ + return sdl_surface; +} + +static SDL_Surface *LoadImageFromRWops_ImageIO (SDL_RWops *rw_ops, CFStringRef uti_string_hint) +{ + CFDictionaryRef hint_dictionary = CreateHintDictionary(uti_string_hint); + CGImageSourceRef image_source = CreateCGImageSourceFromRWops(rw_ops, hint_dictionary); + + if (hint_dictionary != NULL) + CFRelease(hint_dictionary); + + if (NULL == image_source) + return NULL; + + CGImageRef image_ref = CreateCGImageFromCGImageSource(image_source); + CFRelease(image_source); + + if (NULL == image_ref) + return NULL; + SDL_Surface *sdl_surface = Create_SDL_Surface_From_CGImage(image_ref); + CFRelease(image_ref); + + return sdl_surface; +} + +static SDL_Surface *LoadImageFromRWops (SDL_RWops *rw_ops, CFStringRef uti_string_hint) +{ +#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) + if (USE_UIIMAGE_BACKEND()) + return LoadImageFromRWops_UIImage(rw_ops, uti_string_hint); + else +#endif + return LoadImageFromRWops_ImageIO(rw_ops, uti_string_hint); +} + +static SDL_Surface* LoadImageFromFile_UIImage (const char *file) +{ + SDL_Surface *sdl_surface = NULL; + +#if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) + NSAutoreleasePool* autorelease_pool = [[NSAutoreleasePool alloc] init]; + NSString *ns_string = [[NSString alloc] initWithUTF8String:file]; + UIImage *ui_image = [[UIImage alloc] initWithContentsOfFile:ns_string]; + if (ui_image != nil) + sdl_surface = Create_SDL_Surface_From_CGImage([ui_image CGImage]); + [ui_image release]; + [ns_string release]; + [autorelease_pool drain]; + +#endif /* #if defined(ALLOW_UIIMAGE_FALLBACK) && ((TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1)) */ + return sdl_surface; +} + +static SDL_Surface* LoadImageFromFile_ImageIO (const char *file) +{ + CGImageSourceRef image_source = NULL; + + image_source = CreateCGImageSourceFromFile(file); + + if(NULL == image_source) + return NULL; + + CGImageRef image_ref = CreateCGImageFromCGImageSource(image_source); + CFRelease(image_source); + + if (NULL == image_ref) + return NULL; + SDL_Surface *sdl_surface = Create_SDL_Surface_From_CGImage(image_ref); + CFRelease(image_ref); + return sdl_surface; +} + +static SDL_Surface* LoadImageFromFile (const char *file) +{ +#if (TARGET_OS_IPHONE == 1) || (TARGET_IPHONE_SIMULATOR == 1) + if (USE_UIIMAGE_BACKEND()) + return LoadImageFromFile_UIImage(file); + else +#endif + return LoadImageFromFile_ImageIO(file); +} + +SDL_Surface* IMG_LoadCUR_RW (SDL_RWops *src) +{ + /* FIXME: Is this a supported type? */ + return LoadImageFromRWops(src, CFSTR("com.microsoft.cur")); +} + +SDL_Surface* IMG_LoadICO_RW (SDL_RWops *src) +{ + return LoadImageFromRWops(src, kUTTypeICO); +} + +SDL_Surface* IMG_LoadBMP_RW (SDL_RWops *src) +{ + return LoadImageFromRWops(src, kUTTypeBMP); +} + +SDL_Surface* IMG_LoadGIF_RW (SDL_RWops *src) +{ + return LoadImageFromRWops (src, kUTTypeGIF); +} + +SDL_Surface* IMG_LoadJPG_RW (SDL_RWops *src) +{ + return LoadImageFromRWops (src, kUTTypeJPEG); +} + +SDL_Surface* IMG_LoadPNG_RW (SDL_RWops *src) +{ + return LoadImageFromRWops (src, kUTTypePNG); +} + +SDL_Surface* IMG_LoadTGA_RW (SDL_RWops *src) +{ + return LoadImageFromRWops(src, CFSTR("com.truevision.tga-image")); +} + +SDL_Surface* IMG_LoadTIF_RW (SDL_RWops *src) +{ + return LoadImageFromRWops(src, kUTTypeTIFF); +} + +// Since UIImage doesn't really support streams well, we should optimize for the file case. +// Apple provides both stream and file loading functions in ImageIO. +// Potentially, Apple can optimize for either case. +SDL_Surface* IMG_Load (const char *file) +{ + SDL_Surface* sdl_surface = NULL; + + sdl_surface = LoadImageFromFile(file); + if(NULL == sdl_surface) + { + // Either the file doesn't exist or ImageIO doesn't understand the format. + // For the latter case, fallback to the native SDL_image handlers. + SDL_RWops *src = SDL_RWFromFile(file, "rb"); + char *ext = strrchr(file, '.'); + if (ext) { + ext++; + } + if (!src) { + /* The error message has been set in SDL_RWFromFile */ + return NULL; + } + sdl_surface = IMG_LoadTyped_RW(src, 1, ext); + } + return sdl_surface; +} + +#endif /* defined(__APPLE__) && !defined(SDL_IMAGE_USE_COMMON_BACKEND) */ diff --git a/Makefile.am b/Makefile.am index 2144cd80..42a21aec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,7 +21,7 @@ libSDL_image_la_SOURCES = \ IMG_xpm.c \ IMG_xv.c \ IMG_webp.c \ - IMG_ImageIO.c + IMG_ImageIO.m EXTRA_DIST = \ Android.mk \ diff --git a/Xcode/SDL_image.xcodeproj/project.pbxproj b/Xcode/SDL_image.xcodeproj/project.pbxproj index 810f2518..78478b71 100755 --- a/Xcode/SDL_image.xcodeproj/project.pbxproj +++ b/Xcode/SDL_image.xcodeproj/project.pbxproj @@ -8,8 +8,8 @@ /* Begin PBXBuildFile section */ 005DF5E90A140CA2006B0BD5 /* IMG_xv.c in Sources */ = {isa = PBXBuildFile; fileRef = 005DF5E70A140CA2006B0BD5 /* IMG_xv.c */; }; - 007287E40F0D997300C302A9 /* IMG_ImageIO.c in Sources */ = {isa = PBXBuildFile; fileRef = 007287E30F0D997300C302A9 /* IMG_ImageIO.c */; }; - 007287E50F0D997300C302A9 /* IMG_ImageIO.c in Sources */ = {isa = PBXBuildFile; fileRef = 007287E30F0D997300C302A9 /* IMG_ImageIO.c */; }; + 007287E40F0D997300C302A9 /* IMG_ImageIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 007287E30F0D997300C302A9 /* IMG_ImageIO.m */; }; + 007287E50F0D997300C302A9 /* IMG_ImageIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 007287E30F0D997300C302A9 /* IMG_ImageIO.m */; }; 007288A70F0DA79800C302A9 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007288A60F0DA79800C302A9 /* ApplicationServices.framework */; }; 007288A80F0DA79800C302A9 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007288A60F0DA79800C302A9 /* ApplicationServices.framework */; }; 007289690F0DC29B00C302A9 /* IMG_lbm.c in Sources */ = {isa = PBXBuildFile; fileRef = F5FB1F0001CD818601FAFB42 /* IMG_lbm.c */; }; @@ -19,6 +19,7 @@ 0072897B0F0DC2D100C302A9 /* IMG_xpm.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C062012FAC847F000001 /* IMG_xpm.c */; }; 0072897C0F0DC2D300C302A9 /* IMG_xv.c in Sources */ = {isa = PBXBuildFile; fileRef = 005DF5E70A140CA2006B0BD5 /* IMG_xv.c */; }; 0072897D0F0DC2D400C302A9 /* IMG_xxx.c in Sources */ = {isa = PBXBuildFile; fileRef = B2D7A06503FAB42200A8000A /* IMG_xxx.c */; }; + 61F8544A145A19BC002CA294 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61F85449145A19BC002CA294 /* Foundation.framework */; }; BE1FA71A07AF4C44004B6283 /* SDL_image.h in Headers */ = {isa = PBXBuildFile; fileRef = 1014BAEA010A4B677F000001 /* SDL_image.h */; settings = {ATTRIBUTES = (Public, ); }; }; BE1FA71D07AF4C44004B6283 /* IMG.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C058012FAC847F000001 /* IMG.c */; }; BE1FA73207AF4C45004B6283 /* IMG.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C058012FAC847F000001 /* IMG.c */; }; @@ -43,7 +44,7 @@ /* Begin PBXFileReference section */ 005DF5E70A140CA2006B0BD5 /* IMG_xv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xv.c; path = ../IMG_xv.c; sourceTree = SOURCE_ROOT; }; - 007287E30F0D997300C302A9 /* IMG_ImageIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IMG_ImageIO.c; path = ../IMG_ImageIO.c; sourceTree = ""; }; + 007287E30F0D997300C302A9 /* IMG_ImageIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IMG_ImageIO.m; path = ../IMG_ImageIO.m; sourceTree = ""; }; 007288A60F0DA79800C302A9 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; 1014BAEA010A4B677F000001 /* SDL_image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_image.h; path = ../SDL_image.h; sourceTree = SOURCE_ROOT; }; 3BB4C058012FAC847F000001 /* IMG.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG.c; path = ../IMG.c; sourceTree = SOURCE_ROOT; }; @@ -57,6 +58,7 @@ 3BB4C060012FAC847F000001 /* IMG_tif.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_tif.c; path = ../IMG_tif.c; sourceTree = SOURCE_ROOT; }; 3BB4C061012FAC847F000001 /* IMG_xcf.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xcf.c; path = ../IMG_xcf.c; sourceTree = SOURCE_ROOT; }; 3BB4C062012FAC847F000001 /* IMG_xpm.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xpm.c; path = ../IMG_xpm.c; sourceTree = SOURCE_ROOT; }; + 61F85449145A19BC002CA294 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; B2D7A06503FAB42200A8000A /* IMG_xxx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG_xxx.c; path = ../IMG_xxx.c; sourceTree = SOURCE_ROOT; }; BE1FA72D07AF4C44004B6283 /* Info-Framework__Upgraded_.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-Framework__Upgraded_.plist"; sourceTree = ""; }; BE1FA72E07AF4C45004B6283 /* SDL_image.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL_image.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -76,6 +78,7 @@ files = ( BE1FA76307AF7335004B6283 /* SDL.framework in Frameworks */, 007288A70F0DA79800C302A9 /* ApplicationServices.framework in Frameworks */, + 61F8544A145A19BC002CA294 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -146,7 +149,7 @@ 3BB4C062012FAC847F000001 /* IMG_xpm.c */, 005DF5E70A140CA2006B0BD5 /* IMG_xv.c */, B2D7A06503FAB42200A8000A /* IMG_xxx.c */, - 007287E30F0D997300C302A9 /* IMG_ImageIO.c */, + 007287E30F0D997300C302A9 /* IMG_ImageIO.m */, ); name = "Library Source"; sourceTree = ""; @@ -164,6 +167,7 @@ isa = PBXGroup; children = ( BE1FA76007AF72B1004B6283 /* Linked Frameworks */, + 61F85449145A19BC002CA294 /* Foundation.framework */, ); name = Frameworks; sourceTree = ""; @@ -271,7 +275,14 @@ isa = PBXProject; buildConfigurationList = 00B7E3B6097EB73D00826121 /* Build configuration list for PBXProject "SDL_image" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 0867D691FE84028FC02AAC07 /* SDL_imageFramework */; productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */; projectDirPath = ""; @@ -329,7 +340,7 @@ buildActionMask = 2147483647; files = ( BE1FA71D07AF4C44004B6283 /* IMG.c in Sources */, - 007287E40F0D997300C302A9 /* IMG_ImageIO.c in Sources */, + 007287E40F0D997300C302A9 /* IMG_ImageIO.m in Sources */, 007289690F0DC29B00C302A9 /* IMG_lbm.c in Sources */, 0072896A0F0DC29F00C302A9 /* IMG_pcx.c in Sources */, 007289720F0DC2BD00C302A9 /* IMG_pnm.c in Sources */, @@ -352,7 +363,7 @@ BE1FA73D07AF4C45004B6283 /* IMG_lbm.c in Sources */, BE1FA73E07AF4C45004B6283 /* IMG_xxx.c in Sources */, 005DF5E90A140CA2006B0BD5 /* IMG_xv.c in Sources */, - 007287E50F0D997300C302A9 /* IMG_ImageIO.c in Sources */, + 007287E50F0D997300C302A9 /* IMG_ImageIO.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Xcode/showimage/showimage.xcodeproj/project.pbxproj b/Xcode/showimage/showimage.xcodeproj/project.pbxproj index 8c912a6a..6d2d85b4 100644 --- a/Xcode/showimage/showimage.xcodeproj/project.pbxproj +++ b/Xcode/showimage/showimage.xcodeproj/project.pbxproj @@ -158,7 +158,14 @@ isa = PBXProject; buildConfigurationList = 00B7E563097EF9A500826121 /* Build configuration list for PBXProject "showimage" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 0; + knownRegions = ( + English, + Japanese, + French, + German, + ); mainGroup = 29B97314FDCFA39411CA2CEA /* SDL App */; projectDirPath = ""; projectRoot = ""; diff --git a/Xcode_iPhone/SDL_image.xcodeproj/project.pbxproj b/Xcode_iPhone/SDL_image.xcodeproj/project.pbxproj index e37c81c2..6ce93890 100755 --- a/Xcode_iPhone/SDL_image.xcodeproj/project.pbxproj +++ b/Xcode_iPhone/SDL_image.xcodeproj/project.pbxproj @@ -11,7 +11,7 @@ 007288A80F0DA79800C302A9 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007288A60F0DA79800C302A9 /* ApplicationServices.framework */; }; 00728B2A0F0E004C00C302A9 /* IMG_tga.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C05F012FAC847F000001 /* IMG_tga.c */; }; 00A06D7812FFBFD5009F1A11 /* SDL_image.h in Headers */ = {isa = PBXBuildFile; fileRef = 1014BAEA010A4B677F000001 /* SDL_image.h */; }; - 00A6250312F4E9CC00577F68 /* IMG_ImageIO.c in Sources */ = {isa = PBXBuildFile; fileRef = 00A624FD12F4E99800577F68 /* IMG_ImageIO.c */; }; + 00A6250312F4E9CC00577F68 /* IMG_ImageIO.m in Sources */ = {isa = PBXBuildFile; fileRef = 00A624FD12F4E99800577F68 /* IMG_ImageIO.m */; }; 00A625CF12F544F400577F68 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00A625CE12F544F400577F68 /* ImageIO.framework */; }; BE1FA73207AF4C45004B6283 /* IMG.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C058012FAC847F000001 /* IMG.c */; }; BE1FA73607AF4C45004B6283 /* IMG_pcx.c in Sources */ = {isa = PBXBuildFile; fileRef = 3BB4C05C012FAC847F000001 /* IMG_pcx.c */; }; @@ -27,23 +27,16 @@ isa = PBXContainerItemProxy; containerPortal = 00A06D6A12FFBF9F009F1A11 /* SDLiPhoneOS.xcodeproj */; proxyType = 2; - remoteGlobalIDString = FD6526630DE8FCCB002AD96B /* libSDL.a */; + remoteGlobalIDString = FD6526630DE8FCCB002AD96B; remoteInfo = libSDL; }; 00A06D7412FFBF9F009F1A11 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 00A06D6A12FFBF9F009F1A11 /* SDLiPhoneOS.xcodeproj */; proxyType = 2; - remoteGlobalIDString = 006E982211955059001DE610 /* testsdl.app */; + remoteGlobalIDString = 006E982211955059001DE610; remoteInfo = testsdl; }; - 00A06D7612FFBFB4009F1A11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00A06D6A12FFBF9F009F1A11 /* SDLiPhoneOS.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 0064653F107E3D7400183915 /* Generate Header Files */; - remoteInfo = "Generate Header Files"; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -51,7 +44,7 @@ 007288A60F0DA79800C302A9 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; 00728B3F0F0E008100C302A9 /* IMG_UIImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IMG_UIImage.m; path = ../IMG_UIImage.m; sourceTree = SOURCE_ROOT; }; 00A06D6A12FFBF9F009F1A11 /* SDLiPhoneOS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDLiPhoneOS.xcodeproj; path = "../../SDL/Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj"; sourceTree = SOURCE_ROOT; }; - 00A624FD12F4E99800577F68 /* IMG_ImageIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = IMG_ImageIO.c; path = ../IMG_ImageIO.c; sourceTree = SOURCE_ROOT; }; + 00A624FD12F4E99800577F68 /* IMG_ImageIO.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IMG_ImageIO.m; path = ../IMG_ImageIO.m; sourceTree = SOURCE_ROOT; }; 00A625CE12F544F400577F68 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; 1014BAEA010A4B677F000001 /* SDL_image.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_image.h; path = ../SDL_image.h; sourceTree = SOURCE_ROOT; }; 3BB4C058012FAC847F000001 /* IMG.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = IMG.c; path = ../IMG.c; sourceTree = SOURCE_ROOT; }; @@ -136,7 +129,7 @@ 08FB77ACFE841707C02AAC07 /* Library Source */ = { isa = PBXGroup; children = ( - 00A624FD12F4E99800577F68 /* IMG_ImageIO.c */, + 00A624FD12F4E99800577F68 /* IMG_ImageIO.m */, 3BB4C058012FAC847F000001 /* IMG.c */, 3BB4C059012FAC847F000001 /* IMG_bmp.c */, 3BB4C05A012FAC847F000001 /* IMG_gif.c */, @@ -218,7 +211,6 @@ buildRules = ( ); dependencies = ( - 00A06D7712FFBFB4009F1A11 /* PBXTargetDependency */, ); name = libSDL_image; productInstallPath = /usr/local/lib; @@ -298,20 +290,12 @@ BE1FA73E07AF4C45004B6283 /* IMG_xxx.c in Sources */, 005DF5E90A140CA2006B0BD5 /* IMG_xv.c in Sources */, 00728B2A0F0E004C00C302A9 /* IMG_tga.c in Sources */, - 00A6250312F4E9CC00577F68 /* IMG_ImageIO.c in Sources */, + 00A6250312F4E9CC00577F68 /* IMG_ImageIO.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 00A06D7712FFBFB4009F1A11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "Generate Header Files"; - targetProxy = 00A06D7612FFBFB4009F1A11 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 007288110F0DA5BA00C302A9 /* Debug */ = { isa = XCBuildConfiguration; diff --git a/configure.in b/configure.in index 459037cd..6d2c0a38 100644 --- a/configure.in +++ b/configure.in @@ -47,6 +47,7 @@ AM_INIT_AUTOMAKE(SDL_image, $VERSION) dnl Check for tools AC_PROG_LIBTOOL AC_PROG_CC +AC_PROG_OBJC AC_C_INLINE AC_PROG_INSTALL AC_PROG_MAKE_SET @@ -370,6 +371,8 @@ LIBS="$saved_LIBS" AC_SUBST([WINDRES]) AC_SUBST([IMG_LIBS]) +OBJCFLAGS=$CFLAGS + # Finally create all the generated files AC_OUTPUT([ Makefile