SkCreateCGImageRef.cpp revision 0d55f1e73cbbf5456fb05108a0db1f33dafdae79
1#include "SkCGUtils.h"
2#include "SkBitmap.h"
3
4extern CGImageRef SkCreateCGImageRef(const SkBitmap&);
5
6static const void* SkBitmap_GetBytesPointer(void* info) {
7    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
8    bitmap->lockPixels();
9    return bitmap->getPixels();
10}
11
12static void SkBitmap_ReleaseBytePointer(void* info, const void* pointer) {
13    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
14    bitmap->unlockPixels();
15}
16
17static size_t SkBitmap_GetBytesAtPosition(void* info, void* buffer,
18                                             off_t offset, size_t count) {
19    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
20    bitmap->lockPixels();
21    memcpy(buffer, (const char*)bitmap->getPixels() + offset, count);
22    bitmap->unlockPixels();
23    return count;
24}
25
26static void SkBitmap_ReleaseInfo(void* info) {
27    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
28    delete bitmap;
29}
30
31static SkBitmap* prepareForImageRef(const SkBitmap& bm,
32                                    size_t* bitsPerComponent,
33                                    CGBitmapInfo* info) {
34    switch (bm.config()) {
35        case SkBitmap::kARGB_8888_Config:
36            *bitsPerComponent = 8;
37            // try to match our argb ordering in SkColorPriv
38            *info = kCGBitmapByteOrder32Big |
39                    kCGImageAlphaPremultipliedLast;
40            break;
41        default:
42            return NULL;
43    }
44
45    return new SkBitmap(bm);
46}
47
48CGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
49    size_t bitsPerComponent;
50    CGBitmapInfo info;
51
52    SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
53    if (NULL == bitmap) {
54        return NULL;
55    }
56
57    const int w = bitmap->width();
58    const int h = bitmap->height();
59    const size_t s = bitmap->getSize();
60
61    CGDataProviderDirectCallbacks procs;
62    procs.version = 0;
63    procs.getBytePointer = SkBitmap_GetBytesPointer;
64    procs.releaseBytePointer = SkBitmap_ReleaseBytePointer;
65    procs.getBytesAtPosition = SkBitmap_GetBytesAtPosition;
66    procs.releaseInfo = SkBitmap_ReleaseInfo;
67
68    // our provider "owns" the bitmap*, and will take care of deleting it
69    CGDataProviderRef dataRef = CGDataProviderCreateDirect(bitmap, s, &procs);
70    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
71    CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
72                                   bitmap->bytesPerPixel() * 8,
73                                   bitmap->rowBytes(), space, info, dataRef,
74                                   NULL, false, kCGRenderingIntentDefault);
75    CGColorSpaceRelease(space);
76    CGDataProviderRelease(dataRef);
77    return ref;
78}
79
80
81