• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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