FilterProcessing.h (8916B)
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::gfx { 14 15 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_B = 16 static_cast<ptrdiff_t>(mozilla::gfx::SurfaceFormatBit::OS_B) / 8; 17 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_G = 18 static_cast<ptrdiff_t>(mozilla::gfx::SurfaceFormatBit::OS_G) / 8; 19 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_R = 20 static_cast<ptrdiff_t>(mozilla::gfx::SurfaceFormatBit::OS_R) / 8; 21 const ptrdiff_t B8G8R8A8_COMPONENT_BYTEOFFSET_A = 22 static_cast<ptrdiff_t>(mozilla::gfx::SurfaceFormatBit::OS_A) / 8; 23 24 class FilterProcessing { 25 public: 26 // Fast approximate division by 255. It has the property that 27 // for all 0 <= v <= 255*255, FastDivideBy255(v) == v/255. 28 // But it only uses two adds and two shifts instead of an 29 // integer division (which is expensive on many processors). 30 template <class B, class A> 31 static B FastDivideBy255(A v) { 32 return ((v << 8) + v + 255) >> 16; 33 } 34 35 static already_AddRefed<DataSourceSurface> ExtractAlpha( 36 DataSourceSurface* aSource); 37 static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8( 38 SourceSurface* aSurface); 39 static already_AddRefed<DataSourceSurface> ApplyBlending( 40 DataSourceSurface* aInput1, DataSourceSurface* aInput2, 41 BlendMode aBlendMode); 42 static void ApplyMorphologyHorizontal(const uint8_t* aSourceData, 43 int32_t aSourceStride, 44 uint8_t* aDestData, int32_t aDestStride, 45 const IntRect& aDestRect, 46 int32_t aRadius, 47 MorphologyOperator aOperator); 48 static void ApplyMorphologyVertical(const uint8_t* aSourceData, 49 int32_t aSourceStride, uint8_t* aDestData, 50 int32_t aDestStride, 51 const IntRect& aDestRect, int32_t aRadius, 52 MorphologyOperator aOperator); 53 static already_AddRefed<DataSourceSurface> ApplyColorMatrix( 54 DataSourceSurface* aInput, const Matrix5x4& aMatrix); 55 static void ApplyComposition(DataSourceSurface* aSource, 56 DataSourceSurface* aDest, 57 CompositeOperator aOperator); 58 static void DoPremultiplicationCalculation(const IntSize& aSize, 59 uint8_t* aTargetData, 60 int32_t aTargetStride, 61 const uint8_t* aSourceData, 62 int32_t aSourceStride); 63 static void DoUnpremultiplicationCalculation(const IntSize& aSize, 64 uint8_t* aTargetData, 65 int32_t aTargetStride, 66 const uint8_t* aSourceData, 67 int32_t aSourceStride); 68 static void DoOpacityCalculation(const IntSize& aSize, uint8_t* aTargetData, 69 int32_t aTargetStride, 70 const uint8_t* aSourceData, 71 int32_t aSourceStride, Float aValue); 72 static void DoOpacityCalculationA8(const IntSize& aSize, uint8_t* aTargetData, 73 int32_t aTargetStride, 74 const uint8_t* aSourceData, 75 int32_t aSourceStride, Float aValue); 76 static already_AddRefed<DataSourceSurface> RenderTurbulence( 77 const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency, 78 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, 79 const Rect& aTileRect); 80 static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine( 81 DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, 82 Float aK2, Float aK3, Float aK4); 83 84 protected: 85 static void ExtractAlpha_Scalar(const IntSize& size, 86 const uint8_t* sourceData, 87 int32_t sourceStride, uint8_t* alphaData, 88 int32_t alphaStride); 89 static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8_Scalar( 90 SourceSurface* aSurface); 91 static void ApplyMorphologyHorizontal_Scalar( 92 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 93 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 94 MorphologyOperator aOperator); 95 static void ApplyMorphologyVertical_Scalar( 96 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 97 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 98 MorphologyOperator aOperator); 99 static already_AddRefed<DataSourceSurface> ApplyColorMatrix_Scalar( 100 DataSourceSurface* aInput, const Matrix5x4& aMatrix); 101 static void ApplyComposition_Scalar(DataSourceSurface* aSource, 102 DataSourceSurface* aDest, 103 CompositeOperator aOperator); 104 static void DoOpacityCalculation_Scalar(const IntSize& aSize, 105 uint8_t* aTargetData, 106 int32_t aTargetStride, 107 const uint8_t* aSourceData, 108 int32_t aSourceStride, Float aValue); 109 static void DoOpacityCalculationA8_Scalar( 110 const IntSize& aSize, uint8_t* aTargetData, int32_t aTargetStride, 111 const uint8_t* aSourceData, int32_t aSourceStride, Float aValue); 112 static already_AddRefed<DataSourceSurface> RenderTurbulence_Scalar( 113 const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency, 114 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, 115 const Rect& aTileRect); 116 static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine_Scalar( 117 DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, 118 Float aK2, Float aK3, Float aK4); 119 120 #ifdef USE_SSE2 121 static void ExtractAlpha_SSE2(const IntSize& size, const uint8_t* sourceData, 122 int32_t sourceStride, uint8_t* alphaData, 123 int32_t alphaStride); 124 static already_AddRefed<DataSourceSurface> ConvertToB8G8R8A8_SSE2( 125 SourceSurface* aSurface); 126 static already_AddRefed<DataSourceSurface> ApplyBlending_SSE2( 127 DataSourceSurface* aInput1, DataSourceSurface* aInput2, 128 BlendMode aBlendMode); 129 static void ApplyMorphologyHorizontal_SSE2( 130 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 131 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 132 MorphologyOperator aOperator); 133 static void ApplyMorphologyVertical_SSE2( 134 const uint8_t* aSourceData, int32_t aSourceStride, uint8_t* aDestData, 135 int32_t aDestStride, const IntRect& aDestRect, int32_t aRadius, 136 MorphologyOperator aOperator); 137 static already_AddRefed<DataSourceSurface> ApplyColorMatrix_SSE2( 138 DataSourceSurface* aInput, const Matrix5x4& aMatrix); 139 static void ApplyComposition_SSE2(DataSourceSurface* aSource, 140 DataSourceSurface* aDest, 141 CompositeOperator aOperator); 142 static void DoOpacityCalculation_SSE2(const IntSize& aSize, 143 uint8_t* aTargetData, 144 int32_t aTargetStride, 145 const uint8_t* aSourceData, 146 int32_t aSourceStride, Float aValue); 147 static already_AddRefed<DataSourceSurface> RenderTurbulence_SSE2( 148 const IntSize& aSize, const Point& aOffset, const Size& aBaseFrequency, 149 int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, 150 const Rect& aTileRect); 151 static already_AddRefed<DataSourceSurface> ApplyArithmeticCombine_SSE2( 152 DataSourceSurface* aInput1, DataSourceSurface* aInput2, Float aK1, 153 Float aK2, Float aK3, Float aK4); 154 #endif 155 }; 156 157 // Constant-time max and min functions for unsigned arguments 158 static inline unsigned umax(unsigned a, unsigned b) { 159 return a - ((a - b) & -(a < b)); 160 } 161 162 static inline unsigned umin(unsigned a, unsigned b) { 163 return a - ((a - b) & -(a > b)); 164 } 165 166 } // namespace mozilla::gfx 167 168 #endif // _MOZILLA_GFX_FILTERPROCESSING_H_