1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
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.
28void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
29                              const uint32_t* SK_RESTRICT xy,
30                              int count, DSTTYPE* SK_RESTRICT colors);
31void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
32                            const uint32_t* SK_RESTRICT xy,
33                            int count, DSTTYPE* SK_RESTRICT colors);
34void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
35                          const uint32_t* SK_RESTRICT xy,
36                           int count, DSTTYPE* SK_RESTRICT colors);
37void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
38                            const uint32_t* SK_RESTRICT xy,
39                            int count, DSTTYPE* SK_RESTRICT colors);
40
41void 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(SkPaint::kNone_FilterLevel == 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
83void 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(SkPaint::kNone_FilterLevel == 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
138void 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 != SkPaint::kNone_FilterLevel);
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}
184void 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 != SkPaint::kNone_FilterLevel);
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