Blur.h 5.9 KB

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