1 #include "quartzloader.h"
3 #include <ApplicationServices/ApplicationServices.h>
9 size_t get_bytes(void *info, void *buffer, size_t count)
11 Msp::IO::Seekable *io = reinterpret_cast<Msp::IO::Seekable *>(info);
12 char *cbuf = reinterpret_cast<char *>(buffer);
13 return io->read(cbuf, count);
16 off_t skip_forward(void *info, off_t count)
18 Msp::IO::Seekable *io = reinterpret_cast<Msp::IO::Seekable *>(info);
23 i += io->read(buf, min<unsigned>(sizeof(buf), count-i));
28 void rewind(void *info)
30 Msp::IO::Seekable *io = reinterpret_cast<Msp::IO::Seekable *>(info);
31 io->seek(0, Msp::IO::S_BEG);
34 CGDataProviderSequentialCallbacks callbacks =
49 struct QuartzLoader::Private
51 CGDataProviderRef provider;
52 CGImageSourceRef source;
56 QuartzLoader::QuartzLoader(IO::Seekable &io):
59 priv->provider = CGDataProviderCreateSequential(&io, &callbacks);
60 priv->source = CGImageSourceCreateWithDataProvider(priv->provider, 0);
63 QuartzLoader::~QuartzLoader()
65 CFRelease(priv->source);
66 CFRelease(priv->provider);
70 bool QuartzLoader::detect(const string &sig)
72 CGImageSourceRef source = CGImageSourceCreateIncremental(0);
73 CFDataRef data = CFDataCreate(0, reinterpret_cast<const UInt8 *>(sig.data()), sig.size());
74 CGImageSourceUpdateData(source, data, false);
75 CGImageSourceStatus status = CGImageSourceGetStatus(source);
79 return status==kCGImageStatusIncomplete || status==kCGImageStatusReadingHeader;
82 void QuartzLoader::load_(Image::Data &data)
84 CGImageRef image = CGImageSourceCreateImageAtIndex(priv->source, 0, 0);
86 throw bad_image_data("null image");
90 data.width = CGImageGetWidth(image);
91 data.height = CGImageGetHeight(image);
92 data.stride = CGImageGetBytesPerRow(image);
94 CGColorSpaceRef color = CGImageGetColorSpace(image);
95 CGColorSpaceModel model = CGColorSpaceGetModel(color);
96 CGImageAlphaInfo alpha = CGImageGetAlphaInfo(image);
97 if(model==kCGColorSpaceModelRGB)
99 if(alpha==kCGImageAlphaLast)
101 else if(alpha==kCGImageAlphaNoneSkipLast || alpha==kCGImageAlphaNoneSkipFirst)
103 else if(alpha==kCGImageAlphaNone)
106 throw unsupported_image_format("unknown alpha mode");
109 throw unsupported_image_format("unknown colorspace");
118 void QuartzLoader::load_(Image::Data &data)
120 CGDataProviderRef dp = CGImageGetDataProvider(image);
121 CFDataRef image_data = CGDataProviderCopyData(dp);
122 unsigned offset = (alpha==kCGImageAlphaNoneSkipFirst);
123 CFRange range = CFRangeMake(offset, CFDataGetLength(image_data)-offset);
124 CFDataGetBytes(image_data, range, reinterpret_cast<UInt8 *>(data.pixels));
125 CFRelease(image_data);
130 } // namespace Graphics