OLD | NEW |
1 #include "SkConfig8888.h" | 1 #include "SkConfig8888.h" |
| 2 #include "SkColorPriv.h" |
2 #include "SkMathPriv.h" | 3 #include "SkMathPriv.h" |
3 #include "SkUnPreMultiply.h" | 4 #include "SkUnPreMultiply.h" |
4 | 5 |
5 namespace { | 6 #if 0 |
6 | 7 |
7 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX> | 8 template <int A_IDX, int R_IDX, int G_IDX, int B_IDX> |
8 inline uint32_t pack_config8888(uint32_t a, uint32_t r, | 9 inline uint32_t pack_config8888(uint32_t a, uint32_t r, |
9 uint32_t g, uint32_t b) { | 10 uint32_t g, uint32_t b) { |
10 #ifdef SK_CPU_LENDIAN | 11 #ifdef SK_CPU_LENDIAN |
11 return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) | | 12 return (a << (A_IDX * 8)) | (r << (R_IDX * 8)) | |
12 (g << (G_IDX * 8)) | (b << (B_IDX * 8)); | 13 (g << (G_IDX * 8)) | (b << (B_IDX * 8)); |
13 #else | 14 #else |
14 return (a << ((3-A_IDX) * 8)) | (r << ((3-R_IDX) * 8)) | | 15 return (a << ((3-A_IDX) * 8)) | (r << ((3-R_IDX) * 8)) | |
15 (g << ((3-G_IDX) * 8)) | (b << ((3-B_IDX) * 8)); | 16 (g << ((3-G_IDX) * 8)) | (b << ((3-B_IDX) * 8)); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 case SkCanvas::kBGRA_Unpremul_Config8888: | 272 case SkCanvas::kBGRA_Unpremul_Config8888: |
272 return pack_config8888<3, 2, 1, 0>(a, r, g, b); | 273 return pack_config8888<3, 2, 1, 0>(a, r, g, b); |
273 case SkCanvas::kRGBA_Premul_Config8888: | 274 case SkCanvas::kRGBA_Premul_Config8888: |
274 case SkCanvas::kRGBA_Unpremul_Config8888: | 275 case SkCanvas::kRGBA_Unpremul_Config8888: |
275 return pack_config8888<3, 0, 1, 2>(a, r, g, b); | 276 return pack_config8888<3, 0, 1, 2>(a, r, g, b); |
276 default: | 277 default: |
277 SkDEBUGFAIL("Unexpected config8888"); | 278 SkDEBUGFAIL("Unexpected config8888"); |
278 return 0; | 279 return 0; |
279 } | 280 } |
280 } | 281 } |
| 282 #endif |
| 283 |
| 284 enum AlphaVerb { |
| 285 kNothing_AlphaVerb, |
| 286 kPremul_AlphaVerb, |
| 287 kUnpremul_AlphaVerb, |
| 288 }; |
| 289 |
| 290 static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT); |
| 291 |
| 292 template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) { |
| 293 if (doSwapRB) { |
| 294 // Lucky for us, both RGBA and BGRA only differ by R and B, and they as
a pair are always |
| 295 // in the same two slots, so to perform a swizzle from one order to anot
her, it is enough |
| 296 // to just swap those two bytes. |
| 297 unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF; |
| 298 unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF; |
| 299 c = (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT); |
| 300 } |
| 301 |
| 302 // Lucky for us, in both RGBA and BGRA, the alpha component is always in the
same place, so |
| 303 // we can perform premul or unpremul the same way without knowing the swizzl
es for RGB. |
| 304 switch (doAlpha) { |
| 305 case kNothing_AlphaVerb: |
| 306 // no change |
| 307 break; |
| 308 case kPremul_AlphaVerb: |
| 309 c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), |
| 310 SkGetPackedG32(c), SkGetPackedB32(c)); |
| 311 break; |
| 312 case kUnpremul_AlphaVerb: |
| 313 c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c); |
| 314 break; |
| 315 } |
| 316 return c; |
| 317 } |
| 318 |
| 319 template <bool doSwapRB, AlphaVerb doAlpha> |
| 320 void convert32_row(uint32_t* dst, const uint32_t* src, int count) { |
| 321 for (int i = 0; i < count; ++i) { |
| 322 dst[i] = convert32<doSwapRB, doAlpha>(src[i]); |
| 323 } |
| 324 } |
| 325 |
| 326 static bool is_32bit_colortype(SkColorType ct) { |
| 327 return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct; |
| 328 } |
| 329 |
| 330 static AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) { |
| 331 SkASSERT(kIgnore_SkAlphaType != src); |
| 332 SkASSERT(kIgnore_SkAlphaType != dst); |
| 333 |
| 334 if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst)
{ |
| 335 return kNothing_AlphaVerb; |
| 336 } |
| 337 if (kPremul_SkAlphaType == dst) { |
| 338 SkASSERT(kUnpremul_SkAlphaType == src); |
| 339 return kPremul_AlphaVerb; |
| 340 } else { |
| 341 SkASSERT(kPremul_SkAlphaType == src); |
| 342 SkASSERT(kUnpremul_SkAlphaType == dst); |
| 343 return kUnpremul_AlphaVerb; |
| 344 } |
| 345 } |
| 346 |
| 347 static void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) { |
| 348 memcpy(dst, src, count * 4); |
| 349 } |
| 350 |
| 351 bool SkPixelInfo::convertPixelsTo(SkPixelInfo* dst, int width, int height) const
{ |
| 352 if (width <= 0 || height <= 0) { |
| 353 return false; |
| 354 } |
| 355 |
| 356 if (!is_32bit_colortype(fColorType) || !is_32bit_colortype(dst->fColorType))
{ |
| 357 return false; |
| 358 } |
| 359 |
| 360 void (*proc)(uint32_t* dst, const uint32_t* src, int count); |
| 361 AlphaVerb doAlpha = compute_AlphaVerb(fAlphaType, dst->fAlphaType); |
| 362 bool doSwapRB = fColorType != dst->fColorType; |
| 363 |
| 364 switch (doAlpha) { |
| 365 case kNothing_AlphaVerb: |
| 366 if (doSwapRB) { |
| 367 proc = convert32_row<true, kNothing_AlphaVerb>; |
| 368 } else { |
| 369 proc = memcpy32_row; |
| 370 } |
| 371 break; |
| 372 case kPremul_AlphaVerb: |
| 373 if (doSwapRB) { |
| 374 proc = convert32_row<true, kPremul_AlphaVerb>; |
| 375 } else { |
| 376 proc = convert32_row<false, kPremul_AlphaVerb>; |
| 377 } |
| 378 break; |
| 379 case kUnpremul_AlphaVerb: |
| 380 if (doSwapRB) { |
| 381 proc = convert32_row<true, kUnpremul_AlphaVerb>; |
| 382 } else { |
| 383 proc = convert32_row<false, kUnpremul_AlphaVerb>; |
| 384 } |
| 385 break; |
| 386 } |
| 387 |
| 388 uint32_t* dstP = static_cast<uint32_t*>(dst->fPixels); |
| 389 const uint32_t* srcP = static_cast<const uint32_t*>(fPixels); |
| 390 size_t srcInc = fRowBytes >> 2; |
| 391 size_t dstInc = dst->fRowBytes >> 2; |
| 392 for (int y = 0; y < height; ++y) { |
| 393 proc(dstP, srcP, width); |
| 394 dstP += dstInc; |
| 395 srcP += srcInc; |
| 396 } |
| 397 return true; |
| 398 } |
| 399 |
OLD | NEW |