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.

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

mercurial