Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: src/utils/mac/SkCreateCGImageRef.cpp

Issue 243463005: expose CGImage -> SkBitmap (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« gm/aaclip.cpp ('K') | « src/ports/SkImageDecoder_CG.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkCGUtils.h" 8 #include "SkCGUtils.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 11
12 static uint32_t ComputeCGAlphaInfo_RGBA(SkAlphaType at) {
scroggo 2014/04/22 14:58:17 Should these return CGBitmapInfo for documentation
reed1 2014/04/22 17:51:39 Done.
13 uint32_t info = kCGBitmapByteOrder32Big;
14 switch (at) {
15 case kOpaque_SkAlphaType:
16 case kIgnore_SkAlphaType:
17 info |= kCGImageAlphaNoneSkipLast;
18 break;
19 case kPremul_SkAlphaType:
20 info |= kCGImageAlphaPremultipliedLast;
21 break;
22 case kUnpremul_SkAlphaType:
23 info |= kCGImageAlphaLast;
24 break;
25 }
26 return info;
27 }
28
29 static uint32_t ComputeCGAlphaInfo_BGRA(SkAlphaType at) {
30 uint32_t info = kCGBitmapByteOrder32Little;
31 switch (at) {
32 case kOpaque_SkAlphaType:
33 case kIgnore_SkAlphaType:
34 info |= kCGImageAlphaNoneSkipFirst;
35 break;
36 case kPremul_SkAlphaType:
37 info |= kCGImageAlphaPremultipliedFirst;
38 break;
39 case kUnpremul_SkAlphaType:
40 info |= kCGImageAlphaFirst;
41 break;
42 }
43 return info;
44 }
45
12 static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) { 46 static void SkBitmap_ReleaseInfo(void* info, const void* pixelData, size_t size) {
13 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info); 47 SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(info);
14 delete bitmap; 48 delete bitmap;
15 } 49 }
16 50
17 static bool getBitmapInfo(const SkBitmap& bm, 51 static bool getBitmapInfo(const SkBitmap& bm,
18 size_t* bitsPerComponent, 52 size_t* bitsPerComponent,
19 CGBitmapInfo* info, 53 CGBitmapInfo* info,
20 bool* upscaleTo32) { 54 bool* upscaleTo32) {
21 if (upscaleTo32) { 55 if (upscaleTo32) {
22 *upscaleTo32 = false; 56 *upscaleTo32 = false;
23 } 57 }
24 58
59 const bool opaque = kOpaque_SkAlphaType == bm.alphaType();
scroggo 2014/04/22 14:58:17 It seems like this could go in the 4444 case (the
reed1 2014/04/22 17:51:39 Done.
60 const bool premul = kUnpremul_SkAlphaType != bm.alphaType();
scroggo 2014/04/22 14:58:17 This variable is unused.
reed1 2014/04/22 17:51:39 Done.
61
25 switch (bm.colorType()) { 62 switch (bm.colorType()) {
26 case kRGB_565_SkColorType: 63 case kRGB_565_SkColorType:
27 #if 0 64 #if 0
28 // doesn't see quite right. Are they thinking 1555? 65 // doesn't see quite right. Are they thinking 1555?
29 *bitsPerComponent = 5; 66 *bitsPerComponent = 5;
30 *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; 67 *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
31 break; 68 #else
32 #endif
33 if (upscaleTo32) { 69 if (upscaleTo32) {
34 *upscaleTo32 = true; 70 *upscaleTo32 = true;
35 } 71 }
36 // fall through 72 // now treat like RGBA
37 case kN32_SkColorType: 73 *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType);
74 #endif
75 break;
76 case kRGBA_8888_SkColorType:
38 *bitsPerComponent = 8; 77 *bitsPerComponent = 8;
39 #if SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 78 *info = ComputeCGAlphaInfo_RGBA(bm.alphaType());
40 *info = kCGBitmapByteOrder32Big; 79 break;
41 if (bm.isOpaque()) { 80 case kBGRA_8888_SkColorType:
42 *info |= kCGImageAlphaNoneSkipLast; 81 *bitsPerComponent = 8;
43 } else { 82 *info = ComputeCGAlphaInfo_BGRA(bm.alphaType());
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; 83 break;
69 case kARGB_4444_SkColorType: 84 case kARGB_4444_SkColorType:
70 *bitsPerComponent = 4; 85 *bitsPerComponent = 4;
71 *info = kCGBitmapByteOrder16Little; 86 *info = kCGBitmapByteOrder16Little;
72 if (bm.isOpaque()) { 87 if (opaque) {
73 *info |= kCGImageAlphaNoneSkipLast; 88 *info |= kCGImageAlphaNoneSkipLast;
74 } else { 89 } else {
75 *info |= kCGImageAlphaPremultipliedLast; 90 *info |= kCGImageAlphaPremultipliedLast;
76 } 91 }
77 break; 92 break;
78 default: 93 default:
79 return false; 94 return false;
80 } 95 }
81 return true; 96 return true;
82 } 97 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 CGColorSpaceRelease(cs); 239 CGColorSpaceRelease(cs);
225 240
226 if (ctx) { 241 if (ctx) {
227 CGContextDrawPDFPage(ctx, page); 242 CGContextDrawPDFPage(ctx, page);
228 CGContextRelease(ctx); 243 CGContextRelease(ctx);
229 } 244 }
230 245
231 output->swap(bitmap); 246 output->swap(bitmap);
232 return true; 247 return true;
233 } 248 }
249
250 //////////////////////////////////////////////////////////////////////////////// ///////////////////
251
252 SK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, vo id* pixels,
253 CGImageRef image) {
254 CGBitmapInfo cg_bitmap_info = 0;
255 size_t bitsPerComponent = 0;
256 switch (info.colorType()) {
257 case kRGBA_8888_SkColorType:
258 bitsPerComponent = 8;
259 cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType());
260 break;
261 case kBGRA_8888_SkColorType:
262 bitsPerComponent = 8;
263 cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType());
264 break;
265 default:
266 return false; // no other colortypes are supported (for now)
267 }
268
269 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
270 CGContextRef cg = CGBitmapContextCreate(pixels, info.width(), info.height(), bitsPerComponent,
271 rowBytes, cs, cg_bitmap_info);
272 CFRelease(cs);
273 if (NULL == cg) {
274 return false;
275 }
276
277 // use this blend mode, to avoid having to erase the pixels first, and to av oid CG performing
278 // any blending (which could introduce errors and be slower).
279 CGContextSetBlendMode(cg, kCGBlendModeCopy);
280
281 CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image) ;
282 CGContextRelease(cg);
283 return true;
284 }
285
286 bool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef image, SkISize* scaleTo Fit) {
287 const int width = scaleToFit ? scaleToFit->width() : SkToInt(CGImageGetWidth (image));
288 const int height = scaleToFit ? scaleToFit->height() : SkToInt(CGImageGetHei ght(image));
289 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
290
291 SkBitmap tmp;
292 if (!tmp.allocPixels(info)) {
293 return false;
294 }
295
296 if (!SkCopyPixelsFromCGImage(tmp.info(), tmp.rowBytes(), tmp.getPixels(), im age)) {
297 return false;
298 }
299
300 CGImageAlphaInfo cgInfo = CGImageGetAlphaInfo(image);
301 switch (cgInfo) {
302 case kCGImageAlphaNone:
303 case kCGImageAlphaNoneSkipLast:
304 case kCGImageAlphaNoneSkipFirst:
305 SkASSERT(SkBitmap::ComputeIsOpaque(tmp));
306 tmp.setAlphaType(kOpaque_SkAlphaType);
307 break;
308 default:
309 // we don't know if we're opaque or not, so compute it.
310 if (SkBitmap::ComputeIsOpaque(tmp)) {
311 tmp.setAlphaType(kOpaque_SkAlphaType);
312 }
313 }
314
315 *dst = tmp;
316 return true;
317 }
318
OLDNEW
« gm/aaclip.cpp ('K') | « src/ports/SkImageDecoder_CG.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698