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_FILTERPROCESSING_H_
8 #define _MOZILLA_GFX_FILTERPROCESSING_H_
9 
10 #include "2D.h"
11 #include "Filters.h"
12 
13 namespace mozilla {
14 namespace gfx {
15 
16 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_B = 0;
17 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_G = 1;
18 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_R = 2;
19 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_A = 3;
20 
21 class FilterProcessing {
22  public:
23   // Fast approximate division by 255. It has the property that
24   // for all 0 <= v <= 255*255, FastDivideBy255(v) == v/255.
25   // But it only uses two adds and two shifts instead of an
26   // integer division (which is expensive on many processors).
27   template <class B, class A>
FastDivideBy255(A v)28   static B FastDivideBy255(A v) {
29     return ((v << 8) + v + 255) >> 16;
30   }
31 
32   static already_AddRefed<DataSourceSurface> ExtractAlpha(
33       DataSourceSurface* aSource);
34   static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8(
35       SourceSurface* aSurface);
36   static already_AddRefed<DataSourceSurface> ApplyBlending(
37       DataSourceSurface* aInput1, DataSourceSurface* aInput2,
38       BlendMode aBlendMode);
39   static void ApplyMorphologyHorizontal(uint8_t* aSourceData,
40                                         int32_t aSourceStride,
41                                         uint8_t* aDestData, int32_t aDestStride,
42                                         const IntRect& aDestRect,
43                                         int32_t aRadius,
44                                         MorphologyOperator aOperator);
45   static void ApplyMorphologyVertical(uint8_t* aSourceData,
46                                       int32_t aSourceStride, uint8_t* aDestData,
47                                       int32_t aDestStride,
48                                       const IntRect& aDestRect, int32_t aRadius,
49                                       MorphologyOperator aOperator);
50   static already_AddRefed<DataSourceSurface> ApplyColorMatrix(
51       DataSourceSurface* aInput, const Matrix5x4& aMatrix);
52   static void ApplyComposition(DataSourceSurface* aSource,
53                                DataSourceSurface* aDest,
54                                CompositeOperator aOperator);
55   static void SeparateColorChannels(DataSourceSurface* aSource,
56                                     RefPtr<DataSourceSurface>& aChannel0,
57                                     RefPtr<DataSourceSurface>& aChannel1,
58                                     RefPtr<DataSourceSurface>& aChannel2,
59                                     RefPtr<DataSourceSurface>& aChannel3);
60   static already_AddRefed<DataSourceSurface> CombineColorChannels(
61       DataSourceSurface* aChannel0, DataSourceSurface* aChannel1,
62       DataSourceSurface* aChannel2, DataSourceSurface* aChannel3);
63   static void DoPremultiplicationCalculation(const IntSize& aSize,
64                                              uint8_t* aTargetData,
65                                              int32_t aTargetStride,
66                                              uint8_t* aSourceData,
67                                              int32_t aSourceStride);
68   static void DoUnpremultiplicationCalculation(const IntSize& aSize,
69                                                uint8_t* aTargetData,
70                                                int32_t aTargetStride,
71                                                uint8_t* aSourceData,
72                                                int32_t aSourceStride);
73   static void DoOpacityCalculation(const IntSize& aSize, uint8_t* aTargetData,
74                                    int32_t aTargetStride, uint8_t* aSourceData,
75                                    int32_t aSourceStride, Float aValue);
76   static void DoOpacityCalculationA8(const IntSize& aSize, uint8_t* aTargetData,
77                                      int32_t aTargetStride,
78                                      uint8_t* aSourceData,
79                                      int32_t aSourceStride, Float aValue);
80   static already_AddRefed<DataSourceSurface> RenderTurbulence(
81       const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency,
82       int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch,
83       const Rect& aTileRect);
84   static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine(
85       DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1,
86       Float aK2, Float aK3, Float aK4);
87 
88  protected:
89   static void ExtractAlpha_Scalar(const IntSize& size, uint8_t* sourceData,
90                                   int32_t sourceStride, uint8_t* alphaData,
91                                   int32_t alphaStride);
92   static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8_Scalar(
93       SourceSurface* aSurface);
94   static void ApplyMorphologyHorizontal_Scalar(
95       uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData,
96       int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius,
97       MorphologyOperator aOperator);
98   static void ApplyMorphologyVertical_Scalar(
99       uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData,
100       int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius,
101       MorphologyOperator aOperator);
102   static already_AddRefed<DataSourceSurface> ApplyColorMatrix_Scalar(
103       DataSourceSurface* aInput, const Matrix5x4& aMatrix);
104   static void ApplyComposition_Scalar(DataSourceSurface* aSource,
105                                       DataSourceSurface* aDest,
106                                       CompositeOperator aOperator);
107 
108   static void SeparateColorChannels_Scalar(
109       const IntSize& size, uint8_t* sourceData, int32_t sourceStride,
110       uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data,
111       uint8_t* channel3Data, int32_t channelStride);
112   static void CombineColorChannels_Scalar(
113       const IntSize& size, int32_t resultStride, uint8_t* resultData,
114       int32_t channelStride, uint8_t* channel0Data, uint8_t* channel1Data,
115       uint8_t* channel2Data, uint8_t* channel3Data);
116   static void DoPremultiplicationCalculation_Scalar(const IntSize& aSize,
117                                                     uint8_t* aTargetData,
118                                                     int32_t aTargetStride,
119                                                     uint8_t* aSourceData,
120                                                     int32_t aSourceStride);
121   static void DoUnpremultiplicationCalculation_Scalar(const IntSize& aSize,
122                                                       uint8_t* aTargetData,
123                                                       int32_t aTargetStride,
124                                                       uint8_t* aSourceData,
125                                                       int32_t aSourceStride);
126   static void DoOpacityCalculation_Scalar(const IntSize& aSize,
127                                           uint8_t* aTargetData,
128                                           int32_t aTargetStride,
129                                           uint8_t* aSourceData,
130                                           int32_t aSourceStride, Float aValue);
131   static void DoOpacityCalculationA8_Scalar(
132       const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride,
133       uint8_t* aSourceData, int32_t aSourceStride, Float aValue);
134   static already_AddRefed<DataSourceSurface> RenderTurbulence_Scalar(
135       const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency,
136       int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch,
137       const Rect& aTileRect);
138   static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine_Scalar(
139       DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1,
140       Float aK2, Float aK3, Float aK4);
141 
142 #ifdef USE_SSE2
143   static void ExtractAlpha_SSE2(const IntSize& size, uint8_t* sourceData,
144                                 int32_t sourceStride, uint8_t* alphaData,
145                                 int32_t alphaStride);
146   static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8_SSE2(
147       SourceSurface* aSurface);
148   static already_AddRefed<DataSourceSurface> ApplyBlending_SSE2(
149       DataSourceSurface* aInput1, DataSourceSurface* aInput2,
150       BlendMode aBlendMode);
151   static void ApplyMorphologyHorizontal_SSE2(
152       uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData,
153       int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius,
154       MorphologyOperator aOperator);
155   static void ApplyMorphologyVertical_SSE2(
156       uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData,
157       int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius,
158       MorphologyOperator aOperator);
159   static already_AddRefed<DataSourceSurface> ApplyColorMatrix_SSE2(
160       DataSourceSurface* aInput, const Matrix5x4& aMatrix);
161   static void ApplyComposition_SSE2(DataSourceSurface* aSource,
162                                     DataSourceSurface* aDest,
163                                     CompositeOperator aOperator);
164   static void SeparateColorChannels_SSE2(
165       const IntSize& size, uint8_t* sourceData, int32_t sourceStride,
166       uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data,
167       uint8_t* channel3Data, int32_t channelStride);
168   static void CombineColorChannels_SSE2(
169       const IntSize& size, int32_t resultStride, uint8_t* resultData,
170       int32_t channelStride, uint8_t* channel0Data, uint8_t* channel1Data,
171       uint8_t* channel2Data, uint8_t* channel3Data);
172   static void DoPremultiplicationCalculation_SSE2(const IntSize& aSize,
173                                                   uint8_t* aTargetData,
174                                                   int32_t aTargetStride,
175                                                   uint8_t* aSourceData,
176                                                   int32_t aSourceStride);
177   static void DoUnpremultiplicationCalculation_SSE2(const IntSize& aSize,
178                                                     uint8_t* aTargetData,
179                                                     int32_t aTargetStride,
180                                                     uint8_t* aSourceData,
181                                                     int32_t aSourceStride);
182   static void DoOpacityCalculation_SSE2(const IntSize& aSize,
183                                         uint8_t* aTargetData,
184                                         int32_t aTargetStride,
185                                         uint8_t* aSourceData,
186                                         int32_t aSourceStride, Float aValue);
187   static already_AddRefed<DataSourceSurface> RenderTurbulence_SSE2(
188       const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency,
189       int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch,
190       const Rect& aTileRect);
191   static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine_SSE2(
192       DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1,
193       Float aK2, Float aK3, Float aK4);
194 #endif
195 };
196 
197 // Constant-time max and min functions for unsigned arguments
umax(unsigned a,unsigned b)198 static inline unsigned umax(unsigned a, unsigned b) {
199   return a - ((a - b) & -(a < b));
200 }
201 
umin(unsigned a,unsigned b)202 static inline unsigned umin(unsigned a, unsigned b) {
203   return a - ((a - b) & -(a > b));
204 }
205 
206 }  // namespace gfx
207 }  // namespace mozilla
208 
209 #endif  // _MOZILLA_GFX_FILTERPROCESSING_H_
210