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;
 }