|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef _MOZILLA_GFX_FILTERPROCESSING_H_ |
|
7 #define _MOZILLA_GFX_FILTERPROCESSING_H_ |
|
8 |
|
9 #include "2D.h" |
|
10 #include "Filters.h" |
|
11 |
|
12 namespace mozilla { |
|
13 namespace gfx { |
|
14 |
|
15 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_B = 0; |
|
16 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_G = 1; |
|
17 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_R = 2; |
|
18 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_A = 3; |
|
19 |
|
20 class FilterProcessing |
|
21 { |
|
22 public: |
|
23 |
|
24 // Fast approximate division by 255. It has the property that |
|
25 // for all 0 <= v <= 255*255, FastDivideBy255(v) == v/255. |
|
26 // But it only uses two adds and two shifts instead of an |
|
27 // integer division (which is expensive on many processors). |
|
28 template<class B, class A> |
|
29 static B FastDivideBy255(A v) |
|
30 { |
|
31 return ((v << 8) + v + 255) >> 16; |
|
32 } |
|
33 |
|
34 static TemporaryRef<DataSourceSurface> ExtractAlpha(DataSourceSurface* aSource); |
|
35 static TemporaryRef<DataSourceSurface> ConvertToB8G8R8A8(SourceSurface* aSurface); |
|
36 static TemporaryRef<DataSourceSurface> ApplyBlending(DataSourceSurface* aInput1, DataSourceSurface* aInput2, BlendMode aBlendMode); |
|
37 static void ApplyMorphologyHorizontal(uint8_t* aSourceData, int32_t aSourceStride, |
|
38 uint8_t* aDestData, int32_t aDestStride, |
|
39 const IntRect& aDestRect, int32_t aRadius, |
|
40 MorphologyOperator aOperator); |
|
41 static void ApplyMorphologyVertical(uint8_t* aSourceData, int32_t aSourceStride, |
|
42 uint8_t* aDestData, int32_t aDestStride, |
|
43 const IntRect& aDestRect, int32_t aRadius, |
|
44 MorphologyOperator aOperator); |
|
45 static TemporaryRef<DataSourceSurface> ApplyColorMatrix(DataSourceSurface* aInput, const Matrix5x4 &aMatrix); |
|
46 static void ApplyComposition(DataSourceSurface* aSource, DataSourceSurface* aDest, CompositeOperator aOperator); |
|
47 static void SeparateColorChannels(DataSourceSurface* aSource, |
|
48 RefPtr<DataSourceSurface>& aChannel0, |
|
49 RefPtr<DataSourceSurface>& aChannel1, |
|
50 RefPtr<DataSourceSurface>& aChannel2, |
|
51 RefPtr<DataSourceSurface>& aChannel3); |
|
52 static TemporaryRef<DataSourceSurface> |
|
53 CombineColorChannels(DataSourceSurface* aChannel0, DataSourceSurface* aChannel1, |
|
54 DataSourceSurface* aChannel2, DataSourceSurface* aChannel3); |
|
55 static void DoPremultiplicationCalculation(const IntSize& aSize, |
|
56 uint8_t* aTargetData, int32_t aTargetStride, |
|
57 uint8_t* aSourceData, int32_t aSourceStride); |
|
58 static void DoUnpremultiplicationCalculation(const IntSize& aSize, |
|
59 uint8_t* aTargetData, int32_t aTargetStride, |
|
60 uint8_t* aSourceData, int32_t aSourceStride); |
|
61 static TemporaryRef<DataSourceSurface> |
|
62 RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency, |
|
63 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect); |
|
64 static TemporaryRef<DataSourceSurface> |
|
65 ApplyArithmeticCombine(DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, Float aK2, Float aK3, Float aK4); |
|
66 |
|
67 protected: |
|
68 static void ExtractAlpha_Scalar(const IntSize& size, uint8_t* sourceData, int32_t sourceStride, uint8_t* alphaData, int32_t alphaStride); |
|
69 static TemporaryRef<DataSourceSurface> ConvertToB8G8R8A8_Scalar(SourceSurface* aSurface); |
|
70 static TemporaryRef<DataSourceSurface> ApplyBlending_Scalar(DataSourceSurface* aInput1, DataSourceSurface* aInput2, BlendMode aBlendMode); |
|
71 static void ApplyMorphologyHorizontal_Scalar(uint8_t* aSourceData, int32_t aSourceStride, |
|
72 uint8_t* aDestData, int32_t aDestStride, |
|
73 const IntRect& aDestRect, int32_t aRadius, |
|
74 MorphologyOperator aOperator); |
|
75 static void ApplyMorphologyVertical_Scalar(uint8_t* aSourceData, int32_t aSourceStride, |
|
76 uint8_t* aDestData, int32_t aDestStride, |
|
77 const IntRect& aDestRect, int32_t aRadius, |
|
78 MorphologyOperator aOperator); |
|
79 static TemporaryRef<DataSourceSurface> ApplyColorMatrix_Scalar(DataSourceSurface* aInput, const Matrix5x4 &aMatrix); |
|
80 static void ApplyComposition_Scalar(DataSourceSurface* aSource, DataSourceSurface* aDest, CompositeOperator aOperator); |
|
81 |
|
82 static void SeparateColorChannels_Scalar(const IntSize &size, uint8_t* sourceData, int32_t sourceStride, uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data, uint8_t* channel3Data, int32_t channelStride); |
|
83 static void CombineColorChannels_Scalar(const IntSize &size, int32_t resultStride, uint8_t* resultData, int32_t channelStride, uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data, uint8_t* channel3Data); |
|
84 static void DoPremultiplicationCalculation_Scalar(const IntSize& aSize, |
|
85 uint8_t* aTargetData, int32_t aTargetStride, |
|
86 uint8_t* aSourceData, int32_t aSourceStride); |
|
87 static void DoUnpremultiplicationCalculation_Scalar(const IntSize& aSize, |
|
88 uint8_t* aTargetData, int32_t aTargetStride, |
|
89 uint8_t* aSourceData, int32_t aSourceStride); |
|
90 static TemporaryRef<DataSourceSurface> |
|
91 RenderTurbulence_Scalar(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency, |
|
92 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect); |
|
93 static TemporaryRef<DataSourceSurface> |
|
94 ApplyArithmeticCombine_Scalar(DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, Float aK2, Float aK3, Float aK4); |
|
95 |
|
96 #ifdef USE_SSE2 |
|
97 static void ExtractAlpha_SSE2(const IntSize& size, uint8_t* sourceData, int32_t sourceStride, uint8_t* alphaData, int32_t alphaStride); |
|
98 static TemporaryRef<DataSourceSurface> ConvertToB8G8R8A8_SSE2(SourceSurface* aSurface); |
|
99 static TemporaryRef<DataSourceSurface> ApplyBlending_SSE2(DataSourceSurface* aInput1, DataSourceSurface* aInput2, BlendMode aBlendMode); |
|
100 static void ApplyMorphologyHorizontal_SSE2(uint8_t* aSourceData, int32_t aSourceStride, |
|
101 uint8_t* aDestData, int32_t aDestStride, |
|
102 const IntRect& aDestRect, int32_t aRadius, |
|
103 MorphologyOperator aOperator); |
|
104 static void ApplyMorphologyVertical_SSE2(uint8_t* aSourceData, int32_t aSourceStride, |
|
105 uint8_t* aDestData, int32_t aDestStride, |
|
106 const IntRect& aDestRect, int32_t aRadius, |
|
107 MorphologyOperator aOperator); |
|
108 static TemporaryRef<DataSourceSurface> ApplyColorMatrix_SSE2(DataSourceSurface* aInput, const Matrix5x4 &aMatrix); |
|
109 static void ApplyComposition_SSE2(DataSourceSurface* aSource, DataSourceSurface* aDest, CompositeOperator aOperator); |
|
110 static void SeparateColorChannels_SSE2(const IntSize &size, uint8_t* sourceData, int32_t sourceStride, uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data, uint8_t* channel3Data, int32_t channelStride); |
|
111 static void CombineColorChannels_SSE2(const IntSize &size, int32_t resultStride, uint8_t* resultData, int32_t channelStride, uint8_t* channel0Data, uint8_t* channel1Data, uint8_t* channel2Data, uint8_t* channel3Data); |
|
112 static void DoPremultiplicationCalculation_SSE2(const IntSize& aSize, |
|
113 uint8_t* aTargetData, int32_t aTargetStride, |
|
114 uint8_t* aSourceData, int32_t aSourceStride); |
|
115 static void DoUnpremultiplicationCalculation_SSE2(const IntSize& aSize, |
|
116 uint8_t* aTargetData, int32_t aTargetStride, |
|
117 uint8_t* aSourceData, int32_t aSourceStride); |
|
118 static TemporaryRef<DataSourceSurface> |
|
119 RenderTurbulence_SSE2(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency, |
|
120 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect); |
|
121 static TemporaryRef<DataSourceSurface> |
|
122 ApplyArithmeticCombine_SSE2(DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, Float aK2, Float aK3, Float aK4); |
|
123 #endif |
|
124 }; |
|
125 |
|
126 // Constant-time max and min functions for unsigned arguments |
|
127 static inline unsigned |
|
128 umax(unsigned a, unsigned b) |
|
129 { |
|
130 return a - ((a - b) & -(a < b)); |
|
131 } |
|
132 |
|
133 static inline unsigned |
|
134 umin(unsigned a, unsigned b) |
|
135 { |
|
136 return a - ((a - b) & -(a > b)); |
|
137 } |
|
138 |
|
139 } // namespace gfx |
|
140 } // namespace mozilla |
|
141 |
|
142 #endif // _MOZILLA_GFX_FILTERPROCESSING_H_ |