OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
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 "SkMatrixConvolutionImageFilter.h" | 8 #include "SkMatrixConvolutionImageFilter.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkImagePriv.h" |
| 12 #include "SkImage_Base.h" |
11 #include "SkReadBuffer.h" | 13 #include "SkReadBuffer.h" |
12 #include "SkWriteBuffer.h" | |
13 #include "SkRect.h" | 14 #include "SkRect.h" |
14 #include "SkUnPreMultiply.h" | 15 #include "SkUnPreMultiply.h" |
| 16 #include "SkWriteBuffer.h" |
15 | 17 |
16 #if SK_SUPPORT_GPU | 18 #if SK_SUPPORT_GPU |
17 #include "effects/GrMatrixConvolutionEffect.h" | 19 #include "effects/GrMatrixConvolutionEffect.h" |
18 #endif | 20 #endif |
19 | 21 |
20 // We need to be able to read at most SK_MaxS32 bytes, so divide that | 22 // We need to be able to read at most SK_MaxS32 bytes, so divide that |
21 // by the size of a scalar to know how many scalars we can read. | 23 // by the size of a scalar to know how many scalars we can read. |
22 static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); | 24 static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); |
23 | 25 |
24 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( | 26 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 const uint32_t* srcRow = src.getAddr32(0, y); | 258 const uint32_t* srcRow = src.getAddr32(0, y); |
257 uint32_t* dstRow = result.getAddr32(0, y); | 259 uint32_t* dstRow = result.getAddr32(0, y); |
258 for (int x = 0; x < src.width(); ++x) { | 260 for (int x = 0; x < src.width(); ++x) { |
259 dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]); | 261 dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]); |
260 } | 262 } |
261 } | 263 } |
262 return result; | 264 return result; |
263 } | 265 } |
264 | 266 |
265 bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, | 267 bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, |
266 const SkBitmap& source, | 268 const SkImage* source, |
267 const Context& ctx, | 269 const Context& ctx, |
268 SkBitmap* result, | 270 SkAutoTUnref<const SkImage>&
result, |
269 SkIPoint* offset) const { | 271 SkIPoint* offset) const { |
270 SkBitmap src = source; | 272 SkAutoTUnref<const SkImage> src(SkRef(source)); |
271 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 273 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
272 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcO
ffset)) { | 274 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOf
fset)) { |
273 return false; | |
274 } | |
275 | |
276 if (src.colorType() != kN32_SkColorType) { | |
277 return false; | 275 return false; |
278 } | 276 } |
279 | 277 |
280 SkIRect bounds; | 278 SkIRect bounds; |
281 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { | 279 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, src)) { |
282 return false; | 280 return false; |
283 } | 281 } |
284 | 282 |
285 if (!fConvolveAlpha && !src.isOpaque()) { | 283 SkBitmap srcBitmap; |
286 src = unpremultiplyBitmap(src); | 284 if (!as_IB(src)->getROPixels(&srcBitmap)) { |
287 } | |
288 | |
289 SkAutoLockPixels alp(src); | |
290 if (!src.getPixels()) { | |
291 return false; | 285 return false; |
292 } | 286 } |
293 | 287 |
294 if (!result->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height(
)))) { | 288 if (srcBitmap.colorType() != kN32_SkColorType) { |
295 return false; | 289 return false; |
296 } | 290 } |
297 | 291 |
298 offset->fX = bounds.fLeft; | 292 src.reset(NULL); |
299 offset->fY = bounds.fTop; | 293 |
| 294 if (!fConvolveAlpha && !srcBitmap.isOpaque()) { |
| 295 srcBitmap = unpremultiplyBitmap(srcBitmap); |
| 296 } |
| 297 |
| 298 SkAutoLockPixels alp(srcBitmap); |
| 299 if (!srcBitmap.getPixels()) { |
| 300 return false; |
| 301 } |
| 302 |
| 303 SkBitmap resultBitmap; |
| 304 if (!resultBitmap.tryAllocPixels(srcBitmap.info().makeWH(bounds.width(), bou
nds.height()))) { |
| 305 return false; |
| 306 } |
| 307 |
| 308 int32_t resultX = bounds.fLeft; |
| 309 int32_t resultY = bounds.fTop; |
300 bounds.offset(-srcOffset); | 310 bounds.offset(-srcOffset); |
301 SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, | 311 SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, |
302 bounds.top() + fKernelOffset.fY, | 312 bounds.top() + fKernelOffset.fY, |
303 bounds.width() - fKernelSize.fWidth + 1
, | 313 bounds.width() - fKernelSize.fWidth + 1
, |
304 bounds.height() - fKernelSize.fHeight +
1); | 314 bounds.height() - fKernelSize.fHeight +
1); |
305 SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(),
interior.top()); | 315 SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(),
interior.top()); |
306 SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), | 316 SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), |
307 bounds.right(), bounds.bottom()); | 317 bounds.right(), bounds.bottom()); |
308 SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), | 318 SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), |
309 interior.left(), interior.bottom()); | 319 interior.left(), interior.bottom()); |
310 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), | 320 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), |
311 bounds.right(), interior.bottom()); | 321 bounds.right(), interior.bottom()); |
312 filterBorderPixels(src, result, top, bounds); | 322 filterBorderPixels(srcBitmap, &resultBitmap, top, bounds); |
313 filterBorderPixels(src, result, left, bounds); | 323 filterBorderPixels(srcBitmap, &resultBitmap, left, bounds); |
314 filterInteriorPixels(src, result, interior, bounds); | 324 filterInteriorPixels(srcBitmap, &resultBitmap, interior, bounds); |
315 filterBorderPixels(src, result, right, bounds); | 325 filterBorderPixels(srcBitmap, &resultBitmap, right, bounds); |
316 filterBorderPixels(src, result, bottom, bounds); | 326 filterBorderPixels(srcBitmap, &resultBitmap, bottom, bounds); |
| 327 |
| 328 srcBitmap = SkBitmap(); |
| 329 |
| 330 SkImage* image = SkNewImageFromBitmap(resultBitmap, NULL); |
| 331 if (NULL == image) { |
| 332 return false; |
| 333 } |
| 334 result.reset(image); |
| 335 offset->fX = resultX; |
| 336 offset->fY = resultY; |
317 return true; | 337 return true; |
318 } | 338 } |
319 | 339 |
320 bool SkMatrixConvolutionImageFilter::onFilterBounds(const SkIRect& src, const Sk
Matrix& ctm, | 340 bool SkMatrixConvolutionImageFilter::onFilterBounds(const SkIRect& src, const Sk
Matrix& ctm, |
321 SkIRect* dst) const { | 341 SkIRect* dst) const { |
322 SkIRect bounds = src; | 342 SkIRect bounds = src; |
323 bounds.fRight += fKernelSize.width() - 1; | 343 bounds.fRight += fKernelSize.width() - 1; |
324 bounds.fBottom += fKernelSize.height() - 1; | 344 bounds.fBottom += fKernelSize.height() - 1; |
325 bounds.offset(-fKernelOffset); | 345 bounds.offset(-fKernelOffset); |
326 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { | 346 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 str->appendf("%f ", fKernel[y * fKernelSize.width() + x]); | 397 str->appendf("%f ", fKernel[y * fKernelSize.width() + x]); |
378 } | 398 } |
379 } | 399 } |
380 str->appendf(")"); | 400 str->appendf(")"); |
381 str->appendf("gain: %f bias: %f ", fGain, fBias); | 401 str->appendf("gain: %f bias: %f ", fGain, fBias); |
382 str->appendf("offset: (%d, %d) ", fKernelOffset.fX, fKernelOffset.fY); | 402 str->appendf("offset: (%d, %d) ", fKernelOffset.fX, fKernelOffset.fY); |
383 str->appendf("convolveAlpha: %s", fConvolveAlpha ? "true" : "false"); | 403 str->appendf("convolveAlpha: %s", fConvolveAlpha ? "true" : "false"); |
384 str->append(")"); | 404 str->append(")"); |
385 } | 405 } |
386 #endif | 406 #endif |
OLD | NEW |