LCOV - code coverage report
Current view: directory - gfx/2d - Blur.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 216 0 0.0 %
Date: 2012-06-02 Functions: 15 0 0.0 %

       1                 : /* ***** BEGIN LICENSE BLOCK *****
       2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       3                 :  *
       4                 :  * The contents of this file are subject to the Mozilla Public License Version
       5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       6                 :  * the License. You may obtain a copy of the License at
       7                 :  * http://www.mozilla.org/MPL/
       8                 :  *
       9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      11                 :  * for the specific language governing rights and limitations under the
      12                 :  * License.
      13                 :  *
      14                 :  * The Original Code is Mozilla gfx.
      15                 :  *
      16                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
      17                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      18                 :  * the Initial Developer. All Rights Reserved.
      19                 :  *
      20                 :  * Contributor(s):
      21                 :  *
      22                 :  * Alternatively, the contents of this file may be used under the terms of
      23                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      24                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      25                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      26                 :  * of those above. If you wish to allow use of your version of this file only
      27                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      28                 :  * use your version of this file under the terms of the MPL, indicate your
      29                 :  * decision by deleting the provisions above and replace them with the notice
      30                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      31                 :  * the provisions above, a recipient may use your version of this file under
      32                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      33                 :  *
      34                 :  * ***** END LICENSE BLOCK ***** */
      35                 : 
      36                 : #include "mozilla/gfx/Blur.h"
      37                 : 
      38                 : #include <algorithm>
      39                 : #include <math.h>
      40                 : #include <string.h>
      41                 : 
      42                 : #include "CheckedInt.h"
      43                 : #include "mozilla/Util.h"
      44                 : 
      45                 : #ifndef M_PI
      46                 : #define M_PI 3.14159265358979323846
      47                 : #endif
      48                 : 
      49                 : using namespace std;
      50                 : 
      51                 : namespace mozilla {
      52                 : namespace gfx {
      53                 : 
      54                 : /**
      55                 :  * Box blur involves looking at one pixel, and setting its value to the average
      56                 :  * of its neighbouring pixels.
      57                 :  * @param aInput The input buffer.
      58                 :  * @param aOutput The output buffer.
      59                 :  * @param aLeftLobe The number of pixels to blend on the left.
      60                 :  * @param aRightLobe The number of pixels to blend on the right.
      61                 :  * @param aWidth The number of columns in the buffers.
      62                 :  * @param aRows The number of rows in the buffers.
      63                 :  * @param aSkipRect An area to skip blurring in.
      64                 :  * XXX shouldn't we pass stride in separately here?
      65                 :  */
      66                 : static void
      67               0 : BoxBlurHorizontal(unsigned char* aInput,
      68                 :                   unsigned char* aOutput,
      69                 :                   int32_t aLeftLobe,
      70                 :                   int32_t aRightLobe,
      71                 :                   int32_t aWidth,
      72                 :                   int32_t aRows,
      73                 :                   const IntRect& aSkipRect)
      74                 : {
      75               0 :     MOZ_ASSERT(aWidth > 0);
      76                 : 
      77               0 :     int32_t boxSize = aLeftLobe + aRightLobe + 1;
      78                 :     bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
      79               0 :                                   aWidth <= aSkipRect.XMost();
      80                 : 
      81               0 :     for (int32_t y = 0; y < aRows; y++) {
      82                 :         // Check whether the skip rect intersects this row. If the skip
      83                 :         // rect covers the whole surface in this row, we can avoid
      84                 :         // this row entirely (and any others along the skip rect).
      85                 :         bool inSkipRectY = y >= aSkipRect.y &&
      86               0 :                            y < aSkipRect.YMost();
      87               0 :         if (inSkipRectY && skipRectCoversWholeRow) {
      88               0 :             y = aSkipRect.YMost() - 1;
      89               0 :             continue;
      90                 :         }
      91                 : 
      92               0 :         int32_t alphaSum = 0;
      93               0 :         for (int32_t i = 0; i < boxSize; i++) {
      94               0 :             int32_t pos = i - aLeftLobe;
      95                 :             // See assertion above; if aWidth is zero, then we would have no
      96                 :             // valid position to clamp to.
      97               0 :             pos = max(pos, 0);
      98               0 :             pos = min(pos, aWidth - 1);
      99               0 :             alphaSum += aInput[aWidth * y + pos];
     100                 :         }
     101               0 :         for (int32_t x = 0; x < aWidth; x++) {
     102                 :             // Check whether we are within the skip rect. If so, go
     103                 :             // to the next point outside the skip rect.
     104               0 :             if (inSkipRectY && x >= aSkipRect.x &&
     105               0 :                 x < aSkipRect.XMost()) {
     106               0 :                 x = aSkipRect.XMost();
     107               0 :                 if (x >= aWidth)
     108               0 :                     break;
     109                 : 
     110                 :                 // Recalculate the neighbouring alpha values for
     111                 :                 // our new point on the surface.
     112               0 :                 alphaSum = 0;
     113               0 :                 for (int32_t i = 0; i < boxSize; i++) {
     114               0 :                     int32_t pos = x + i - aLeftLobe;
     115                 :                     // See assertion above; if aWidth is zero, then we would have no
     116                 :                     // valid position to clamp to.
     117               0 :                     pos = max(pos, 0);
     118               0 :                     pos = min(pos, aWidth - 1);
     119               0 :                     alphaSum += aInput[aWidth * y + pos];
     120                 :                 }
     121                 :             }
     122               0 :             int32_t tmp = x - aLeftLobe;
     123               0 :             int32_t last = max(tmp, 0);
     124               0 :             int32_t next = min(tmp + boxSize, aWidth - 1);
     125                 : 
     126               0 :             aOutput[aWidth * y + x] = alphaSum / boxSize;
     127                 : 
     128               0 :             alphaSum += aInput[aWidth * y + next] -
     129               0 :                         aInput[aWidth * y + last];
     130                 :         }
     131                 :     }
     132               0 : }
     133                 : 
     134                 : /**
     135                 :  * Identical to BoxBlurHorizontal, except it blurs top and bottom instead of
     136                 :  * left and right.
     137                 :  * XXX shouldn't we pass stride in separately here?
     138                 :  */
     139                 : static void
     140               0 : BoxBlurVertical(unsigned char* aInput,
     141                 :                 unsigned char* aOutput,
     142                 :                 int32_t aTopLobe,
     143                 :                 int32_t aBottomLobe,
     144                 :                 int32_t aWidth,
     145                 :                 int32_t aRows,
     146                 :                 const IntRect& aSkipRect)
     147                 : {
     148               0 :     MOZ_ASSERT(aRows > 0);
     149                 : 
     150               0 :     int32_t boxSize = aTopLobe + aBottomLobe + 1;
     151                 :     bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
     152               0 :                                      aRows <= aSkipRect.YMost();
     153                 : 
     154               0 :     for (int32_t x = 0; x < aWidth; x++) {
     155                 :         bool inSkipRectX = x >= aSkipRect.x &&
     156               0 :                            x < aSkipRect.XMost();
     157               0 :         if (inSkipRectX && skipRectCoversWholeColumn) {
     158               0 :             x = aSkipRect.XMost() - 1;
     159               0 :             continue;
     160                 :         }
     161                 : 
     162               0 :         int32_t alphaSum = 0;
     163               0 :         for (int32_t i = 0; i < boxSize; i++) {
     164               0 :             int32_t pos = i - aTopLobe;
     165                 :             // See assertion above; if aRows is zero, then we would have no
     166                 :             // valid position to clamp to.
     167               0 :             pos = max(pos, 0);
     168               0 :             pos = min(pos, aRows - 1);
     169               0 :             alphaSum += aInput[aWidth * pos + x];
     170                 :         }
     171               0 :         for (int32_t y = 0; y < aRows; y++) {
     172               0 :             if (inSkipRectX && y >= aSkipRect.y &&
     173               0 :                 y < aSkipRect.YMost()) {
     174               0 :                 y = aSkipRect.YMost();
     175               0 :                 if (y >= aRows)
     176               0 :                     break;
     177                 : 
     178               0 :                 alphaSum = 0;
     179               0 :                 for (int32_t i = 0; i < boxSize; i++) {
     180               0 :                     int32_t pos = y + i - aTopLobe;
     181                 :                     // See assertion above; if aRows is zero, then we would have no
     182                 :                     // valid position to clamp to.
     183               0 :                     pos = max(pos, 0);
     184               0 :                     pos = min(pos, aRows - 1);
     185               0 :                     alphaSum += aInput[aWidth * pos + x];
     186                 :                 }
     187                 :             }
     188               0 :             int32_t tmp = y - aTopLobe;
     189               0 :             int32_t last = max(tmp, 0);
     190               0 :             int32_t next = min(tmp + boxSize, aRows - 1);
     191                 : 
     192               0 :             aOutput[aWidth * y + x] = alphaSum/boxSize;
     193                 : 
     194               0 :             alphaSum += aInput[aWidth * next + x] -
     195               0 :                         aInput[aWidth * last + x];
     196                 :         }
     197                 :     }
     198               0 : }
     199                 : 
     200               0 : static void ComputeLobes(int32_t aRadius, int32_t aLobes[3][2])
     201                 : {
     202                 :     int32_t major, minor, final;
     203                 : 
     204                 :     /* See http://www.w3.org/TR/SVG/filters.html#feGaussianBlur for
     205                 :      * some notes about approximating the Gaussian blur with box-blurs.
     206                 :      * The comments below are in the terminology of that page.
     207                 :      */
     208               0 :     int32_t z = aRadius / 3;
     209               0 :     switch (aRadius % 3) {
     210                 :     case 0:
     211                 :         // aRadius = z*3; choose d = 2*z + 1
     212               0 :         major = minor = final = z;
     213               0 :         break;
     214                 :     case 1:
     215                 :         // aRadius = z*3 + 1
     216                 :         // This is a tricky case since there is no value of d which will
     217                 :         // yield a radius of exactly aRadius. If d is odd, i.e. d=2*k + 1
     218                 :         // for some integer k, then the radius will be 3*k. If d is even,
     219                 :         // i.e. d=2*k, then the radius will be 3*k - 1.
     220                 :         // So we have to choose values that don't match the standard
     221                 :         // algorithm.
     222               0 :         major = z + 1;
     223               0 :         minor = final = z;
     224               0 :         break;
     225                 :     case 2:
     226                 :         // aRadius = z*3 + 2; choose d = 2*z + 2
     227               0 :         major = final = z + 1;
     228               0 :         minor = z;
     229               0 :         break;
     230                 :     default:
     231                 :         // Mathematical impossibility!
     232               0 :         MOZ_ASSERT(false);
     233               0 :         major = minor = final = 0;
     234                 :     }
     235               0 :     MOZ_ASSERT(major + minor + final == aRadius);
     236                 : 
     237               0 :     aLobes[0][0] = major;
     238               0 :     aLobes[0][1] = minor;
     239               0 :     aLobes[1][0] = minor;
     240               0 :     aLobes[1][1] = major;
     241               0 :     aLobes[2][0] = final;
     242               0 :     aLobes[2][1] = final;
     243               0 : }
     244                 : 
     245                 : static void
     246               0 : SpreadHorizontal(unsigned char* aInput,
     247                 :                  unsigned char* aOutput,
     248                 :                  int32_t aRadius,
     249                 :                  int32_t aWidth,
     250                 :                  int32_t aRows,
     251                 :                  int32_t aStride,
     252                 :                  const IntRect& aSkipRect)
     253                 : {
     254               0 :     if (aRadius == 0) {
     255               0 :         memcpy(aOutput, aInput, aStride * aRows);
     256               0 :         return;
     257                 :     }
     258                 : 
     259                 :     bool skipRectCoversWholeRow = 0 >= aSkipRect.x &&
     260               0 :                                     aWidth <= aSkipRect.XMost();
     261               0 :     for (int32_t y = 0; y < aRows; y++) {
     262                 :         // Check whether the skip rect intersects this row. If the skip
     263                 :         // rect covers the whole surface in this row, we can avoid
     264                 :         // this row entirely (and any others along the skip rect).
     265                 :         bool inSkipRectY = y >= aSkipRect.y &&
     266               0 :                              y < aSkipRect.YMost();
     267               0 :         if (inSkipRectY && skipRectCoversWholeRow) {
     268               0 :             y = aSkipRect.YMost() - 1;
     269               0 :             continue;
     270                 :         }
     271                 : 
     272               0 :         for (int32_t x = 0; x < aWidth; x++) {
     273                 :             // Check whether we are within the skip rect. If so, go
     274                 :             // to the next point outside the skip rect.
     275               0 :             if (inSkipRectY && x >= aSkipRect.x &&
     276               0 :                 x < aSkipRect.XMost()) {
     277               0 :                 x = aSkipRect.XMost();
     278               0 :                 if (x >= aWidth)
     279               0 :                     break;
     280                 :             }
     281                 : 
     282               0 :             int32_t sMin = max(x - aRadius, 0);
     283               0 :             int32_t sMax = min(x + aRadius, aWidth - 1);
     284               0 :             int32_t v = 0;
     285               0 :             for (int32_t s = sMin; s <= sMax; ++s) {
     286               0 :                 v = max<int32_t>(v, aInput[aStride * y + s]);
     287                 :             }
     288               0 :             aOutput[aStride * y + x] = v;
     289                 :         }
     290                 :     }
     291                 : }
     292                 : 
     293                 : static void
     294               0 : SpreadVertical(unsigned char* aInput,
     295                 :                unsigned char* aOutput,
     296                 :                int32_t aRadius,
     297                 :                int32_t aWidth,
     298                 :                int32_t aRows,
     299                 :                int32_t aStride,
     300                 :                const IntRect& aSkipRect)
     301                 : {
     302               0 :     if (aRadius == 0) {
     303               0 :         memcpy(aOutput, aInput, aStride * aRows);
     304               0 :         return;
     305                 :     }
     306                 : 
     307                 :     bool skipRectCoversWholeColumn = 0 >= aSkipRect.y &&
     308               0 :                                      aRows <= aSkipRect.YMost();
     309               0 :     for (int32_t x = 0; x < aWidth; x++) {
     310                 :         bool inSkipRectX = x >= aSkipRect.x &&
     311               0 :                            x < aSkipRect.XMost();
     312               0 :         if (inSkipRectX && skipRectCoversWholeColumn) {
     313               0 :             x = aSkipRect.XMost() - 1;
     314               0 :             continue;
     315                 :         }
     316                 : 
     317               0 :         for (int32_t y = 0; y < aRows; y++) {
     318                 :             // Check whether we are within the skip rect. If so, go
     319                 :             // to the next point outside the skip rect.
     320               0 :             if (inSkipRectX && y >= aSkipRect.y &&
     321               0 :                 y < aSkipRect.YMost()) {
     322               0 :                 y = aSkipRect.YMost();
     323               0 :                 if (y >= aRows)
     324               0 :                     break;
     325                 :             }
     326                 : 
     327               0 :             int32_t sMin = max(y - aRadius, 0);
     328               0 :             int32_t sMax = min(y + aRadius, aRows - 1);
     329               0 :             int32_t v = 0;
     330               0 :             for (int32_t s = sMin; s <= sMax; ++s) {
     331               0 :                 v = max<int32_t>(v, aInput[aStride * s + x]);
     332                 :             }
     333               0 :             aOutput[aStride * y + x] = v;
     334                 :         }
     335                 :     }
     336                 : }
     337                 : 
     338                 : static CheckedInt<int32_t>
     339               0 : RoundUpToMultipleOf4(int32_t aVal)
     340                 : {
     341               0 :   CheckedInt<int32_t> val(aVal);
     342                 : 
     343               0 :   val += 3;
     344               0 :   val /= 4;
     345               0 :   val *= 4;
     346                 : 
     347                 :   return val;
     348                 : }
     349                 : 
     350               0 : AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
     351                 :                            const IntSize& aSpreadRadius,
     352                 :                            const IntSize& aBlurRadius,
     353                 :                            const Rect* aDirtyRect,
     354                 :                            const Rect* aSkipRect)
     355                 :  : mSpreadRadius(aSpreadRadius),
     356                 :    mBlurRadius(aBlurRadius),
     357               0 :    mData(NULL)
     358                 : {
     359               0 :   Rect rect(aRect);
     360               0 :   rect.Inflate(Size(aBlurRadius + aSpreadRadius));
     361               0 :   rect.RoundOut();
     362                 : 
     363               0 :   if (aDirtyRect) {
     364                 :     // If we get passed a dirty rect from layout, we can minimize the
     365                 :     // shadow size and make painting faster.
     366               0 :     mHasDirtyRect = true;
     367               0 :     mDirtyRect = *aDirtyRect;
     368               0 :     Rect requiredBlurArea = mDirtyRect.Intersect(rect);
     369               0 :     requiredBlurArea.Inflate(Size(aBlurRadius + aSpreadRadius));
     370               0 :     rect = requiredBlurArea.Intersect(rect);
     371                 :   } else {
     372               0 :     mHasDirtyRect = false;
     373                 :   }
     374                 : 
     375               0 :   if (rect.IsEmpty()) {
     376               0 :     return;
     377                 :   }
     378                 : 
     379               0 :   if (aSkipRect) {
     380                 :     // If we get passed a skip rect, we can lower the amount of
     381                 :     // blurring/spreading we need to do. We convert it to IntRect to avoid
     382                 :     // expensive int<->float conversions if we were to use Rect instead.
     383               0 :     Rect skipRect = *aSkipRect;
     384               0 :     skipRect.RoundIn();
     385               0 :     skipRect.Deflate(Size(aBlurRadius + aSpreadRadius));
     386               0 :     mSkipRect = IntRect(skipRect.x, skipRect.y, skipRect.width, skipRect.height);
     387                 : 
     388               0 :     IntRect shadowIntRect(rect.x, rect.y, rect.width, rect.height);
     389               0 :     mSkipRect.IntersectRect(mSkipRect, shadowIntRect);
     390                 : 
     391               0 :     if (mSkipRect.IsEqualInterior(shadowIntRect))
     392               0 :       return;
     393                 : 
     394               0 :     mSkipRect -= shadowIntRect.TopLeft();
     395                 :   } else {
     396               0 :     mSkipRect = IntRect(0, 0, 0, 0);
     397                 :   }
     398                 : 
     399               0 :   mRect = IntRect(rect.x, rect.y, rect.width, rect.height);
     400                 : 
     401               0 :   CheckedInt<int32_t> stride = RoundUpToMultipleOf4(mRect.width);
     402               0 :   if (stride.valid()) {
     403               0 :     mStride = stride.value();
     404                 : 
     405               0 :     CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height *
     406               0 :                                sizeof(unsigned char);
     407               0 :     if (size.valid()) {
     408               0 :       mData = static_cast<unsigned char*>(malloc(size.value()));
     409               0 :       memset(mData, 0, size.value());
     410                 :     }
     411                 :   }
     412                 : }
     413                 : 
     414               0 : AlphaBoxBlur::~AlphaBoxBlur()
     415                 : {
     416               0 :   free(mData);
     417               0 : }
     418                 : 
     419                 : unsigned char*
     420               0 : AlphaBoxBlur::GetData()
     421                 : {
     422               0 :   return mData;
     423                 : }
     424                 : 
     425                 : IntSize
     426               0 : AlphaBoxBlur::GetSize()
     427                 : {
     428               0 :   IntSize size(mRect.width, mRect.height);
     429                 :   return size;
     430                 : }
     431                 : 
     432                 : int32_t
     433               0 : AlphaBoxBlur::GetStride()
     434                 : {
     435               0 :   return mStride;
     436                 : }
     437                 : 
     438                 : IntRect
     439               0 : AlphaBoxBlur::GetRect()
     440                 : {
     441               0 :   return mRect;
     442                 : }
     443                 : 
     444                 : Rect*
     445               0 : AlphaBoxBlur::GetDirtyRect()
     446                 : {
     447               0 :   if (mHasDirtyRect) {
     448               0 :     return &mDirtyRect;
     449                 :   }
     450                 : 
     451               0 :   return NULL;
     452                 : }
     453                 : 
     454                 : void
     455               0 : AlphaBoxBlur::Blur()
     456                 : {
     457               0 :   if (!mData) {
     458               0 :     return;
     459                 :   }
     460                 : 
     461                 :   // no need to do all this if not blurring or spreading
     462               0 :   if (mBlurRadius != IntSize(0,0) || mSpreadRadius != IntSize(0,0)) {
     463               0 :     int32_t stride = GetStride();
     464                 : 
     465                 :     // No need to use CheckedInt here - we have validated it in the constructor.
     466               0 :     size_t szB = stride * GetSize().height * sizeof(unsigned char);
     467               0 :     unsigned char* tmpData = static_cast<unsigned char*>(malloc(szB));
     468               0 :     if (!tmpData)
     469               0 :       return; // OOM
     470                 : 
     471               0 :     memset(tmpData, 0, szB);
     472                 : 
     473               0 :     if (mSpreadRadius.width > 0 || mSpreadRadius.height > 0) {
     474               0 :       SpreadHorizontal(mData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
     475               0 :       SpreadVertical(tmpData, mData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
     476                 :     }
     477                 : 
     478               0 :     if (mBlurRadius.width > 0) {
     479                 :       int32_t lobes[3][2];
     480               0 :       ComputeLobes(mBlurRadius.width, lobes);
     481               0 :       BoxBlurHorizontal(mData, tmpData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
     482               0 :       BoxBlurHorizontal(tmpData, mData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
     483               0 :       BoxBlurHorizontal(mData, tmpData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
     484                 :     } else {
     485               0 :       memcpy(tmpData, mData, stride * GetSize().height);
     486                 :     }
     487                 : 
     488               0 :     if (mBlurRadius.height > 0) {
     489                 :       int32_t lobes[3][2];
     490               0 :       ComputeLobes(mBlurRadius.height, lobes);
     491               0 :       BoxBlurVertical(tmpData, mData, lobes[0][0], lobes[0][1], stride, GetSize().height, mSkipRect);
     492               0 :       BoxBlurVertical(mData, tmpData, lobes[1][0], lobes[1][1], stride, GetSize().height, mSkipRect);
     493               0 :       BoxBlurVertical(tmpData, mData, lobes[2][0], lobes[2][1], stride, GetSize().height, mSkipRect);
     494                 :     } else {
     495               0 :       memcpy(mData, tmpData, stride * GetSize().height);
     496                 :     }
     497                 : 
     498               0 :     free(tmpData);
     499                 :   }
     500                 : 
     501                 : }
     502                 : 
     503                 : /**
     504                 :  * Compute the box blur size (which we're calling the blur radius) from
     505                 :  * the standard deviation.
     506                 :  *
     507                 :  * Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
     508                 :  * approximating a Gaussian using box blurs.  This yields quite a good
     509                 :  * approximation for a Gaussian.  Then we multiply this by 1.5 since our
     510                 :  * code wants the radius of the entire triple-box-blur kernel instead of
     511                 :  * the diameter of an individual box blur.  For more details, see:
     512                 :  *   http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
     513                 :  *   https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
     514                 :  */
     515                 : static const Float GAUSSIAN_SCALE_FACTOR = (3 * sqrt(2 * M_PI) / 4) * 1.5;
     516                 : 
     517                 : IntSize
     518               0 : AlphaBoxBlur::CalculateBlurRadius(const Point& aStd)
     519                 : {
     520               0 :     IntSize size(static_cast<int32_t>(floor(aStd.x * GAUSSIAN_SCALE_FACTOR + 0.5)),
     521               0 :                  static_cast<int32_t>(floor(aStd.y * GAUSSIAN_SCALE_FACTOR + 0.5)));
     522                 : 
     523                 :     return size;
     524                 : }
     525                 : 
     526                 : }
     527                 : }

Generated by: LCOV version 1.7