Index: src/effects/SkMatrixConvolutionImageFilter.cpp |
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp |
index 4cba043e99c227f9243bc9e548237bb9a9d3d0b4..9ed9fd573f885304ed81bf3af046cabce620bb2f 100644 |
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp |
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp |
@@ -8,10 +8,12 @@ |
#include "SkMatrixConvolutionImageFilter.h" |
#include "SkBitmap.h" |
#include "SkColorPriv.h" |
+#include "SkImagePriv.h" |
+#include "SkImage_Base.h" |
#include "SkReadBuffer.h" |
-#include "SkWriteBuffer.h" |
#include "SkRect.h" |
#include "SkUnPreMultiply.h" |
+#include "SkWriteBuffer.h" |
#if SK_SUPPORT_GPU |
#include "effects/GrMatrixConvolutionEffect.h" |
@@ -263,40 +265,48 @@ static SkBitmap unpremultiplyBitmap(const SkBitmap& src) |
} |
bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, |
- const SkBitmap& source, |
+ const SkImage* source, |
const Context& ctx, |
- SkBitmap* result, |
+ SkAutoTUnref<const SkImage>& result, |
SkIPoint* offset) const { |
- SkBitmap src = source; |
+ SkAutoTUnref<const SkImage> src(SkRef(source)); |
SkIPoint srcOffset = SkIPoint::Make(0, 0); |
- if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { |
+ if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOffset)) { |
return false; |
} |
- if (src.colorType() != kN32_SkColorType) { |
+ SkIRect bounds; |
+ if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, src)) { |
return false; |
} |
- SkIRect bounds; |
- if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { |
+ SkBitmap srcBitmap; |
+ if (!as_IB(src)->getROPixels(&srcBitmap)) { |
return false; |
} |
- if (!fConvolveAlpha && !src.isOpaque()) { |
- src = unpremultiplyBitmap(src); |
+ if (srcBitmap.colorType() != kN32_SkColorType) { |
+ return false; |
} |
- SkAutoLockPixels alp(src); |
- if (!src.getPixels()) { |
+ src.reset(NULL); |
+ |
+ if (!fConvolveAlpha && !srcBitmap.isOpaque()) { |
+ srcBitmap = unpremultiplyBitmap(srcBitmap); |
+ } |
+ |
+ SkAutoLockPixels alp(srcBitmap); |
+ if (!srcBitmap.getPixels()) { |
return false; |
} |
- if (!result->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height()))) { |
+ SkBitmap resultBitmap; |
+ if (!resultBitmap.tryAllocPixels(srcBitmap.info().makeWH(bounds.width(), bounds.height()))) { |
return false; |
} |
- offset->fX = bounds.fLeft; |
- offset->fY = bounds.fTop; |
+ int32_t resultX = bounds.fLeft; |
+ int32_t resultY = bounds.fTop; |
bounds.offset(-srcOffset); |
SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, |
bounds.top() + fKernelOffset.fY, |
@@ -309,11 +319,21 @@ bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, |
interior.left(), interior.bottom()); |
SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), |
bounds.right(), interior.bottom()); |
- filterBorderPixels(src, result, top, bounds); |
- filterBorderPixels(src, result, left, bounds); |
- filterInteriorPixels(src, result, interior, bounds); |
- filterBorderPixels(src, result, right, bounds); |
- filterBorderPixels(src, result, bottom, bounds); |
+ filterBorderPixels(srcBitmap, &resultBitmap, top, bounds); |
+ filterBorderPixels(srcBitmap, &resultBitmap, left, bounds); |
+ filterInteriorPixels(srcBitmap, &resultBitmap, interior, bounds); |
+ filterBorderPixels(srcBitmap, &resultBitmap, right, bounds); |
+ filterBorderPixels(srcBitmap, &resultBitmap, bottom, bounds); |
+ |
+ srcBitmap = SkBitmap(); |
+ |
+ SkImage* image = SkNewImageFromBitmap(resultBitmap, NULL); |
+ if (NULL == image) { |
+ return false; |
+ } |
+ result.reset(image); |
+ offset->fX = resultX; |
+ offset->fY = resultY; |
return true; |
} |