utils/mac/SkCreateCGImageRef: cleanup
* Use SkUniqueCFRef
* static fns use snake_case.
* use unique_ptr to signify ownership
Change-Id: I57c2100a64bcf5d343af43b5fe9de117cfdbcd4f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/259098
Auto-Submit: Hal Canary <halcanary@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp
index 5423efe..123d382 100644
--- a/src/utils/mac/SkCreateCGImageRef.cpp
+++ b/src/utils/mac/SkCreateCGImageRef.cpp
@@ -13,87 +13,68 @@
#include "include/private/SkMacros.h"
#include "include/private/SkTo.h"
#include "include/utils/mac/SkCGUtils.h"
+#include "src/utils/mac/SkUniqueCFRef.h"
-static CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) {
+#include <climits>
+
+static CGBitmapInfo compute_cgalpha_info_rgba(SkAlphaType at) {
CGBitmapInfo info = kCGBitmapByteOrder32Big;
switch (at) {
- case kUnknown_SkAlphaType:
- break;
- case kOpaque_SkAlphaType:
- info |= kCGImageAlphaNoneSkipLast;
- break;
- case kPremul_SkAlphaType:
- info |= kCGImageAlphaPremultipliedLast;
- break;
- case kUnpremul_SkAlphaType:
- info |= kCGImageAlphaLast;
- break;
+ case kUnknown_SkAlphaType: break;
+ case kOpaque_SkAlphaType: info |= kCGImageAlphaNoneSkipLast; break;
+ case kPremul_SkAlphaType: info |= kCGImageAlphaPremultipliedLast; break;
+ case kUnpremul_SkAlphaType: info |= kCGImageAlphaLast; break;
}
return info;
}
-static CGBitmapInfo ComputeCGAlphaInfo_BGRA(SkAlphaType at) {
+static CGBitmapInfo compute_cgalpha_info_bgra(SkAlphaType at) {
CGBitmapInfo info = kCGBitmapByteOrder32Little;
switch (at) {
- case kUnknown_SkAlphaType:
- break;
- case kOpaque_SkAlphaType:
- info |= kCGImageAlphaNoneSkipFirst;
- break;
- case kPremul_SkAlphaType:
- info |= kCGImageAlphaPremultipliedFirst;
- break;
- case kUnpremul_SkAlphaType:
- info |= kCGImageAlphaFirst;
- break;
+ case kUnknown_SkAlphaType: break;
+ case kOpaque_SkAlphaType: info |= kCGImageAlphaNoneSkipFirst; break;
+ case kPremul_SkAlphaType: info |= kCGImageAlphaPremultipliedFirst; break;
+ case kUnpremul_SkAlphaType: info |= kCGImageAlphaFirst; break;
+ }
+ return info;
+}
+static CGBitmapInfo compute_cgalpha_info_4444(SkAlphaType at) {
+ CGBitmapInfo info = kCGBitmapByteOrder16Little;
+ switch (at) {
+ case kOpaque_SkAlphaType: info |= kCGImageAlphaNoneSkipLast; break;
+ default: info |= kCGImageAlphaPremultipliedLast; break;
}
return info;
}
-static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
- SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
- delete bitmap;
-}
-
-static bool getBitmapInfo(const SkBitmap& bm,
- size_t* bitsPerComponent,
- CGBitmapInfo* info,
- bool* upscaleTo32) {
+static bool get_bitmap_info(SkColorType skColorType,
+ SkAlphaType skAlphaType,
+ size_t* bitsPerComponent,
+ CGBitmapInfo* info,
+ bool* upscaleTo32) {
if (upscaleTo32) {
*upscaleTo32 = false;
}
-
- switch (bm.colorType()) {
+ switch (skColorType) {
case kRGB_565_SkColorType:
-#if 0
- // doesn't see quite right. Are they thinking 1555?
- *bitsPerComponent = 5;
- *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
-#else
if (upscaleTo32) {
*upscaleTo32 = true;
}
// now treat like RGBA
*bitsPerComponent = 8;
- *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType);
-#endif
+ *info = compute_cgalpha_info_rgba(kOpaque_SkAlphaType);
break;
case kRGBA_8888_SkColorType:
*bitsPerComponent = 8;
- *info = ComputeCGAlphaInfo_RGBA(bm.alphaType());
+ *info = compute_cgalpha_info_rgba(skAlphaType);
break;
case kBGRA_8888_SkColorType:
*bitsPerComponent = 8;
- *info = ComputeCGAlphaInfo_BGRA(bm.alphaType());
+ *info = compute_cgalpha_info_bgra(skAlphaType);
break;
case kARGB_4444_SkColorType:
*bitsPerComponent = 4;
- *info = kCGBitmapByteOrder16Little;
- if (bm.isOpaque()) {
- *info |= kCGImageAlphaNoneSkipLast;
- } else {
- *info |= kCGImageAlphaPremultipliedLast;
- }
+ *info = compute_cgalpha_info_4444(skAlphaType);
break;
default:
return false;
@@ -101,65 +82,58 @@
return true;
}
-static SkBitmap* prepareForImageRef(const SkBitmap& bm,
- size_t* bitsPerComponent,
- CGBitmapInfo* info) {
+static std::unique_ptr<SkBitmap> prepare_for_image_ref(const SkBitmap& bm,
+ size_t* bitsPerComponent,
+ CGBitmapInfo* info) {
bool upscaleTo32;
- if (!getBitmapInfo(bm, bitsPerComponent, info, &upscaleTo32)) {
+ if (!get_bitmap_info(bm.colorType(), bm.alphaType(), bitsPerComponent, info, &upscaleTo32)) {
return nullptr;
}
-
- SkBitmap* copy;
if (upscaleTo32) {
- copy = new SkBitmap;
+ std::unique_ptr<SkBitmap> copy(new SkBitmap);
// here we make a deep copy of the pixels, since CG won't take our
// 565 directly
copy->allocPixels(bm.info().makeColorType(kN32_SkColorType));
bm.readPixels(copy->info(), copy->getPixels(), copy->rowBytes(), 0, 0);
- } else {
- copy = new SkBitmap(bm);
+ return copy;
}
- return copy;
+ return std::unique_ptr<SkBitmap>(new SkBitmap(bm));
}
CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm,
CGColorSpaceRef colorSpace) {
+ if (bm.drawsNothing()) {
+ return nullptr;
+ }
size_t bitsPerComponent SK_INIT_TO_AVOID_WARNING;
CGBitmapInfo info SK_INIT_TO_AVOID_WARNING;
- SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
+ std::unique_ptr<SkBitmap> bitmap = prepare_for_image_ref(bm, &bitsPerComponent, &info);
if (nullptr == bitmap) {
return nullptr;
}
- const int w = bitmap->width();
- const int h = bitmap->height();
+ SkPixmap pm = bitmap->pixmap(); // Copy bitmap info before releasing it.
const size_t s = bitmap->computeByteSize();
+ void* pixels = bitmap->getPixels();
// our provider "owns" the bitmap*, and will take care of deleting it
- CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s,
- SkBitmap_ReleaseInfo);
+ SkUniqueCFRef<CGDataProviderRef> dataRef(CGDataProviderCreateWithData(
+ bitmap.release(), pixels, s,
+ [](void* p, const void*, size_t) { delete reinterpret_cast<SkBitmap*>(p); }));
- bool releaseColorSpace = false;
+ SkUniqueCFRef<CGColorSpaceRef> rgb;
if (nullptr == colorSpace) {
- colorSpace = CGColorSpaceCreateDeviceRGB();
- releaseColorSpace = true;
+ rgb.reset(CGColorSpaceCreateDeviceRGB());
+ colorSpace = rgb.get();
}
-
- CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
- bitmap->bytesPerPixel() * 8,
- bitmap->rowBytes(), colorSpace, info, dataRef,
- nullptr, false, kCGRenderingIntentDefault);
-
- if (releaseColorSpace) {
- CGColorSpaceRelease(colorSpace);
- }
- CGDataProviderRelease(dataRef);
- return ref;
+ return CGImageCreate(pm.width(), pm.height(), bitsPerComponent,
+ pm.info().bytesPerPixel() * CHAR_BIT, pm.rowBytes(), colorSpace,
+ info, dataRef.get(), nullptr, false, kCGRenderingIntentDefault);
}
void SkCGDrawBitmap(CGContextRef cg, const SkBitmap& bm, float x, float y) {
- CGImageRef img = SkCreateCGImageRef(bm);
+ SkUniqueCFRef<CGImageRef> img(SkCreateCGImageRef(bm));
if (img) {
CGRect r = CGRectMake(0, 0, bm.width(), bm.height());
@@ -168,11 +142,9 @@
CGContextTranslateCTM(cg, x, r.size.height + y);
CGContextScaleCTM(cg, 1, -1);
- CGContextDrawImage(cg, r, img);
+ CGContextDrawImage(cg, r, img.get());
CGContextRestoreGState(cg);
-
- CGImageRelease(img);
}
}
@@ -184,21 +156,20 @@
switch (pmap.colorType()) {
case kRGBA_8888_SkColorType:
bitsPerComponent = 8;
- cg_bitmap_info = ComputeCGAlphaInfo_RGBA(pmap.alphaType());
+ cg_bitmap_info = compute_cgalpha_info_rgba(pmap.alphaType());
break;
case kBGRA_8888_SkColorType:
bitsPerComponent = 8;
- cg_bitmap_info = ComputeCGAlphaInfo_BGRA(pmap.alphaType());
+ cg_bitmap_info = compute_cgalpha_info_bgra(pmap.alphaType());
break;
default:
return nullptr; // no other colortypes are supported (for now)
}
size_t rb = pmap.addr() ? pmap.rowBytes() : 0;
- CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
+ SkUniqueCFRef<CGColorSpaceRef> cs(CGColorSpaceCreateDeviceRGB());
CGContextRef cg = CGBitmapContextCreate(pmap.writable_addr(), pmap.width(), pmap.height(),
- bitsPerComponent, rb, cs, cg_bitmap_info);
- CFRelease(cs);
+ bitsPerComponent, rb, cs.get(), cg_bitmap_info);
return cg;
}
@@ -209,30 +180,29 @@
switch (info.colorType()) {
case kRGBA_8888_SkColorType:
bitsPerComponent = 8;
- cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType());
+ cg_bitmap_info = compute_cgalpha_info_rgba(info.alphaType());
break;
case kBGRA_8888_SkColorType:
bitsPerComponent = 8;
- cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType());
+ cg_bitmap_info = compute_cgalpha_info_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 (nullptr == cg) {
+ SkUniqueCFRef<CGColorSpaceRef> cs(CGColorSpaceCreateDeviceRGB());
+ SkUniqueCFRef<CGContextRef> cg(CGBitmapContextCreate(
+ pixels, info.width(), info.height(), bitsPerComponent,
+ rowBytes, cs.get(), cg_bitmap_info));
+ if (!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);
+ CGContextSetBlendMode(cg.get(), kCGBlendModeCopy);
- CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image);
- CGContextRelease(cg);
+ CGContextDrawImage(cg.get(), CGRectMake(0, 0, info.width(), info.height()), image);
return true;
}