gfx/skia/trunk/src/utils/mac/SkCreateCGImageRef.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2011 Google Inc.
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
     8 #include "SkCGUtils.h"
     9 #include "SkBitmap.h"
    10 #include "SkColorPriv.h"
    12 static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
    13     SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
    14     delete bitmap;
    15 }
    17 static bool getBitmapInfo(const SkBitmap& bm,
    18                           size_t* bitsPerComponent,
    19                           CGBitmapInfo* info,
    20                           bool* upscaleTo32) {
    21     if (upscaleTo32) {
    22         *upscaleTo32 = false;
    23     }
    25     switch (bm.colorType()) {
    26         case kRGB_565_SkColorType:
    27 #if 0
    28             // doesn't see quite right. Are they thinking 1555?
    29             *bitsPerComponent = 5;
    30             *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
    31             break;
    32 #endif
    33             if (upscaleTo32) {
    34                 *upscaleTo32 = true;
    35             }
    36             // fall through
    37         case kPMColor_SkColorType:
    38             *bitsPerComponent = 8;
    39 #if SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
    40             *info = kCGBitmapByteOrder32Big;
    41             if (bm.isOpaque()) {
    42                 *info |= kCGImageAlphaNoneSkipLast;
    43             } else {
    44                 *info |= kCGImageAlphaPremultipliedLast;
    45             }
    46 #elif SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
    47             // Matches the CGBitmapInfo that Apple recommends for best
    48             // performance, used by google chrome.
    49             *info = kCGBitmapByteOrder32Little;
    50             if (bm.isOpaque()) {
    51                 *info |= kCGImageAlphaNoneSkipFirst;
    52             } else {
    53                 *info |= kCGImageAlphaPremultipliedFirst;
    54             }
    55 #else
    56             // ...add more formats as required...
    57 #warning Cannot convert SkBitmap to CGImageRef with these shiftmasks. \
    58 This will probably not work.
    59             // Legacy behavior. Perhaps turn this into an error at some
    60             // point.
    61             *info = kCGBitmapByteOrder32Big;
    62             if (bm.isOpaque()) {
    63                 *info |= kCGImageAlphaNoneSkipLast;
    64             } else {
    65                 *info |= kCGImageAlphaPremultipliedLast;
    66             }
    67 #endif
    68             break;
    69         case kARGB_4444_SkColorType:
    70             *bitsPerComponent = 4;
    71             *info = kCGBitmapByteOrder16Little;
    72             if (bm.isOpaque()) {
    73                 *info |= kCGImageAlphaNoneSkipLast;
    74             } else {
    75                 *info |= kCGImageAlphaPremultipliedLast;
    76             }
    77             break;
    78         default:
    79             return false;
    80     }
    81     return true;
    82 }
    84 static SkBitmap* prepareForImageRef(const SkBitmap& bm,
    85                                     size_t* bitsPerComponent,
    86                                     CGBitmapInfo* info) {
    87     bool upscaleTo32;
    88     if (!getBitmapInfo(bm, bitsPerComponent, info, &upscaleTo32)) {
    89         return NULL;
    90     }
    92     SkBitmap* copy;
    93     if (upscaleTo32) {
    94         copy = new SkBitmap;
    95         // here we make a ceep copy of the pixels, since CG won't take our
    96         // 565 directly
    97         bm.copyTo(copy, kPMColor_SkColorType);
    98     } else {
    99         copy = new SkBitmap(bm);
   100     }
   101     return copy;
   102 }
   104 CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm,
   105                                             CGColorSpaceRef colorSpace) {
   106     size_t bitsPerComponent SK_INIT_TO_AVOID_WARNING;
   107     CGBitmapInfo info       SK_INIT_TO_AVOID_WARNING;
   109     SkBitmap* bitmap = prepareForImageRef(bm, &bitsPerComponent, &info);
   110     if (NULL == bitmap) {
   111         return NULL;
   112     }
   114     const int w = bitmap->width();
   115     const int h = bitmap->height();
   116     const size_t s = bitmap->getSize();
   118     // our provider "owns" the bitmap*, and will take care of deleting it
   119     // we initially lock it, so we can access the pixels. The bitmap will be deleted in the release
   120     // proc, which will in turn unlock the pixels
   121     bitmap->lockPixels();
   122     CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s,
   123                                                              SkBitmap_ReleaseInfo);
   125     bool releaseColorSpace = false;
   126     if (NULL == colorSpace) {
   127         colorSpace = CGColorSpaceCreateDeviceRGB();
   128         releaseColorSpace = true;
   129     }
   131     CGImageRef ref = CGImageCreate(w, h, bitsPerComponent,
   132                                    bitmap->bytesPerPixel() * 8,
   133                                    bitmap->rowBytes(), colorSpace, info, dataRef,
   134                                    NULL, false, kCGRenderingIntentDefault);
   136     if (releaseColorSpace) {
   137         CGColorSpaceRelease(colorSpace);
   138     }
   139     CGDataProviderRelease(dataRef);
   140     return ref;
   141 }
   143 void SkCGDrawBitmap(CGContextRef cg, const SkBitmap& bm, float x, float y) {
   144     CGImageRef img = SkCreateCGImageRef(bm);
   146     if (img) {
   147         CGRect r = CGRectMake(0, 0, bm.width(), bm.height());
   149         CGContextSaveGState(cg);
   150         CGContextTranslateCTM(cg, x, r.size.height + y);
   151         CGContextScaleCTM(cg, 1, -1);
   153         CGContextDrawImage(cg, r, img);
   155         CGContextRestoreGState(cg);
   157         CGImageRelease(img);
   158     }
   159 }
   161 ///////////////////////////////////////////////////////////////////////////////
   163 #include "SkStream.h"
   165 class SkAutoPDFRelease {
   166 public:
   167     SkAutoPDFRelease(CGPDFDocumentRef doc) : fDoc(doc) {}
   168     ~SkAutoPDFRelease() {
   169         if (fDoc) {
   170             CGPDFDocumentRelease(fDoc);
   171         }
   172     }
   173 private:
   174     CGPDFDocumentRef fDoc;
   175 };
   176 #define SkAutoPDFRelease(...) SK_REQUIRE_LOCAL_VAR(SkAutoPDFRelease)
   178 static void CGDataProviderReleaseData_FromMalloc(void*, const void* data,
   179                                                  size_t size) {
   180     sk_free((void*)data);
   181 }
   183 bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
   184     size_t size = stream->getLength();
   185     void* ptr = sk_malloc_throw(size);
   186     stream->read(ptr, size);
   187     CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size,
   188                                           CGDataProviderReleaseData_FromMalloc);
   189     if (NULL == data) {
   190         return false;
   191     }
   193     CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
   194     CGDataProviderRelease(data);
   195     if (NULL == pdf) {
   196         return false;
   197     }
   198     SkAutoPDFRelease releaseMe(pdf);
   200     CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
   201     if (NULL == page) {
   202         return false;
   203     }
   205     CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
   207     int w = (int)CGRectGetWidth(bounds);
   208     int h = (int)CGRectGetHeight(bounds);
   210     SkBitmap bitmap;
   211     if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
   212         return false;
   213     }
   214     bitmap.eraseColor(SK_ColorWHITE);
   216     size_t bitsPerComponent;
   217     CGBitmapInfo info;
   218     getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);
   220     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
   221     CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
   222                                              bitsPerComponent, bitmap.rowBytes(),
   223                                              cs, info);
   224     CGColorSpaceRelease(cs);
   226     if (ctx) {
   227         CGContextDrawPDFPage(ctx, page);
   228         CGContextRelease(ctx);
   229     }
   231     output->swap(bitmap);
   232     return true;
   233 }

mercurial