• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkBlitRow.h"
9 #include "SkColorPriv.h"
10 #include "SkDither.h"
11 
12 ///////////////////////////////////////////////////////////////////////////////
13 
S32_D4444_Opaque(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)14 static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst,
15                              const SkPMColor* SK_RESTRICT src, int count,
16                              U8CPU alpha, int /*x*/, int /*y*/) {
17     SkASSERT(255 == alpha);
18 
19     if (count > 0) {
20         do {
21             SkPMColor c = *src++;
22             SkPMColorAssert(c);
23             SkASSERT(SkGetPackedA32(c) == 255);
24             *dst++ = SkPixel32ToPixel4444(c);
25         } while (--count != 0);
26     }
27 }
28 
S32_D4444_Blend(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)29 static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst,
30                             const SkPMColor* SK_RESTRICT src, int count,
31                             U8CPU alpha, int /*x*/, int /*y*/) {
32     SkASSERT(255 > alpha);
33 
34     if (count > 0) {
35         unsigned scale16 = SkAlpha255To256(alpha) >> 4;
36         do {
37             SkPMColor c = *src++;
38             SkPMColorAssert(c);
39             SkASSERT(SkGetPackedA32(c) == 255);
40 
41             uint32_t src_expand = SkExpand32_4444(c);
42             uint32_t dst_expand = SkExpand_4444(*dst);
43             dst_expand += (src_expand - dst_expand) * scale16 >> 4;
44             *dst++ = SkCompact_4444(dst_expand);
45         } while (--count != 0);
46     }
47 }
48 
S32A_D4444_Opaque(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)49 static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst,
50                               const SkPMColor* SK_RESTRICT src, int count,
51                               U8CPU alpha, int /*x*/, int /*y*/) {
52     SkASSERT(255 == alpha);
53 
54     if (count > 0) {
55         do {
56             SkPMColor c = *src++;
57             SkPMColorAssert(c);
58 //            if (__builtin_expect(c!=0, 1))
59             if (c)
60             {
61                 unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4;
62                 uint32_t src_expand = SkExpand_8888(c);
63                 uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
64                 *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
65             }
66             dst += 1;
67         } while (--count != 0);
68     }
69 }
70 
S32A_D4444_Blend(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int,int)71 static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst,
72                              const SkPMColor* SK_RESTRICT src, int count,
73                              U8CPU alpha, int /*x*/, int /*y*/) {
74     SkASSERT(255 > alpha);
75 
76     if (count > 0) {
77         int src_scale = SkAlpha255To256(alpha) >> 4;
78         do {
79             SkPMColor sc = *src++;
80             SkPMColorAssert(sc);
81 
82             if (sc) {
83                 unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8);
84                 uint32_t src_expand = SkExpand32_4444(sc) * src_scale;
85                 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
86                 *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
87             }
88             dst += 1;
89         } while (--count != 0);
90     }
91 }
92 
93 /////////////////////////////////////////////////////////////////////////////
94 
S32_D4444_Opaque_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)95 static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
96                                     const SkPMColor* SK_RESTRICT src,
97                                     int count, U8CPU alpha, int x, int y) {
98     SkASSERT(255 == alpha);
99 
100     if (count > 0) {
101         DITHER_4444_SCAN(y);
102         do {
103             SkPMColor c = *src++;
104             SkPMColorAssert(c);
105 
106             unsigned dither = DITHER_VALUE(x);
107             *dst++ = SkDitherARGB32To4444(c, dither);
108             DITHER_INC_X(x);
109         } while (--count != 0);
110     }
111 }
112 
S32_D4444_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)113 static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
114                                    const SkPMColor* SK_RESTRICT src,
115                                    int count, U8CPU alpha, int x, int y) {
116     SkASSERT(255 > alpha);
117 
118     if (count > 0) {
119         int scale16 = SkAlpha255To256(alpha) >> 4;
120         DITHER_4444_SCAN(y);
121         do {
122             SkPMColor c = *src++;
123             SkPMColorAssert(c);
124             SkASSERT(SkGetPackedA32(c) == 255);
125 
126             uint32_t src_expand = SkExpand32_4444(c) * scale16;
127             uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16);
128 
129             c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor
130             *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
131             DITHER_INC_X(x);
132         } while (--count != 0);
133     }
134 }
135 
S32A_D4444_Opaque_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)136 static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
137                                      const SkPMColor* SK_RESTRICT src,
138                                      int count, U8CPU alpha, int x, int y) {
139     SkASSERT(255 == alpha);
140 
141     if (count > 0) {
142         DITHER_4444_SCAN(y);
143         do {
144             SkPMColor c = *src++;
145             SkPMColorAssert(c);
146             if (c) {
147                 unsigned a = SkGetPackedA32(c);
148                 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a));
149 
150                 unsigned scale16 = SkAlpha255To256(255 - a) >> 4;
151                 uint32_t src_expand = SkExpand_8888(c);
152                 uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
153                 // convert back to SkPMColor
154                 c = SkCompact_8888(src_expand + dst_expand);
155                 *dst = SkDitherARGB32To4444(c, d);
156             }
157             dst += 1;
158             DITHER_INC_X(x);
159         } while (--count != 0);
160     }
161 }
162 
163 // need DitherExpand888To4444(expand, dither)
164 
S32A_D4444_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)165 static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
166                                     const SkPMColor* SK_RESTRICT src,
167                                     int count, U8CPU alpha, int x, int y) {
168     SkASSERT(255 > alpha);
169 
170     if (count > 0) {
171         int src_scale = SkAlpha255To256(alpha) >> 4;
172         DITHER_4444_SCAN(y);
173         do {
174             SkPMColor c = *src++;
175             SkPMColorAssert(c);
176             if (c) {
177                 unsigned a = SkAlpha255To256(SkGetPackedA32(c));
178                 int d = SkAlphaMul(DITHER_VALUE(x), a);
179 
180                 unsigned dst_scale = 16 - SkAlphaMul(src_scale, a);
181                 uint32_t src_expand = SkExpand32_4444(c) * src_scale;
182                 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
183                 // convert back to SkPMColor
184                 c = SkCompact_8888(src_expand + dst_expand);
185                 *dst = SkDitherARGB32To4444(c, d);
186             }
187             dst += 1;
188             DITHER_INC_X(x);
189         } while (--count != 0);
190     }
191 }
192 
193 ///////////////////////////////////////////////////////////////////////////////
194 ///////////////////////////////////////////////////////////////////////////////
195 
196 static const SkBlitRow::Proc gProcs4444[] = {
197     // no dither
198     S32_D4444_Opaque,
199     S32_D4444_Blend,
200 
201     S32A_D4444_Opaque,
202     S32A_D4444_Blend,
203 
204     // dither
205     S32_D4444_Opaque_Dither,
206     S32_D4444_Blend_Dither,
207 
208     S32A_D4444_Opaque_Dither,
209     S32A_D4444_Blend_Dither
210 };
211 
212 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags);
SkBlitRow_Factory_4444(unsigned flags)213 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags)
214 {
215     SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444));
216 
217     return gProcs4444[flags];
218 }
219