blob: ccee2fd2f3a49b2722a5bf569c84e258dcf107dc [file] [log] [blame]
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +00001/*
2 * Copyright 2012 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkMatrixConvolutionImageFilter_DEFINED
9#define SkMatrixConvolutionImageFilter_DEFINED
10
Cary Clark4dc5a452018-05-21 11:56:57 -040011#include "SkFlattenable.h"
senorblanco@chromium.org377c14a2013-02-04 22:57:21 +000012#include "SkImageFilter.h"
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000013#include "SkScalar.h"
14#include "SkSize.h"
15#include "SkPoint.h"
16
senorblanco32eaa892016-04-21 06:49:15 -070017class SkBitmap;
18
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000019/*! \class SkMatrixConvolutionImageFilter
20 Matrix convolution image filter. This filter applies an NxM image
21 processing kernel to a given input image. This can be used to produce
22 effects such as sharpening, blurring, edge detection, etc.
23 */
24
senorblanco@chromium.org377c14a2013-02-04 22:57:21 +000025class SK_API SkMatrixConvolutionImageFilter : public SkImageFilter {
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000026public:
27 /*! \enum TileMode */
28 enum TileMode {
joshualittac977922014-07-22 09:52:11 -070029 kClamp_TileMode = 0, /*!< Clamp to the image's edge pixels. */
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000030 kRepeat_TileMode, /*!< Wrap around to the image's opposite edge. */
31 kClampToBlack_TileMode, /*!< Fill with transparent black. */
Robert Phillipsbee27322018-01-23 09:58:18 -050032 kLast_TileMode = kClampToBlack_TileMode,
33
34 // TODO: remove kMax - it is non-standard but used by Chromium!
joshualittac977922014-07-22 09:52:11 -070035 kMax_TileMode = kClampToBlack_TileMode
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000036 };
37
robertphillipsdada4dd2016-04-13 04:54:36 -070038 ~SkMatrixConvolutionImageFilter() override;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000039
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +000040 /** Construct a matrix convolution image filter.
41 @param kernelSize The kernel size in pixels, in each dimension (N by M).
42 @param kernel The image processing kernel. Must contain N * M
43 elements, in row order.
44 @param gain A scale factor applied to each pixel after
45 convolution. This can be used to normalize the
46 kernel, if it does not sum to 1.
47 @param bias A bias factor added to each pixel after convolution.
48 @param kernelOffset An offset applied to each pixel coordinate before
49 convolution. This can be used to center the kernel
50 over the image (e.g., a 3x3 kernel should have an
51 offset of {1, 1}).
52 @param tileMode How accesses outside the image are treated. (@see
53 TileMode).
54 @param convolveAlpha If true, all channels are convolved. If false,
55 only the RGB channels are convolved, and
56 alpha is copied from the source image.
57 @param input The input image filter. If NULL, the src bitmap
58 passed to filterImage() is used instead.
59 @param cropRect The rectangle to which the output processing will be limited.
60 */
robertphillipsef6a47b2016-04-08 08:01:20 -070061 static sk_sp<SkImageFilter> Make(const SkISize& kernelSize,
62 const SkScalar* kernel,
63 SkScalar gain,
64 SkScalar bias,
65 const SkIPoint& kernelOffset,
66 TileMode tileMode,
67 bool convolveAlpha,
68 sk_sp<SkImageFilter> input,
69 const CropRect* cropRect = nullptr);
70
Cary Clark4dc5a452018-05-21 11:56:57 -040071 Factory getFactory() const override { return CreateProc; }
robertphillipsef6a47b2016-04-08 08:01:20 -070072
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000073protected:
commit-bot@chromium.orgbd0be252014-05-15 15:40:41 +000074 SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
75 const SkScalar* kernel,
76 SkScalar gain,
77 SkScalar bias,
78 const SkIPoint& kernelOffset,
79 TileMode tileMode,
80 bool convolveAlpha,
robertphillipsef6a47b2016-04-08 08:01:20 -070081 sk_sp<SkImageFilter> input,
senorblanco24e06d52015-03-18 12:11:33 -070082 const CropRect* cropRect);
mtklein36352bf2015-03-25 18:17:31 -070083 void flatten(SkWriteBuffer&) const override;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000084
robertphillipsdada4dd2016-04-13 04:54:36 -070085 sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
86 SkIPoint* offset) const override;
Matt Sarett6d72ed92017-04-10 16:35:33 -040087 sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
Robert Phillips12078432018-05-17 11:17:39 -040088 SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix& ctm,
89 MapDirection, const SkIRect* inputRect) const override;
senorblanco6db0a7b2016-04-01 16:41:10 -070090 bool affectsTransparentBlack() const override;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000091
92private:
Cary Clark4dc5a452018-05-21 11:56:57 -040093 static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
94 friend class SkFlattenable::PrivateInitializer;
95
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +000096 SkISize fKernelSize;
97 SkScalar* fKernel;
98 SkScalar fGain;
99 SkScalar fBias;
commit-bot@chromium.orgcac5fd52014-03-10 10:51:58 +0000100 SkIPoint fKernelOffset;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +0000101 TileMode fTileMode;
senorblanco@chromium.org8640d502012-09-25 14:32:42 +0000102 bool fConvolveAlpha;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +0000103
senorblanco@chromium.org8640d502012-09-25 14:32:42 +0000104 template <class PixelFetcher, bool convolveAlpha>
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000105 void filterPixels(const SkBitmap& src,
106 SkBitmap* result,
Robert Phillips12078432018-05-17 11:17:39 -0400107 SkIVector& offset,
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000108 const SkIRect& rect,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +0000109 const SkIRect& bounds) const;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +0000110 template <class PixelFetcher>
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000111 void filterPixels(const SkBitmap& src,
112 SkBitmap* result,
Robert Phillips12078432018-05-17 11:17:39 -0400113 SkIVector& offset,
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000114 const SkIRect& rect,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +0000115 const SkIRect& bounds) const;
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000116 void filterInteriorPixels(const SkBitmap& src,
117 SkBitmap* result,
Robert Phillips12078432018-05-17 11:17:39 -0400118 SkIVector& offset,
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000119 const SkIRect& rect,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +0000120 const SkIRect& bounds) const;
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000121 void filterBorderPixels(const SkBitmap& src,
122 SkBitmap* result,
Robert Phillips12078432018-05-17 11:17:39 -0400123 SkIVector& offset,
senorblanco@chromium.org7938bae2013-10-18 20:08:14 +0000124 const SkIRect& rect,
commit-bot@chromium.orgae761f72014-02-05 22:32:02 +0000125 const SkIRect& bounds) const;
robertphillipsef6a47b2016-04-08 08:01:20 -0700126
127 typedef SkImageFilter INHERITED;
senorblanco@chromium.org5faa2dc2012-09-18 20:32:34 +0000128};
129
130#endif