1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 71ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 81ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include "SkTypes.h" 91ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 101ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 110d55f1e73cbbf5456fb05108a0db1f33dafdae79reed@android.com#include "SkCGUtils.h" 12758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com#include "SkBitmap.h" 13a545a5598e59c22c529e5f33964df1ddd6601ac2reed@android.com#include "SkColorPriv.h" 14758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 1560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgstatic CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) { 1660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo info = kCGBitmapByteOrder32Big; 1760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (at) { 1844977485bdac75c055c3fa638f118874ccd2d22freed case kUnknown_SkAlphaType: 1944977485bdac75c055c3fa638f118874ccd2d22freed break; 2060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kOpaque_SkAlphaType: 2160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaNoneSkipLast; 2260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 2360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kPremul_SkAlphaType: 2460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaPremultipliedLast; 2560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 2660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kUnpremul_SkAlphaType: 2760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaLast; 2860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 2960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 3060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return info; 3160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 3260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 3360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgstatic CGBitmapInfo ComputeCGAlphaInfo_BGRA(SkAlphaType at) { 3460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo info = kCGBitmapByteOrder32Little; 3560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (at) { 3644977485bdac75c055c3fa638f118874ccd2d22freed case kUnknown_SkAlphaType: 3744977485bdac75c055c3fa638f118874ccd2d22freed break; 3860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kOpaque_SkAlphaType: 3960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaNoneSkipFirst; 4060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 4160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kPremul_SkAlphaType: 4260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaPremultipliedFirst; 4360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 4460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kUnpremul_SkAlphaType: 4560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaFirst; 4660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 4760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 4860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return info; 4960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 5060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 512b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.comstatic void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) { 52758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info); 53758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com delete bitmap; 54758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 55758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 56d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic bool getBitmapInfo(const SkBitmap& bm, 579c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com size_t* bitsPerComponent, 589c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com CGBitmapInfo* info, 599c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com bool* upscaleTo32) { 609c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (upscaleTo32) { 619c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com *upscaleTo32 = false; 629c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 64e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org switch (bm.colorType()) { 65e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org case kRGB_565_SkColorType: 66e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org#if 0 67e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org // doesn't see quite right. Are they thinking 1555? 68e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org *bitsPerComponent = 5; 69e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; 7060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org#else 719c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (upscaleTo32) { 729c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com *upscaleTo32 = true; 739c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 7460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // now treat like RGBA 75758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com *bitsPerComponent = 8; 7660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType); 778ede49268daa98c4b2bce1c379aeb592f96243eereed@android.com#endif 78758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com break; 7960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 8060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *bitsPerComponent = 8; 8160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_RGBA(bm.alphaType()); 8260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 8360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 8460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *bitsPerComponent = 8; 8560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_BGRA(bm.alphaType()); 8660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 87e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org case kARGB_4444_SkColorType: 880680d6c7caa9c2d4b1e5ee49e5816b96be0cc7bfreed@android.com *bitsPerComponent = 4; 89426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info = kCGBitmapByteOrder16Little; 90426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com if (bm.isOpaque()) { 91426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info |= kCGImageAlphaNoneSkipLast; 92426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com } else { 93426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info |= kCGImageAlphaPremultipliedLast; 94426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com } 950680d6c7caa9c2d4b1e5ee49e5816b96be0cc7bfreed@android.com break; 96758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com default: 979c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com return false; 989c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 999c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com return true; 1009c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com} 1019c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com 1029c16bc020f1e8991e2068760fe49521a94ded3efreed@google.comstatic SkBitmap* prepareForImageRef(const SkBitmap& bm, 1039c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com size_t* bitsPerComponent, 1049c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com CGBitmapInfo* info) { 1059c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com bool upscaleTo32; 1069c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (!getBitmapInfo(bm, bitsPerComponent, info, &upscaleTo32)) { 10796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 108758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com } 109758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 11032a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com SkBitmap* copy; 11132a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com if (upscaleTo32) { 11232a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com copy = new SkBitmap; 11332a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com // here we make a ceep copy of the pixels, since CG won't take our 11432a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com // 565 directly 11528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org bm.copyTo(copy, kN32_SkColorType); 11632a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com } else { 11732a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com copy = new SkBitmap(bm); 11832a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com } 11932a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com return copy; 120758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 121758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 12238669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.comCGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, 12338669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGColorSpaceRef colorSpace) { 12438669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com size_t bitsPerComponent SK_INIT_TO_AVOID_WARNING; 12538669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGBitmapInfo info SK_INIT_TO_AVOID_WARNING; 126758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 127758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info); 12896fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == bitmap) { 12996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 130758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com } 131758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 132758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const int w = bitmap->width(); 133758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const int h = bitmap->height(); 134758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const size_t s = bitmap->getSize(); 135758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 136758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com // our provider "owns" the bitmap*, and will take care of deleting it 137d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // we initially lock it, so we can access the pixels. The bitmap will be deleted in the release 138d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // proc, which will in turn unlock the pixels 139d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com bitmap->lockPixels(); 1402b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.com CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s, 141d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkBitmap_ReleaseInfo); 1422b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.com 14338669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com bool releaseColorSpace = false; 14496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == colorSpace) { 145c280d112a820fce69bf6bac4dafdbb99d84077e9reed@google.com colorSpace = CGColorSpaceCreateDeviceRGB(); 14638669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com releaseColorSpace = true; 14738669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com } 14838669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com 149758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com CGImageRef ref = CGImageCreate(w, h, bitsPerComponent, 150758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com bitmap->bytesPerPixel() * 8, 15138669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com bitmap->rowBytes(), colorSpace, info, dataRef, 15296fcdcc219d2a0d3579719b84b28bede76efba64halcanary nullptr, false, kCGRenderingIntentDefault); 15338669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com 15438669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com if (releaseColorSpace) { 15538669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGColorSpaceRelease(colorSpace); 15638669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com } 157758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com CGDataProviderRelease(dataRef); 158758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com return ref; 159758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 160758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 161f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkCGDrawBitmap(CGContextRef cg, const SkBitmap& bm, float x, float y) { 162f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGImageRef img = SkCreateCGImageRef(bm); 163f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 164f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (img) { 165f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGRect r = CGRectMake(0, 0, bm.width(), bm.height()); 16662f465940d57139dfd83e2aef67081017a232417reed@google.com 167f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextSaveGState(cg); 168f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextTranslateCTM(cg, x, r.size.height + y); 169f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextScaleCTM(cg, 1, -1); 17062f465940d57139dfd83e2aef67081017a232417reed@google.com 171f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextDrawImage(cg, r, img); 17262f465940d57139dfd83e2aef67081017a232417reed@google.com 173f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextRestoreGState(cg); 17462f465940d57139dfd83e2aef67081017a232417reed@google.com 175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGImageRelease(img); 176f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 177f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 178f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 17960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////////////////////////// 18060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 181356f7c2600ef54237fb8678cf63d5953f065b7daMike ReedCGContextRef SkCreateCGContext(const SkPixmap& pmap) { 182356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed CGBitmapInfo cg_bitmap_info = 0; 183356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed size_t bitsPerComponent = 0; 184356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed switch (pmap.colorType()) { 185356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed case kRGBA_8888_SkColorType: 186356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed bitsPerComponent = 8; 187356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed cg_bitmap_info = ComputeCGAlphaInfo_RGBA(pmap.alphaType()); 188356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed break; 189356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed case kBGRA_8888_SkColorType: 190356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed bitsPerComponent = 8; 191356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed cg_bitmap_info = ComputeCGAlphaInfo_BGRA(pmap.alphaType()); 192356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed break; 193356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed default: 194356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return nullptr; // no other colortypes are supported (for now) 195356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed } 196356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 197356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed size_t rb = pmap.addr() ? pmap.rowBytes() : 0; 198356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 199356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed CGContextRef cg = CGBitmapContextCreate(pmap.writable_addr(), pmap.width(), pmap.height(), 200356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed bitsPerComponent, rb, cs, cg_bitmap_info); 201356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed CFRelease(cs); 202356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed return cg; 203356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed} 204356f7c2600ef54237fb8678cf63d5953f065b7daMike Reed 20560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgSK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, void* pixels, 20660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGImageRef image) { 20760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo cg_bitmap_info = 0; 20860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org size_t bitsPerComponent = 0; 20960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (info.colorType()) { 21060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 21160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org bitsPerComponent = 8; 21260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType()); 21360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 21460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 21560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org bitsPerComponent = 8; 21660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType()); 21760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 21860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org default: 21960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; // no other colortypes are supported (for now) 22060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 22160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 22260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 22360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextRef cg = CGBitmapContextCreate(pixels, info.width(), info.height(), bitsPerComponent, 22460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org rowBytes, cs, cg_bitmap_info); 22560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CFRelease(cs); 22696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == cg) { 22760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 22860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 22960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 23060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // use this blend mode, to avoid having to erase the pixels first, and to avoid CG performing 23160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // any blending (which could introduce errors and be slower). 23260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextSetBlendMode(cg, kCGBlendModeCopy); 23360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 23460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image); 23560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextRelease(cg); 23660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return true; 23760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 23860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 239463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reedbool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef image) { 240463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed const int width = SkToInt(CGImageGetWidth(image)); 241463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed const int height = SkToInt(CGImageGetHeight(image)); 24260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 24360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 24460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkBitmap tmp; 245848250415eddc54075f7eb8795e8db79e749c6abreed if (!tmp.tryAllocPixels(info)) { 24660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 24760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 24860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 24960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (!SkCopyPixelsFromCGImage(tmp.info(), tmp.rowBytes(), tmp.getPixels(), image)) { 25060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 25160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 25260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 25360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGImageAlphaInfo cgInfo = CGImageGetAlphaInfo(image); 25460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (cgInfo) { 25560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNone: 25660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNoneSkipLast: 25760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNoneSkipFirst: 25860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkASSERT(SkBitmap::ComputeIsOpaque(tmp)); 25960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org tmp.setAlphaType(kOpaque_SkAlphaType); 26060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 26160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org default: 26260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // we don't know if we're opaque or not, so compute it. 26360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (SkBitmap::ComputeIsOpaque(tmp)) { 26460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org tmp.setAlphaType(kOpaque_SkAlphaType); 26560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 26660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 26760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 26860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *dst = tmp; 26960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return true; 27060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 2711ee76510f5dbf632d30975fc3509ef4f609156d2mtklein 272463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reedsk_sp<SkImage> SkMakeImageFromCGImage(CGImageRef src) { 273463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed SkBitmap bm; 274463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed if (!SkCreateBitmapFromCGImage(&bm, src)) { 275463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed return nullptr; 276463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed } 277463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed 278463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed bm.setImmutable(); 279463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed return SkImage::MakeFromBitmap(bm); 280463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed} 281463c848f3b63b52e3834e405ff11fd1e653ed271Mike Reed 2821ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 283