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 :
14 0 : 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 0 : SkASSERT(255 == alpha);
18 :
19 0 : if (count > 0) {
20 0 : do {
21 0 : SkPMColor c = *src++;
22 0 : SkPMColorAssert(c);
23 0 : SkASSERT(SkGetPackedA32(c) == 255);
24 0 : *dst++ = SkPixel32ToPixel4444(c);
25 : } while (--count != 0);
26 : }
27 0 : }
28 :
29 0 : 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 0 : SkASSERT(255 > alpha);
33 :
34 0 : if (count > 0) {
35 0 : unsigned scale16 = SkAlpha255To256(alpha) >> 4;
36 0 : do {
37 0 : SkPMColor c = *src++;
38 0 : SkPMColorAssert(c);
39 0 : SkASSERT(SkGetPackedA32(c) == 255);
40 :
41 0 : uint32_t src_expand = SkExpand32_4444(c);
42 0 : uint32_t dst_expand = SkExpand_4444(*dst);
43 0 : dst_expand += (src_expand - dst_expand) * scale16 >> 4;
44 0 : *dst++ = SkCompact_4444(dst_expand);
45 : } while (--count != 0);
46 : }
47 0 : }
48 :
49 0 : 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 0 : SkASSERT(255 == alpha);
53 :
54 0 : if (count > 0) {
55 0 : do {
56 0 : SkPMColor c = *src++;
57 0 : SkPMColorAssert(c);
58 : // if (__builtin_expect(c!=0, 1))
59 0 : if (c)
60 : {
61 0 : unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4;
62 0 : uint32_t src_expand = SkExpand_8888(c);
63 0 : uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
64 0 : *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
65 : }
66 0 : dst += 1;
67 : } while (--count != 0);
68 : }
69 0 : }
70 :
71 0 : 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 0 : SkASSERT(255 > alpha);
75 :
76 0 : if (count > 0) {
77 0 : int src_scale = SkAlpha255To256(alpha) >> 4;
78 0 : do {
79 0 : SkPMColor sc = *src++;
80 0 : SkPMColorAssert(sc);
81 :
82 0 : if (sc) {
83 0 : unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8);
84 0 : uint32_t src_expand = SkExpand32_4444(sc) * src_scale;
85 0 : uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
86 0 : *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
87 : }
88 0 : dst += 1;
89 : } while (--count != 0);
90 : }
91 0 : }
92 :
93 : /////////////////////////////////////////////////////////////////////////////
94 :
95 0 : 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 0 : SkASSERT(255 == alpha);
99 :
100 0 : if (count > 0) {
101 0 : DITHER_4444_SCAN(y);
102 0 : do {
103 0 : SkPMColor c = *src++;
104 0 : SkPMColorAssert(c);
105 0 : SkASSERT(SkGetPackedA32(c) == 255);
106 :
107 0 : unsigned dither = DITHER_VALUE(x);
108 0 : *dst++ = SkDitherARGB32To4444(c, dither);
109 0 : DITHER_INC_X(x);
110 : } while (--count != 0);
111 : }
112 0 : }
113 :
114 0 : 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 0 : SkASSERT(255 > alpha);
118 :
119 0 : if (count > 0) {
120 0 : int scale16 = SkAlpha255To256(alpha) >> 4;
121 0 : DITHER_4444_SCAN(y);
122 0 : do {
123 0 : SkPMColor c = *src++;
124 0 : SkPMColorAssert(c);
125 0 : SkASSERT(SkGetPackedA32(c) == 255);
126 :
127 0 : uint32_t src_expand = SkExpand32_4444(c) * scale16;
128 0 : uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16);
129 :
130 0 : c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor
131 0 : *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
132 0 : DITHER_INC_X(x);
133 : } while (--count != 0);
134 : }
135 0 : }
136 :
137 0 : 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 0 : SkASSERT(255 == alpha);
141 :
142 0 : if (count > 0) {
143 0 : DITHER_4444_SCAN(y);
144 0 : do {
145 0 : SkPMColor c = *src++;
146 0 : SkPMColorAssert(c);
147 0 : if (c) {
148 0 : unsigned a = SkGetPackedA32(c);
149 0 : int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a));
150 :
151 0 : unsigned scale16 = SkAlpha255To256(255 - a) >> 4;
152 0 : uint32_t src_expand = SkExpand_8888(c);
153 0 : uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
154 : // convert back to SkPMColor
155 0 : c = SkCompact_8888(src_expand + dst_expand);
156 0 : *dst = SkDitherARGB32To4444(c, d);
157 : }
158 0 : dst += 1;
159 0 : DITHER_INC_X(x);
160 : } while (--count != 0);
161 : }
162 0 : }
163 :
164 : // need DitherExpand888To4444(expand, dither)
165 :
166 0 : 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 0 : SkASSERT(255 > alpha);
170 :
171 0 : if (count > 0) {
172 0 : int src_scale = SkAlpha255To256(alpha) >> 4;
173 0 : DITHER_4444_SCAN(y);
174 0 : do {
175 0 : SkPMColor c = *src++;
176 0 : SkPMColorAssert(c);
177 0 : if (c) {
178 0 : unsigned a = SkAlpha255To256(SkGetPackedA32(c));
179 0 : int d = SkAlphaMul(DITHER_VALUE(x), a);
180 :
181 0 : unsigned dst_scale = 16 - SkAlphaMul(src_scale, a);
182 0 : uint32_t src_expand = SkExpand32_4444(c) * src_scale;
183 0 : uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
184 : // convert back to SkPMColor
185 0 : c = SkCompact_8888(src_expand + dst_expand);
186 0 : *dst = SkDitherARGB32To4444(c, d);
187 : }
188 0 : dst += 1;
189 0 : DITHER_INC_X(x);
190 : } while (--count != 0);
191 : }
192 0 : }
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);
214 0 : SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags)
215 : {
216 0 : SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444));
217 :
218 0 : return gProcs4444[flags];
219 : }
220 :
221 :
|