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. 28 void MAKENAME(_nofilter_DXDY)(const SkBitmapProcState& s, 29 const uint32_t* SK_RESTRICT xy, 30 int count, DSTTYPE* SK_RESTRICT colors); 31 void MAKENAME(_nofilter_DX)(const SkBitmapProcState& s, 32 const uint32_t* SK_RESTRICT xy, 33 int count, DSTTYPE* SK_RESTRICT colors); 34 void MAKENAME(_filter_DX)(const SkBitmapProcState& s, 35 const uint32_t* SK_RESTRICT xy, 36 int count, DSTTYPE* SK_RESTRICT colors); 37 void MAKENAME(_filter_DXDY)(const SkBitmapProcState& s, 38 const uint32_t* SK_RESTRICT xy, 39 int count, DSTTYPE* SK_RESTRICT colors); 40 41 void 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 83 void 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 138 void 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 } 184 void 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