|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
|
3 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef MOZILLA_GFX_BLUR_H_ |
|
8 #define MOZILLA_GFX_BLUR_H_ |
|
9 |
|
10 #include "mozilla/gfx/Rect.h" |
|
11 #include "mozilla/gfx/Point.h" |
|
12 #include "mozilla/CheckedInt.h" |
|
13 |
|
14 namespace mozilla { |
|
15 namespace gfx { |
|
16 |
|
17 #ifdef _MSC_VER |
|
18 #pragma warning( disable : 4251 ) |
|
19 #endif |
|
20 |
|
21 /** |
|
22 * Implementation of a triple box blur approximation of a Gaussian blur. |
|
23 * |
|
24 * A Gaussian blur is good for blurring because, when done independently |
|
25 * in the horizontal and vertical directions, it matches the result that |
|
26 * would be obtained using a different (rotated) set of axes. A triple |
|
27 * box blur is a very close approximation of a Gaussian. |
|
28 * |
|
29 * This is a "service" class; the constructors set up all the information |
|
30 * based on the values and compute the minimum size for an 8-bit alpha |
|
31 * channel context. |
|
32 * The callers are responsible for creating and managing the backing surface |
|
33 * and passing the pointer to the data to the Blur() method. This class does |
|
34 * not retain the pointer to the data outside of the Blur() call. |
|
35 * |
|
36 * A spread N makes each output pixel the maximum value of all source |
|
37 * pixels within a square of side length 2N+1 centered on the output pixel. |
|
38 */ |
|
39 class GFX2D_API AlphaBoxBlur |
|
40 { |
|
41 public: |
|
42 |
|
43 /** Constructs a box blur and computes the backing surface size. |
|
44 * |
|
45 * @param aRect The coordinates of the surface to create in device units. |
|
46 * |
|
47 * @param aBlurRadius The blur radius in pixels. This is the radius of the |
|
48 * entire (triple) kernel function. Each individual box blur has radius |
|
49 * approximately 1/3 this value, or diameter approximately 2/3 this value. |
|
50 * This parameter should nearly always be computed using CalculateBlurRadius, |
|
51 * below. |
|
52 * |
|
53 * @param aDirtyRect A pointer to a dirty rect, measured in device units, if |
|
54 * available. This will be used for optimizing the blur operation. It is |
|
55 * safe to pass nullptr here. |
|
56 * |
|
57 * @param aSkipRect A pointer to a rect, measured in device units, that |
|
58 * represents an area where blurring is unnecessary and shouldn't be done for |
|
59 * speed reasons. It is safe to pass nullptr here. |
|
60 */ |
|
61 AlphaBoxBlur(const Rect& aRect, |
|
62 const IntSize& aSpreadRadius, |
|
63 const IntSize& aBlurRadius, |
|
64 const Rect* aDirtyRect, |
|
65 const Rect* aSkipRect); |
|
66 |
|
67 AlphaBoxBlur(const Rect& aRect, |
|
68 int32_t aStride, |
|
69 float aSigmaX, |
|
70 float aSigmaY); |
|
71 |
|
72 ~AlphaBoxBlur(); |
|
73 |
|
74 /** |
|
75 * Return the size, in pixels, of the 8-bit alpha surface we'd use. |
|
76 */ |
|
77 IntSize GetSize(); |
|
78 |
|
79 /** |
|
80 * Return the stride, in bytes, of the 8-bit alpha surface we'd use. |
|
81 */ |
|
82 int32_t GetStride(); |
|
83 |
|
84 /** |
|
85 * Returns the device-space rectangle the 8-bit alpha surface covers. |
|
86 */ |
|
87 IntRect GetRect(); |
|
88 |
|
89 /** |
|
90 * Return a pointer to a dirty rect, as passed in to the constructor, or nullptr |
|
91 * if none was passed in. |
|
92 */ |
|
93 Rect* GetDirtyRect(); |
|
94 |
|
95 /** |
|
96 * Return the minimum buffer size that should be given to Blur() method. If |
|
97 * zero, the class is not properly setup for blurring. Note that this |
|
98 * includes the extra three bytes on top of the stride*width, where something |
|
99 * like gfxImageSurface::GetDataSize() would report without it, even if it |
|
100 * happens to have the extra bytes. |
|
101 */ |
|
102 size_t GetSurfaceAllocationSize() const; |
|
103 |
|
104 /** |
|
105 * Perform the blur in-place on the surface backed by specified 8-bit |
|
106 * alpha surface data. The size must be at least that returned by |
|
107 * GetSurfaceAllocationSize() or bad things will happen. |
|
108 */ |
|
109 void Blur(uint8_t* aData); |
|
110 |
|
111 /** |
|
112 * Calculates a blur radius that, when used with box blur, approximates a |
|
113 * Gaussian blur with the given standard deviation. The result of this |
|
114 * function should be used as the aBlurRadius parameter to AlphaBoxBlur's |
|
115 * constructor, above. |
|
116 */ |
|
117 static IntSize CalculateBlurRadius(const Point& aStandardDeviation); |
|
118 |
|
119 private: |
|
120 |
|
121 void BoxBlur_C(uint8_t* aData, |
|
122 int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe, |
|
123 int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride); |
|
124 void BoxBlur_SSE2(uint8_t* aData, |
|
125 int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe, |
|
126 int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride); |
|
127 |
|
128 static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal); |
|
129 |
|
130 /** |
|
131 * A rect indicating the area where blurring is unnecessary, and the blur |
|
132 * algorithm should skip over it. |
|
133 */ |
|
134 IntRect mSkipRect; |
|
135 |
|
136 /** |
|
137 * The device-space rectangle the the backing 8-bit alpha surface covers. |
|
138 */ |
|
139 IntRect mRect; |
|
140 |
|
141 /** |
|
142 * A copy of the dirty rect passed to the constructor. This will only be valid if |
|
143 * mHasDirtyRect is true. |
|
144 */ |
|
145 Rect mDirtyRect; |
|
146 |
|
147 /** |
|
148 * The spread radius, in pixels. |
|
149 */ |
|
150 IntSize mSpreadRadius; |
|
151 |
|
152 /** |
|
153 * The blur radius, in pixels. |
|
154 */ |
|
155 IntSize mBlurRadius; |
|
156 |
|
157 /** |
|
158 * The stride of the data passed to Blur() |
|
159 */ |
|
160 int32_t mStride; |
|
161 |
|
162 /** |
|
163 * The minimum size of the buffer needed for the Blur() operation. |
|
164 */ |
|
165 size_t mSurfaceAllocationSize; |
|
166 |
|
167 /** |
|
168 * Whether mDirtyRect contains valid data. |
|
169 */ |
|
170 bool mHasDirtyRect; |
|
171 }; |
|
172 |
|
173 } |
|
174 } |
|
175 |
|
176 #endif /* MOZILLA_GFX_BLUR_H_ */ |