| Index: src/utils/mac/SkCreateCGImageRef.cpp
|
| diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
|
| index 00166e9ed7488b4976d8c426a90061a7d3b40fd3..f4374a48777b1457f3abda31f3724b69c20325d7 100644
|
| --- a/src/utils/mac/SkCreateCGImageRef.cpp
|
| +++ b/src/utils/mac/SkCreateCGImageRef.cpp
|
| @@ -9,6 +9,40 @@
|
| #include "SkBitmap.h"
|
| #include "SkColorPriv.h"
|
|
|
| +static CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) {
|
| + CGBitmapInfo info = kCGBitmapByteOrder32Big;
|
| + switch (at) {
|
| + case kOpaque_SkAlphaType:
|
| + case kIgnore_SkAlphaType:
|
| + info |= kCGImageAlphaNoneSkipLast;
|
| + break;
|
| + case kPremul_SkAlphaType:
|
| + info |= kCGImageAlphaPremultipliedLast;
|
| + break;
|
| + case kUnpremul_SkAlphaType:
|
| + info |= kCGImageAlphaLast;
|
| + break;
|
| + }
|
| + return info;
|
| +}
|
| +
|
| +static CGBitmapInfo ComputeCGAlphaInfo_BGRA(SkAlphaType at) {
|
| + CGBitmapInfo info = kCGBitmapByteOrder32Little;
|
| + switch (at) {
|
| + case kOpaque_SkAlphaType:
|
| + case kIgnore_SkAlphaType:
|
| + info |= kCGImageAlphaNoneSkipFirst;
|
| + break;
|
| + case kPremul_SkAlphaType:
|
| + info |= kCGImageAlphaPremultipliedFirst;
|
| + break;
|
| + case kUnpremul_SkAlphaType:
|
| + info |= kCGImageAlphaFirst;
|
| + break;
|
| + }
|
| + return info;
|
| +}
|
| +
|
| static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
|
| SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
|
| delete bitmap;
|
| @@ -28,44 +62,23 @@ static bool getBitmapInfo(const SkBitmap& bm,
|
| // doesn't see quite right. Are they thinking 1555?
|
| *bitsPerComponent = 5;
|
| *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
|
| - break;
|
| -#endif
|
| +#else
|
| if (upscaleTo32) {
|
| *upscaleTo32 = true;
|
| }
|
| - // fall through
|
| - case kN32_SkColorType:
|
| + // now treat like RGBA
|
| *bitsPerComponent = 8;
|
| -#if SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
|
| - *info = kCGBitmapByteOrder32Big;
|
| - if (bm.isOpaque()) {
|
| - *info |= kCGImageAlphaNoneSkipLast;
|
| - } else {
|
| - *info |= kCGImageAlphaPremultipliedLast;
|
| - }
|
| -#elif SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
|
| - // Matches the CGBitmapInfo that Apple recommends for best
|
| - // performance, used by google chrome.
|
| - *info = kCGBitmapByteOrder32Little;
|
| - if (bm.isOpaque()) {
|
| - *info |= kCGImageAlphaNoneSkipFirst;
|
| - } else {
|
| - *info |= kCGImageAlphaPremultipliedFirst;
|
| - }
|
| -#else
|
| - // ...add more formats as required...
|
| -#warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
|
| -This will probably not work.
|
| - // Legacy behavior. Perhaps turn this into an error at some
|
| - // point.
|
| - *info = kCGBitmapByteOrder32Big;
|
| - if (bm.isOpaque()) {
|
| - *info |= kCGImageAlphaNoneSkipLast;
|
| - } else {
|
| - *info |= kCGImageAlphaPremultipliedLast;
|
| - }
|
| + *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType);
|
| #endif
|
| break;
|
| + case kRGBA_8888_SkColorType:
|
| + *bitsPerComponent = 8;
|
| + *info = ComputeCGAlphaInfo_RGBA(bm.alphaType());
|
| + break;
|
| + case kBGRA_8888_SkColorType:
|
| + *bitsPerComponent = 8;
|
| + *info = ComputeCGAlphaInfo_BGRA(bm.alphaType());
|
| + break;
|
| case kARGB_4444_SkColorType:
|
| *bitsPerComponent = 4;
|
| *info = kCGBitmapByteOrder16Little;
|
| @@ -231,3 +244,73 @@ bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
|
| output->swap(bitmap);
|
| return true;
|
| }
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, void* pixels,
|
| + CGImageRef image) {
|
| + CGBitmapInfo cg_bitmap_info = 0;
|
| + size_t bitsPerComponent = 0;
|
| + switch (info.colorType()) {
|
| + case kRGBA_8888_SkColorType:
|
| + bitsPerComponent = 8;
|
| + cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType());
|
| + break;
|
| + case kBGRA_8888_SkColorType:
|
| + bitsPerComponent = 8;
|
| + cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType());
|
| + break;
|
| + default:
|
| + return false; // no other colortypes are supported (for now)
|
| + }
|
| +
|
| + CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
|
| + CGContextRef cg = CGBitmapContextCreate(pixels, info.width(), info.height(), bitsPerComponent,
|
| + rowBytes, cs, cg_bitmap_info);
|
| + CFRelease(cs);
|
| + if (NULL == cg) {
|
| + return false;
|
| + }
|
| +
|
| + // use this blend mode, to avoid having to erase the pixels first, and to avoid CG performing
|
| + // any blending (which could introduce errors and be slower).
|
| + CGContextSetBlendMode(cg, kCGBlendModeCopy);
|
| +
|
| + CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image);
|
| + CGContextRelease(cg);
|
| + return true;
|
| +}
|
| +
|
| +bool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef image, SkISize* scaleToFit) {
|
| + const int width = scaleToFit ? scaleToFit->width() : SkToInt(CGImageGetWidth(image));
|
| + const int height = scaleToFit ? scaleToFit->height() : SkToInt(CGImageGetHeight(image));
|
| + SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
|
| +
|
| + SkBitmap tmp;
|
| + if (!tmp.allocPixels(info)) {
|
| + return false;
|
| + }
|
| +
|
| + if (!SkCopyPixelsFromCGImage(tmp.info(), tmp.rowBytes(), tmp.getPixels(), image)) {
|
| + return false;
|
| + }
|
| +
|
| + CGImageAlphaInfo cgInfo = CGImageGetAlphaInfo(image);
|
| + switch (cgInfo) {
|
| + case kCGImageAlphaNone:
|
| + case kCGImageAlphaNoneSkipLast:
|
| + case kCGImageAlphaNoneSkipFirst:
|
| + SkASSERT(SkBitmap::ComputeIsOpaque(tmp));
|
| + tmp.setAlphaType(kOpaque_SkAlphaType);
|
| + break;
|
| + default:
|
| + // we don't know if we're opaque or not, so compute it.
|
| + if (SkBitmap::ComputeIsOpaque(tmp)) {
|
| + tmp.setAlphaType(kOpaque_SkAlphaType);
|
| + }
|
| + }
|
| +
|
| + *dst = tmp;
|
| + return true;
|
| +}
|
| +
|
|
|