aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkMaskBlurFilter.cpp
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2018-05-10 15:24:20 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-10 23:00:56 +0000
commite3f1b59d9f578e34b32aa57b9686688f0ddd7877 (patch)
treee4860d6ba8b2499596e83990dc9b9fe440eadf38 /src/core/SkMaskBlurFilter.cpp
parent2128b4ac44e5c9f123259b11c675a2152b19f44b (diff)
Non-normal blur styles to work with non-a8.
BUG=skia:7941 Change-Id: I500561c2fec1bcab324fd9519f1d20d356afdfb5 Reviewed-on: https://skia-review.googlesource.com/127500 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkMaskBlurFilter.cpp')
-rw-r--r--src/core/SkMaskBlurFilter.cpp122
1 files changed, 40 insertions, 82 deletions
diff --git a/src/core/SkMaskBlurFilter.cpp b/src/core/SkMaskBlurFilter.cpp
index 594760a35c..7674bddf41 100644
--- a/src/core/SkMaskBlurFilter.cpp
+++ b/src/core/SkMaskBlurFilter.cpp
@@ -11,6 +11,7 @@
#include "SkMalloc.h"
#include "SkMaskBlurFilter.h"
#include "SkNx.h"
+#include "SkTemplates.h"
#include <cmath>
#include <climits>
@@ -959,63 +960,6 @@ static SkIPoint small_blur(double sigmaX, double sigmaY, const SkMask& src, SkMa
return {radiusX, radiusY};
}
-struct AlphaIterA1 {
- AlphaIterA1(const uint8_t* ptr, int offset) : fPtr(ptr), fOffset(7 - offset) {}
- AlphaIterA1(const AlphaIterA1& that) : fPtr(that.fPtr), fOffset(that.fOffset) {}
- AlphaIterA1& operator++() {
- if (0 < fOffset ) {
- --fOffset;
- } else {
- ++fPtr;
- fOffset = 7;
- }
- return *this;
- }
- AlphaIterA1& operator--() {
- if (fOffset < 7) {
- ++fOffset;
- } else {
- --fPtr;
- fOffset = 0;
- }
- return *this;
- }
- uint8_t operator*() { return ((*fPtr) >> fOffset) & 1 ? 0xFF : 0; }
- bool operator<(const AlphaIterA1& that) {
- return fPtr < that.fPtr || (fPtr == that.fPtr && fOffset > that.fOffset);
- }
- const uint8_t* fPtr;
- int fOffset;
-};
-
-using AlphaIterA8 = uint8_t*;
-
-struct AlphaIterARGB {
- AlphaIterARGB(const uint32_t* ptr) : fPtr(ptr) {}
- AlphaIterARGB(const AlphaIterARGB& that) : fPtr(that.fPtr) {}
- AlphaIterARGB& operator++() { ++fPtr; return *this; }
- AlphaIterARGB& operator--() { --fPtr; return *this; }
- uint8_t operator*() { return SkGetPackedA32(*fPtr); }
- bool operator<(const AlphaIterARGB& that) { return fPtr < that.fPtr; }
- const uint32_t* fPtr;
-};
-
-struct AlphaIterLCD {
- AlphaIterLCD(const uint16_t* ptr) : fPtr(ptr) {}
- AlphaIterLCD(const AlphaIterLCD& that) : fPtr(that.fPtr) {}
- AlphaIterLCD& operator++() { ++fPtr; return *this; }
- AlphaIterLCD& operator--() { --fPtr; return *this; }
- uint8_t operator*() {
- unsigned packed = *fPtr;
- unsigned r = SkPacked16ToR32(packed);
- unsigned g = SkPacked16ToG32(packed);
- unsigned b = SkPacked16ToB32(packed);
- return (r + g + b) / 3;
- }
- bool operator<(const AlphaIterLCD& that) { return fPtr < that.fPtr; }
- const uint16_t* fPtr;
-};
-
} // namespace
// TODO: assuming sigmaW = sigmaH. Allow different sigmas. Right now the
@@ -1062,31 +1006,45 @@ SkIPoint SkMaskBlurFilter::blur(const SkMask& src, SkMask* dst) const {
// Blur horizontally, and transpose.
const PlanGauss::Scan& scanW = planW.makeBlurScan(srcW, buffer);
- for (int y = 0; y < srcH; y++) {
- uint8_t* srcStart = &src.fImage[y * src.fRowBytes];
- auto tmpStart = &tmp[y];
- switch (src.fFormat) {
- case SkMask::kBW_Format:
- scanW.blur(AlphaIterA1(srcStart, 0), AlphaIterA1(srcStart + (srcW / 8), srcW % 8),
- tmpStart, tmpW, tmpStart + tmpW * tmpH);
- break;
- case SkMask::kA8_Format:
- scanW.blur(AlphaIterA8(srcStart), AlphaIterA8(srcStart + srcW),
- tmpStart, tmpW, tmpStart + tmpW * tmpH);
- break;
- case SkMask::kARGB32_Format: {
- const uint32_t* argbStart = reinterpret_cast<const uint32_t*>(srcStart);
- scanW.blur(AlphaIterARGB(argbStart), AlphaIterARGB(argbStart + srcW),
- tmpStart, tmpW, tmpStart + tmpW * tmpH);
- } break;
- case SkMask::kLCD16_Format: {
- const uint16_t* lcdStart = reinterpret_cast<const uint16_t*>(srcStart);
- scanW.blur(AlphaIterLCD(lcdStart), AlphaIterLCD(lcdStart + srcW),
- tmpStart, tmpW, tmpStart + tmpW * tmpH);
- } break;
- default:
- SK_ABORT("Unhandled format.");
- }
+ switch (src.fFormat) {
+ case SkMask::kBW_Format: {
+ const uint8_t* bwStart = src.fImage;
+ auto start = SkMask::AlphaIter<SkMask::kBW_Format>(bwStart, 0);
+ auto end = SkMask::AlphaIter<SkMask::kBW_Format>(bwStart + (srcW / 8), srcW % 8);
+ for (int y = 0; y < srcH; ++y, start >>= src.fRowBytes, end >>= src.fRowBytes) {
+ auto tmpStart = &tmp[y];
+ scanW.blur(start, end, tmpStart, tmpW, tmpStart + tmpW * tmpH);
+ }
+ } break;
+ case SkMask::kA8_Format: {
+ const uint8_t* a8Start = src.fImage;
+ auto start = SkMask::AlphaIter<SkMask::kA8_Format>(a8Start);
+ auto end = SkMask::AlphaIter<SkMask::kA8_Format>(a8Start + srcW);
+ for (int y = 0; y < srcH; ++y, start >>= src.fRowBytes, end >>= src.fRowBytes) {
+ auto tmpStart = &tmp[y];
+ scanW.blur(start, end, tmpStart, tmpW, tmpStart + tmpW * tmpH);
+ }
+ } break;
+ case SkMask::kARGB32_Format: {
+ const uint32_t* argbStart = reinterpret_cast<const uint32_t*>(src.fImage);
+ auto start = SkMask::AlphaIter<SkMask::kARGB32_Format>(argbStart);
+ auto end = SkMask::AlphaIter<SkMask::kARGB32_Format>(argbStart + srcW);
+ for (int y = 0; y < srcH; ++y, start >>= src.fRowBytes, end >>= src.fRowBytes) {
+ auto tmpStart = &tmp[y];
+ scanW.blur(start, end, tmpStart, tmpW, tmpStart + tmpW * tmpH);
+ }
+ } break;
+ case SkMask::kLCD16_Format: {
+ const uint16_t* lcdStart = reinterpret_cast<const uint16_t*>(src.fImage);
+ auto start = SkMask::AlphaIter<SkMask::kLCD16_Format>(lcdStart);
+ auto end = SkMask::AlphaIter<SkMask::kLCD16_Format>(lcdStart + srcW);
+ for (int y = 0; y < srcH; ++y, start >>= src.fRowBytes, end >>= src.fRowBytes) {
+ auto tmpStart = &tmp[y];
+ scanW.blur(start, end, tmpStart, tmpW, tmpStart + tmpW * tmpH);
+ }
+ } break;
+ default:
+ SK_ABORT("Unhandled format.");
}
// Blur vertically (scan in memory order because of the transposition),