gfx/2d/Blur.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/2d/Blur.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,176 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef MOZILLA_GFX_BLUR_H_
    1.11 +#define MOZILLA_GFX_BLUR_H_
    1.12 +
    1.13 +#include "mozilla/gfx/Rect.h"
    1.14 +#include "mozilla/gfx/Point.h"
    1.15 +#include "mozilla/CheckedInt.h"
    1.16 +
    1.17 +namespace mozilla {
    1.18 +namespace gfx {
    1.19 +
    1.20 +#ifdef _MSC_VER
    1.21 +#pragma warning( disable : 4251 )
    1.22 +#endif
    1.23 +
    1.24 +/**
    1.25 + * Implementation of a triple box blur approximation of a Gaussian blur.
    1.26 + *
    1.27 + * A Gaussian blur is good for blurring because, when done independently
    1.28 + * in the horizontal and vertical directions, it matches the result that
    1.29 + * would be obtained using a different (rotated) set of axes.  A triple
    1.30 + * box blur is a very close approximation of a Gaussian.
    1.31 + *
    1.32 + * This is a "service" class; the constructors set up all the information
    1.33 + * based on the values and compute the minimum size for an 8-bit alpha
    1.34 + * channel context.
    1.35 + * The callers are responsible for creating and managing the backing surface
    1.36 + * and passing the pointer to the data to the Blur() method.  This class does
    1.37 + * not retain the pointer to the data outside of the Blur() call.
    1.38 + *
    1.39 + * A spread N makes each output pixel the maximum value of all source
    1.40 + * pixels within a square of side length 2N+1 centered on the output pixel.
    1.41 + */
    1.42 +class GFX2D_API AlphaBoxBlur
    1.43 +{
    1.44 +public:
    1.45 +
    1.46 +  /** Constructs a box blur and computes the backing surface size.
    1.47 +   *
    1.48 +   * @param aRect The coordinates of the surface to create in device units.
    1.49 +   *
    1.50 +   * @param aBlurRadius The blur radius in pixels.  This is the radius of the
    1.51 +   *   entire (triple) kernel function.  Each individual box blur has radius
    1.52 +   *   approximately 1/3 this value, or diameter approximately 2/3 this value.
    1.53 +   *   This parameter should nearly always be computed using CalculateBlurRadius,
    1.54 +   *   below.
    1.55 +   *
    1.56 +   * @param aDirtyRect A pointer to a dirty rect, measured in device units, if
    1.57 +   *   available.  This will be used for optimizing the blur operation. It is
    1.58 +   *   safe to pass nullptr here.
    1.59 +   *
    1.60 +   * @param aSkipRect A pointer to a rect, measured in device units, that
    1.61 +   *   represents an area where blurring is unnecessary and shouldn't be done for
    1.62 +   *   speed reasons. It is safe to pass nullptr here.
    1.63 +   */
    1.64 +  AlphaBoxBlur(const Rect& aRect,
    1.65 +               const IntSize& aSpreadRadius,
    1.66 +               const IntSize& aBlurRadius,
    1.67 +               const Rect* aDirtyRect,
    1.68 +               const Rect* aSkipRect);
    1.69 +
    1.70 +  AlphaBoxBlur(const Rect& aRect,
    1.71 +               int32_t aStride,
    1.72 +               float aSigmaX,
    1.73 +               float aSigmaY);
    1.74 +
    1.75 +  ~AlphaBoxBlur();
    1.76 +
    1.77 +  /**
    1.78 +   * Return the size, in pixels, of the 8-bit alpha surface we'd use.
    1.79 +   */
    1.80 +  IntSize GetSize();
    1.81 +
    1.82 +  /**
    1.83 +   * Return the stride, in bytes, of the 8-bit alpha surface we'd use.
    1.84 +   */
    1.85 +  int32_t GetStride();
    1.86 +
    1.87 +  /**
    1.88 +   * Returns the device-space rectangle the 8-bit alpha surface covers.
    1.89 +   */
    1.90 +  IntRect GetRect();
    1.91 +
    1.92 +  /**
    1.93 +   * Return a pointer to a dirty rect, as passed in to the constructor, or nullptr
    1.94 +   * if none was passed in.
    1.95 +   */
    1.96 +  Rect* GetDirtyRect();
    1.97 +
    1.98 +  /**
    1.99 +   * Return the minimum buffer size that should be given to Blur() method.  If
   1.100 +   * zero, the class is not properly setup for blurring.  Note that this
   1.101 +   * includes the extra three bytes on top of the stride*width, where something
   1.102 +   * like gfxImageSurface::GetDataSize() would report without it, even if it 
   1.103 +   * happens to have the extra bytes.
   1.104 +   */
   1.105 +  size_t GetSurfaceAllocationSize() const;
   1.106 +
   1.107 +  /**
   1.108 +   * Perform the blur in-place on the surface backed by specified 8-bit
   1.109 +   * alpha surface data. The size must be at least that returned by
   1.110 +   * GetSurfaceAllocationSize() or bad things will happen.
   1.111 +   */
   1.112 +  void Blur(uint8_t* aData);
   1.113 +
   1.114 +  /**
   1.115 +   * Calculates a blur radius that, when used with box blur, approximates a
   1.116 +   * Gaussian blur with the given standard deviation.  The result of this
   1.117 +   * function should be used as the aBlurRadius parameter to AlphaBoxBlur's
   1.118 +   * constructor, above.
   1.119 +   */
   1.120 +  static IntSize CalculateBlurRadius(const Point& aStandardDeviation);
   1.121 +
   1.122 +private:
   1.123 +
   1.124 +  void BoxBlur_C(uint8_t* aData,
   1.125 +                 int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
   1.126 +                 int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
   1.127 +  void BoxBlur_SSE2(uint8_t* aData,
   1.128 +                    int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
   1.129 +                    int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
   1.130 +
   1.131 +  static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal);
   1.132 +
   1.133 +  /**
   1.134 +   * A rect indicating the area where blurring is unnecessary, and the blur
   1.135 +   * algorithm should skip over it.
   1.136 +   */
   1.137 +  IntRect mSkipRect;
   1.138 +
   1.139 +  /**
   1.140 +   * The device-space rectangle the the backing 8-bit alpha surface covers.
   1.141 +   */
   1.142 +  IntRect mRect;
   1.143 +
   1.144 +  /**
   1.145 +   * A copy of the dirty rect passed to the constructor. This will only be valid if
   1.146 +   * mHasDirtyRect is true.
   1.147 +   */
   1.148 +  Rect mDirtyRect;
   1.149 +
   1.150 +  /**
   1.151 +   * The spread radius, in pixels.
   1.152 +   */
   1.153 +  IntSize mSpreadRadius;
   1.154 +
   1.155 +  /**
   1.156 +   * The blur radius, in pixels.
   1.157 +   */
   1.158 +  IntSize mBlurRadius;
   1.159 +
   1.160 +  /**
   1.161 +   * The stride of the data passed to Blur()
   1.162 +   */
   1.163 +  int32_t mStride;
   1.164 +
   1.165 +  /**
   1.166 +   * The minimum size of the buffer needed for the Blur() operation.
   1.167 +   */
   1.168 +  size_t mSurfaceAllocationSize;
   1.169 +
   1.170 +  /**
   1.171 +   * Whether mDirtyRect contains valid data.
   1.172 +   */
   1.173 +  bool mHasDirtyRect;
   1.174 +};
   1.175 +
   1.176 +}
   1.177 +}
   1.178 +
   1.179 +#endif /* MOZILLA_GFX_BLUR_H_ */

mercurial