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