• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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