• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #include "SkFlattenable.h"
12 #include "SkImageFilter.h"
13 #include "SkScalar.h"
14 #include "SkSize.h"
15 #include "SkPoint.h"
16 
17 class SkBitmap;
18 
19 /*! \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 
25 class SK_API SkMatrixConvolutionImageFilter : public SkImageFilter {
26 public:
27     /*! \enum TileMode */
28     enum TileMode {
29       kClamp_TileMode = 0,         /*!< Clamp to the image's edge pixels. */
30       kRepeat_TileMode,        /*!< Wrap around to the image's opposite edge. */
31       kClampToBlack_TileMode,  /*!< Fill with transparent black. */
32       kLast_TileMode = kClampToBlack_TileMode,
33 
34       // TODO: remove kMax - it is non-standard but used by Chromium!
35       kMax_TileMode = kClampToBlack_TileMode
36     };
37 
38     ~SkMatrixConvolutionImageFilter() override;
39 
40     /** 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     */
61     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 
71 protected:
72     SkMatrixConvolutionImageFilter(const SkISize& kernelSize,
73                                    const SkScalar* kernel,
74                                    SkScalar gain,
75                                    SkScalar bias,
76                                    const SkIPoint& kernelOffset,
77                                    TileMode tileMode,
78                                    bool convolveAlpha,
79                                    sk_sp<SkImageFilter> input,
80                                    const CropRect* cropRect);
81     void flatten(SkWriteBuffer&) const override;
82 
83     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
84                                         SkIPoint* offset) const override;
85     sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
86     SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix& ctm,
87                                MapDirection, const SkIRect* inputRect) const override;
88     bool affectsTransparentBlack() const override;
89 
90 private:
91     SK_FLATTENABLE_HOOKS(SkMatrixConvolutionImageFilter)
92 
93     SkISize   fKernelSize;
94     SkScalar* fKernel;
95     SkScalar  fGain;
96     SkScalar  fBias;
97     SkIPoint  fKernelOffset;
98     TileMode  fTileMode;
99     bool      fConvolveAlpha;
100 
101     template <class PixelFetcher, bool convolveAlpha>
102     void filterPixels(const SkBitmap& src,
103                       SkBitmap* result,
104                       SkIVector& offset,
105                       const SkIRect& rect,
106                       const SkIRect& bounds) const;
107     template <class PixelFetcher>
108     void filterPixels(const SkBitmap& src,
109                       SkBitmap* result,
110                       SkIVector& offset,
111                       const SkIRect& rect,
112                       const SkIRect& bounds) const;
113     void filterInteriorPixels(const SkBitmap& src,
114                               SkBitmap* result,
115                               SkIVector& offset,
116                               const SkIRect& rect,
117                               const SkIRect& bounds) const;
118     void filterBorderPixels(const SkBitmap& src,
119                             SkBitmap* result,
120                             SkIVector& offset,
121                             const SkIRect& rect,
122                             const SkIRect& bounds) const;
123 
124     typedef SkImageFilter INHERITED;
125 };
126 
127 #endif
128