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
This commit is contained in:
Tommi Komulainen 2008-06-09 21:15:12 +00:00
parent bbf536ac41
commit 5bd37a1113

View File

@ -33,7 +33,9 @@
#include <string.h> #include <string.h>
#ifdef USE_GDKPIXBUF #ifdef USE_QUARTZ
#include <ApplicationServices/ApplicationServices.h>
#elif defined(USE_GDKPIXBUF)
#include <gdk-pixbuf/gdk-pixbuf.h> #include <gdk-pixbuf/gdk-pixbuf.h>
#endif #endif
@ -64,7 +66,115 @@ _cogl_bitmap_unpremult (const CoglBitmap *bmp,
return FALSE; 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 gboolean
_cogl_bitmap_from_file (CoglBitmap *bmp, _cogl_bitmap_from_file (CoglBitmap *bmp,