Chromium Code Reviews| 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 |