Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1013)

Side by Side Diff: src/core/SkBitmapFilter.cpp

Issue 18942002: fix compile warnings (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: virtual destructor Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/core/SkBitmapFilter.h ('k') | src/core/SkBitmapProcBicubic.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBitmapProcState.h"
9 #include "SkBitmap.h"
10 #include "SkColor.h"
11 #include "SkColorPriv.h"
12 #include "SkUnPreMultiply.h"
13 #include "SkShader.h"
14 #include "SkRTConf.h"
15 #include "SkMath.h"
16
17 void highQualityFilter(const SkBitmapProcState& s, int x, int y,
18 SkPMColor* SK_RESTRICT colors, int count) {
19
20 const int maxX = s.fBitmap->width() - 1;
21 const int maxY = s.fBitmap->height() - 1;
22
23 while (count-- > 0) {
24 SkPoint srcPt;
25 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x),
26 SkIntToScalar(y), &srcPt);
27 srcPt.fX -= SK_ScalarHalf;
28 srcPt.fY -= SK_ScalarHalf;
29
30 int sx = SkScalarFloorToInt(srcPt.fX);
31 int sy = SkScalarFloorToInt(srcPt.fY);
32
33 SkFixed weight = 0;
34 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
35
36 int y0 = SkClampMax(int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)), m axY);
37 int y1 = SkClampMax(int(floor(sy+s.getBitmapFilter()->width() + 0.5f)), maxY);
38 int x0 = SkClampMax(int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)), m axX);
39 int x1 = SkClampMax(int(floor(sx+s.getBitmapFilter()->width() + 0.5f)), maxX);
40
41 for (int src_y = y0; src_y <= y1; src_y++) {
42 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y));
43
44 for (int src_x = x0; src_x <= x1 ; src_x++) {
45 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x) );
46
47 SkFixed combined_weight = SkFixedMul(xweight, yweight);
48
49 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y);
50 fr += combined_weight * SkGetPackedR32(c);
51 fg += combined_weight * SkGetPackedG32(c);
52 fb += combined_weight * SkGetPackedB32(c);
53 fa += combined_weight * SkGetPackedA32(c);
54 weight += combined_weight;
55 }
56 }
57
58 fr = SkFixedDiv(fr, weight);
59 fg = SkFixedDiv(fg, weight);
60 fb = SkFixedDiv(fb, weight);
61 fa = SkFixedDiv(fa, weight);
62
63 int a = SkClampMax(SkFixedRoundToInt(fa), 255);
64 int r = SkClampMax(SkFixedRoundToInt(fr), a);
65 int g = SkClampMax(SkFixedRoundToInt(fg), a);
66 int b = SkClampMax(SkFixedRoundToInt(fb), a);
67
68 *colors++ = SkPackARGB32(a, r, g, b);
69
70 x++;
71 }
72 }
73
74 void highQualityFilter_ScaleOnly(const SkBitmapProcState &s, int x, int y,
75 SkPMColor *SK_RESTRICT colors, int count) {
76 const int maxX = s.fBitmap->width() - 1;
77 const int maxY = s.fBitmap->height() - 1;
78
79 SkPoint srcPt;
80
81 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x),
82 SkIntToScalar(y), &srcPt);
83 srcPt.fY -= SK_ScalarHalf;
84 int sy = SkScalarFloorToInt(srcPt.fY);
85 int y0 = SkClampMax(int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)), maxY );
86 int y1 = SkClampMax(int(floor(sy+s.getBitmapFilter()->width() + 0.5f)), max Y);
87
88 while (count-- > 0) {
89 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x),
90 SkIntToScalar(y), &srcPt);
91 srcPt.fX -= SK_ScalarHalf;
92 srcPt.fY -= SK_ScalarHalf;
93
94 int sx = SkScalarFloorToInt(srcPt.fX);
95
96 SkFixed weight = 0;
97 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
98
99 int x0 = SkClampMax(int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)), maxX);
100 int x1 = SkClampMax(int(floor(sx+s.getBitmapFilter()->width() + 0.5f)), maxX);
101
102 for (int src_y = y0; src_y <= y1; src_y++) {
103 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y));
104
105 for (int src_x = x0; src_x <= x1 ; src_x++) {
106 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x ));
107
108 SkFixed combined_weight = SkFixedMul(xweight, yweight);
109
110 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y);
111 fr += combined_weight * SkGetPackedR32(c);
112 fg += combined_weight * SkGetPackedG32(c);
113 fb += combined_weight * SkGetPackedB32(c);
114 fa += combined_weight * SkGetPackedA32(c);
115 weight += combined_weight;
116 }
117 }
118
119 fr = SkFixedDiv(fr, weight);
120 fg = SkFixedDiv(fg, weight);
121 fb = SkFixedDiv(fb, weight);
122 fa = SkFixedDiv(fa, weight);
123
124 int a = SkClampMax(SkFixedRoundToInt(fa), 255);
125 int r = SkClampMax(SkFixedRoundToInt(fr), a);
126 int g = SkClampMax(SkFixedRoundToInt(fg), a);
127 int b = SkClampMax(SkFixedRoundToInt(fb), a);
128
129 *colors++ = SkPackARGB32(a, r, g, b);
130
131 x++;
132 }
133 }
134
135 SK_CONF_DECLARE(const char *, c_bitmapFilter, "bitmap.filter", "mitchell", "Whic h bitmap filter to use [mitchell, sinc, gaussian, triangle, box]");
136
137 static SkBitmapFilter *allocateBitmapFilter() {
138 if (!strcmp(c_bitmapFilter, "mitchell")) {
139 return SkNEW_ARGS(SkMitchellFilter,(1.f/3.f,1.f/3.f));
140 } else if (!strcmp(c_bitmapFilter, "sinc")) {
141 return SkNEW_ARGS(SkSincFilter,(3));
142 } else if (!strcmp(c_bitmapFilter, "gaussian")) {
143 return SkNEW_ARGS(SkGaussianFilter,(2));
144 } else if (!strcmp(c_bitmapFilter, "triangle")) {
145 return SkNEW(SkTriangleFilter);
146 } else if (!strcmp(c_bitmapFilter, "box")) {
147 return SkNEW(SkBoxFilter);
148 } else {
149 SkASSERT(!!!"Unknown filter type");
150 }
151
152 return NULL;
153 }
154
155 SkBitmapProcState::ShaderProc32
156 SkBitmapProcState::chooseBitmapFilterProc(const SkPaint& paint) {
157 // we need to be requested
158 uint32_t mask = SkPaint::kFilterBitmap_Flag
159 | SkPaint::kHighQualityFilterBitmap_Flag
160 ;
161 if ((paint.getFlags() & mask) != mask) {
162 return NULL;
163 }
164
165 // TODO: consider supporting other configs (e.g. 565, A8)
166 if (fBitmap->config() != SkBitmap::kARGB_8888_Config) {
167 return NULL;
168 }
169
170 // TODO: consider supporting repeat and mirror
171 if (SkShader::kClamp_TileMode != fTileModeX || SkShader::kClamp_TileMode != fTileModeY) {
172 return NULL;
173 }
174
175 // TODO: support blending inside our procs
176 if (0xFF != paint.getAlpha()) {
177 return NULL;
178 }
179
180 if (fInvType & (SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask)) {
181 fBitmapFilter = allocateBitmapFilter();
182 }
183
184 if (fInvType & SkMatrix::kAffine_Mask) {
185 return highQualityFilter;
186 } else if (fInvType & SkMatrix::kScale_Mask) {
187 return highQualityFilter_ScaleOnly;
188 } else {
189 return NULL;
190 }
191 }
192
193 static void divideByWeights(SkFixed *sums, SkFixed *weights, SkBitmap *dst) {
194 for (int y = 0 ; y < dst->height() ; y++) {
195 for (int x = 0 ; x < dst->width() ; x++) {
196 SkFixed fr = SkFixedDiv(sums[4*(y*dst->width() + x) + 0], weights[y* dst->width() + x]);
197 SkFixed fg = SkFixedDiv(sums[4*(y*dst->width() + x) + 1], weights[y* dst->width() + x]);
198 SkFixed fb = SkFixedDiv(sums[4*(y*dst->width() + x) + 2], weights[y* dst->width() + x]);
199 SkFixed fa = SkFixedDiv(sums[4*(y*dst->width() + x) + 3], weights[y* dst->width() + x]);
200 int a = SkClampMax(SkFixedRoundToInt(fa), 255);
201 int r = SkClampMax(SkFixedRoundToInt(fr), a);
202 int g = SkClampMax(SkFixedRoundToInt(fg), a);
203 int b = SkClampMax(SkFixedRoundToInt(fb), a);
204
205 *dst->getAddr32(x,y) = SkPackARGB32(a, r, g, b);
206 }
207 }
208 }
209
210 static void upScaleHoriz(const SkBitmap *src, SkBitmap *dst, float scale, SkBitm apFilter *filter) {
211 for (int y = 0 ; y < src->height() ; y++) {
212 for (int x = 0 ; x < dst->width() ; x++) {
213 float sx = x / scale - 0.5f;
214 int x0 = SkClampMax(int(ceil(sx-filter->width() + 0.5f)), src->width ()-1);
215 int x1 = SkClampMax(int(floor(sx+filter->width() + 0.5f)), src->widt h()-1);
216
217 SkFixed total_weight = 0;
218 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
219
220 for (int src_x = x0 ; src_x <= x1 ; src_x++) {
221 SkFixed weight = filter->lookup(sx - src_x);
222 SkPMColor c = *src->getAddr32(src_x,y);
223 fr += weight * SkGetPackedR32(c);
224 fg += weight * SkGetPackedG32(c);
225 fb += weight * SkGetPackedB32(c);
226 fa += weight * SkGetPackedA32(c);
227 total_weight += weight;
228 }
229 fr = SkFixedDiv(fr, total_weight);
230 fg = SkFixedDiv(fg, total_weight);
231 fb = SkFixedDiv(fb, total_weight);
232 fa = SkFixedDiv(fa, total_weight);
233
234 int a = SkClampMax(SkFixedRoundToInt(fa), 255);
235 int r = SkClampMax(SkFixedRoundToInt(fr), a);
236 int g = SkClampMax(SkFixedRoundToInt(fg), a);
237 int b = SkClampMax(SkFixedRoundToInt(fb), a);
238
239 *dst->getAddr32(x,y) = SkPackARGB32(a, r, g, b);
240 }
241 }
242 }
243
244 static void downScaleHoriz(const SkBitmap *src, SkBitmap *dst, float scale, SkBi tmapFilter *filter) {
245 SkFixed *sums = SkNEW_ARRAY(SkFixed, dst->width() * dst->height() * 4);
246 SkFixed *weights = SkNEW_ARRAY(SkFixed, dst->width() * dst->height());
247
248 SkAutoTDeleteArray<SkFixed> ada1(sums);
249 SkAutoTDeleteArray<SkFixed> ada2(weights);
250
251 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4);
252 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed));
253
254 for (int y = 0 ; y < src->height() ; y++) {
255 for (int x = 0 ; x < src->width() ; x++) {
256 // splat each source pixel into the destination image
257 float dx = (x + 0.5f) * scale;
258 int x0 = SkClampMax(int(ceil(dx-filter->width() + 0.5f)), dst->width ()-1);
259 int x1 = SkClampMax(int(floor(dx+filter->width() + 0.5f)), dst->widt h()-1);
260
261 SkPMColor c = *src->getAddr32(x,y);
262
263 for (int dst_x = x0 ; dst_x <= x1 ; dst_x++) {
264 SkFixed weight = filter->lookup(dx - dst_x);
265 sums[4*(y*dst->width() + dst_x) + 0] += weight*SkGetPackedR32(c) ;
266 sums[4*(y*dst->width() + dst_x) + 1] += weight*SkGetPackedG32(c) ;
267 sums[4*(y*dst->width() + dst_x) + 2] += weight*SkGetPackedB32(c) ;
268 sums[4*(y*dst->width() + dst_x) + 3] += weight*SkGetPackedA32(c) ;
269 weights[y*dst->width() + dst_x] += weight;
270 }
271 }
272 }
273
274 divideByWeights(sums, weights, dst);
275 }
276
277 static void upScaleVert(const SkBitmap *src, SkBitmap *dst, float scale, SkBitma pFilter *filter) {
278 for (int y = 0 ; y < dst->height() ; y++) {
279 for (int x = 0 ; x < dst->width() ; x++) {
280 float sy = y / scale - 0.5f;
281 int y0 = SkClampMax(int(ceil(sy-filter->width() + 0.5f)), src->heigh t()-1);
282 int y1 = SkClampMax(int(floor(sy+filter->width() + 0.5f)), src->heig ht()-1);
283
284 SkFixed total_weight = 0;
285 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
286
287 for (int src_y = y0 ; src_y <= y1 ; src_y++) {
288 SkFixed weight = filter->lookup(sy - src_y);
289 SkPMColor c = *src->getAddr32(x,src_y);
290 fr += weight * SkGetPackedR32(c);
291 fg += weight * SkGetPackedG32(c);
292 fb += weight * SkGetPackedB32(c);
293 fa += weight * SkGetPackedA32(c);
294 total_weight += weight;
295 }
296 fr = SkFixedDiv(fr, total_weight);
297 fg = SkFixedDiv(fg, total_weight);
298 fb = SkFixedDiv(fb, total_weight);
299 fa = SkFixedDiv(fa, total_weight);
300
301 int a = SkClampMax(SkFixedRoundToInt(fa), 255);
302 int r = SkClampMax(SkFixedRoundToInt(fr), a);
303 int g = SkClampMax(SkFixedRoundToInt(fg), a);
304 int b = SkClampMax(SkFixedRoundToInt(fb), a);
305
306 *dst->getAddr32(x,y) = SkPackARGB32(a, r, g, b);
307 }
308 }
309 }
310
311 static void downScaleVert(const SkBitmap *src, SkBitmap *dst, float scale, SkBit mapFilter *filter) {
312 SkFixed *sums = SkNEW_ARRAY(SkFixed, dst->width() * dst->height() * 4);
313 SkFixed *weights = SkNEW_ARRAY(SkFixed, dst->width() * dst->height());
314
315 SkAutoTDeleteArray<SkFixed> ada1(sums);
316 SkAutoTDeleteArray<SkFixed> ada2(weights);
317
318 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4);
319 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed));
320
321 for (int y = 0 ; y < src->height() ; y++) {
322 for (int x = 0 ; x < src->width() ; x++) {
323 // splat each source pixel into the destination image
324 float dy = (y + 0.5f) * scale;
325 int y0 = SkClampMax(int(ceil(dy-filter->width() + 0.5f)), dst->heigh t()-1);
326 int y1 = SkClampMax(int(floor(dy+filter->width() + 0.5f)), dst->heig ht()-1);
327
328 SkPMColor c = *src->getAddr32(x,y);
329
330 for (int dst_y = y0 ; dst_y <= y1 ; dst_y++) {
331 SkFixed weight = filter->lookup(dy - dst_y);
332 sums[4*(dst_y*dst->width() + x) + 0] += weight*SkGetPackedR32(c) ;
333 sums[4*(dst_y*dst->width() + x) + 1] += weight*SkGetPackedG32(c) ;
334 sums[4*(dst_y*dst->width() + x) + 2] += weight*SkGetPackedB32(c) ;
335 sums[4*(dst_y*dst->width() + x) + 3] += weight*SkGetPackedA32(c) ;
336 weights[dst_y*dst->width() + x] += weight;
337 }
338 }
339 }
340
341 divideByWeights(sums, weights, dst);
342 }
343
344 void SkBitmap::scale(SkBitmap *dst) const {
345
346 SkBitmap horiz_temp;
347
348 horiz_temp.setConfig(SkBitmap::kARGB_8888_Config, dst->width(), height());
349 horiz_temp.allocPixels();
350
351 SkBitmapFilter *filter = allocateBitmapFilter();
352
353 float horiz_scale = float(dst->width()) / width();
354
355 if (horiz_scale == 1) {
356 this->copyPixelsTo(horiz_temp.getPixels(), getSize());
357 } else if (horiz_scale > 1) {
358 upScaleHoriz(this, &horiz_temp, horiz_scale, filter);
359 } else if (horiz_scale < 1) {
360 downScaleHoriz(this, &horiz_temp, horiz_scale, filter);
361 }
362
363 float vert_scale = float(dst->height()) / height();
364
365 if (vert_scale == 1) {
366 horiz_temp.copyPixelsTo(dst->getPixels(), dst->getSize());
367 } else if (vert_scale > 1) {
368 upScaleVert(&horiz_temp, dst, vert_scale, filter);
369 } else if (vert_scale < 1) {
370 downScaleVert(&horiz_temp, dst, vert_scale, filter);
371 }
372
373 SkDELETE(filter);
374 }
OLDNEW
« no previous file with comments | « src/core/SkBitmapFilter.h ('k') | src/core/SkBitmapProcBicubic.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698