bool SkBlurImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const SkMatrix& ctm, SkBitmap* dst, SkIPoint* offset) { SkBitmap src = this->getInputResult(proxy, source, ctm, offset); if (src.config() != SkBitmap::kARGB_8888_Config) { return false; } SkAutoLockPixels alp(src); if (!src.getPixels()) { return false; } dst->setConfig(src.config(), src.width(), src.height()); dst->allocPixels(); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; getBox3Params(fSigma.width(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX); getBox3Params(fSigma.height(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY); if (kernelSizeX < 0 || kernelSizeY < 0) { return false; } if (kernelSizeX == 0 && kernelSizeY == 0) { src.copyTo(dst, dst->config()); return true; } SkBitmap temp; temp.setConfig(dst->config(), dst->width(), dst->height()); if (!temp.allocPixels()) { return false; } if (kernelSizeX > 0 && kernelSizeY > 0) { boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX); boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY); boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); } else if (kernelSizeX > 0) { boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX); boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX); } else if (kernelSizeY > 0) { boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY); boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY); } return true; }
bool SkBlurImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } if (src.colorType() != kN32_SkColorType) { return false; } SkIRect srcBounds, dstBounds; if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) { return false; } SkAutoLockPixels alp(src); if (!src.getPixels()) { return false; } if (!dst->allocPixels(src.info().makeWH(srcBounds.width(), srcBounds.height()))) { return false; } dst->getBounds(&dstBounds); SkVector sigma = SkVector::Make(fSigma.width(), fSigma.height()); ctx.ctm().mapVectors(&sigma, 1); sigma.fX = SkMinScalar(sigma.fX, MAX_SIGMA); sigma.fY = SkMinScalar(sigma.fY, MAX_SIGMA); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX); getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY); if (kernelSizeX < 0 || kernelSizeY < 0) { return false; } if (kernelSizeX == 0 && kernelSizeY == 0) { src.copyTo(dst, dst->colorType()); offset->fX = srcBounds.fLeft; offset->fY = srcBounds.fTop; return true; } SkBitmap temp; if (!temp.allocPixels(dst->info())) { return false; } offset->fX = srcBounds.fLeft; offset->fY = srcBounds.fTop; srcBounds.offset(-srcOffset); const SkPMColor* s = src.getAddr32(srcBounds.left(), srcBounds.top()); SkPMColor* t = temp.getAddr32(0, 0); SkPMColor* d = dst->getAddr32(0, 0); int w = dstBounds.width(), h = dstBounds.height(); int sw = src.rowBytesAsPixels(); SkBoxBlurProc boxBlurX, boxBlurY, boxBlurXY, boxBlurYX; if (!SkBoxBlurGetPlatformProcs(&boxBlurX, &boxBlurY, &boxBlurXY, &boxBlurYX)) { boxBlurX = boxBlur<kX, kX>; boxBlurY = boxBlur<kY, kY>; boxBlurXY = boxBlur<kX, kY>; boxBlurYX = boxBlur<kY, kX>; } if (kernelSizeX > 0 && kernelSizeY > 0) { boxBlurX(s, sw, t, kernelSizeX, lowOffsetX, highOffsetX, w, h); boxBlurX(t, w, d, kernelSizeX, highOffsetX, lowOffsetX, w, h); boxBlurXY(d, w, t, kernelSizeX3, highOffsetX, highOffsetX, w, h); boxBlurX(t, h, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); } else if (kernelSizeX > 0) { boxBlurX(s, sw, d, kernelSizeX, lowOffsetX, highOffsetX, w, h); boxBlurX(d, w, t, kernelSizeX, highOffsetX, lowOffsetX, w, h); boxBlurX(t, w, d, kernelSizeX3, highOffsetX, highOffsetX, w, h); } else if (kernelSizeY > 0) { boxBlurYX(s, sw, d, kernelSizeY, lowOffsetY, highOffsetY, h, w); boxBlurX(d, h, t, kernelSizeY, highOffsetY, lowOffsetY, h, w); boxBlurXY(t, h, d, kernelSizeY3, highOffsetY, highOffsetY, h, w); } return true; }
bool SkBlurImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const SkMatrix& ctm, SkBitmap* dst, SkIPoint* offset) { SkBitmap src = source; if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offset)) { return false; } if (src.config() != SkBitmap::kARGB_8888_Config) { return false; } SkAutoLockPixels alp(src); if (!src.getPixels()) { return false; } SkIRect srcBounds, dstBounds; src.getBounds(&srcBounds); if (!this->applyCropRect(&srcBounds, ctm)) { return false; } dst->setConfig(src.config(), srcBounds.width(), srcBounds.height()); dst->getBounds(&dstBounds); dst->allocPixels(); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; getBox3Params(fSigma.width(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX); getBox3Params(fSigma.height(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY); if (kernelSizeX < 0 || kernelSizeY < 0) { return false; } if (kernelSizeX == 0 && kernelSizeY == 0) { src.copyTo(dst, dst->config()); return true; } SkBitmap temp; temp.setConfig(dst->config(), dst->width(), dst->height()); if (!temp.allocPixels()) { return false; } if (kernelSizeX > 0 && kernelSizeY > 0) { boxBlurX(src, &temp, kernelSizeX, lowOffsetX, highOffsetX, srcBounds); boxBlurY(temp, dst, kernelSizeY, lowOffsetY, highOffsetY, dstBounds); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds); boxBlurY(temp, dst, kernelSizeY, highOffsetY, lowOffsetY, dstBounds); boxBlurX(*dst, &temp, kernelSizeX3, highOffsetX, highOffsetX, dstBounds); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds); } else if (kernelSizeX > 0) { boxBlurX(src, dst, kernelSizeX, lowOffsetX, highOffsetX, srcBounds); boxBlurX(*dst, &temp, kernelSizeX, highOffsetX, lowOffsetX, dstBounds); boxBlurX(temp, dst, kernelSizeX3, highOffsetX, highOffsetX, dstBounds); } else if (kernelSizeY > 0) { boxBlurY(src, dst, kernelSizeY, lowOffsetY, highOffsetY, srcBounds); boxBlurY(*dst, &temp, kernelSizeY, highOffsetY, lowOffsetY, dstBounds); boxBlurY(temp, dst, kernelSizeY3, highOffsetY, highOffsetY, dstBounds); } offset->fX += srcBounds.fLeft; offset->fY += srcBounds.fTop; return true; }