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

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
« no previous file with comments | « 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 CGBitmapInfo ComputeCGAlphaInfo_RGBA(SkAlphaType at) {
13 CGBitmapInfo 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 CGBitmapInfo ComputeCGAlphaInfo_BGRA(SkAlphaType at) {
30 CGBitmapInfo 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
25 switch (bm.colorType()) { 59 switch (bm.colorType()) {
26 case kRGB_565_SkColorType: 60 case kRGB_565_SkColorType:
27 #if 0 61 #if 0
28 // doesn't see quite right. Are they thinking 1555? 62 // doesn't see quite right. Are they thinking 1555?
29 *bitsPerComponent = 5; 63 *bitsPerComponent = 5;
30 *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; 64 *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone;
31 break; 65 #else
32 #endif
33 if (upscaleTo32) { 66 if (upscaleTo32) {
34 *upscaleTo32 = true; 67 *upscaleTo32 = true;
35 } 68 }
36 // fall through 69 // now treat like RGBA
37 case kN32_SkColorType:
38 *bitsPerComponent = 8; 70 *bitsPerComponent = 8;
39 #if SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 71 *info = ComputeCGAlphaInfo_RGBA(kOpaque_SkAlphaType);
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 72 #endif
68 break; 73 break;
74 case kRGBA_8888_SkColorType:
75 *bitsPerComponent = 8;
76 *info = ComputeCGAlphaInfo_RGBA(bm.alphaType());
77 break;
78 case kBGRA_8888_SkColorType:
79 *bitsPerComponent = 8;
80 *info = ComputeCGAlphaInfo_BGRA(bm.alphaType());
81 break;
69 case kARGB_4444_SkColorType: 82 case kARGB_4444_SkColorType:
70 *bitsPerComponent = 4; 83 *bitsPerComponent = 4;
71 *info = kCGBitmapByteOrder16Little; 84 *info = kCGBitmapByteOrder16Little;
72 if (bm.isOpaque()) { 85 if (bm.isOpaque()) {
73 *info |= kCGImageAlphaNoneSkipLast; 86 *info |= kCGImageAlphaNoneSkipLast;
74 } else { 87 } else {
75 *info |= kCGImageAlphaPremultipliedLast; 88 *info |= kCGImageAlphaPremultipliedLast;
76 } 89 }
77 break; 90 break;
78 default: 91 default:
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 CGColorSpaceRelease(cs); 237 CGColorSpaceRelease(cs);
225 238
226 if (ctx) { 239 if (ctx) {
227 CGContextDrawPDFPage(ctx, page); 240 CGContextDrawPDFPage(ctx, page);
228 CGContextRelease(ctx); 241 CGContextRelease(ctx);
229 } 242 }
230 243
231 output->swap(bitmap); 244 output->swap(bitmap);
232 return true; 245 return true;
233 } 246 }
247
248 //////////////////////////////////////////////////////////////////////////////// ///////////////////
249
250 SK_API bool SkCopyPixelsFromCGImage(const SkImageInfo& info, size_t rowBytes, vo id* pixels,
251 CGImageRef image) {
252 CGBitmapInfo cg_bitmap_info = 0;
253 size_t bitsPerComponent = 0;
254 switch (info.colorType()) {
255 case kRGBA_8888_SkColorType:
256 bitsPerComponent = 8;
257 cg_bitmap_info = ComputeCGAlphaInfo_RGBA(info.alphaType());
258 break;
259 case kBGRA_8888_SkColorType:
260 bitsPerComponent = 8;
261 cg_bitmap_info = ComputeCGAlphaInfo_BGRA(info.alphaType());
262 break;
263 default:
264 return false; // no other colortypes are supported (for now)
265 }
266
267 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
268 CGContextRef cg = CGBitmapContextCreate(pixels, info.width(), info.height(), bitsPerComponent,
269 rowBytes, cs, cg_bitmap_info);
270 CFRelease(cs);
271 if (NULL == cg) {
272 return false;
273 }
274
275 // use this blend mode, to avoid having to erase the pixels first, and to av oid CG performing
276 // any blending (which could introduce errors and be slower).
277 CGContextSetBlendMode(cg, kCGBlendModeCopy);
278
279 CGContextDrawImage(cg, CGRectMake(0, 0, info.width(), info.height()), image) ;
280 CGContextRelease(cg);
281 return true;
282 }
283
284 bool SkCreateBitmapFromCGImage(SkBitmap* dst, CGImageRef image, SkISize* scaleTo Fit) {
285 const int width = scaleToFit ? scaleToFit->width() : SkToInt(CGImageGetWidth (image));
286 const int height = scaleToFit ? scaleToFit->height() : SkToInt(CGImageGetHei ght(image));
287 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
288
289 SkBitmap tmp;
290 if (!tmp.allocPixels(info)) {
291 return false;
292 }
293
294 if (!SkCopyPixelsFromCGImage(tmp.info(), tmp.rowBytes(), tmp.getPixels(), im age)) {
295 return false;
296 }
297
298 CGImageAlphaInfo cgInfo = CGImageGetAlphaInfo(image);
299 switch (cgInfo) {
300 case kCGImageAlphaNone:
301 case kCGImageAlphaNoneSkipLast:
302 case kCGImageAlphaNoneSkipFirst:
303 SkASSERT(SkBitmap::ComputeIsOpaque(tmp));
304 tmp.setAlphaType(kOpaque_SkAlphaType);
305 break;
306 default:
307 // we don't know if we're opaque or not, so compute it.
308 if (SkBitmap::ComputeIsOpaque(tmp)) {
309 tmp.setAlphaType(kOpaque_SkAlphaType);
310 }
311 }
312
313 *dst = tmp;
314 return true;
315 }
316
OLDNEW
« no previous file with comments | « src/ports/SkImageDecoder_CG.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698