1 #include "SkConfig8888.h"
2 #include "SkColorPriv.h"
3 #include "SkMathPriv.h"
4 #include "SkUnPreMultiply.h"
5
6 enum AlphaVerb {
7 kNothing_AlphaVerb,
8 kPremul_AlphaVerb,
9 kUnpremul_AlphaVerb,
10 };
11
convert32(uint32_t c)12 template <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
34 template <bool doSwapRB, AlphaVerb doAlpha>
convert32_row(uint32_t * dst,const uint32_t * src,int count)35 void 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
is_32bit_colortype(SkColorType ct)42 static bool is_32bit_colortype(SkColorType ct) {
43 return kRGBA_8888_SkColorType == ct || kBGRA_8888_SkColorType == ct;
44 }
45
compute_AlphaVerb(SkAlphaType src,SkAlphaType dst)46 static 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
memcpy32_row(uint32_t * dst,const uint32_t * src,int count)63 static void memcpy32_row(uint32_t* dst, const uint32_t* src, int count) {
64 memcpy(dst, src, count * 4);
65 }
66
convertPixelsTo(SkDstPixelInfo * dst,int width,int height) const67 bool 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