blob: e6b587f9128140dd104c35fbec5f0dc299b32750 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com0becfc5b2009-01-13 13:26:44 +00008#include "SkUtils.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
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
reed@android.com0becfc5b2009-01-13 13:26:44 +000018#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
reed@android.com6f252972009-01-14 16:46:16 +000023 #error "unsupported DSTSIZE"
reed@android.com0becfc5b2009-01-13 13:26:44 +000024#endif
25
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000026void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
27 const uint32_t* SK_RESTRICT xy,
28 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000029 SkASSERT(count > 0 && colors != NULL);
30 SkASSERT(s.fDoFilter == false);
31 SkDEBUGCODE(CHECKSTATE(s);)
32
33#ifdef PREAMBLE
34 PREAMBLE(s);
35#endif
36 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
37 int i, rb = s.fBitmap->rowBytes();
38
39 uint32_t XY;
40 SRCTYPE src;
41
42 for (i = (count >> 1); i > 0; --i) {
43 XY = *xy++;
44 SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
45 (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
46 src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
47 *colors++ = RETURNDST(src);
48
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 if (count & 1) {
56 XY = *xy++;
57 SkASSERT((XY >> 16) < (unsigned)s.fBitmap->height() &&
58 (XY & 0xFFFF) < (unsigned)s.fBitmap->width());
59 src = ((const SRCTYPE*)(srcAddr + (XY >> 16) * rb))[XY & 0xFFFF];
60 *colors++ = RETURNDST(src);
61 }
62
63#ifdef POSTAMBLE
64 POSTAMBLE(s);
65#endif
66}
67
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000068void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
69 const uint32_t* SK_RESTRICT xy,
70 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000071 SkASSERT(count > 0 && colors != NULL);
72 SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
73 SkASSERT(s.fDoFilter == false);
74 SkDEBUGCODE(CHECKSTATE(s);)
75
76#ifdef PREAMBLE
77 PREAMBLE(s);
78#endif
79 const SRCTYPE* SK_RESTRICT srcAddr = (const SRCTYPE*)s.fBitmap->getPixels();
reed@android.com8a1c16f2008-12-17 15:59:43 +000080
reed@android.com0becfc5b2009-01-13 13:26:44 +000081 // buffer is y32, x16, x16, x16, x16, x16
reed@android.com8a1c16f2008-12-17 15:59:43 +000082 // bump srcAddr to the proper row, since we're told Y never changes
83 SkASSERT((unsigned)xy[0] < (unsigned)s.fBitmap->height());
84 srcAddr = (const SRCTYPE*)((const char*)srcAddr +
85 xy[0] * s.fBitmap->rowBytes());
reed@android.com152f7482009-08-07 19:14:34 +000086 xy += 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +000087
88 SRCTYPE src;
89
reed@android.com0becfc5b2009-01-13 13:26:44 +000090 if (1 == s.fBitmap->width()) {
91 src = srcAddr[0];
92 DSTTYPE dstValue = RETURNDST(src);
93 BITMAPPROC_MEMSET(colors, dstValue, count);
94 } else {
95 int i;
reed@android.com0becfc5b2009-01-13 13:26:44 +000096 for (i = (count >> 2); i > 0; --i) {
reed@android.com152f7482009-08-07 19:14:34 +000097 uint32_t xx0 = *xy++;
98 uint32_t xx1 = *xy++;
99 SRCTYPE x0 = srcAddr[UNPACK_PRIMARY_SHORT(xx0)];
100 SRCTYPE x1 = srcAddr[UNPACK_SECONDARY_SHORT(xx0)];
101 SRCTYPE x2 = srcAddr[UNPACK_PRIMARY_SHORT(xx1)];
102 SRCTYPE x3 = srcAddr[UNPACK_SECONDARY_SHORT(xx1)];
reed@android.com0becfc5b2009-01-13 13:26:44 +0000103
reed@android.com152f7482009-08-07 19:14:34 +0000104 *colors++ = RETURNDST(x0);
105 *colors++ = RETURNDST(x1);
106 *colors++ = RETURNDST(x2);
107 *colors++ = RETURNDST(x3);
reed@android.com0becfc5b2009-01-13 13:26:44 +0000108 }
reed@android.com152f7482009-08-07 19:14:34 +0000109 const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy);
reed@android.com0becfc5b2009-01-13 13:26:44 +0000110 for (i = (count & 3); i > 0; --i) {
111 SkASSERT(*xx < (unsigned)s.fBitmap->width());
112 src = srcAddr[*xx++]; *colors++ = RETURNDST(src);
113 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 }
115
116#ifdef POSTAMBLE
117 POSTAMBLE(s);
118#endif
119}
120
121///////////////////////////////////////////////////////////////////////////////
122
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +0000123void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
124 const uint32_t* SK_RESTRICT xy,
125 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126 SkASSERT(count > 0 && colors != NULL);
127 SkASSERT(s.fDoFilter);
128 SkDEBUGCODE(CHECKSTATE(s);)
129
130#ifdef PREAMBLE
131 PREAMBLE(s);
132#endif
133 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
134 unsigned rb = s.fBitmap->rowBytes();
135 unsigned subY;
136 const SRCTYPE* SK_RESTRICT row0;
137 const SRCTYPE* SK_RESTRICT row1;
138
139 // setup row ptrs and update proc_table
140 {
141 uint32_t XY = *xy++;
142 unsigned y0 = XY >> 14;
143 row0 = (const SRCTYPE*)(srcAddr + (y0 >> 4) * rb);
144 row1 = (const SRCTYPE*)(srcAddr + (XY & 0x3FFF) * rb);
145 subY = y0 & 0xF;
146 }
147
148 do {
149 uint32_t XX = *xy++; // x0:14 | 4 | x1:14
150 unsigned x0 = XX >> 14;
151 unsigned x1 = XX & 0x3FFF;
152 unsigned subX = x0 & 0xF;
153 x0 >>= 4;
154
reed@android.com152f7482009-08-07 19:14:34 +0000155 FILTER_PROC(subX, subY,
156 SRC_TO_FILTER(row0[x0]),
157 SRC_TO_FILTER(row0[x1]),
158 SRC_TO_FILTER(row1[x0]),
159 SRC_TO_FILTER(row1[x1]),
160 colors);
161 colors += 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000162
163 } while (--count != 0);
164
165#ifdef POSTAMBLE
166 POSTAMBLE(s);
167#endif
168}
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +0000169void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
170 const uint32_t* SK_RESTRICT xy,
171 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000172 SkASSERT(count > 0 && colors != NULL);
173 SkASSERT(s.fDoFilter);
174 SkDEBUGCODE(CHECKSTATE(s);)
175
176#ifdef PREAMBLE
177 PREAMBLE(s);
178#endif
179 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
180 int rb = s.fBitmap->rowBytes();
181
182 do {
183 uint32_t data = *xy++;
184 unsigned y0 = data >> 14;
185 unsigned y1 = data & 0x3FFF;
186 unsigned subY = y0 & 0xF;
187 y0 >>= 4;
188
189 data = *xy++;
190 unsigned x0 = data >> 14;
191 unsigned x1 = data & 0x3FFF;
192 unsigned subX = x0 & 0xF;
193 x0 >>= 4;
194
195 const SRCTYPE* SK_RESTRICT row0 = (const SRCTYPE*)(srcAddr + y0 * rb);
196 const SRCTYPE* SK_RESTRICT row1 = (const SRCTYPE*)(srcAddr + y1 * rb);
197
reed@android.com152f7482009-08-07 19:14:34 +0000198 FILTER_PROC(subX, subY,
199 SRC_TO_FILTER(row0[x0]),
200 SRC_TO_FILTER(row0[x1]),
201 SRC_TO_FILTER(row1[x0]),
202 SRC_TO_FILTER(row1[x1]),
203 colors);
204 colors += 1;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 } while (--count != 0);
206
207#ifdef POSTAMBLE
208 POSTAMBLE(s);
209#endif
210}
211
212#undef MAKENAME
213#undef DSTSIZE
214#undef DSTTYPE
215#undef SRCTYPE
216#undef CHECKSTATE
217#undef RETURNDST
218#undef SRC_TO_FILTER
219#undef FILTER_TO_DST
220
221#ifdef PREAMBLE
222 #undef PREAMBLE
223#endif
224#ifdef POSTAMBLE
225 #undef POSTAMBLE
226#endif
227
228#undef FILTER_PROC_TYPE
229#undef GET_FILTER_TABLE
230#undef GET_FILTER_ROW
231#undef GET_FILTER_ROW_PROC
232#undef GET_FILTER_PROC
reed@android.com0becfc5b2009-01-13 13:26:44 +0000233#undef BITMAPPROC_MEMSET