| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkCGUtils.h" | 8 #include "SkCGUtils.h" |
| 9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) { | 41 static CGImageSourceRef SkStreamToCGImageSource(SkStream* stream) { |
| 42 CGDataProviderRef data = SkStreamToDataProvider(stream); | 42 CGDataProviderRef data = SkStreamToDataProvider(stream); |
| 43 SkASSERT(data); | 43 SkASSERT(data); |
| 44 CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0); | 44 CGImageSourceRef imageSrc = CGImageSourceCreateWithDataProvider(data, 0); |
| 45 CGDataProviderRelease(data); | 45 CGDataProviderRelease(data); |
| 46 return imageSrc; | 46 return imageSrc; |
| 47 } | 47 } |
| 48 | 48 |
| 49 class SkImageDecoder_CG : public SkImageDecoder { | 49 class SkImageDecoder_CG : public SkImageDecoder { |
| 50 protected: | 50 protected: |
| 51 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); | 51 virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode); |
| 52 }; | 52 }; |
| 53 | 53 |
| 54 static void argb_4444_force_opaque(void* row, int count) { | 54 static void argb_4444_force_opaque(void* row, int count) { |
| 55 uint16_t* row16 = (uint16_t*)row; | 55 uint16_t* row16 = (uint16_t*)row; |
| 56 for (int i = 0; i < count; ++i) { | 56 for (int i = 0; i < count; ++i) { |
| 57 row16[i] |= 0xF000; | 57 row16[i] |= 0xF000; |
| 58 } | 58 } |
| 59 } | 59 } |
| 60 | 60 |
| 61 static void argb_8888_force_opaque(void* row, int count) { | 61 static void argb_8888_force_opaque(void* row, int count) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 char* row = (char*)bm->getPixels(); | 96 char* row = (char*)bm->getPixels(); |
| 97 for (int y = 0; y < bm->height(); ++y) { | 97 for (int y = 0; y < bm->height(); ++y) { |
| 98 proc(row, bm->width()); | 98 proc(row, bm->width()); |
| 99 row += bm->rowBytes(); | 99 row += bm->rowBytes(); |
| 100 } | 100 } |
| 101 bm->setAlphaType(kOpaque_SkAlphaType); | 101 bm->setAlphaType(kOpaque_SkAlphaType); |
| 102 } | 102 } |
| 103 | 103 |
| 104 #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) | 104 #define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) |
| 105 | 105 |
| 106 bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | 106 SkImageDecoder::Result SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* b
m, Mode mode) { |
| 107 CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); | 107 CGImageSourceRef imageSrc = SkStreamToCGImageSource(stream); |
| 108 | 108 |
| 109 if (NULL == imageSrc) { | 109 if (NULL == imageSrc) { |
| 110 return false; | 110 return kFailure; |
| 111 } | 111 } |
| 112 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); | 112 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); |
| 113 | 113 |
| 114 CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL); | 114 CGImageRef image = CGImageSourceCreateImageAtIndex(imageSrc, 0, NULL); |
| 115 if (NULL == image) { | 115 if (NULL == image) { |
| 116 return false; | 116 return kFailure; |
| 117 } | 117 } |
| 118 SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); | 118 SkAutoTCallVProc<CGImage, CGImageRelease> arimage(image); |
| 119 | 119 |
| 120 const int width = SkToInt(CGImageGetWidth(image)); | 120 const int width = SkToInt(CGImageGetWidth(image)); |
| 121 const int height = SkToInt(CGImageGetHeight(image)); | 121 const int height = SkToInt(CGImageGetHeight(image)); |
| 122 | 122 |
| 123 bm->setInfo(SkImageInfo::MakeN32Premul(width, height)); | 123 bm->setInfo(SkImageInfo::MakeN32Premul(width, height)); |
| 124 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 124 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
| 125 return true; | 125 return kSuccess; |
| 126 } | 126 } |
| 127 | 127 |
| 128 if (!this->allocPixelRef(bm, NULL)) { | 128 if (!this->allocPixelRef(bm, NULL)) { |
| 129 return false; | 129 return kFailure; |
| 130 } | 130 } |
| 131 | 131 |
| 132 SkAutoLockPixels alp(*bm); | 132 SkAutoLockPixels alp(*bm); |
| 133 | 133 |
| 134 if (!SkCopyPixelsFromCGImage(bm->info(), bm->rowBytes(), bm->getPixels(), im
age)) { | 134 if (!SkCopyPixelsFromCGImage(bm->info(), bm->rowBytes(), bm->getPixels(), im
age)) { |
| 135 return false; | 135 return kFailure; |
| 136 } | 136 } |
| 137 | 137 |
| 138 CGImageAlphaInfo info = CGImageGetAlphaInfo(image); | 138 CGImageAlphaInfo info = CGImageGetAlphaInfo(image); |
| 139 switch (info) { | 139 switch (info) { |
| 140 case kCGImageAlphaNone: | 140 case kCGImageAlphaNone: |
| 141 case kCGImageAlphaNoneSkipLast: | 141 case kCGImageAlphaNoneSkipLast: |
| 142 case kCGImageAlphaNoneSkipFirst: | 142 case kCGImageAlphaNoneSkipFirst: |
| 143 // We're opaque, but we can't rely on the data always having 0xFF | 143 // We're opaque, but we can't rely on the data always having 0xFF |
| 144 // in the alpha slot (which Skia wants), so we have to ram it in | 144 // in the alpha slot (which Skia wants), so we have to ram it in |
| 145 // ourselves. | 145 // ourselves. |
| 146 force_opaque(bm); | 146 force_opaque(bm); |
| 147 break; | 147 break; |
| 148 default: | 148 default: |
| 149 // we don't know if we're opaque or not, so compute it. | 149 // we don't know if we're opaque or not, so compute it. |
| 150 if (SkBitmap::ComputeIsOpaque(*bm)) { | 150 if (SkBitmap::ComputeIsOpaque(*bm)) { |
| 151 bm->setAlphaType(kOpaque_SkAlphaType); | 151 bm->setAlphaType(kOpaque_SkAlphaType); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) { | 154 if (!bm->isOpaque() && this->getRequireUnpremultipliedColors()) { |
| 155 // CGBitmapContext does not support unpremultiplied, so the image has be
en premultiplied. | 155 // CGBitmapContext does not support unpremultiplied, so the image has be
en premultiplied. |
| 156 // Convert to unpremultiplied. | 156 // Convert to unpremultiplied. |
| 157 for (int i = 0; i < width; ++i) { | 157 for (int i = 0; i < width; ++i) { |
| 158 for (int j = 0; j < height; ++j) { | 158 for (int j = 0; j < height; ++j) { |
| 159 uint32_t* addr = bm->getAddr32(i, j); | 159 uint32_t* addr = bm->getAddr32(i, j); |
| 160 *addr = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*addr)
; | 160 *addr = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(*addr)
; |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 bm->setAlphaType(kUnpremul_SkAlphaType); | 163 bm->setAlphaType(kUnpremul_SkAlphaType); |
| 164 } | 164 } |
| 165 return true; | 165 return kSuccess; |
| 166 } | 166 } |
| 167 | 167 |
| 168 /////////////////////////////////////////////////////////////////////////////// | 168 /////////////////////////////////////////////////////////////////////////////// |
| 169 | 169 |
| 170 extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); | 170 extern SkImageDecoder* image_decoder_from_stream(SkStreamRewindable*); |
| 171 | 171 |
| 172 SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) { | 172 SkImageDecoder* SkImageDecoder::Factory(SkStreamRewindable* stream) { |
| 173 SkImageDecoder* decoder = image_decoder_from_stream(stream); | 173 SkImageDecoder* decoder = image_decoder_from_stream(stream); |
| 174 if (NULL == decoder) { | 174 if (NULL == decoder) { |
| 175 // If no image decoder specific to the stream exists, use SkImageDecoder
_CG. | 175 // If no image decoder specific to the stream exists, use SkImageDecoder
_CG. |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 | 346 |
| 347 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); | 347 SkAutoTCallVProc<const void, CFRelease> arsrc(imageSrc); |
| 348 const CFStringRef name = CGImageSourceGetType(imageSrc); | 348 const CFStringRef name = CGImageSourceGetType(imageSrc); |
| 349 if (NULL == name) { | 349 if (NULL == name) { |
| 350 return SkImageDecoder::kUnknown_Format; | 350 return SkImageDecoder::kUnknown_Format; |
| 351 } | 351 } |
| 352 return UTType_to_Format(name); | 352 return UTType_to_Format(name); |
| 353 } | 353 } |
| 354 | 354 |
| 355 static SkImageDecoder_FormatReg gFormatReg(get_format_cg); | 355 static SkImageDecoder_FormatReg gFormatReg(get_format_cg); |
| OLD | NEW |