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

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

Issue 19013004: fix bug with awesome filtered images sometimes being slightly offset. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapProcState.h" 8 #include "SkBitmapProcState.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkColor.h" 10 #include "SkColor.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkUnPreMultiply.h" 12 #include "SkUnPreMultiply.h"
13 #include "SkShader.h" 13 #include "SkShader.h"
14 #include "SkRTConf.h" 14 #include "SkRTConf.h"
15 #include "SkMath.h" 15 #include "SkMath.h"
16 16
17 void highQualityFilter(const SkBitmapProcState& s, int x, int y, 17 void highQualityFilter(const SkBitmapProcState& s, int x, int y,
18 SkPMColor* SK_RESTRICT colors, int count) { 18 SkPMColor* SK_RESTRICT colors, int count) {
19 19
20 const int maxX = s.fBitmap->width() - 1; 20 const int maxX = s.fBitmap->width() - 1;
21 const int maxY = s.fBitmap->height() - 1; 21 const int maxY = s.fBitmap->height() - 1;
22 22
23 while (count-- > 0) { 23 while (count-- > 0) {
24 SkPoint srcPt; 24 SkPoint srcPt;
25 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x), 25 s.fInvProc(*s.fInvMatrix, SkFloatToScalar(x + 0.5),
26 SkIntToScalar(y), &srcPt); 26 SkFloatToScalar(y + 0.5), &srcPt);
27 srcPt.fX -= SK_ScalarHalf; 27 srcPt.fX -= SK_ScalarHalf;
28 srcPt.fY -= SK_ScalarHalf; 28 srcPt.fY -= SK_ScalarHalf;
29 29
30 int sx = SkScalarFloorToInt(srcPt.fX); 30 int sx = SkScalarFloorToInt(srcPt.fX);
31 int sy = SkScalarFloorToInt(srcPt.fY); 31 int sy = SkScalarFloorToInt(srcPt.fY);
32 32
33 SkFixed weight = 0; 33 SkFixed weight = 0;
34 SkFixed fr = 0, fg = 0, fb = 0, fa = 0; 34 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
35 35
36 int y0 = SkClampMax(int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)), m axY); 36 int y0 = SkClampMax(int(ceil(SkScalarToFloat(srcPt.fY)-s.getBitmapFilter ()->width())), maxY);
37 int y1 = SkClampMax(int(floor(sy+s.getBitmapFilter()->width() + 0.5f)), maxY); 37 int y1 = SkClampMax(int(floor(SkScalarToFloat(srcPt.fY)+s.getBitmapFilte r()->width())), maxY);
38 int x0 = SkClampMax(int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)), m axX); 38 int x0 = SkClampMax(int(ceil(SkScalarToFloat(srcPt.fX)-s.getBitmapFilter ()->width())), maxX);
39 int x1 = SkClampMax(int(floor(sx+s.getBitmapFilter()->width() + 0.5f)), maxX); 39 int x1 = SkClampMax(int(floor(SkScalarToFloat(srcPt.fX)+s.getBitmapFilte r()->width())), maxX);
40 40
41 for (int src_y = y0; src_y <= y1; src_y++) { 41 for (int src_y = y0; src_y <= y1; src_y++) {
42 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y)); 42 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y));
43 43
44 for (int src_x = x0; src_x <= x1 ; src_x++) { 44 for (int src_x = x0; src_x <= x1 ; src_x++) {
45 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x) ); 45 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x) );
46 46
47 SkFixed combined_weight = SkFixedMul(xweight, yweight); 47 SkFixed combined_weight = SkFixedMul(xweight, yweight);
48 48
49 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y); 49 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y);
(...skipping 21 matching lines...) Expand all
71 } 71 }
72 } 72 }
73 73
74 void highQualityFilter_ScaleOnly(const SkBitmapProcState &s, int x, int y, 74 void highQualityFilter_ScaleOnly(const SkBitmapProcState &s, int x, int y,
75 SkPMColor *SK_RESTRICT colors, int count) { 75 SkPMColor *SK_RESTRICT colors, int count) {
76 const int maxX = s.fBitmap->width() - 1; 76 const int maxX = s.fBitmap->width() - 1;
77 const int maxY = s.fBitmap->height() - 1; 77 const int maxY = s.fBitmap->height() - 1;
78 78
79 SkPoint srcPt; 79 SkPoint srcPt;
80 80
81 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x), 81 s.fInvProc(*s.fInvMatrix, SkFloatToScalar(x + 0.5),
82 SkIntToScalar(y), &srcPt); 82 SkFloatToScalar(y + 0.5), &srcPt);
83 srcPt.fY -= SK_ScalarHalf; 83 srcPt.fY -= SK_ScalarHalf;
84 int sy = SkScalarFloorToInt(srcPt.fY); 84 int sy = SkScalarFloorToInt(srcPt.fY);
85 int y0 = SkClampMax(int(ceil(sy-s.getBitmapFilter()->width() + 0.5f)), maxY ); 85 int y0 = SkClampMax(int(ceil(SkScalarToFloat(srcPt.fY)-s.getBitmapFilter()- >width())), maxY);
86 int y1 = SkClampMax(int(floor(sy+s.getBitmapFilter()->width() + 0.5f)), max Y); 86 int y1 = SkClampMax(int(floor(SkScalarToFloat(srcPt.fY)+s.getBitmapFilter() ->width())), maxY);
87 87
88 while (count-- > 0) { 88 while (count-- > 0) {
89 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x), 89 s.fInvProc(*s.fInvMatrix, SkFloatToScalar(x + 0.5),
90 SkIntToScalar(y), &srcPt); 90 SkFloatToScalar(y + 0.5), &srcPt);
91 srcPt.fX -= SK_ScalarHalf; 91 srcPt.fX -= SK_ScalarHalf;
92 srcPt.fY -= SK_ScalarHalf; 92 srcPt.fY -= SK_ScalarHalf;
93 93
94 int sx = SkScalarFloorToInt(srcPt.fX); 94 int sx = SkScalarFloorToInt(srcPt.fX);
95 95
96 SkFixed weight = 0; 96 SkFixed weight = 0;
97 SkFixed fr = 0, fg = 0, fb = 0, fa = 0; 97 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
98 98
99 int x0 = SkClampMax(int(ceil(sx-s.getBitmapFilter()->width() + 0.5f)), maxX); 99 int x0 = SkClampMax(int(ceil(SkScalarToFloat(srcPt.fX)-s.getBitmapFilte r()->width())), maxX);
reed1 2013/07/10 20:56:12 sk_float_ceil2int sk_float_floor2int These guys w
100 int x1 = SkClampMax(int(floor(sx+s.getBitmapFilter()->width() + 0.5f)), maxX); 100 int x1 = SkClampMax(int(floor(SkScalarToFloat(srcPt.fX)+s.getBitmapFilt er()->width())), maxX);
101 101
102 for (int src_y = y0; src_y <= y1; src_y++) { 102 for (int src_y = y0; src_y <= y1; src_y++) {
103 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y)); 103 SkFixed yweight = s.getBitmapFilter()->lookup((srcPt.fY - src_y));
104 104
105 for (int src_x = x0; src_x <= x1 ; src_x++) { 105 for (int src_x = x0; src_x <= x1 ; src_x++) {
106 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x )); 106 SkFixed xweight = s.getBitmapFilter()->lookup((srcPt.fX - src_x ));
107 107
108 SkFixed combined_weight = SkFixedMul(xweight, yweight); 108 SkFixed combined_weight = SkFixedMul(xweight, yweight);
109 109
110 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y); 110 SkPMColor c = *s.fBitmap->getAddr32(src_x, src_y);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 int b = SkClampMax(SkFixedRoundToInt(fb), a); 203 int b = SkClampMax(SkFixedRoundToInt(fb), a);
204 204
205 *dst->getAddr32(x,y) = SkPackARGB32(a, r, g, b); 205 *dst->getAddr32(x,y) = SkPackARGB32(a, r, g, b);
206 } 206 }
207 } 207 }
208 } 208 }
209 209
210 static void upScaleHoriz(const SkBitmap *src, SkBitmap *dst, float scale, SkBitm apFilter *filter) { 210 static void upScaleHoriz(const SkBitmap *src, SkBitmap *dst, float scale, SkBitm apFilter *filter) {
211 for (int y = 0 ; y < src->height() ; y++) { 211 for (int y = 0 ; y < src->height() ; y++) {
212 for (int x = 0 ; x < dst->width() ; x++) { 212 for (int x = 0 ; x < dst->width() ; x++) {
213 float sx = x / scale - 0.5f; 213 float sx = (x + 0.5f) / scale - 0.5f;
214 int x0 = SkClampMax(int(ceil(sx-filter->width() + 0.5f)), src->width ()-1); 214 int x0 = SkClampMax(int(ceil(sx-filter->width())), src->width()-1);
215 int x1 = SkClampMax(int(floor(sx+filter->width() + 0.5f)), src->widt h()-1); 215 int x1 = SkClampMax(int(floor(sx+filter->width())), src->width()-1);
216 216
217 SkFixed total_weight = 0; 217 SkFixed total_weight = 0;
218 SkFixed fr = 0, fg = 0, fb = 0, fa = 0; 218 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
219 219
220 for (int src_x = x0 ; src_x <= x1 ; src_x++) { 220 for (int src_x = x0 ; src_x <= x1 ; src_x++) {
221 SkFixed weight = filter->lookup(sx - src_x); 221 SkFixed weight = filter->lookup(sx - src_x);
222 SkPMColor c = *src->getAddr32(src_x,y); 222 SkPMColor c = *src->getAddr32(src_x,y);
223 fr += weight * SkGetPackedR32(c); 223 fr += weight * SkGetPackedR32(c);
224 fg += weight * SkGetPackedG32(c); 224 fg += weight * SkGetPackedG32(c);
225 fb += weight * SkGetPackedB32(c); 225 fb += weight * SkGetPackedB32(c);
(...skipping 21 matching lines...) Expand all
247 247
248 SkAutoTDeleteArray<SkFixed> ada1(sums); 248 SkAutoTDeleteArray<SkFixed> ada1(sums);
249 SkAutoTDeleteArray<SkFixed> ada2(weights); 249 SkAutoTDeleteArray<SkFixed> ada2(weights);
250 250
251 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4); 251 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4);
252 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed)); 252 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed));
253 253
254 for (int y = 0 ; y < src->height() ; y++) { 254 for (int y = 0 ; y < src->height() ; y++) {
255 for (int x = 0 ; x < src->width() ; x++) { 255 for (int x = 0 ; x < src->width() ; x++) {
256 // splat each source pixel into the destination image 256 // splat each source pixel into the destination image
257 float dx = (x + 0.5f) * scale; 257 float dx = (x + 0.5f) * scale - 0.5f;
258 int x0 = SkClampMax(int(ceil(dx-filter->width() + 0.5f)), dst->width ()-1); 258 int x0 = SkClampMax(int(ceil(dx-filter->width())), dst->width()-1);
259 int x1 = SkClampMax(int(floor(dx+filter->width() + 0.5f)), dst->widt h()-1); 259 int x1 = SkClampMax(int(floor(dx+filter->width())), dst->width()-1);
260 260
261 SkPMColor c = *src->getAddr32(x,y); 261 SkPMColor c = *src->getAddr32(x,y);
262 262
263 for (int dst_x = x0 ; dst_x <= x1 ; dst_x++) { 263 for (int dst_x = x0 ; dst_x <= x1 ; dst_x++) {
264 SkFixed weight = filter->lookup(dx - dst_x); 264 SkFixed weight = filter->lookup(dx - dst_x);
265 sums[4*(y*dst->width() + dst_x) + 0] += weight*SkGetPackedR32(c) ; 265 sums[4*(y*dst->width() + dst_x) + 0] += weight*SkGetPackedR32(c) ;
266 sums[4*(y*dst->width() + dst_x) + 1] += weight*SkGetPackedG32(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) ; 267 sums[4*(y*dst->width() + dst_x) + 2] += weight*SkGetPackedB32(c) ;
268 sums[4*(y*dst->width() + dst_x) + 3] += weight*SkGetPackedA32(c) ; 268 sums[4*(y*dst->width() + dst_x) + 3] += weight*SkGetPackedA32(c) ;
269 weights[y*dst->width() + dst_x] += weight; 269 weights[y*dst->width() + dst_x] += weight;
270 } 270 }
271 } 271 }
272 } 272 }
273 273
274 divideByWeights(sums, weights, dst); 274 divideByWeights(sums, weights, dst);
275 } 275 }
276 276
277 static void upScaleVert(const SkBitmap *src, SkBitmap *dst, float scale, SkBitma pFilter *filter) { 277 static void upScaleVert(const SkBitmap *src, SkBitmap *dst, float scale, SkBitma pFilter *filter) {
278 for (int y = 0 ; y < dst->height() ; y++) { 278 for (int y = 0 ; y < dst->height() ; y++) {
279 for (int x = 0 ; x < dst->width() ; x++) { 279 for (int x = 0 ; x < dst->width() ; x++) {
280 float sy = y / scale - 0.5f; 280 float sy = (y + 0.5f) / scale - 0.5f;
281 int y0 = SkClampMax(int(ceil(sy-filter->width() + 0.5f)), src->heigh t()-1); 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); 282 int y1 = SkClampMax(int(floor(sy+filter->width() + 0.5f)), src->heig ht()-1);
283 283
284 SkFixed total_weight = 0; 284 SkFixed total_weight = 0;
285 SkFixed fr = 0, fg = 0, fb = 0, fa = 0; 285 SkFixed fr = 0, fg = 0, fb = 0, fa = 0;
286 286
287 for (int src_y = y0 ; src_y <= y1 ; src_y++) { 287 for (int src_y = y0 ; src_y <= y1 ; src_y++) {
288 SkFixed weight = filter->lookup(sy - src_y); 288 SkFixed weight = filter->lookup(sy - src_y);
289 SkPMColor c = *src->getAddr32(x,src_y); 289 SkPMColor c = *src->getAddr32(x,src_y);
290 fr += weight * SkGetPackedR32(c); 290 fr += weight * SkGetPackedR32(c);
(...skipping 23 matching lines...) Expand all
314 314
315 SkAutoTDeleteArray<SkFixed> ada1(sums); 315 SkAutoTDeleteArray<SkFixed> ada1(sums);
316 SkAutoTDeleteArray<SkFixed> ada2(weights); 316 SkAutoTDeleteArray<SkFixed> ada2(weights);
317 317
318 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4); 318 memset(sums, 0, dst->width() * dst->height() * sizeof(SkFixed) * 4);
319 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed)); 319 memset(weights, 0, dst->width() * dst->height() * sizeof(SkFixed));
320 320
321 for (int y = 0 ; y < src->height() ; y++) { 321 for (int y = 0 ; y < src->height() ; y++) {
322 for (int x = 0 ; x < src->width() ; x++) { 322 for (int x = 0 ; x < src->width() ; x++) {
323 // splat each source pixel into the destination image 323 // splat each source pixel into the destination image
324 float dy = (y + 0.5f) * scale; 324 float dy = (y + 0.5f) * scale - 0.5f;
325 int y0 = SkClampMax(int(ceil(dy-filter->width() + 0.5f)), dst->heigh t()-1); 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); 326 int y1 = SkClampMax(int(floor(dy+filter->width() + 0.5f)), dst->heig ht()-1);
327 327
328 SkPMColor c = *src->getAddr32(x,y); 328 SkPMColor c = *src->getAddr32(x,y);
329 329
330 for (int dst_y = y0 ; dst_y <= y1 ; dst_y++) { 330 for (int dst_y = y0 ; dst_y <= y1 ; dst_y++) {
331 SkFixed weight = filter->lookup(dy - dst_y); 331 SkFixed weight = filter->lookup(dy - dst_y);
332 sums[4*(dst_y*dst->width() + x) + 0] += weight*SkGetPackedR32(c) ; 332 sums[4*(dst_y*dst->width() + x) + 0] += weight*SkGetPackedR32(c) ;
333 sums[4*(dst_y*dst->width() + x) + 1] += weight*SkGetPackedG32(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) ; 334 sums[4*(dst_y*dst->width() + x) + 2] += weight*SkGetPackedB32(c) ;
(...skipping 30 matching lines...) Expand all
365 if (vert_scale == 1) { 365 if (vert_scale == 1) {
366 horiz_temp.copyPixelsTo(dst->getPixels(), dst->getSize()); 366 horiz_temp.copyPixelsTo(dst->getPixels(), dst->getSize());
367 } else if (vert_scale > 1) { 367 } else if (vert_scale > 1) {
368 upScaleVert(&horiz_temp, dst, vert_scale, filter); 368 upScaleVert(&horiz_temp, dst, vert_scale, filter);
369 } else if (vert_scale < 1) { 369 } else if (vert_scale < 1) {
370 downScaleVert(&horiz_temp, dst, vert_scale, filter); 370 downScaleVert(&horiz_temp, dst, vert_scale, filter);
371 } 371 }
372 372
373 SkDELETE(filter); 373 SkDELETE(filter);
374 } 374 }
OLDNEW
« no previous file with comments | « src/core/SkBitmapFilter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698