From 5bd37a1113a7d20560149bce0102b5361a19d451 Mon Sep 17 00:00:00 2001 From: Tommi Komulainen Date: Mon, 9 Jun 2008 21:15:12 +0000 Subject: [PATCH] cogl: add support for quartz imagebackend Bug #930 - add support for quartz imagebackend * clutter/cogl/common/cogl-bitmap-pixbuf.c (_cogl_bitmap_from_file): When USE_QUARTZ is defined implement using Core Graphics. * configure.ac: support --with-imagebackend=quartz and print which imagebackend is selected. Make quartz default on OSX --- common/cogl-bitmap-pixbuf.c | 114 +++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) diff --git a/common/cogl-bitmap-pixbuf.c b/common/cogl-bitmap-pixbuf.c index 906cee01b..dd9dd0277 100644 --- a/common/cogl-bitmap-pixbuf.c +++ b/common/cogl-bitmap-pixbuf.c @@ -33,7 +33,9 @@ #include -#ifdef USE_GDKPIXBUF +#ifdef USE_QUARTZ +#include +#elif defined(USE_GDKPIXBUF) #include #endif @@ -64,7 +66,115 @@ _cogl_bitmap_unpremult (const CoglBitmap *bmp, return FALSE; } -#ifdef USE_GDKPIXBUF +#ifdef USE_QUARTZ + +/* lacking GdkPixbuf and other useful GError domains, define one of our own */ + +#define COGL_BITMAP_ERROR cogl_bitmap_error_quark () + +typedef enum { + COGL_BITMAP_ERROR_FAILED, + COGL_BITMAP_ERROR_UNKNOWN_TYPE, + COGL_BITMAP_ERROR_CORRUPT_IMAGE +} CoglBitmapError; + +GQuark +cogl_bitmap_error_quark (void) +{ + return g_quark_from_static_string ("cogl-bitmap-error-quark"); +} + +/* the error does not contain the filename as the caller already has it */ +gboolean +_cogl_bitmap_from_file (CoglBitmap *bmp, + const gchar *filename, + GError **error) +{ + g_assert (bmp != NULL); + g_assert (filename != NULL); + g_assert (error == NULL || *error == NULL); + + CFURLRef url = CFURLCreateFromFileSystemRepresentation (NULL, (guchar*)filename, strlen(filename), false); + CGImageSourceRef image_source = CGImageSourceCreateWithURL (url, NULL); + int save_errno = errno; + CFRelease (url); + if (image_source == NULL) + { + /* doesn't exist, not readable, etc. */ + g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_FAILED, + "%s", g_strerror (save_errno)); + return FALSE; + } + + /* Unknown images would be cleanly caught as zero width/height below, but try + * to provide better error message + */ + CFStringRef type = CGImageSourceGetType (image_source); + if (type == NULL) + { + CFRelease (image_source); + g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_UNKNOWN_TYPE, + "Unknown image type"); + return FALSE; + } + CFRelease (type); + + CGImageRef image = CGImageSourceCreateImageAtIndex (image_source, 0, NULL); + CFRelease (image_source); + + size_t width = CGImageGetWidth (image); + size_t height = CGImageGetHeight (image); + if (width == 0 || height == 0) + { + /* incomplete or corrupt */ + CFRelease (image); + g_set_error (error, COGL_BITMAP_ERROR, COGL_BITMAP_ERROR_CORRUPT_IMAGE, + "Image has zero width or height"); + return FALSE; + } + + /* allocate buffer big enough to hold pixel data */ + size_t rowstride; + CGBitmapInfo bitmap_info = CGImageGetBitmapInfo (image); + if ((bitmap_info & kCGBitmapAlphaInfoMask) == kCGImageAlphaNone) + { + bitmap_info = kCGImageAlphaNone; + rowstride = 3 * width; + } + else + { + bitmap_info = kCGImageAlphaPremultipliedFirst; + rowstride = 4 * width; + } + guint8 *out_data = g_malloc0 (height * rowstride); + + /* render to buffer */ + CGColorSpaceRef color_space = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB); + CGContextRef bitmap_context = CGBitmapContextCreate (out_data, + width, height, 8, + rowstride, color_space, + bitmap_info); + CGColorSpaceRelease (color_space); + + const CGRect rect = {{0, 0}, {width, height}}; + CGContextDrawImage (bitmap_context, rect, image); + + CGImageRelease (image); + CGContextRelease (bitmap_context); + + /* store bitmap info */ + bmp->data = out_data; + bmp->format = bitmap_info == kCGImageAlphaPremultipliedFirst + ? COGL_PIXEL_FORMAT_ARGB_8888 + : COGL_PIXEL_FORMAT_RGB_888; + bmp->width = width; + bmp->height = height; + bmp->rowstride = rowstride; + + return TRUE; +} + +#elif defined(USE_GDKPIXBUF) gboolean _cogl_bitmap_from_file (CoglBitmap *bmp,