• 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             SkASSERT(SkGetPackedA32(c) == 255);
106 
107             unsigned dither = DITHER_VALUE(x);
108             *dst++ = SkDitherARGB32To4444(c, dither);
109             DITHER_INC_X(x);
110         } while (--count != 0);
111     }
112 }
113 
S32_D4444_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)114 static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
115                                    const SkPMColor* SK_RESTRICT src,
116                                    int count, U8CPU alpha, int x, int y) {
117     SkASSERT(255 > alpha);
118 
119     if (count > 0) {
120         int scale16 = SkAlpha255To256(alpha) >> 4;
121         DITHER_4444_SCAN(y);
122         do {
123             SkPMColor c = *src++;
124             SkPMColorAssert(c);
125             SkASSERT(SkGetPackedA32(c) == 255);
126 
127             uint32_t src_expand = SkExpand32_4444(c) * scale16;
128             uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16);
129 
130             c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor
131             *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
132             DITHER_INC_X(x);
133         } while (--count != 0);
134     }
135 }
136 
S32A_D4444_Opaque_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)137 static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
138                                      const SkPMColor* SK_RESTRICT src,
139                                      int count, U8CPU alpha, int x, int y) {
140     SkASSERT(255 == alpha);
141 
142     if (count > 0) {
143         DITHER_4444_SCAN(y);
144         do {
145             SkPMColor c = *src++;
146             SkPMColorAssert(c);
147             if (c) {
148                 unsigned a = SkGetPackedA32(c);
149                 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a));
150 
151                 unsigned scale16 = SkAlpha255To256(255 - a) >> 4;
152                 uint32_t src_expand = SkExpand_8888(c);
153                 uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
154                 // convert back to SkPMColor
155                 c = SkCompact_8888(src_expand + dst_expand);
156                 *dst = SkDitherARGB32To4444(c, d);
157             }
158             dst += 1;
159             DITHER_INC_X(x);
160         } while (--count != 0);
161     }
162 }
163 
164 // need DitherExpand888To4444(expand, dither)
165 
S32A_D4444_Blend_Dither(uint16_t * SK_RESTRICT dst,const SkPMColor * SK_RESTRICT src,int count,U8CPU alpha,int x,int y)166 static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
167                                     const SkPMColor* SK_RESTRICT src,
168                                     int count, U8CPU alpha, int x, int y) {
169     SkASSERT(255 > alpha);
170 
171     if (count > 0) {
172         int src_scale = SkAlpha255To256(alpha) >> 4;
173         DITHER_4444_SCAN(y);
174         do {
175             SkPMColor c = *src++;
176             SkPMColorAssert(c);
177             if (c) {
178                 unsigned a = SkAlpha255To256(SkGetPackedA32(c));
179                 int d = SkAlphaMul(DITHER_VALUE(x), a);
180 
181                 unsigned dst_scale = 16 - SkAlphaMul(src_scale, a);
182                 uint32_t src_expand = SkExpand32_4444(c) * src_scale;
183                 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
184                 // convert back to SkPMColor
185                 c = SkCompact_8888(src_expand + dst_expand);
186                 *dst = SkDitherARGB32To4444(c, d);
187             }
188             dst += 1;
189             DITHER_INC_X(x);
190         } while (--count != 0);
191     }
192 }
193 
194 ///////////////////////////////////////////////////////////////////////////////
195 ///////////////////////////////////////////////////////////////////////////////
196 
197 static const SkBlitRow::Proc gProcs4444[] = {
198     // no dither
199     S32_D4444_Opaque,
200     S32_D4444_Blend,
201 
202     S32A_D4444_Opaque,
203     S32A_D4444_Blend,
204 
205     // dither
206     S32_D4444_Opaque_Dither,
207     S32_D4444_Blend_Dither,
208 
209     S32A_D4444_Opaque_Dither,
210     S32A_D4444_Blend_Dither
211 };
212 
213 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags);
SkBlitRow_Factory_4444(unsigned flags)214 SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags)
215 {
216     SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444));
217 
218     return gProcs4444[flags];
219 }
220 
221 
222