OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |