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 |