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 "SkUtils.h"
9 
10 #if DSTSIZE==32
11     #define DSTTYPE SkPMColor
12 #elif DSTSIZE==16
13     #define DSTTYPE uint16_t
14 #else
15     #error "need DSTSIZE to be 32 or 16"
16 #endif
17 
18 #if (DSTSIZE == 32)
19     #define BITMAPPROC_MEMSET(ptr, value, n) sk_memset32(ptr, value, n)
20 #elif (DSTSIZE == 16)
21     #define BITMAPPROC_MEMSET(ptr, value, n) sk_memset16(ptr, value, n)
22 #else
23     #error "unsupported DSTSIZE"
24 #endif
25 
26 
27 // declare functions externally to suppress warnings.
28 void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
29                               const uint32_t* SK_RESTRICT xy,
30                               int count, DSTTYPE* SK_RESTRICT colors);
31 void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
32                             const uint32_t* SK_RESTRICT xy,
33                             int count, DSTTYPE* SK_RESTRICT colors);
34 void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
35                           const uint32_t* SK_RESTRICT xy,
36                            int count, DSTTYPE* SK_RESTRICT colors);
37 void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
38                             const uint32_t* SK_RESTRICT xy,
39                             int count, DSTTYPE* SK_RESTRICT colors);
40 
MAKENAME(_nofilter_DXDY)41 void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
42                               const uint32_t* SK_RESTRICT xy,
43                               int count, DSTTYPE* SK_RESTRICT colors) {
44     SkASSERT(count > 0 && colors != NULL);
45     SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
46     SkDEBUGCODE(CHECKSTATE(s);)
47 
48 #ifdef PREAMBLE
49     PREAMBLE(s);
50 #endif
51     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
52     size_t rb = s.fBitmap->rowBytes();
53 
54     uint32_t XY;
55     SRCTYPE src;
56 
57     for (int i = (count >> 1); i > 0; --i) {
58         XY = *xy++;
59         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
60                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
61         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
62         *colors++ = RETURNDST(src);
63 
64         XY = *xy++;
65         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
66                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
67         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
68         *colors++ = RETURNDST(src);
69     }
70     if (count & 1) {
71         XY = *xy++;
72         SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
73                  (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
74         src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
75         *colors++ = RETURNDST(src);
76     }
77 
78 #ifdef POSTAMBLE
79     POSTAMBLE(s);
80 #endif
81 }
82 
MAKENAME(_nofilter_DX)83 void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
84                             const uint32_t* SK_RESTRICT xy,
85                             int count, DSTTYPE* SK_RESTRICT colors) {
86     SkASSERT(count > 0 && colors != NULL);
87     SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
88     SkASSERT(kNone_SkFilterQuality == s.fFilterLevel);
89     SkDEBUGCODE(CHECKSTATE(s);)
90 
91 #ifdef PREAMBLE
92     PREAMBLE(s);
93 #endif
94     const SRCTYPE* SK_RESTRICT srcAddr = (const SRCTYPE*)s.fBitmap->getPixels();
95 
96     // buffer is y32, x16, x16, x16, x16, x16
97     // bump srcAddr to the proper row, since we're told Y never changes
98     SkASSERT((unsigned)xy[0] < (unsigned)s.fBitmap->height());
99     srcAddr = (const SRCTYPE*)((const char*)srcAddr +
100                                                 xy[0] * s.fBitmap->rowBytes());
101     xy += 1;
102 
103     SRCTYPE src;
104 
105     if (1 == s.fBitmap->width()) {
106         src = srcAddr[0];
107         DSTTYPE dstValue = RETURNDST(src);
108         BITMAPPROC_MEMSET(colors, dstValue, count);
109     } else {
110         int i;
111         for (i = (count >> 2); i > 0; --i) {
112             uint32_t xx0 = *xy++;
113             uint32_t xx1 = *xy++;
114             SRCTYPE x0 = srcAddr[UNPACK_PRIMARY_SHORT(xx0)];
115             SRCTYPE x1 = srcAddr[UNPACK_SECONDARY_SHORT(xx0)];
116             SRCTYPE x2 = srcAddr[UNPACK_PRIMARY_SHORT(xx1)];
117             SRCTYPE x3 = srcAddr[UNPACK_SECONDARY_SHORT(xx1)];
118 
119             *colors++ = RETURNDST(x0);
120             *colors++ = RETURNDST(x1);
121             *colors++ = RETURNDST(x2);
122             *colors++ = RETURNDST(x3);
123         }
124         const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy);
125         for (i = (count & 3); i > 0; --i) {
126             SkASSERT(*xx < (unsigned)s.fBitmap->width());
127             src = srcAddr[*xx++]; *colors++ = RETURNDST(src);
128         }
129     }
130 
131 #ifdef POSTAMBLE
132     POSTAMBLE(s);
133 #endif
134 }
135 
136 ///////////////////////////////////////////////////////////////////////////////
137 
MAKENAME(_filter_DX)138 void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
139                           const uint32_t* SK_RESTRICT xy,
140                            int count, DSTTYPE* SK_RESTRICT colors) {
141     SkASSERT(count > 0 && colors != NULL);
142     SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
143     SkDEBUGCODE(CHECKSTATE(s);)
144 
145 #ifdef PREAMBLE
146     PREAMBLE(s);
147 #endif
148     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
149     size_t rb = s.fBitmap->rowBytes();
150     unsigned subY;
151     const SRCTYPE* SK_RESTRICT row0;
152     const SRCTYPE* SK_RESTRICT row1;
153 
154     // setup row ptrs and update proc_table
155     {
156         uint32_t XY = *xy++;
157         unsigned y0 = XY >> 14;
158         row0 = (const SRCTYPE*)(srcAddr + (y0 >> 4) * rb);
159         row1 = (const SRCTYPE*)(srcAddr + (XY & 0x3FFF) * rb);
160         subY = y0 & 0xF;
161     }
162 
163     do {
164         uint32_t XX = *xy++;    // x0:14 | 4 | x1:14
165         unsigned x0 = XX >> 14;
166         unsigned x1 = XX & 0x3FFF;
167         unsigned subX = x0 & 0xF;
168         x0 >>= 4;
169 
170         FILTER_PROC(subX, subY,
171                     SRC_TO_FILTER(row0[x0]),
172                     SRC_TO_FILTER(row0[x1]),
173                     SRC_TO_FILTER(row1[x0]),
174                     SRC_TO_FILTER(row1[x1]),
175                     colors);
176         colors += 1;
177 
178     } while (--count != 0);
179 
180 #ifdef POSTAMBLE
181     POSTAMBLE(s);
182 #endif
183 }
MAKENAME(_filter_DXDY)184 void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
185                             const uint32_t* SK_RESTRICT xy,
186                             int count, DSTTYPE* SK_RESTRICT colors) {
187     SkASSERT(count > 0 && colors != NULL);
188     SkASSERT(s.fFilterLevel != kNone_SkFilterQuality);
189     SkDEBUGCODE(CHECKSTATE(s);)
190 
191 #ifdef PREAMBLE
192         PREAMBLE(s);
193 #endif
194     const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
195     size_t rb = s.fBitmap->rowBytes();
196 
197     do {
198         uint32_t data = *xy++;
199         unsigned y0 = data >> 14;
200         unsigned y1 = data & 0x3FFF;
201         unsigned subY = y0 & 0xF;
202         y0 >>= 4;
203 
204         data = *xy++;
205         unsigned x0 = data >> 14;
206         unsigned x1 = data & 0x3FFF;
207         unsigned subX = x0 & 0xF;
208         x0 >>= 4;
209 
210         const SRCTYPE* SK_RESTRICT row0 = (const SRCTYPE*)(srcAddr + y0 * rb);
211         const SRCTYPE* SK_RESTRICT row1 = (const SRCTYPE*)(srcAddr + y1 * rb);
212 
213         FILTER_PROC(subX, subY,
214                     SRC_TO_FILTER(row0[x0]),
215                     SRC_TO_FILTER(row0[x1]),
216                     SRC_TO_FILTER(row1[x0]),
217                     SRC_TO_FILTER(row1[x1]),
218                     colors);
219         colors += 1;
220     } while (--count != 0);
221 
222 #ifdef POSTAMBLE
223     POSTAMBLE(s);
224 #endif
225 }
226 
227 #undef MAKENAME
228 #undef DSTSIZE
229 #undef DSTTYPE
230 #undef SRCTYPE
231 #undef CHECKSTATE
232 #undef RETURNDST
233 #undef SRC_TO_FILTER
234 #undef FILTER_TO_DST
235 
236 #ifdef PREAMBLE
237     #undef PREAMBLE
238 #endif
239 #ifdef POSTAMBLE
240     #undef POSTAMBLE
241 #endif
242 
243 #undef FILTER_PROC_TYPE
244 #undef GET_FILTER_TABLE
245 #undef GET_FILTER_ROW
246 #undef GET_FILTER_ROW_PROC
247 #undef GET_FILTER_PROC
248 #undef BITMAPPROC_MEMSET
249