[Libreoffice-commits] core.git: vcl/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Wed Apr 29 08:40:36 UTC 2020


 vcl/source/bitmap/BitmapFilterStackBlur.cxx |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

New commits:
commit c28b3286435851ce82875ab6d3551f673de4a3eb
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Wed Apr 29 10:25:32 2020 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Wed Apr 29 10:40:01 2020 +0200

    Fix row/column pre-initialization in stack blur
    
    The changed code is used to initialize data before processing first
    pixel of each row/column of the bitmap, since in order to blur it,
    we need some information about assumed previous pixels. But previous
    code assumed that information for the first pixel or each row and
    each column is taken from first pixels of first column, not from
    first pixels of respective row or respective column. This doesn't
    make practical difference for the pre-extended bitmap with a solid
    color of the border (see centerExtendBitmap; it's the only actual
    case ATM). But in case of not pre-extended bitmap with non-solid
    border color, that would result in wrong blur of first pixels.
    
    Consider this bitmap (* is white, 0 is black):
    
        *00000000
        *00000000
        *00000000
        *00000000
        *00000000
        000000000
        ...
    
    For this bitmap, existing code pre-initialized each row and each
    column as if it were prepended with "******" from column 0, and so
    each first pixel of each column and each row would be blurred with
    white, even where it's all black (consider columns >=1, and rows
    >=5).
    
    Additionally, the existing initialization assumed that there's
    always at least as many scanlines as min(radius, bmpWidth), which
    might be false. See how aArrays was initialized using nLastIndexX
    in stackBlurHorizontal, and then that value affected the index
    passed to pReadAccess->GetScanline.
    
    This changes the code to consistently consider first pixels of
    respective rows/columns for pre-initialization data.
    
    Change-Id: Ibe3be8750fe5347302eca782a00b36096d99820c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/93118
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/vcl/source/bitmap/BitmapFilterStackBlur.cxx b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
index adac14248753..fde6ab089a3b 100644
--- a/vcl/source/bitmap/BitmapFilterStackBlur.cxx
+++ b/vcl/source/bitmap/BitmapFilterStackBlur.cxx
@@ -98,7 +98,7 @@ public:
     {
         for (long i = 0; i < maShared.mnDiv; i++)
         {
-            maPositionTable[i] = std::min(nLastIndex, std::max(0L, i - maShared.mnRadius));
+            maPositionTable[i] = std::clamp(i - maShared.mnRadius, 0L, nLastIndex);
             maWeightTable[i] = maShared.mnRadius + 1 - std::abs(i - maShared.mnRadius);
         }
     }
@@ -261,9 +261,15 @@ void stackBlurHorizontal(BlurSharedData const& rShared, long nStart, long nEnd)
         SumFunction::set(nInSum, 0L);
         SumFunction::set(nOutSum, 0L);
 
+        // Pre-initialize blur data for first pixel.
+        // aArrays.maPositionTable contains values like (for radius of 5): [0,0,0,0,0,0,1,2,3,4,5],
+        // which are used as pixels indices in the current row that we use to prepare information
+        // for the first pixel; aArrays.maWeightTable has [1,2,3,4,5,6,5,4,3,2,1]. Before looking at
+        // the first row pixel, we pretend to have processed fake previous pixels, as if the row was
+        // extended to the left with the same color as that of the first pixel.
         for (long i = 0; i < nDiv; i++)
         {
-            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+            pSourcePointer = pReadAccess->GetScanline(y) + nComponentWidth * pPositionPointer[i];
 
             pStackPtr = &pStack[nComponentWidth * i];
 
@@ -374,9 +380,15 @@ void stackBlurVertical(BlurSharedData const& rShared, long nStart, long nEnd)
         SumFunction::set(nInSum, 0L);
         SumFunction::set(nOutSum, 0L);
 
+        // Pre-initialize blur data for first pixel.
+        // aArrays.maPositionTable contains values like (for radius of 5): [0,0,0,0,0,0,1,2,3,4,5],
+        // which are used as pixels indices in the current column that we use to prepare information
+        // for the first pixel; aArrays.maWeightTable has [1,2,3,4,5,6,5,4,3,2,1]. Before looking at
+        // the first column pixels, we pretend to have processed fake previous pixels, as if the
+        // column was extended to the top with the same color as that of the first pixel.
         for (long i = 0; i < nDiv; i++)
         {
-            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]);
+            pSourcePointer = pReadAccess->GetScanline(pPositionPointer[i]) + nComponentWidth * x;
 
             pStackPtr = &pStack[nComponentWidth * i];
 


More information about the Libreoffice-commits mailing list