chromium/third_party/skia/src/core/SkBlurMask.cpp

/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/core/SkBlurMask.h"

#include "include/core/SkBlurTypes.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/private/base/SkMath.h"
#include "include/private/base/SkSafe32.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkMathPriv.h"
#include "src/core/SkMaskBlurFilter.h"

#include <cmath>
#include <cstring>
#include <utility>

class SkRRect;

usingnamespaceskia_private;

// This constant approximates the scaling done in the software path's
// "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)).
// IMHO, it actually should be 1:  we blur "less" than we should do
// according to the CSS and canvas specs, simply because Safari does the same.
// Firefox used to do the same too, until 4.0 where they fixed it.  So at some
// point we should probably get rid of these scaling constants and rebaseline
// all the blur tests.
static const SkScalar kBLUR_SIGMA_SCALE =;

SkScalar SkBlurMask::ConvertRadiusToSigma(SkScalar radius) {}

SkScalar SkBlurMask::ConvertSigmaToRadius(SkScalar sigma) {}


template <typename AlphaIter>
static void merge_src_with_blur(uint8_t dst[], int dstRB,
                                AlphaIter src, int srcRB,
                                const uint8_t blur[], int blurRB,
                                int sw, int sh) {}

template <typename AlphaIter>
static void clamp_solid_with_orig(uint8_t dst[], int dstRowBytes,
                                  AlphaIter src, int srcRowBytes,
                                  int sw, int sh) {}

template <typename AlphaIter>
static void clamp_outer_with_orig(uint8_t dst[], int dstRowBytes,
                                  AlphaIter src, int srcRowBytes,
                                  int sw, int sh) {}
///////////////////////////////////////////////////////////////////////////////

// we use a local function to wrap the class static method to work around
// a bug in gcc98
void SkMask_FreeImage(uint8_t* image);
void SkMask_FreeImage(uint8_t* image) {}

bool SkBlurMask::BoxBlur(SkMaskBuilder* dst, const SkMask& src, SkScalar sigma, SkBlurStyle style,
                         SkIPoint* margin) {}

/* Convolving a box with itself three times results in a piecewise
   quadratic function:

   0                              x <= -1.5
   9/8 + 3/2 x + 1/2 x^2   -1.5 < x <= -.5
   3/4 - x^2                -.5 < x <= .5
   9/8 - 3/2 x + 1/2 x^2    0.5 < x <= 1.5
   0                        1.5 < x

   Mathematica:

   g[x_] := Piecewise [ {
     {9/8 + 3/2 x + 1/2 x^2 ,  -1.5 < x <= -.5},
     {3/4 - x^2             ,   -.5 < x <= .5},
     {9/8 - 3/2 x + 1/2 x^2 ,   0.5 < x <= 1.5}
   }, 0]

   To get the profile curve of the blurred step function at the rectangle
   edge, we evaluate the indefinite integral, which is piecewise cubic:

   0                                        x <= -1.5
   9/16 + 9/8 x + 3/4 x^2 + 1/6 x^3   -1.5 < x <= -0.5
   1/2 + 3/4 x - 1/3 x^3              -.5 < x <= .5
   7/16 + 9/8 x - 3/4 x^2 + 1/6 x^3     .5 < x <= 1.5
   1                                  1.5 < x

   in Mathematica code:

   gi[x_] := Piecewise[ {
     { 0 , x <= -1.5 },
     { 9/16 + 9/8 x + 3/4 x^2 + 1/6 x^3, -1.5 < x <= -0.5 },
     { 1/2 + 3/4 x - 1/3 x^3          ,  -.5 < x <= .5},
     { 7/16 + 9/8 x - 3/4 x^2 + 1/6 x^3,   .5 < x <= 1.5}
   },1]
*/

static float gaussianIntegral(float x) {}

/*  ComputeBlurProfile fills in an array of floating
    point values between 0 and 255 for the profile signature of
    a blurred half-plane with the given blur radius.  Since we're
    going to be doing screened multiplications (i.e., 1 - (1-x)(1-y))
    all the time, we actually fill in the profile pre-inverted
    (already done 255-x).
*/

void SkBlurMask::ComputeBlurProfile(uint8_t* profile, int size, SkScalar sigma) {}

// TODO MAYBE: Maintain a profile cache to avoid recomputing this for
// commonly used radii.  Consider baking some of the most common blur radii
// directly in as static data?

// Implementation adapted from Michael Herf's approach:
// http://stereopsis.com/shadowrect/

uint8_t SkBlurMask::ProfileLookup(const uint8_t *profile, int loc,
                                  int blurredWidth, int sharpWidth) {}

void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile,
                                        unsigned int width, SkScalar sigma) {}

bool SkBlurMask::BlurRect(SkScalar sigma, SkMaskBuilder *dst,
                          const SkRect &src, SkBlurStyle style,
                          SkIPoint *margin, SkMaskBuilder::CreateMode createMode) {}

bool SkBlurMask::BlurRRect(SkScalar sigma, SkMaskBuilder *dst,
                           const SkRRect &src, SkBlurStyle style,
                           SkIPoint *margin, SkMaskBuilder::CreateMode createMode) {}

// The "simple" blur is a direct implementation of separable convolution with a discrete
// gaussian kernel.  It's "ground truth" in a sense; too slow to be used, but very
// useful for correctness comparisons.

bool SkBlurMask::BlurGroundTruth(SkScalar sigma, SkMaskBuilder* dst, const SkMask& src,
                                 SkBlurStyle style, SkIPoint* margin) {}