SkCreateCGImageRef.cpp revision 0d55f1e73cbbf5456fb05108a0db1f33dafdae79
10d55f1e73cbbf5456fb05108a0db1f33dafdae79reed@android.com#include "SkCGUtils.h"
2758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com#include "SkBitmap.h"
3758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
4758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comextern CGImageRef SkCreateCGImageRef(const SkBitmap&);
5758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
6758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comstatic const void* SkBitmap_GetBytesPointer(void* info) {
7758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
8758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    bitmap->lockPixels();
9758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    return bitmap->getPixels();
10758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
11758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
12758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comstatic void SkBitmap_ReleaseBytePointer(void* info, const void* pointer) {
13758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
14758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    bitmap->unlockPixels();
15758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
16758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
17758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comstatic size_t SkBitmap_GetBytesAtPosition(void* info, void* buffer,
18758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                             off_t offset, size_t count) {
19758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
20758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    bitmap->lockPixels();
21758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    memcpy(buffer, (const char*)bitmap->getPixels() + offset, count);
22758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    bitmap->unlockPixels();
23758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    return count;
24758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
25758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
26758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comstatic void SkBitmap_ReleaseInfo(void* info) {
27758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
28758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    delete bitmap;
29758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
30758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
31758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comstatic SkBitmap* prepareForImageRef(const SkBitmap& bm,
32758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                    size_t* bitsPerComponent,
33758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                    CGBitmapInfo* info) {
34758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    switch (bm.config()) {
35758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com        case SkBitmap::kARGB_8888_Config:
36758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com            *bitsPerComponent = 8;
37758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com            // try to match our argb ordering in SkColorPriv
38758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com            *info = kCGBitmapByteOrder32Big |
39758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                    kCGImageAlphaPremultipliedLast;
40758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com            break;
41758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com        default:
42758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com            return NULL;
43758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    }
44758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
45758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    return new SkBitmap(bm);
46758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
47758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
48758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.comCGImageRef SkCreateCGImageRef(const SkBitmap& bm) {
49758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    size_t bitsPerComponent;
50758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGBitmapInfo info;
51758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
52758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
53758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    if (NULL == bitmap) {
54758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com        return NULL;
55758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    }
56758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
57758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    const int w = bitmap->width();
58758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    const int h = bitmap->height();
59758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    const size_t s = bitmap->getSize();
60758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
61758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGDataProviderDirectCallbacks procs;
62758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    procs.version = 0;
63758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    procs.getBytePointer = SkBitmap_GetBytesPointer;
64758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    procs.releaseBytePointer = SkBitmap_ReleaseBytePointer;
65758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    procs.getBytesAtPosition = SkBitmap_GetBytesAtPosition;
66758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    procs.releaseInfo = SkBitmap_ReleaseInfo;
67758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
68758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    // our provider "owns" the bitmap*, and will take care of deleting it
69758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGDataProviderRef dataRef = CGDataProviderCreateDirect(bitmap, s, &procs);
70758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
71758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
72758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                   bitmap->bytesPerPixel() * 8,
73758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                   bitmap->rowBytes(), space, info, dataRef,
74758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com                                   NULL, false, kCGRenderingIntentDefault);
75758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGColorSpaceRelease(space);
76758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    CGDataProviderRelease(dataRef);
77758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com    return ref;
78758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com}
79758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
80758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com
81