blob: 5c5f199f25cfe56b1cb25fe36c3d800628c93287 [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
caryclark@google.com803eceb2012-06-06 12:09:34 +000026
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
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000041void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s,
42 const uint32_t* SK_RESTRICT xy,
43 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 SkASSERT(count > 0 && colors != NULL);
reed@google.com9cfc83c2013-07-22 17:18:18 +000045 SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
reed@android.com8a1c16f2008-12-17 15:59:43 +000046 SkDEBUGCODE(CHECKSTATE(s);)
47
48#ifdef PREAMBLE
49 PREAMBLE(s);
50#endif
51 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
scroggo@google.come5f48242013-02-25 21:47:41 +000052 size_t rb = s.fBitmap->rowBytes();
reed@android.com8a1c16f2008-12-17 15:59:43 +000053
54 uint32_t XY;
55 SRCTYPE src;
rmistry@google.comfbfcd562012-08-23 18:09:54 +000056
scroggo@google.come5f48242013-02-25 21:47:41 +000057 for (int i = (count >> 1); i > 0; --i) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000058 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);
rmistry@google.comfbfcd562012-08-23 18:09:54 +000063
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 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
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +000083void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s,
84 const uint32_t* SK_RESTRICT xy,
85 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000086 SkASSERT(count > 0 && colors != NULL);
87 SkASSERT(s.fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask));
reed@google.com9cfc83c2013-07-22 17:18:18 +000088 SkASSERT(SkPaint::kNone_FilterLevel == s.fFilterLevel);
reed@android.com8a1c16f2008-12-17 15:59:43 +000089 SkDEBUGCODE(CHECKSTATE(s);)
90
91#ifdef PREAMBLE
92 PREAMBLE(s);
93#endif
94 const SRCTYPE* SK_RESTRICT srcAddr = (const SRCTYPE*)s.fBitmap->getPixels();
reed@android.com8a1c16f2008-12-17 15:59:43 +000095
reed@android.com0becfc5b2009-01-13 13:26:44 +000096 // buffer is y32, x16, x16, x16, x16, x16
reed@android.com8a1c16f2008-12-17 15:59:43 +000097 // 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());
reed@android.com152f7482009-08-07 19:14:34 +0000101 xy += 1;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000102
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103 SRCTYPE src;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000104
reed@android.com0becfc5b2009-01-13 13:26:44 +0000105 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;
reed@android.com0becfc5b2009-01-13 13:26:44 +0000111 for (i = (count >> 2); i > 0; --i) {
reed@android.com152f7482009-08-07 19:14:34 +0000112 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)];
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000118
reed@android.com152f7482009-08-07 19:14:34 +0000119 *colors++ = RETURNDST(x0);
120 *colors++ = RETURNDST(x1);
121 *colors++ = RETURNDST(x2);
122 *colors++ = RETURNDST(x3);
reed@android.com0becfc5b2009-01-13 13:26:44 +0000123 }
reed@android.com152f7482009-08-07 19:14:34 +0000124 const uint16_t* SK_RESTRICT xx = (const uint16_t*)(xy);
reed@android.com0becfc5b2009-01-13 13:26:44 +0000125 for (i = (count & 3); i > 0; --i) {
126 SkASSERT(*xx < (unsigned)s.fBitmap->width());
127 src = srcAddr[*xx++]; *colors++ = RETURNDST(src);
128 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000130
reed@android.com8a1c16f2008-12-17 15:59:43 +0000131#ifdef POSTAMBLE
132 POSTAMBLE(s);
133#endif
134}
135
136///////////////////////////////////////////////////////////////////////////////
137
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +0000138void MAKENAME(_filter_DX)(const SkBitmapProcState& s,
139 const uint32_t* SK_RESTRICT xy,
140 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141 SkASSERT(count > 0 && colors != NULL);
reed@google.com9cfc83c2013-07-22 17:18:18 +0000142 SkASSERT(s.fFilterLevel != SkPaint::kNone_FilterLevel);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 SkDEBUGCODE(CHECKSTATE(s);)
144
145#ifdef PREAMBLE
146 PREAMBLE(s);
147#endif
148 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
scroggo@google.come5f48242013-02-25 21:47:41 +0000149 size_t rb = s.fBitmap->rowBytes();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000150 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 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000162
reed@android.com8a1c16f2008-12-17 15:59:43 +0000163 do {
164 uint32_t XX = *xy++; // x0:14 | 4 | x1:14
165 unsigned x0 = XX >> 14;
166 unsigned x1 = XX & 0x3FFF;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000167 unsigned subX = x0 & 0xF;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000168 x0 >>= 4;
169
reed@android.com152f7482009-08-07 19:14:34 +0000170 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;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177
178 } while (--count != 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000179
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180#ifdef POSTAMBLE
181 POSTAMBLE(s);
182#endif
183}
senorblanco@chromium.orgdc7de742009-11-30 20:00:29 +0000184void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s,
185 const uint32_t* SK_RESTRICT xy,
186 int count, DSTTYPE* SK_RESTRICT colors) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187 SkASSERT(count > 0 && colors != NULL);
reed@google.com9cfc83c2013-07-22 17:18:18 +0000188 SkASSERT(s.fFilterLevel != SkPaint::kNone_FilterLevel);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189 SkDEBUGCODE(CHECKSTATE(s);)
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000190
reed@android.com8a1c16f2008-12-17 15:59:43 +0000191#ifdef PREAMBLE
192 PREAMBLE(s);
193#endif
194 const char* SK_RESTRICT srcAddr = (const char*)s.fBitmap->getPixels();
scroggo@google.come5f48242013-02-25 21:47:41 +0000195 size_t rb = s.fBitmap->rowBytes();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000196
reed@android.com8a1c16f2008-12-17 15:59:43 +0000197 do {
198 uint32_t data = *xy++;
199 unsigned y0 = data >> 14;
200 unsigned y1 = data & 0x3FFF;
201 unsigned subY = y0 & 0xF;
202 y0 >>= 4;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000203
reed@android.com8a1c16f2008-12-17 15:59:43 +0000204 data = *xy++;
205 unsigned x0 = data >> 14;
206 unsigned x1 = data & 0x3FFF;
207 unsigned subX = x0 & 0xF;
208 x0 >>= 4;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000209
reed@android.com8a1c16f2008-12-17 15:59:43 +0000210 const SRCTYPE* SK_RESTRICT row0 = (const SRCTYPE*)(srcAddr + y0 * rb);
211 const SRCTYPE* SK_RESTRICT row1 = (const SRCTYPE*)(srcAddr + y1 * rb);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000212
reed@android.com152f7482009-08-07 19:14:34 +0000213 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;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000220 } while (--count != 0);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000221
reed@android.com8a1c16f2008-12-17 15:59:43 +0000222#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
reed@android.com0becfc5b2009-01-13 13:26:44 +0000248#undef BITMAPPROC_MEMSET