| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <base/logging.h> |
| 6 #include "chrome/browser/cocoa/cocoa_utils.h" |
| 7 #import <QuartzCore/CIImage.h> |
| 8 #include "third_party/skia/include/utils/mac/SkCGUtils.h" |
| 9 #include "third_party/skia/include/core/SkColorPriv.h" |
| 10 |
| 11 namespace { |
| 12 |
| 13 // Callback passed to CGDataProviderCreateWithData() |
| 14 void ReleaseData(void* info, const void* pixelData, size_t size) { |
| 15 // info is a non-const pixelData |
| 16 if (info) |
| 17 free(info); |
| 18 } |
| 19 |
| 20 } |
| 21 |
| 22 namespace CocoaUtils { |
| 23 |
| 24 NSImage* SkBitmapToNSImage(const SkBitmap& icon) { |
| 25 // First convert SkBitmap to CGImageRef. |
| 26 CGImageRef cgimage; |
| 27 if (icon.config() != SkBitmap::kARGB_8888_Config) { |
| 28 cgimage = SkCreateCGImageRef(icon); |
| 29 } else { |
| 30 // The above code returns a valid NSImage even in the |
| 31 // kARGB_8888_Config case. As an example, the unit test which |
| 32 // draws a blue SkBitmap can lockPixels, NSReadPixel, and pull out |
| 33 // a single pixel from the NSImage and see it blue. However, the |
| 34 // NSImage returned will be in ABGR format. Although Cocoa is |
| 35 // otherwise happy with that format (as seen in simple tests |
| 36 // outside Chromium), Chromium is NOT happy. In Chromium, B and R |
| 37 // are swapped. |
| 38 // |
| 39 // As a hint, CIImage supports a few formats, such as ARGB. |
| 40 // Interestingly, it does NOT support ABGR. I speculate there is |
| 41 // some way we set up our drawing context which has the format |
| 42 // specified wrong (in skia/ext/bitmap_platform_device_mac.cc), |
| 43 // but I have not been able to solve this yet. |
| 44 // |
| 45 // TODO(jrg): track down the disconnect. |
| 46 // TODO(jrg): Remove byte conversion. |
| 47 // TODO(jrg): Fix unit tests to NOT swap bytes. |
| 48 // http://crbug.com/14020 |
| 49 CGBitmapInfo info = (kCGImageAlphaPremultipliedFirst | |
| 50 kCGBitmapByteOrder32Host); |
| 51 int width = icon.width(); |
| 52 int height = icon.height(); |
| 53 int rowbytes = icon.rowBytes(); |
| 54 int rowwords = rowbytes/4; |
| 55 unsigned length = rowbytes * height; |
| 56 DCHECK(length > 0); |
| 57 uint32_t* rawptr = static_cast<uint32_t*>(malloc(length)); |
| 58 DCHECK(rawptr); |
| 59 if (!rawptr || !length) |
| 60 return nil; |
| 61 |
| 62 // Convert ABGR to ARGB |
| 63 icon.lockPixels(); |
| 64 uint32_t* rawbitmap = static_cast<uint32_t*>(icon.getPixels()); |
| 65 uint32_t rawbit; |
| 66 int offset; |
| 67 for (int y = 0; y < height; y++) { |
| 68 for (int x = 0; x < width; x++) { |
| 69 offset = x + y*rowwords; |
| 70 rawbit = rawbitmap[offset]; |
| 71 rawptr[offset] = SkPackARGB32(SkGetPackedA32(rawbit), |
| 72 SkGetPackedR32(rawbit), |
| 73 SkGetPackedG32(rawbit), |
| 74 SkGetPackedB32(rawbit)); |
| 75 } |
| 76 } |
| 77 icon.unlockPixels(); |
| 78 |
| 79 CGDataProviderRef dataRef = |
| 80 CGDataProviderCreateWithData(rawptr, rawptr, length, ReleaseData); |
| 81 CGColorSpaceRef space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); |
| 82 cgimage = CGImageCreate(width, height, 8, |
| 83 icon.bytesPerPixel() * 8, |
| 84 rowbytes, space, info, dataRef, |
| 85 NULL, false, kCGRenderingIntentDefault); |
| 86 CGColorSpaceRelease(space); |
| 87 CGDataProviderRelease(dataRef); |
| 88 } |
| 89 |
| 90 // Now convert to NSImage. |
| 91 NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] |
| 92 initWithCGImage:cgimage] autorelease]; |
| 93 NSImage* image = [[[NSImage alloc] init] autorelease]; |
| 94 [image addRepresentation:bitmap]; |
| 95 return image; |
| 96 } |
| 97 |
| 98 } // namespace CocoaUtils |
| 99 |
| OLD | NEW |