14f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/*
24f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Copyright 2012 The Android Open Source Project
34f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger *
44f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
54f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * found in the LICENSE file.
64f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */
74f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
84f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkMorphologyImageFilter.h"
94f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "SkColorPriv.h"
104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
114f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer)
124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger  : INHERITED(buffer) {
134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fRadius.fWidth = buffer.readScalar();
144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    fRadius.fHeight = buffer.readScalar();
154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
174f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, int radiusY)
184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    : fRadius(SkISize::Make(radiusX, radiusY)) {
194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergervoid SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) {
234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    this->INHERITED::flatten(buffer);
244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    buffer.writeScalar(fRadius.fWidth);
254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    buffer.writeScalar(fRadius.fHeight);
264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void erode(const SkPMColor* src, SkPMColor* dst,
294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                  int radius, int width, int height,
304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                  int srcStrideX, int srcStrideY,
314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                  int dstStrideX, int dstStrideY)
324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const SkPMColor* upperSrc = src + SkMin32(radius, width - 1) * srcStrideX;
344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    for (int x = 0; x < width; ++x) {
354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const SkPMColor* lp = src;
364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const SkPMColor* up = upperSrc;
374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        SkPMColor* dptr = dst;
384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        for (int y = 0; y < height; ++y) {
394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            int minB = 255, minG = 255, minR = 255, minA = 255;
404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int b = SkGetPackedB32(*p);
424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int g = SkGetPackedG32(*p);
434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int r = SkGetPackedR32(*p);
444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int a = SkGetPackedA32(*p);
454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (b < minB) minB = b;
464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (g < minG) minG = g;
474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (r < minR) minR = r;
484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (a < minA) minA = a;
494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            }
504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            *dptr = SkPackARGB32(minA, minR, minG, minB);
514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            dptr += dstStrideY;
524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            lp += srcStrideY;
534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            up += srcStrideY;
544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (x >= radius) src += srcStrideX;
564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (x + radius < width - 1) upperSrc += srcStrideX;
574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dst += dstStrideX;
584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void erodeX(const SkBitmap& src, SkBitmap* dst, int radiusX)
624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    erode(src.getAddr32(0, 0), dst->getAddr32(0, 0),
644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger          radiusX, src.width(), src.height(),
654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger          1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels());
664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void erodeY(const SkBitmap& src, SkBitmap* dst, int radiusY)
694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    erode(src.getAddr32(0, 0), dst->getAddr32(0, 0),
714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger          radiusY, src.height(), src.width(),
724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger          src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1);
734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void dilate(const SkPMColor* src, SkPMColor* dst,
764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                   int radius, int width, int height,
774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                   int srcStrideX, int srcStrideY,
784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                   int dstStrideX, int dstStrideY)
794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    const SkPMColor* upperSrc = src + SkMin32(radius, width - 1) * srcStrideX;
814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    for (int x = 0; x < width; ++x) {
824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const SkPMColor* lp = src;
834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        const SkPMColor* up = upperSrc;
844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        SkPMColor* dptr = dst;
854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        for (int y = 0; y < height; ++y) {
864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            int maxB = 0, maxG = 0, maxR = 0, maxA = 0;
874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            for (const SkPMColor* p = lp; p <= up; p += srcStrideX) {
884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int b = SkGetPackedB32(*p);
894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int g = SkGetPackedG32(*p);
904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int r = SkGetPackedR32(*p);
914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                int a = SkGetPackedA32(*p);
924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (b > maxB) maxB = b;
934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (g > maxG) maxG = g;
944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (r > maxR) maxR = r;
954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                if (a > maxA) maxA = a;
964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            }
974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            *dptr = SkPackARGB32(maxA, maxR, maxG, maxB);
984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            dptr += dstStrideY;
994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            lp += srcStrideY;
1004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger            up += srcStrideY;
1014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        }
1024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (x >= radius) src += srcStrideX;
1034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        if (x + radius < width - 1) upperSrc += srcStrideX;
1044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dst += dstStrideX;
1054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
1074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void dilateX(const SkBitmap& src, SkBitmap* dst, int radiusX)
1094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
1104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dilate(src.getAddr32(0, 0), dst->getAddr32(0, 0),
1114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger           radiusX, src.width(), src.height(),
1124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger           1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels());
1134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
1144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerstatic void dilateY(const SkBitmap& src, SkBitmap* dst, int radiusY)
1164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger{
1174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dilate(src.getAddr32(0, 0), dst->getAddr32(0, 0),
1184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger           radiusY, src.height(), src.width(),
1194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger           src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1);
1204f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
1214f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1224f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkErodeImageFilter::onFilterImage(Proxy*,
1234f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                       const SkBitmap& src, const SkMatrix&,
1244f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                       SkBitmap* dst, SkIPoint*) {
1254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (src.config() != SkBitmap::kARGB_8888_Config) {
1264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1274f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1284f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1294f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkAutoLockPixels alp(src);
1304f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!src.getPixels()) {
1314f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1324f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1334f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1344f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dst->setConfig(src.config(), src.width(), src.height());
1354f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dst->allocPixels();
1364f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1374f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int width = radius().width();
1384f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int height = radius().height();
1394f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1404f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width < 0 || height < 0) {
1414f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1424f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1434f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1444f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width == 0 && height == 0) {
1454f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        src.copyTo(dst, dst->config());
1464f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return true;
1474f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1484f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1494f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkBitmap temp;
1504f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    temp.setConfig(dst->config(), dst->width(), dst->height());
1514f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!temp.allocPixels()) {
1524f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1534f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1544f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1554f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width > 0 && height > 0) {
1564f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        erodeX(src, &temp, width);
1574f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        erodeY(temp, dst, height);
1584f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (width > 0) {
1594f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        erodeX(src, dst, width);
1604f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (height > 0) {
1614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        erodeY(src, dst, height);
1624f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1634f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return true;
1644f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
1654f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDilateImageFilter::onFilterImage(Proxy*,
1674f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                        const SkBitmap& src, const SkMatrix&,
1684f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger                                        SkBitmap* dst, SkIPoint*) {
1694f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (src.config() != SkBitmap::kARGB_8888_Config) {
1704f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1714f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1724f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1734f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkAutoLockPixels alp(src);
1744f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!src.getPixels()) {
1754f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dst->setConfig(src.config(), src.width(), src.height());
1794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    dst->allocPixels();
1804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int width = radius().width();
1824f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    int height = radius().height();
1834f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1844f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width < 0 || height < 0) {
1854f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1864f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1874f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1884f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width == 0 && height == 0) {
1894f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        src.copyTo(dst, dst->config());
1904f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return true;
1914f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1924f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1934f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    SkBitmap temp;
1944f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    temp.setConfig(dst->config(), dst->width(), dst->height());
1954f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (!temp.allocPixels()) {
1964f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        return false;
1974f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
1984f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
1994f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    if (width > 0 && height > 0) {
2004f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dilateX(src, &temp, width);
2014f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dilateY(temp, dst, height);
2024f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (width > 0) {
2034f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dilateX(src, dst, width);
2044f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    } else if (height > 0) {
2054f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger        dilateY(src, dst, height);
2064f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    }
2074f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return true;
2084f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
2094f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2104f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkDilateImageFilter::asADilate(SkISize* radius) const {
2114f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    *radius = this->radius();
2124f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return true;
2134f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
2144f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2154f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool SkErodeImageFilter::asAnErode(SkISize* radius) const {
2164f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    *radius = this->radius();
2174f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger    return true;
2184f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger}
2194f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger
2204f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkDilateImageFilter)
2214f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkErodeImageFilter)
222