Limit sigma for software blurs
The value (window + 1)^3 * 255 < 2^32. window = floor(sigma * 3 * sqrt(2 * kPi) / 4) So, max sigma = 135. Bug: skia:9454 Change-Id: I1df5137013da3e80d1e8af9ed6ac2b688ef95e7d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243430 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
867ab81687
commit
f07a363413
@ -18,6 +18,7 @@
|
||||
#include "include/core/SkScalar.h"
|
||||
#include "include/core/SkTypeface.h"
|
||||
#include "include/core/SkTypes.h"
|
||||
#include "include/effects/SkBlurImageFilter.h"
|
||||
#include "src/core/SkBlurMask.h"
|
||||
#include "tools/Resources.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
@ -129,3 +130,11 @@ DEF_SIMPLE_GM(BlurDrawImage, canvas, 256, 256) {
|
||||
canvas->drawImage(image, 256, 256, &paint);
|
||||
}
|
||||
}
|
||||
|
||||
DEF_SIMPLE_GM(BlurBigSigma, canvas, 1024, 1024) {
|
||||
SkPaint layerPaint, p;
|
||||
|
||||
p.setImageFilter(SkBlurImageFilter::Make(0, 500, nullptr));
|
||||
|
||||
canvas->drawRect(SkRect::MakeWH(700, 800), p);
|
||||
}
|
||||
|
@ -236,21 +236,23 @@ public:
|
||||
|
||||
} // namespace
|
||||
|
||||
// NB 136 is the largest sigma that will not cause a buffer full of 255 mask values to overflow
|
||||
// using the Gauss filter. It also limits the size of buffers used hold intermediate values.
|
||||
// NB 135 is the largest sigma that will not cause a buffer full of 255 mask values to overflow
|
||||
// using the Gauss filter. It also limits the size of buffers used hold intermediate values. The
|
||||
// additional + 1 added to window represents adding one more leading element before subtracting the
|
||||
// trailing element.
|
||||
// Explanation of maximums:
|
||||
// sum0 = window * 255
|
||||
// sum1 = window * sum0 -> window * window * 255
|
||||
// sum2 = window * sum1 -> window * window * window * 255 -> window^3 * 255
|
||||
// sum0 = (window + 1) * 255
|
||||
// sum1 = (window + 1) * sum0 -> (window + 1) * (window + 1) * 255
|
||||
// sum2 = (window + 1) * sum1 -> (window + 1) * (window + 1) * (window + 1) * 255 -> window^3 * 255
|
||||
//
|
||||
// The value window^3 * 255 must fit in a uint32_t. So,
|
||||
// window^3 < 2^32. window = 255.
|
||||
// The value (window + 1)^3 * 255 must fit in a uint32_t. So,
|
||||
// (window + 1)^3 * 255 < 2^32. window = 255.
|
||||
//
|
||||
// window = floor(sigma * 3 * sqrt(2 * kPi) / 4 + 0.5)
|
||||
// For window <= 255, the largest value for sigma is 136.
|
||||
// window = floor(sigma * 3 * sqrt(2 * kPi) / 4)
|
||||
// For window <= 255, the largest value for sigma is 135.
|
||||
SkMaskBlurFilter::SkMaskBlurFilter(double sigmaW, double sigmaH)
|
||||
: fSigmaW{SkTPin(sigmaW, 0.0, 136.0)}
|
||||
, fSigmaH{SkTPin(sigmaH, 0.0, 136.0)}
|
||||
: fSigmaW{SkTPin(sigmaW, 0.0, 135.0)}
|
||||
, fSigmaH{SkTPin(sigmaH, 0.0, 135.0)}
|
||||
{
|
||||
SkASSERT(sigmaW >= 0);
|
||||
SkASSERT(sigmaH >= 0);
|
||||
|
@ -605,7 +605,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(const Context& ctx,
|
||||
inputBounds.offset(-inputOffset);
|
||||
dstBounds.offset(-inputOffset);
|
||||
|
||||
const SkVector sigma = map_sigma(fSigma, ctx.ctm());
|
||||
SkVector sigma = map_sigma(fSigma, ctx.ctm());
|
||||
if (sigma.x() < 0 || sigma.y() < 0) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -621,6 +621,23 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(const Context& ctx,
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// NB 135 is the largest sigma that will not cause a buffer full of 255 mask values to overflow
|
||||
// using the Gauss filter. It also limits the size of buffers used hold intermediate values. The
|
||||
// additional + 1 added to window represents adding one more leading element before subtracting the
|
||||
// trailing element.
|
||||
// Explanation of maximums:
|
||||
// sum0 = (window + 1) * 255
|
||||
// sum1 = (window + 1) * sum0 -> (window + 1) * (window + 1) * 255
|
||||
// sum2 = (window + 1) * sum1 -> (window + 1) * (window + 1) * (window + 1) * 255 -> window^3 * 255
|
||||
//
|
||||
// The value (window + 1)^3 * 255 must fit in a uint32_t. So,
|
||||
// (window + 1)^3 * 255 < 2^32. window = 255.
|
||||
//
|
||||
// window = floor(sigma * 3 * sqrt(2 * kPi) / 4)
|
||||
// For window <= 255, the largest value for sigma is 135.
|
||||
sigma.fX = SkTPin(sigma.fX, 0.0f, 135.0f);
|
||||
sigma.fY = SkTPin(sigma.fY, 0.0f, 135.0f);
|
||||
|
||||
result = cpu_blur(ctx, sigma, input, inputBounds, dstBounds);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user