1#include "SkConfig8888.h" 2#include "SkColorPriv.h" 3#include "SkMathPriv.h" 4#include "SkUnPreMultiply.h" 5 6enum AlphaVerb { 7 kNothing_AlphaVerb, 8 kPremul_AlphaVerb, 9 kUnpremul_AlphaVerb, 10}; 11 12template <bool doSwapRB, AlphaVerb doAlpha> uint32_t convert32(uint32_t c) { 13 if (doSwapRB) { 14 c = SkSwizzle_RB(c); 15 } 16 17 // Lucky for us, in both RGBA and BGRA, the alpha component is always in the same place, so 18 // we can perform premul or unpremul the same way without knowing the swizzles for RGB. 19 switch (doAlpha) { 20 case kNothing_AlphaVerb: 21 // no change 22 break; 23 case kPremul_AlphaVerb: 24 c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c), 25 SkGetPackedG32(c), SkGetPackedB32(c)); 26 break; 27 case kUnpremul_AlphaVerb: 28 c = SkUnPreMultiply::UnPreMultiplyPreservingByteOrder(c); 29 break; 30 } 31 return c; 32} 33 34template <bool doSwapRB, AlphaVerb doAlpha> 35void convert32_row(uint32_t* dst, const uint32_t* src, int count) { 36 // This has to be correct if src == dst (but not partial overlap) 37 for (int i = 0; i < count; ++i) { 38 dst[i] = convert32<doSwapRB, doAlpha>(src[i]); 39 } 40} 41 42static bool is_32bit_colortype(SkColorType ct) { 43 return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct; 44} 45 46static AlphaVerb compute_AlphaVerb(SkAlphaType src, SkAlphaType dst) { 47 SkASSERT(kIgnore_SkAlphaType != src); 48 SkASSERT(kIgnore_SkAlphaType != dst); 49 50 if (kOpaque_SkAlphaType == src || kOpaque_SkAlphaType == dst || src == dst) { 51 return kNothing_AlphaVerb; 52 } 53 if (kPremul_SkAlphaType == dst) { 54 SkASSERT(kUnpremul_SkAlphaType == src); 55 return kPremul_AlphaVerb; 56 } else { 57 SkASSERT(kPremul_SkAlphaType == src); 58 SkASSERT(kUnpremul_SkAlphaType == dst); 59 return kUnpremul_AlphaVerb; 60 } 61} 62 63static void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) { 64 memcpy(dst, src, count * 4); 65} 66 67bool SkSrcPixelInfo::convertPixelsTo(SkDstPixelInfo* dst, int width, int height) const { 68 if (width <= 0 || height <= 0) { 69 return false; 70 } 71 72 if (!is_32bit_colortype(fColorType) || !is_32bit_colortype(dst->fColorType)) { 73 return false; 74 } 75 76 void (*proc)(uint32_t* dst, const uint32_t* src, int count); 77 AlphaVerb doAlpha = compute_AlphaVerb(fAlphaType, dst->fAlphaType); 78 bool doSwapRB = fColorType != dst->fColorType; 79 80 switch (doAlpha) { 81 case kNothing_AlphaVerb: 82 if (doSwapRB) { 83 proc = convert32_row<true, kNothing_AlphaVerb>; 84 } else { 85 if (fPixels == dst->fPixels) { 86 return true; 87 } 88 proc = memcpy32_row; 89 } 90 break; 91 case kPremul_AlphaVerb: 92 if (doSwapRB) { 93 proc = convert32_row<true, kPremul_AlphaVerb>; 94 } else { 95 proc = convert32_row<false, kPremul_AlphaVerb>; 96 } 97 break; 98 case kUnpremul_AlphaVerb: 99 if (doSwapRB) { 100 proc = convert32_row<true, kUnpremul_AlphaVerb>; 101 } else { 102 proc = convert32_row<false, kUnpremul_AlphaVerb>; 103 } 104 break; 105 } 106 107 uint32_t* dstP = static_cast<uint32_t*>(dst->fPixels); 108 const uint32_t* srcP = static_cast<const uint32_t*>(fPixels); 109 size_t srcInc = fRowBytes >> 2; 110 size_t dstInc = dst->fRowBytes >> 2; 111 for (int y = 0; y < height; ++y) { 112 proc(dstP, srcP, width); 113 dstP += dstInc; 114 srcP += srcInc; 115 } 116 return true; 117} 118