OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 unsigned alphaMult = a * fixPointMult; | 171 unsigned alphaMult = a * fixPointMult; |
172 r = fixPointUnsignedMultiply(r, alphaMult); | 172 r = fixPointUnsignedMultiply(r, alphaMult); |
173 g = fixPointUnsignedMultiply(g, alphaMult); | 173 g = fixPointUnsignedMultiply(g, alphaMult); |
174 b = fixPointUnsignedMultiply(b, alphaMult); | 174 b = fixPointUnsignedMultiply(b, alphaMult); |
175 } | 175 } |
176 // Call the "NoCheck" version since we may deliberately pass non-pre multiplied | 176 // Call the "NoCheck" version since we may deliberately pass non-pre multiplied |
177 // values, and we don't want an assert. | 177 // values, and we don't want an assert. |
178 *dest = SkPackARGB32NoCheck(a, r, g, b); | 178 *dest = SkPackARGB32NoCheck(a, r, g, b); |
179 } | 179 } |
180 | 180 |
181 inline void fillRowFromRGBSource(int rowIndex, const unsigned char* src) | |
Peter Kasting
2013/06/01 01:22:12
I don't think we gain much from having these first
| |
182 { | |
183 fillRowFromRGBSource(getAddr(0, rowIndex), src, width()); | |
184 } | |
185 | |
186 inline void fillRowFromRGBASource(int rowIndex, const unsigned char* src ) | |
187 { | |
188 bool dummy; | |
189 fillRowFromRGBASource<false>(getAddr(0, rowIndex), src, width(), dum my); | |
190 } | |
191 | |
192 inline void fillRowFromRGBASourceWithNonTrivialAlphaDetection(int rowInd ex, const unsigned char *src, bool& hasNonTrivialAlpha) | |
193 { | |
194 fillRowFromRGBASource<true>(getAddr(0, rowIndex), src, width(), hasN onTrivialAlpha); | |
195 } | |
196 | |
197 inline void fillRowFromInvertedCMYK(int rowIndex, const unsigned char* s rc) | |
198 { | |
199 fillRowFromInvertedCMYK(getAddr(0, rowIndex), src, width()); | |
200 } | |
201 | |
181 private: | 202 private: |
203 // We have specialized fill functions for each case. This way we avoid b ranches in the loop which gives performace. | |
204 // Note: we could benefit further from turning on auto vectorization in the compiler. | |
205 | |
206 ALWAYS_INLINE static void fillRowFromRGBSource(PixelData* dst, const uns igned char* src, int numPixels) | |
207 { | |
208 const unsigned char* pixel = src; | |
209 for (int i = 0; i < numPixels; ++i, pixel += 3) | |
210 dst[i] = SkPackARGB32NoCheck(255, pixel[0], pixel[1], pixel[2]); | |
211 } | |
212 | |
213 template <bool shouldUpdate> | |
214 inline static void updateAlphaMask(unsigned char alpha, unsigned char& m ask) | |
Peter Kasting
2013/06/01 01:22:12
Nit: Honestly, I'm not convinced pulling this into
| |
215 { | |
216 if (shouldUpdate) | |
217 mask &= alpha; | |
218 } | |
219 | |
220 template <bool shouldUpdateAlphaMask> | |
221 ALWAYS_INLINE static void fillRowFromRGBASourceNoPremultiply(PixelData* dst, const unsigned char* src, int numPixels, unsigned char& alphaMask) | |
222 { | |
223 const unsigned char* pixel = src; | |
224 for (int i = 0; i < numPixels; ++i, pixel += 4) { | |
225 unsigned char alpha = pixel[3]; | |
226 dst[i] = SkPackARGB32NoCheck(alpha, pixel[0], pixel[1], pixel[2] ); | |
227 updateAlphaMask<shouldUpdateAlphaMask>(alpha, alphaMask); | |
228 } | |
229 } | |
230 | |
231 template <bool shouldUpdateAlphaMask> | |
232 ALWAYS_INLINE static void fillRowFromRGBASourcePremultiply(PixelData* ds t, const unsigned char* src, int numPixels, unsigned char& alphaMask) | |
233 { | |
234 const unsigned char* pixel = src; | |
235 for (int i = 0; i < numPixels; ++i, pixel += 4) { | |
236 unsigned char r = pixel[0]; | |
237 unsigned char g = pixel[1]; | |
238 unsigned char b = pixel[2]; | |
239 unsigned char a = pixel[3]; | |
240 | |
241 updateAlphaMask<shouldUpdateAlphaMask>(a, alphaMask); | |
242 | |
243 // Note: if once we start using auto vectorization we should ree valuate whether the fast paths are | |
244 // worthwile when alpha is zero or 255. Currently without vector ization they are. | |
245 if (!a) { | |
246 dst[i] = 0; | |
247 continue; | |
248 } | |
249 if (a < 255) { | |
250 unsigned alphaMult = a * fixPointMult; | |
251 r = fixPointUnsignedMultiply(r, alphaMult); | |
252 g = fixPointUnsignedMultiply(g, alphaMult); | |
253 b = fixPointUnsignedMultiply(b, alphaMult); | |
254 } | |
255 dst[i] = SkPackARGB32NoCheck(a, r, g, b); | |
256 } | |
257 } | |
258 | |
259 template <bool shouldUpdateHasNonTrivialAlpha> | |
260 ALWAYS_INLINE void fillRowFromRGBASource(PixelData* dst, const unsigned char* src, int numPixels, bool& hasNonTrivialAlpha) | |
Peter Kasting
2013/06/01 01:22:12
Nit: If you take a bool* as the last arg, we can p
| |
261 { | |
262 unsigned char alphaMask = 255; | |
263 if (m_premultiplyAlpha) | |
264 fillRowFromRGBASourcePremultiply<shouldUpdateHasNonTrivialAlpha> (dst, src, numPixels, alphaMask); | |
265 else | |
266 fillRowFromRGBASourceNoPremultiply<shouldUpdateHasNonTrivialAlph a>(dst, src, numPixels, alphaMask); | |
267 | |
268 if (shouldUpdateHasNonTrivialAlpha) | |
269 hasNonTrivialAlpha = alphaMask != 255; | |
270 } | |
271 | |
272 ALWAYS_INLINE static void fillRowFromInvertedCMYK(PixelData* dst, const unsigned char* src, int numPixels) | |
273 { | |
274 // Source is 'Inverted CMYK', output is RGB. | |
275 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 | |
276 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb | |
277 // From CMYK to CMY: | |
278 // X = X * (1 - K ) + K [for X = C, M, or Y] | |
279 // Thus, from Inverted CMYK to CMY is: | |
280 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK | |
281 // From CMY (0..1) to RGB (0..1): | |
282 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] | |
283 | |
284 const unsigned char* pixel = src; | |
285 for (int i = 0; i < numPixels; ++i, pixel += 4) { | |
286 unsigned char c = pixel[0]; | |
287 unsigned char m = pixel[1]; | |
288 unsigned char y = pixel[2]; | |
289 unsigned char k = pixel[3]; | |
290 | |
291 unsigned kMult = k * fixPointMult; | |
292 c = fixPointUnsignedMultiply(c, kMult); | |
293 m = fixPointUnsignedMultiply(m, kMult); | |
294 y = fixPointUnsignedMultiply(y, kMult); | |
295 | |
296 dst[i] = SkPackARGB32NoCheck(255, c, m, y); | |
Peter Kasting
2013/06/01 01:22:12
It strikes me that this function is effectively id
| |
297 } | |
298 } | |
299 | |
182 int width() const | 300 int width() const |
183 { | 301 { |
184 return m_bitmap->bitmap().width(); | 302 return m_bitmap->bitmap().width(); |
185 } | 303 } |
186 | 304 |
187 int height() const | 305 int height() const |
188 { | 306 { |
189 return m_bitmap->bitmap().height(); | 307 return m_bitmap->bitmap().height(); |
190 } | 308 } |
191 | 309 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 | 514 |
397 IntSize m_size; | 515 IntSize m_size; |
398 bool m_sizeAvailable; | 516 bool m_sizeAvailable; |
399 bool m_isAllDataReceived; | 517 bool m_isAllDataReceived; |
400 bool m_failed; | 518 bool m_failed; |
401 }; | 519 }; |
402 | 520 |
403 } // namespace WebCore | 521 } // namespace WebCore |
404 | 522 |
405 #endif | 523 #endif |
OLD | NEW |