]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/quartz/quartzloader.cpp
Add some state checking to ImageLoader
[libs/gui.git] / source / graphics / quartz / quartzloader.cpp
index 23f7abbed319031ff0e3b23f99b096bf9159174d..472e066f49665a64356cf1c50d93fba878589487 100644 (file)
@@ -1,7 +1,5 @@
 #include <algorithm>
-#include <CoreGraphics/CGColorSpace.h>
-#include <CoreGraphics/CGImage.h>
-#include <ImageIO/CGImageSource.h>
+#include <ApplicationServices/ApplicationServices.h>
 // Avoid messing up sigc++ headers
 #undef nil
 #include "quartzloader.h"
@@ -57,8 +55,6 @@ struct QuartzLoader::Private
 };
 
 
-ImageLoader::Register<QuartzLoader> QuartzLoader::reg;
-
 QuartzLoader::QuartzLoader(IO::Seekable &io):
        priv(new Private)
 {
@@ -82,17 +78,20 @@ bool QuartzLoader::detect(const string &sig)
        CFRelease(data);
        CFRelease(source);
 
-       return status==kCGImageStatusIncomplete;
+       return status==kCGImageStatusIncomplete || status==kCGImageStatusReadingHeader;
 }
 
-void QuartzLoader::load(Image::Data &data)
+void QuartzLoader::load_(Image::Data &data)
 {
        CGImageRef image = CGImageSourceCreateImageAtIndex(priv->source, 0, 0);
+       if(!image)
+               throw bad_image_data("null image");
 
        try
        {
                data.width = CGImageGetWidth(image);
                data.height = CGImageGetHeight(image);
+               data.stride = CGImageGetBytesPerRow(image);
 
                CGColorSpaceRef color = CGImageGetColorSpace(image);
                CGColorSpaceModel model = CGColorSpaceGetModel(color);
@@ -101,7 +100,9 @@ void QuartzLoader::load(Image::Data &data)
                {
                        if(alpha==kCGImageAlphaLast)
                                data.fmt = RGBA;
-                       else if(alpha==kCGImageAlphaNone || alpha==kCGImageAlphaNoneSkipFirst || alpha==kCGImageAlphaNoneSkipLast)
+                       else if(alpha==kCGImageAlphaNoneSkipLast || alpha==kCGImageAlphaNoneSkipFirst)
+                               data.fmt = RGBX;
+                       else if(alpha==kCGImageAlphaNone)
                                data.fmt = RGB;
                        else
                                throw unsupported_image_format("unknown alpha mode");
@@ -109,31 +110,15 @@ void QuartzLoader::load(Image::Data &data)
                else
                        throw unsupported_image_format("unknown colorspace");
 
-               unsigned bytes_per_pixel = (CGImageGetBitsPerPixel(image)+7)/8;
-
                CGDataProviderRef dp = CGImageGetDataProvider(image);
                CFDataRef image_data = CGDataProviderCopyData(dp);
-               data.data = new char[data.width*data.height*bytes_per_pixel];
-               CFDataGetBytes(image_data, CFRangeMake(0, CFDataGetLength(image_data)), reinterpret_cast<UInt8 *>(data.data));
+               data.pixels = new char[data.height*data.stride];
+               unsigned offset = (alpha==kCGImageAlphaNoneSkipFirst);
+               CFRange range = CFRangeMake(offset, CFDataGetLength(image_data)-offset);
+               CFDataGetBytes(image_data, range, reinterpret_cast<UInt8 *>(data.pixels));
                CFRelease(image_data);
 
                CFRelease(image);
-
-               if(alpha==kCGImageAlphaNoneSkipFirst || alpha==kCGImageAlphaNoneSkipLast)
-               {
-                       const char *src = data.data;
-                       if(alpha==kCGImageAlphaNoneSkipFirst)
-                               ++src;
-                       char *dest = data.data;
-                       for(unsigned y=0; y<data.height; ++y)
-                               for(unsigned x=0; x<data.width; ++x)
-                               {
-                                       for(unsigned i=0; i<3; ++i)
-                                               dest[i] = src[i];
-                                       dest += 3;
-                                       src += 4;
-                               }
-               }
        }
        catch(...)
        {