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.
11void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
12                              const uint32_t* SK_RESTRICT xy,
13                              int count, SkPMColor* SK_RESTRICT colors);
14void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
15                            const uint32_t* SK_RESTRICT xy,
16                            int count, SkPMColor* SK_RESTRICT colors);
17void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
18                          const uint32_t* SK_RESTRICT xy,
19                           int count, SkPMColor* SK_RESTRICT colors);
20void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
21                            const uint32_t* SK_RESTRICT xy,
22                            int count, SkPMColor* SK_RESTRICT colors);
23
24void 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
66void 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
121void 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}
167void 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