1 2 /* 3 * Copyright 2006 The Android Open Source Project 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 9 10 #include "SkFilterProc.h" 11 12 class BILERP_BITMAP16_SHADER_CLASS : public HasSpan16_Sampler_BitmapShader { 13 public: BILERP_BITMAP16_SHADER_CLASS(const SkBitmap & src)14 BILERP_BITMAP16_SHADER_CLASS(const SkBitmap& src) 15 : HasSpan16_Sampler_BitmapShader(src, true, 16 SkShader::kClamp_TileMode, 17 SkShader::kClamp_TileMode) 18 { 19 } 20 shadeSpan(int x,int y,SkPMColor dstC[],int count)21 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) 22 { 23 SkASSERT(count > 0); 24 25 U8CPU alpha = this->getPaintAlpha(); 26 27 const SkMatrix& inv = this->getTotalInverse(); 28 const SkBitmap& srcBitmap = this->getSrcBitmap(); 29 unsigned srcMaxX = srcBitmap.width() - 1; 30 unsigned srcMaxY = srcBitmap.height() - 1; 31 unsigned srcRB = srcBitmap.rowBytes(); 32 33 BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); 34 35 const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); 36 const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); 37 38 if (this->getInverseClass() == kPerspective_MatrixClass) 39 { 40 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 41 SkIntToScalar(y) + SK_ScalarHalf, count); 42 while ((count = iter.next()) != 0) 43 { 44 const SkFixed* srcXY = iter.getXY(); 45 while (--count >= 0) 46 { 47 SkFixed fx = *srcXY++ - SK_FixedHalf; 48 SkFixed fy = *srcXY++ - SK_FixedHalf; 49 int ix = fx >> 16; 50 int iy = fy >> 16; 51 int x = SkClampMax(ix, srcMaxX); 52 int y = SkClampMax(iy, srcMaxY); 53 54 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 55 56 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + y * srcRB)) + x; 57 if ((unsigned)ix < srcMaxX) 58 p01 += 1; 59 p10 = p00; 60 p11 = p01; 61 if ((unsigned)iy < srcMaxY) 62 { 63 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 64 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 65 } 66 67 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 68 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 69 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 70 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 71 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 72 73 *dstC++ = expanded_rgb16_to_8888(c, alpha); 74 } 75 } 76 } 77 else // linear case 78 { 79 SkFixed fx, fy, dx, dy; 80 81 // now init fx, fy, dx, dy 82 { 83 SkPoint srcPt; 84 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, 85 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 86 87 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; 88 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; 89 90 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 91 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 92 else 93 { 94 dx = SkScalarToFixed(inv.getScaleX()); 95 dy = SkScalarToFixed(inv.getSkewY()); 96 } 97 } 98 99 do { 100 int ix = fx >> 16; 101 int iy = fy >> 16; 102 103 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 104 105 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 106 SkClampMax(iy, srcMaxY) * srcRB)) + 107 SkClampMax(ix, srcMaxX); 108 if ((unsigned)ix < srcMaxX) 109 p01 += 1; 110 p10 = p00; 111 p11 = p01; 112 if ((unsigned)iy < srcMaxY) 113 { 114 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 115 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 116 } 117 118 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 119 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 120 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 121 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 122 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 123 *dstC++ = expanded_rgb16_to_8888(c, alpha); 124 125 fx += dx; 126 fy += dy; 127 } while (--count != 0); 128 } 129 BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); 130 } 131 shadeSpan16(int x,int y,uint16_t dstC[],int count)132 virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) 133 { 134 SkASSERT(count > 0); 135 136 const SkMatrix& inv = this->getTotalInverse(); 137 const SkBitmap& srcBitmap = this->getSrcBitmap(); 138 unsigned srcMaxX = srcBitmap.width() - 1; 139 unsigned srcMaxY = srcBitmap.height() - 1; 140 unsigned srcRB = srcBitmap.rowBytes(); 141 142 BILERP_BITMAP16_SHADER_PREAMBLE(srcBitmap); 143 144 const SkFilterProc* proc_table = SkGetBilinearFilterProcTable(); 145 const BILERP_BITMAP16_SHADER_TYPE* srcPixels = (const BILERP_BITMAP16_SHADER_TYPE*)srcBitmap.getPixels(); 146 147 if (this->getInverseClass() == kPerspective_MatrixClass) 148 { 149 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, 150 SkIntToScalar(y) + SK_ScalarHalf, count); 151 while ((count = iter.next()) != 0) 152 { 153 const SkFixed* srcXY = iter.getXY(); 154 while (--count >= 0) 155 { 156 SkFixed fx = *srcXY++ - SK_FixedHalf; 157 SkFixed fy = *srcXY++ - SK_FixedHalf; 158 int ix = fx >> 16; 159 int iy = fy >> 16; 160 161 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 162 163 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 164 SkClampMax(iy, srcMaxY) * srcRB)) + 165 SkClampMax(ix, srcMaxX); 166 if ((unsigned)ix < srcMaxX) 167 p01 += 1; 168 p10 = p00; 169 p11 = p01; 170 if ((unsigned)iy < srcMaxY) 171 { 172 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 173 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 174 } 175 176 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 177 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 178 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 179 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 180 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 181 *dstC++ = SkCompact_rgb_16(c); 182 } 183 } 184 } 185 else // linear case 186 { 187 SkFixed fx, fy, dx, dy; 188 189 // now init fx, fy, dx, dy 190 { 191 SkPoint srcPt; 192 this->getInverseMapPtProc()(inv, SkIntToScalar(x) + SK_ScalarHalf, 193 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 194 195 fx = SkScalarToFixed(srcPt.fX) - SK_FixedHalf; 196 fy = SkScalarToFixed(srcPt.fY) - SK_FixedHalf; 197 198 if (this->getInverseClass() == kFixedStepInX_MatrixClass) 199 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); 200 else 201 { 202 dx = SkScalarToFixed(inv.getScaleX()); 203 dy = SkScalarToFixed(inv.getSkewY()); 204 } 205 } 206 207 do { 208 int ix = fx >> 16; 209 int iy = fy >> 16; 210 211 const BILERP_BITMAP16_SHADER_TYPE *p00, *p01, *p10, *p11; 212 213 p00 = p01 = ((const BILERP_BITMAP16_SHADER_TYPE*)((const char*)srcPixels + 214 SkClampMax(iy, srcMaxY) * srcRB)) + 215 SkClampMax(ix, srcMaxX); 216 if ((unsigned)ix < srcMaxX) 217 p01 += 1; 218 p10 = p00; 219 p11 = p01; 220 if ((unsigned)iy < srcMaxY) 221 { 222 p10 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p10 + srcRB); 223 p11 = (const BILERP_BITMAP16_SHADER_TYPE*)((const char*)p11 + srcRB); 224 } 225 226 SkFilterProc proc = SkGetBilinearFilterProc(proc_table, fx, fy); 227 uint32_t c = proc(SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p00)), 228 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p01)), 229 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p10)), 230 SkExpand_rgb_16(BILERP_BITMAP16_SHADER_PIXEL(*p11))); 231 *dstC++ = SkCompact_rgb_16(c); 232 233 fx += dx; 234 fy += dy; 235 } while (--count != 0); 236 } 237 BILERP_BITMAP16_SHADER_POSTAMBLE(srcBitmap); 238 } 239 }; 240 241 #undef BILERP_BITMAP16_SHADER_CLASS 242 #undef BILERP_BITMAP16_SHADER_TYPE 243 #undef BILERP_BITMAP16_SHADER_PREAMBLE 244 #undef BILERP_BITMAP16_SHADER_PIXEL 245 #undef BILERP_BITMAP16_SHADER_POSTAMBLE 246