1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 80d55f1e73cbbf5456fb05108a0db1f33dafdae79reed@android.com#include "SkCGUtils.h" 9758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com#include "SkBitmap.h" 10a545a5598e59c22c529e5f33964df1ddd6601ac2reed@android.com#include "SkColorPriv.h" 11758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 1260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgstatic CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) { 1360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo info = kCGBitmapByteOrder32Big; 1460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (at) { 1560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kOpaque_SkAlphaType: 1660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kIgnore_SkAlphaType: 1760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaNoneSkipLast; 1860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 1960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kPremul_SkAlphaType: 2060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaPremultipliedLast; 2160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 2260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kUnpremul_SkAlphaType: 2360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaLast; 2460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 2560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 2660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return info; 2760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 2860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 2960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgstatic CGBitmapInfo ComputeCGAlphaInfo_BGRA(SkAlphaType at) { 3060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo info = kCGBitmapByteOrder32Little; 3160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (at) { 3260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kOpaque_SkAlphaType: 3360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kIgnore_SkAlphaType: 3460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaNoneSkipFirst; 3560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 3660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kPremul_SkAlphaType: 3760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaPremultipliedFirst; 3860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 3960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kUnpremul_SkAlphaType: 4060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org info |= kCGImageAlphaFirst; 4160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 4260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 4360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return info; 4460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 4560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 462b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.comstatic void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) { 47758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info); 48758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com delete bitmap; 49758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 50758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 51d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comstatic bool getBitmapInfo(const SkBitmap& bm, 529c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com size_t* bitsPerComponent, 539c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com CGBitmapInfo* info, 549c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com bool* upscaleTo32) { 559c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (upscaleTo32) { 569c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com *upscaleTo32 = false; 579c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 59e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org switch (bm.colorType()) { 60e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org case kRGB_565_SkColorType: 61e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org#if 0 62e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org // doesn't see quite right. Are they thinking 1555? 63e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org *bitsPerComponent = 5; 64e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; 6560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org#else 669c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (upscaleTo32) { 679c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com *upscaleTo32 = true; 689c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 6960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // now treat like RGBA 70758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com *bitsPerComponent = 8; 7160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType); 728ede49268daa98c4b2bce1c379aeb592f96243eereed@android.com#endif 73758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com break; 7460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 7560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *bitsPerComponent = 8; 7660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_RGBA(bm.alphaType()); 7760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 7860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 7960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *bitsPerComponent = 8; 8060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *info = ComputeCGAlphaInfo_BGRA(bm.alphaType()); 8160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 82e24ad23ae67ffcb0dc545b7e426cf08d102e0868commit-bot@chromium.org case kARGB_4444_SkColorType: 830680d6c7caa9c2d4b1e5ee49e5816b96be0cc7bfreed@android.com *bitsPerComponent = 4; 84426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info = kCGBitmapByteOrder16Little; 85426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com if (bm.isOpaque()) { 86426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info |= kCGImageAlphaNoneSkipLast; 87426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com } else { 88426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com *info |= kCGImageAlphaPremultipliedLast; 89426648ef313dff7030249f99dcd7bc8badcbe054scroggo@google.com } 900680d6c7caa9c2d4b1e5ee49e5816b96be0cc7bfreed@android.com break; 91758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com default: 929c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com return false; 939c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com } 949c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com return true; 959c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com} 969c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com 979c16bc020f1e8991e2068760fe49521a94ded3efreed@google.comstatic SkBitmap* prepareForImageRef(const SkBitmap& bm, 989c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com size_t* bitsPerComponent, 999c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com CGBitmapInfo* info) { 1009c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com bool upscaleTo32; 1019c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com if (!getBitmapInfo(bm, bitsPerComponent, info, &upscaleTo32)) { 1029c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com return NULL; 103758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com } 104758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 10532a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com SkBitmap* copy; 10632a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com if (upscaleTo32) { 10732a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com copy = new SkBitmap; 10832a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com // here we make a ceep copy of the pixels, since CG won't take our 10932a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com // 565 directly 11028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org bm.copyTo(copy, kN32_SkColorType); 11132a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com } else { 11232a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com copy = new SkBitmap(bm); 11332a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com } 11432a4249cbd3ebcb448fb0824afe875cdf9036686reed@android.com return copy; 115758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 116758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 11738669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.comCGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, 11838669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGColorSpaceRef colorSpace) { 11938669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com size_t bitsPerComponent SK_INIT_TO_AVOID_WARNING; 12038669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGBitmapInfo info SK_INIT_TO_AVOID_WARNING; 121758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 122758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info); 123758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com if (NULL == bitmap) { 124758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com return NULL; 125758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com } 126758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 127758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const int w = bitmap->width(); 128758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const int h = bitmap->height(); 129758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com const size_t s = bitmap->getSize(); 130758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 131758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com // our provider "owns" the bitmap*, and will take care of deleting it 132d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // we initially lock it, so we can access the pixels. The bitmap will be deleted in the release 133d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com // proc, which will in turn unlock the pixels 134d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com bitmap->lockPixels(); 1352b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.com CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s, 136d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com SkBitmap_ReleaseInfo); 1372b26cac4fd1a0ff6bfc84757f35198afba3ee1d2reed@android.com 13838669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com bool releaseColorSpace = false; 13938669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com if (NULL == colorSpace) { 140c280d112a820fce69bf6bac4dafdbb99d84077e9reed@google.com colorSpace = CGColorSpaceCreateDeviceRGB(); 14138669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com releaseColorSpace = true; 14238669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com } 14338669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com 144758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com CGImageRef ref = CGImageCreate(w, h, bitsPerComponent, 145758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com bitmap->bytesPerPixel() * 8, 14638669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com bitmap->rowBytes(), colorSpace, info, dataRef, 147758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com NULL, false, kCGRenderingIntentDefault); 14838669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com 14938669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com if (releaseColorSpace) { 15038669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com CGColorSpaceRelease(colorSpace); 15138669c12c5ab784d5ad94eb2b26b89becac2ba12reed@android.com } 152758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com CGDataProviderRelease(dataRef); 153758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com return ref; 154758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com} 155758b129f11d8ce2d2235f73ea4523f21f3d8b079reed@android.com 156f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.comvoid SkCGDrawBitmap(CGContextRef cg, const SkBitmap& bm, float x, float y) { 157f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGImageRef img = SkCreateCGImageRef(bm); 158f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 159f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (img) { 160f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGRect r = CGRectMake(0, 0, bm.width(), bm.height()); 16162f465940d57139dfd83e2aef67081017a232417reed@google.com 162f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextSaveGState(cg); 163f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextTranslateCTM(cg, x, r.size.height + y); 164f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextScaleCTM(cg, 1, -1); 16562f465940d57139dfd83e2aef67081017a232417reed@google.com 166f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextDrawImage(cg, r, img); 16762f465940d57139dfd83e2aef67081017a232417reed@google.com 168f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGContextRestoreGState(cg); 16962f465940d57139dfd83e2aef67081017a232417reed@google.com 170f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com CGImageRelease(img); 171f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 172f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com} 173f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 174292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com/////////////////////////////////////////////////////////////////////////////// 175f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com 176292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com#include "SkStream.h" 177292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com 178292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.comclass SkAutoPDFRelease { 179292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.compublic: 180292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com SkAutoPDFRelease(CGPDFDocumentRef doc) : fDoc(doc) {} 181292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com ~SkAutoPDFRelease() { 182292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com if (fDoc) { 183292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGPDFDocumentRelease(fDoc); 184292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 185292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 186292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.comprivate: 187292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGPDFDocumentRef fDoc; 188292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com}; 189e61a86cfa00ea393ecc4a71fca94e1d476a37ecccommit-bot@chromium.org#define SkAutoPDFRelease(...) SK_REQUIRE_LOCAL_VAR(SkAutoPDFRelease) 190292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com 191292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.comstatic void CGDataProviderReleaseData_FromMalloc(void*, const void* data, 192292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com size_t size) { 193292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com sk_free((void*)data); 194292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com} 195292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com 196292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.combool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) { 197292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com size_t size = stream->getLength(); 198292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com void* ptr = sk_malloc_throw(size); 199292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com stream->read(ptr, size); 200292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size, 201292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGDataProviderReleaseData_FromMalloc); 202292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com if (NULL == data) { 203292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com return false; 204292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 206292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data); 207292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGDataProviderRelease(data); 208292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com if (NULL == pdf) { 209292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com return false; 210292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 211292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com SkAutoPDFRelease releaseMe(pdf); 212292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com 213292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1); 214292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com if (NULL == page) { 215292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com return false; 216292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 217d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 218292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox); 219d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 220292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com int w = (int)CGRectGetWidth(bounds); 221292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com int h = (int)CGRectGetHeight(bounds); 222d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 223292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com SkBitmap bitmap; 2249ebcac54635cde63110d73ad7c43d70772e7872freed@google.com if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) { 2259ebcac54635cde63110d73ad7c43d70772e7872freed@google.com return false; 2269ebcac54635cde63110d73ad7c43d70772e7872freed@google.com } 227292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com bitmap.eraseColor(SK_ColorWHITE); 2289c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com 2299c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com size_t bitsPerComponent; 2309c16bc020f1e8991e2068760fe49521a94ded3efreed@google.com CGBitmapInfo info; 231d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL); 232cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com 233cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 234cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h, 235cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com bitsPerComponent, bitmap.rowBytes(), 236cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com cs, info); 237cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com CGColorSpaceRelease(cs); 238cd88d7c233f7854e14d5ee8fbf6eedb0e45f2014reed@google.com 239292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com if (ctx) { 240292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGContextDrawPDFPage(ctx, page); 241292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com CGContextRelease(ctx); 242292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com } 243292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com 244292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com output->swap(bitmap); 245292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com return true; 246292ade6625f2f3bed84afbe4d669613ebf3785f9reed@google.com} 24760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 24860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////////////////////////// 24960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 25060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgSK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, void* pixels, 25160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGImageRef image) { 25260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGBitmapInfo cg_bitmap_info = 0; 25360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org size_t bitsPerComponent = 0; 25460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (info.colorType()) { 25560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kRGBA_8888_SkColorType: 25660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org bitsPerComponent = 8; 25760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType()); 25860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 25960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kBGRA_8888_SkColorType: 26060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org bitsPerComponent = 8; 26160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType()); 26260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 26360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org default: 26460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; // no other colortypes are supported (for now) 26560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 26660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 26760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); 26860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextRef cg = CGBitmapContextCreate(pixels, info.width(), info.height(), bitsPerComponent, 26960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org rowBytes, cs, cg_bitmap_info); 27060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CFRelease(cs); 27160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (NULL == cg) { 27260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 27360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 27460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 27560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // use this blend mode, to avoid having to erase the pixels first, and to avoid CG performing 27660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // any blending (which could introduce errors and be slower). 27760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextSetBlendMode(cg, kCGBlendModeCopy); 27860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 27960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image); 28060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGContextRelease(cg); 28160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return true; 28260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 28360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 28460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.orgbool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef image, SkISize* scaleToFit) { 28560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org const int width = scaleToFit ? scaleToFit->width() : SkToInt(CGImageGetWidth(image)); 28660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org const int height = scaleToFit ? scaleToFit->height() : SkToInt(CGImageGetHeight(image)); 28760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); 28860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 28960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkBitmap tmp; 29060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (!tmp.allocPixels(info)) { 29160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 29260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 29360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 29460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (!SkCopyPixelsFromCGImage(tmp.info(), tmp.rowBytes(), tmp.getPixels(), image)) { 29560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return false; 29660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 29760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 29860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org CGImageAlphaInfo cgInfo = CGImageGetAlphaInfo(image); 29960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org switch (cgInfo) { 30060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNone: 30160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNoneSkipLast: 30260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org case kCGImageAlphaNoneSkipFirst: 30360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org SkASSERT(SkBitmap::ComputeIsOpaque(tmp)); 30460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org tmp.setAlphaType(kOpaque_SkAlphaType); 30560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org break; 30660b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org default: 30760b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org // we don't know if we're opaque or not, so compute it. 30860b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org if (SkBitmap::ComputeIsOpaque(tmp)) { 30960b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org tmp.setAlphaType(kOpaque_SkAlphaType); 31060b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 31160b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org } 31260b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org 31360b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org *dst = tmp; 31460b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org return true; 31560b5dce19984a5165f6b2f1d6d477f5e8a940761commit-bot@chromium.org} 316