tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Blur.h (6218B)


      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/gfx/Types.h"
     13 
     14 class SkSurface;
     15 
     16 namespace mozilla {
     17 namespace gfx {
     18 
     19 class DrawTargetSkia;
     20 
     21 #ifdef _MSC_VER
     22 #  pragma warning(disable : 4251)
     23 #endif
     24 
     25 /**
     26 * Implementation of a Gaussian blur.
     27 *
     28 * A Gaussian blur is good for blurring because, when done independently
     29 * in the horizontal and vertical directions, it matches the result that
     30 * would be obtained using a different (rotated) set of axes.
     31 *
     32 * This is a "service" class; the constructors set up all the information
     33 * based on the values.
     34 * The callers are responsible for creating and managing the backing surface
     35 * and passing the pointer to the data to the Blur() method.  This class does
     36 * not retain the pointer to the data outside of the Blur() call.
     37 *
     38 * A spread N makes each output pixel the maximum value of all source
     39 * pixels within a square of side length 2N+1 centered on the output pixel.
     40 */
     41 class GFX2D_API GaussianBlur final {
     42 public:
     43  /** Constructs a Gaussian blur and computes the backing surface size.
     44   *
     45   * @param aRect The coordinates of the surface to create in device units.
     46   *
     47   * @param aSigma The blur sigma.
     48   *
     49   * @param aDirtyRect A pointer to a dirty rect, measured in device units, if
     50   *   available.  This will be used for optimizing the blur operation. It is
     51   *   safe to pass nullptr here.
     52   *
     53   * @param aSkipRect A pointer to a rect, measured in device units, that
     54   *   represents an area where blurring is unnecessary and shouldn't be done
     55   * for speed reasons. It is safe to pass nullptr here.
     56   *
     57   * @param aFormat The format of the surface's data.
     58   *
     59   * @param aClamp Whether clamping at border pixels is required.
     60   */
     61  GaussianBlur(const Rect& aRect, const IntSize& aSpreadRadius,
     62               const Point& aSigma, const Rect* aDirtyRect,
     63               const Rect* aSkipRect, SurfaceFormat aFormat = SurfaceFormat::A8,
     64               bool aClamp = false);
     65 
     66  explicit GaussianBlur(const Point& aSigma, bool aClamp = false);
     67 
     68  GaussianBlur();
     69 
     70  void Init(const Rect& aRect, const IntSize& aSpreadRadius,
     71            const Point& aBlurSigma, const Rect* aDirtyRect,
     72            const Rect* aSkipRect, SurfaceFormat aFormat = SurfaceFormat::A8,
     73            bool aClamp = false);
     74 
     75  ~GaussianBlur();
     76 
     77  /**
     78   * Return the size, in pixels, of the surface we'd use.
     79   */
     80  IntSize GetSize() const;
     81 
     82  /**
     83   * Return the format of the blur data.
     84   */
     85  SurfaceFormat GetFormat() const;
     86 
     87  /**
     88   * Return the stride, in bytes, of the surface we'd use.
     89   */
     90  int32_t GetStride() const;
     91 
     92  /**
     93   * Returns the device-space rectangle the surface covers.
     94   */
     95  IntRect GetRect() const;
     96 
     97  /**
     98   * Return a pointer to a dirty rect, as passed in to the constructor, or
     99   * nullptr if none was passed in.
    100   */
    101  Rect* GetDirtyRect();
    102 
    103  /**
    104   * Return the spread radius, in pixels.
    105   */
    106  IntSize GetSpreadRadius() const { return mSpreadRadius; }
    107 
    108  /**
    109   * Return the blur sigma.
    110   */
    111  Point GetBlurSigma() const { return mBlurSigma; }
    112 
    113  /**
    114   * Return the blur radius, in pixels.
    115   */
    116  IntSize GetBlurRadius() const { return mBlurRadius; }
    117 
    118  /**
    119   * Return the skip rect.
    120   */
    121  IntRect GetSkipRect() const { return mSkipRect; }
    122 
    123  /**
    124   * Return the minimum buffer size that should be given to Blur() method.  If
    125   * zero, the class is not properly setup for blurring.  Note that this
    126   * includes the extra three bytes on top of the stride*width, where something
    127   * like gfxImageSurface::GetDataSize() would report without it, even if it
    128   * happens to have the extra bytes.
    129   */
    130  size_t GetSurfaceAllocationSize() const;
    131 
    132  /**
    133   * Perform the blur in-place on the surface backed by specified surface data.
    134   * The size must be at least that returned by GetSurfaceAllocationSize() or
    135   * bad things will happen.
    136   */
    137  void Blur(uint8_t* aData, int32_t aStride, const IntSize& aSize,
    138            SurfaceFormat aFormat = SurfaceFormat::UNKNOWN) const;
    139 
    140  /**
    141   * Calculates a blur radius that, when used with box blur, approximates a
    142   * Gaussian blur with the given standard deviation.  The result of this
    143   * function should be used as the aBlurRadius parameter to GaussianBlur's
    144   * constructor, above.
    145   */
    146  static IntSize CalculateBlurRadius(const Point& aStandardDeviation);
    147  static Float CalculateBlurSigma(int32_t aBlurRadius);
    148 
    149 private:
    150  /**
    151   * A rect indicating the area where blurring is unnecessary, and the blur
    152   * algorithm should skip over it.
    153   *
    154   * This is guaranteed to be 4-pixel aligned in the x axis.
    155   */
    156  IntRect mSkipRect;
    157 
    158  /**
    159   * The device-space rectangle the backing surface covers.
    160   */
    161  IntRect mRect;
    162 
    163  /**
    164   * A copy of the dirty rect passed to the constructor. This will only be valid
    165   * if mHasDirtyRect is true.
    166   */
    167  Rect mDirtyRect;
    168 
    169  /**
    170   * The spread radius, in pixels.
    171   */
    172  IntSize mSpreadRadius;
    173 
    174  /**
    175   * The blur sigma (standard deviation).
    176   */
    177  Point mBlurSigma;
    178 
    179  /**
    180   * The blur radius, in pixels.
    181   */
    182  IntSize mBlurRadius;
    183 
    184  /**
    185   * The format of the data passed to Blur()
    186   */
    187  SurfaceFormat mFormat = SurfaceFormat::UNKNOWN;
    188 
    189  /**
    190   * Whether clamping at border pixels is required.
    191   */
    192  bool mClamp = false;
    193 
    194  /**
    195   * The stride of the data passed to Blur()
    196   */
    197  int32_t mStride = 0;
    198 
    199  /**
    200   * The minimum size of the buffer needed for the Blur() operation.
    201   */
    202  size_t mSurfaceAllocationSize = 0;
    203 
    204  /**
    205   * Whether mDirtyRect contains valid data.
    206   */
    207  bool mHasDirtyRect = false;
    208 
    209  bool Spread(uint8_t* aData, int32_t aStride, const IntSize& aSize,
    210              SurfaceFormat aFormat) const;
    211 
    212  friend class DrawTargetSkia;
    213 
    214  bool BlurSkSurface(SkSurface* aSurface) const;
    215 };
    216 
    217 }  // namespace gfx
    218 }  // namespace mozilla
    219 
    220 #endif /* MOZILLA_GFX_BLUR_H_ */