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