[Libreoffice-commits] .: 4 commits - cui/source svx/inc svx/source vcl/inc vcl/source
Tomaž Vajngerl
tvajngerl at kemper.freedesktop.org
Fri Jun 15 15:39:23 PDT 2012
cui/source/dialogs/cuigrfflt.cxx | 51 ++++++++
cui/source/dialogs/grfflt.hrc | 7 +
cui/source/dialogs/grfflt.src | 72 ++++++++++++
cui/source/factory/dlgfact.cxx | 15 +-
cui/source/factory/dlgfact.hxx | 22 ++-
cui/source/inc/cuigrfflt.hxx | 20 +++
svx/inc/svx/dialogs.hrc | 1
svx/inc/svx/svxcommands.h | 1
svx/inc/svx/svxdlg.hxx | 3
svx/source/dialog/grfflt.cxx | 25 +---
vcl/inc/vcl/bitmap.hxx | 114 +++++++++++++++++--
vcl/source/gdi/bitmap3.cxx | 232 ++++++++++++---------------------------
vcl/source/gdi/bitmap4.cxx | 206 ++++++++++++++++++++++++++++++++++
13 files changed, 563 insertions(+), 206 deletions(-)
New commits:
commit ee41193f3e12ea55237f7681e4b53162a0d421d2
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Sat Jun 16 00:05:00 2012 +0200
Dialog for Smooth filter
Added dialog for smooth (gaussian blur) filter which now accepts
a parameter for setting the strenth of smoothing (bluring).
Change-Id: Ida6709b060cb5429a63af1994493e716fd0bfebb
diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx
index c1b3ad4..f074e17 100644
--- a/cui/source/dialogs/cuigrfflt.cxx
+++ b/cui/source/dialogs/cuigrfflt.cxx
@@ -245,6 +245,57 @@ Graphic GraphicFilterMosaic::GetFilteredGraphic( const Graphic& rGraphic,
}
// ------------------
+// - GraphicFilterSmooth -
+// ------------------
+
+GraphicFilterSmooth::GraphicFilterSmooth( Window* pParent, const Graphic& rGraphic, double nRadius) :
+ GraphicFilterDialog ( pParent, CUI_RES( RID_SVX_GRFFILTER_DLG_SMOOTH ), rGraphic ),
+ maFtRadius ( this, CUI_RES( DLG_FILTERSMOOTH_FT_RADIUS ) ),
+ maMtrRadius ( this, CUI_RES( DLG_FILTERSMOOTH_MTR_RADIUS ) )
+{
+ FreeResource();
+
+ maMtrRadius.SetValue( nRadius* 10 );
+ maMtrRadius.SetModifyHdl( GetModifyHdl() );
+ maMtrRadius.GrabFocus();
+}
+
+// -----------------------------------------------------------------------------
+
+GraphicFilterSmooth::~GraphicFilterSmooth()
+{
+}
+
+// -----------------------------------------------------------------------------
+
+Graphic GraphicFilterSmooth::GetFilteredGraphic( const Graphic& rGraphic, double /*fScaleX*/, double /*fScaleY*/ )
+{
+ Graphic aRet;
+ BmpFilterParam aParam( GetRadius() );
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if( aAnim.Filter( BMP_FILTER_SMOOTH, &aParam ) )
+ {
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if( aBmpEx.Filter( BMP_FILTER_SMOOTH, &aParam ) )
+ {
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+// ------------------
// - GraphicFilterSolarize -
// ------------------
diff --git a/cui/source/dialogs/grfflt.hrc b/cui/source/dialogs/grfflt.hrc
index 94d7f8f..c0a980f 100644
--- a/cui/source/dialogs/grfflt.hrc
+++ b/cui/source/dialogs/grfflt.hrc
@@ -49,6 +49,13 @@
#define DLG_FILTERMOSAIC_CBX_EDGES 5
// ----------------------
+// - DLG_FILTERSMOOTH -
+// ----------------------
+
+#define DLG_FILTERSMOOTH_FT_RADIUS 1
+#define DLG_FILTERSMOOTH_MTR_RADIUS 2
+
+// ----------------------
// - DLG_FILTERSOLARIZE -
// ----------------------
diff --git a/cui/source/dialogs/grfflt.src b/cui/source/dialogs/grfflt.src
index c13eaf3..8bb22b9 100644
--- a/cui/source/dialogs/grfflt.src
+++ b/cui/source/dialogs/grfflt.src
@@ -428,3 +428,75 @@ ModalDialog RID_SVX_GRFFILTER_DLG_EMBOSS
TabStop = TRUE ;
};
};
+
+// --------------------
+// - DLG_FILTERSMOOTH -
+// --------------------
+
+ModalDialog RID_SVX_GRFFILTER_DLG_SMOOTH
+{
+ HelpID = CMD_SID_GRFFILTER_SMOOTH;
+ OutputSize = TRUE ;
+ Moveable = TRUE ;
+ SVLook = TRUE ;
+ Size = MAP_APPFONT ( 250, 100 ) ;
+
+ Text [ en-US ] = "Smooth" ;
+
+ FixedLine FL_PARAMETER
+ {
+ Pos = MAP_APPFONT ( 6 , 3 ) ;
+ Size = MAP_APPFONT ( 182, RSC_CD_FIXEDLINE_HEIGHT ) ;
+ Text [ en-US ] = "Parameters";
+ };
+ Control CTL_PREVIEW
+ {
+ Pos = MAP_APPFONT ( 104 , 3 + RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_INNERBORDER_TOP ) ;
+ Size = MAP_APPFONT ( 81, 73 ) ;
+ };
+#define MA_Y14 3 + RSC_CD_FIXEDLINE_HEIGHT + RSC_SP_FLGR_INNERBORDER_TOP
+ FixedText DLG_FILTERSMOOTH_FT_RADIUS
+ {
+ Pos = MAP_APPFONT ( 12 , MA_Y14 ) ;
+ Size = MAP_APPFONT ( 77 , 10 ) ;
+ Text [ en-US ] = "Smooth Radius" ;
+ };
+#define MA_Y15 MA_Y14 + RSC_CD_FIXEDTEXT_HEIGHT + RSC_SP_CTRL_DESC_Y
+ NumericField DLG_FILTERSMOOTH_MTR_RADIUS
+ {
+ HelpID = "cui:NumericField:RID_SVX_GRFFILTER_DLG_SMOOTH:DLG_FILTERSMOOTH_MTR_RADIUS";
+ Border = TRUE ;
+ Pos = MAP_APPFONT ( 12 , MA_Y15 );
+ Size = MAP_APPFONT ( 35 , 12 );
+ TabStop = TRUE;
+ Right = TRUE;
+ Repeat = TRUE;
+ Spin = TRUE;
+ Minimum = 0;
+ Maximum = 1000;
+ StrictFormat = TRUE;
+ First = 1;
+ DecimalDigits = 1;
+ Last = 1000;
+ SpinSize = 2;
+ };
+ OKButton BTN_OK
+ {
+ Pos = MAP_APPFONT ( 194, 6 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ TabStop = TRUE ;
+ DefButton = TRUE ;
+ };
+ CancelButton BTN_CANCEL
+ {
+ Pos = MAP_APPFONT ( 194, 23 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ TabStop = TRUE ;
+ };
+ HelpButton BTN_HELP
+ {
+ Pos = MAP_APPFONT ( 194, 43 ) ;
+ Size = MAP_APPFONT ( 50, 14 ) ;
+ TabStop = TRUE ;
+ };
+};
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
index bcb26fd..e65d314 100644
--- a/cui/source/factory/dlgfact.cxx
+++ b/cui/source/factory/dlgfact.cxx
@@ -1574,18 +1574,23 @@ AbstractGraphicFilterDialog * AbstractDialogFactory_Impl::CreateGraphicFilterPos
return 0;
}
+AbstractGraphicFilterDialog * AbstractDialogFactory_Impl::CreateGraphicFilterSmooth ( Window* pParent,
+ const Graphic& rGraphic, double nRadius, sal_uInt32)
+{
+ GraphicFilterDialog* pDlg = new GraphicFilterSmooth( pParent, rGraphic, nRadius );
+ return new AbstractGraphicFilterDialog_Impl( pDlg );
+}
+
AbstractGraphicFilterDialog * AbstractDialogFactory_Impl::CreateGraphicFilterSolarize (Window* pParent, //add for GraphicFilterSolarize
- const Graphic& rGraphic,
- sal_uInt8 nGreyThreshold, sal_Bool bInvert, sal_uInt32 )
+ const Graphic& rGraphic, sal_uInt8 nGreyThreshold, sal_Bool bInvert, sal_uInt32 )
{
GraphicFilterDialog* pDlg = new GraphicFilterSolarize( pParent, rGraphic, nGreyThreshold, bInvert );
return new AbstractGraphicFilterDialog_Impl( pDlg );
}
AbstractGraphicFilterDialog * AbstractDialogFactory_Impl::CreateGraphicFilterMosaic (Window* pParent, //add for GraphicFilterMosaic
- const Graphic& rGraphic,
- sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, sal_Bool bEnhanceEdges,
- sal_uInt32 nResId)
+ const Graphic& rGraphic, sal_uInt16 nTileWidth, sal_uInt16 nTileHeight,
+ sal_Bool bEnhanceEdges, sal_uInt32 nResId)
{
GraphicFilterDialog* pDlg=NULL;
switch ( nResId )
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
index 0f25c25..024300b 100644
--- a/cui/source/factory/dlgfact.hxx
+++ b/cui/source/factory/dlgfact.hxx
@@ -725,18 +725,20 @@ public:
sal_Int16 nInitialContext,
const Link& lnkContextSupplier);
virtual AbstractGraphicFilterDialog * CreateGraphicFilterEmboss (Window* pParent, //add for GraphicFilterEmboss
- const Graphic& rGraphic,
- RECT_POINT eLightSource, sal_uInt32 nResId);
+ const Graphic& rGraphic, RECT_POINT eLightSource,
+ sal_uInt32 nResId);
virtual AbstractGraphicFilterDialog * CreateGraphicFilterPosterSepia (Window* pParent, //add for GraphicFilterPoster & GraphicFilterSepia
- const Graphic& rGraphic,
- sal_uInt16 nCount,
- sal_uInt32 nResId);
- virtual AbstractGraphicFilterDialog * CreateGraphicFilterSolarize (Window* pParent, //add for GraphicFilterSolarize
- const Graphic& rGraphic,
- sal_uInt8 nGreyThreshold, sal_Bool bInvert, sal_uInt32 nResId);
+ const Graphic& rGraphic, sal_uInt16 nCount,
+ sal_uInt32 nResId);
+ virtual AbstractGraphicFilterDialog * CreateGraphicFilterSmooth (Window* pParent, //add for GraphicFilterSolarize
+ const Graphic& rGraphic, double nRadius,
+ sal_uInt32 nResId);
+ virtual AbstractGraphicFilterDialog * CreateGraphicFilterSolarize (Window* pParent, //add for GraphicFilterSmooth
+ const Graphic& rGraphic, sal_uInt8 nGreyThreshold,
+ sal_Bool bInvert, sal_uInt32 nResId);
virtual AbstractGraphicFilterDialog * CreateGraphicFilterMosaic (Window* pParent, //add for GraphicFilterMosaic
- const Graphic& rGraphic,
- sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, sal_Bool bEnhanceEdges, sal_uInt32 nResId);
+ const Graphic& rGraphic, sal_uInt16 nTileWidth, sal_uInt16 nTileHeight,
+ sal_Bool bEnhanceEdges, sal_uInt32 nResId);
virtual AbstractSvxAreaTabDialog* CreateSvxAreaTabDialog( Window* pParent,//add for SvxAreaTabDialog
const SfxItemSet* pAttr,
SdrModel* pModel,
diff --git a/cui/source/inc/cuigrfflt.hxx b/cui/source/inc/cuigrfflt.hxx
index 05b0eec..98303e0 100644
--- a/cui/source/inc/cuigrfflt.hxx
+++ b/cui/source/inc/cuigrfflt.hxx
@@ -95,6 +95,26 @@ public:
virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) = 0;
};
+// -------------------------
+// - GraphicFilterSmooth -
+// -------------------------
+
+class GraphicFilterSmooth : public GraphicFilterDialog
+{
+private:
+
+ FixedText maFtRadius;
+ NumericField maMtrRadius;
+
+public:
+
+ GraphicFilterSmooth( Window* pParent, const Graphic& rGraphic, double nRadius);
+ ~GraphicFilterSmooth();
+
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY );
+ double GetRadius() const { return maMtrRadius.GetValue() / 10.0; }
+};
+
// -----------------------
// - GraphicFilterMosaic -
// -----------------------
diff --git a/svx/inc/svx/dialogs.hrc b/svx/inc/svx/dialogs.hrc
index 201e7f9..008dcb8 100644
--- a/svx/inc/svx/dialogs.hrc
+++ b/svx/inc/svx/dialogs.hrc
@@ -117,6 +117,7 @@
#define RID_SVX_GRFFILTER_DLG_MOSAIC (RID_SVX_START + 332)
#define RID_SVX_GRFFILTER_DLG_SOLARIZE (RID_SVX_START + 333)
#define RID_SVX_GRFFILTER_DLG_EMBOSS (RID_SVX_START + 336)
+#define RID_SVX_GRFFILTER_DLG_SMOOTH (RID_SVX_START + 337)
#define RID_SVXDLG_SEARCHFORMAT (RID_SVX_START + 21)
#define RID_SVXDLG_CHARMAP ( RID_SVX_START + 10 )
#define RID_SVXDLG_POSTIT ( RID_SVX_START + 8 )
diff --git a/svx/inc/svx/svxcommands.h b/svx/inc/svx/svxcommands.h
index 635ed4d..b42be8f 100644
--- a/svx/inc/svx/svxcommands.h
+++ b/svx/inc/svx/svxcommands.h
@@ -94,6 +94,7 @@
#define CMD_SID_GRFFILTER_POSTER ".uno:GraphicFilterPoster"
#define CMD_SID_GRFFILTER_EMBOSS ".uno:GraphicFilterRelief"
#define CMD_SID_GRFFILTER_SEPIA ".uno:GraphicFilterSepia"
+#define CMD_SID_GRFFILTER_SMOOTH ".uno:GraphicFilterSmooth"
#define CMD_SID_GRFFILTER_SOLARIZE ".uno:GraphicFilterSolarize"
#define CMD_SID_GRID_USE ".uno:GridUse"
#define CMD_SID_GRID_VISIBLE ".uno:GridVisible"
diff --git a/svx/inc/svx/svxdlg.hxx b/svx/inc/svx/svxdlg.hxx
index d3bb8b1..b7aee5f 100644
--- a/svx/inc/svx/svxdlg.hxx
+++ b/svx/inc/svx/svxdlg.hxx
@@ -444,6 +444,9 @@ public:
const Graphic& rGraphic,
sal_uInt16 nCount,
sal_uInt32 nResId)=0;
+ virtual AbstractGraphicFilterDialog * CreateGraphicFilterSmooth (Window* pParent, //add for GraphicFilterSmooth
+ const Graphic& rGraphic,
+ double nRadius, sal_uInt32 nResId)=0;
virtual AbstractGraphicFilterDialog * CreateGraphicFilterSolarize (Window* pParent, //add for GraphicFilterSolarize
const Graphic& rGraphic,
sal_uInt8 nGreyThreshold, sal_Bool bInvert, sal_uInt32 nResId)=0;
diff --git a/svx/source/dialog/grfflt.cxx b/svx/source/dialog/grfflt.cxx
index a446e3d..809c3da 100644
--- a/svx/source/dialog/grfflt.cxx
+++ b/svx/source/dialog/grfflt.cxx
@@ -83,26 +83,15 @@ sal_uIntPtr SvxGraphicFilter::ExecuteGrfFilterSlot( SfxRequest& rReq, GraphicObj
case( SID_GRFFILTER_SMOOTH ):
{
- if( pShell )
- pShell->SetWaitCursor( sal_True );
-
- if( rGraphic.IsAnimated() )
- {
- Animation aAnimation( rGraphic.GetAnimation() );
-
- if( aAnimation.Filter( BMP_FILTER_SMOOTH ) )
- aGraphic = aAnimation;
- }
- else
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ if(pFact)
{
- BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
-
- if( aBmpEx.Filter( BMP_FILTER_SMOOTH ) )
- aGraphic = aBmpEx;
+ AbstractGraphicFilterDialog* aDlg = pFact->CreateGraphicFilterSmooth( pWindow, rGraphic, 0.7, RID_SVX_GRFFILTER_DLG_SEPIA);
+ DBG_ASSERT(aDlg, "Dialogdiet fail!");
+ if( aDlg->Execute() == RET_OK )
+ aGraphic = aDlg->GetFilteredGraphic( rGraphic, 1.0, 1.0 );
+ delete aDlg;
}
-
- if( pShell )
- pShell->SetWaitCursor( sal_False );
}
break;
commit d7036ac1c8f620eae2b4f43cdf5840b4c8a584c6
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Fri Jun 15 22:54:02 2012 +0200
Fix wrong variable name in Smooth filter parameters class.
Change-Id: I4ad84a293f662a6e191758c30660ac11142aa3eb
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index dc354cf..2fbe184 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -200,7 +200,7 @@ public:
BmpFilterParam( double nRadius, sal_uLong nProgressStart = 0, sal_uLong nProgressEnd = 0 ) :
meFilter( BMP_FILTER_SMOOTH ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
- mnRadius( cSolarGreyThreshold ) {}
+ mnRadius( nRadius ) {}
BmpFilterParam( sal_uInt16 nSepiaPercent, sal_uLong nProgressStart = 0, sal_uLong nProgressEnd = 0 ) :
meFilter( BMP_FILTER_SEPIA ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
commit 05363527d84119c6759cdd638c76b041f2aa67b7
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Fri Jun 15 07:22:32 2012 +0200
Separable Gaussian Blur and Unsharpen Mask filter.
Currently implemented Gaussian Blur filter uses a static matrix
which means that the filter can not be parameterized. The new
implementation of Gaussian Blur filter and accepts a blur radius
as a parameter so the user can change the strength of the blur.
For this the blur matrix is generated at each call. The new Blur
implementation reuses separable convolution from Lanzcos rescale.
For negative values of radius the Bitmap will be sharpened. For
this an Unsharpen Mask filter is used, which is actually a blurred
image substracted from the original image.
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index 7e6cf3a..dc354cf 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -183,6 +183,7 @@ private:
{
sal_uInt16 mnSepiaPercent;
sal_uInt8 mcSolarGreyThreshold;
+ double mnRadius;
MosaicTileSize maMosaicTileSize;
EmbossAngles maEmbossAngles;
@@ -197,6 +198,10 @@ public:
meFilter( BMP_FILTER_SOLARIZE ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
mcSolarGreyThreshold( cSolarGreyThreshold ) {}
+ BmpFilterParam( double nRadius, sal_uLong nProgressStart = 0, sal_uLong nProgressEnd = 0 ) :
+ meFilter( BMP_FILTER_SMOOTH ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
+ mnRadius( cSolarGreyThreshold ) {}
+
BmpFilterParam( sal_uInt16 nSepiaPercent, sal_uLong nProgressStart = 0, sal_uLong nProgressEnd = 0 ) :
meFilter( BMP_FILTER_SEPIA ), mnProgressStart( nProgressStart ), mnProgressEnd( nProgressEnd ),
mnSepiaPercent( nSepiaPercent ) {}
@@ -397,6 +402,10 @@ public:
SAL_DLLPRIVATE sal_Bool ImplMosaic( const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplPopArt( const BmpFilterParam* pFilterParam, const Link* pProgress );
+ SAL_DLLPRIVATE bool ImplSeparableBlurFilter( const double aRadius = 0.7 );
+ SAL_DLLPRIVATE bool ImplSeparableUnsharpenFilter( const double aRadius = 0.7 );
+ SAL_DLLPRIVATE void ImplBlurContributions( const int aSize, const int aNumberOfContributions,
+ double* pBlurVector, double*& pWeights, int*& pPixels, int*& pCount );
public:
Bitmap();
diff --git a/vcl/source/gdi/bitmap4.cxx b/vcl/source/gdi/bitmap4.cxx
index 331ac8b..2dc6948 100644
--- a/vcl/source/gdi/bitmap4.cxx
+++ b/vcl/source/gdi/bitmap4.cxx
@@ -55,8 +55,20 @@ sal_Bool Bitmap::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam,
{
case( BMP_FILTER_SMOOTH ):
{
- const long pSmoothMatrix[] = { 1, 2, 1, 2, 5, 2, 1, 2, 1 };
- bRet = ImplConvolute3( &pSmoothMatrix[ 0 ], 17, pFilterParam, pProgress );
+ // Blur for positive values of mnRadius
+ if (pFilterParam->mnRadius > 0.0)
+ {
+ bRet = ImplSeparableBlurFilter(pFilterParam->mnRadius);
+ }
+ // Unsharpen Mask for negative values of mnRadius
+ else if (pFilterParam->mnRadius < 0.0)
+ {
+ bRet = ImplSeparableUnsharpenFilter(pFilterParam->mnRadius);
+ }
+ else
+ {
+ bRet = sal_False;
+ }
}
break;
@@ -1006,4 +1018,194 @@ sal_Bool Bitmap::ImplPopArt( const BmpFilterParam* /*pFilterParam*/, const Link*
return bRet;
}
+
+double* MakeBlurKernel(const double radius, int& rows) {
+ int intRadius = (int) radius + 1.0;
+ rows = intRadius * 2 + 1;
+ double* matrix = new double[rows];
+
+ double sigma = radius / 3;
+ double radius2 = radius * radius;
+ int index = 0;
+ for (int row = -intRadius; row <= intRadius; row++)
+ {
+ double distance = row*row;
+ if (distance > radius2) {
+ matrix[index] = 0.0;
+ }else {
+ matrix[index] = exp( -distance / (2.0 * sigma * sigma) ) / sqrt( 2.0 * M_PI * sigma );
+ }
+ index++;
+ }
+ return matrix;
+}
+
+void Bitmap::ImplBlurContributions( const int aSize, const int aNumberOfContributions,
+ double* pBlurVector, double*& pWeights, int*& pPixels, int*& pCount )
+{
+ pWeights = new double[ aSize*aNumberOfContributions ];
+ pPixels = new int[ aSize*aNumberOfContributions ];
+ pCount = new int[ aSize ];
+
+ int aLeft, aRight, aCurrentCount, aPixelIndex;
+ double aWeight;
+
+ for ( int i = 0; i < aSize; i++ )
+ {
+ aLeft = (int) i - aNumberOfContributions / 2;
+ aRight = (int) i + aNumberOfContributions / 2;
+ aCurrentCount = 0;
+ for ( int j = aLeft; j <= aRight; j++ )
+ {
+ aWeight = pBlurVector[aCurrentCount];
+
+ // Mirror edges
+ if (j < 0)
+ {
+ aPixelIndex = -j;
+ }
+ else if ( j >= aSize )
+ {
+ aPixelIndex = (aSize - j) + aSize - 1;
+ }
+ else
+ {
+ aPixelIndex = j;
+ }
+
+ // Edge case for small bitmaps
+ if ( aPixelIndex < 0 || aPixelIndex >= aSize )
+ {
+ aWeight = 0.0;
+ }
+
+ pWeights[ i*aNumberOfContributions + aCurrentCount ] = aWeight;
+ pPixels[ i*aNumberOfContributions + aCurrentCount ] = aPixelIndex;
+
+ aCurrentCount++;
+ }
+ pCount[ i ] = aCurrentCount;
+ }
+}
+
+// Separable Gaussian Blur
+//
+// Separable Gaussian Blur filter and accepts a blur radius
+// as a parameter so the user can change the strength of the blur.
+// Radius of 1.0 is 3 * standard deviation of gauss function.
+//
+// Separable Blur implementation uses 2x separable 1D convolution
+// to process the image.
+bool Bitmap::ImplSeparableBlurFilter(const double radius)
+{
+ const long nWidth = GetSizePixel().Width();
+ const long nHeight = GetSizePixel().Height();
+
+ // Prepare Blur Vector
+ int aNumberOfContributions;
+ double* pBlurVector = MakeBlurKernel(radius, aNumberOfContributions);
+
+ double* pWeights;
+ int* pPixels;
+ int* pCount;
+
+ // Do horizontal filtering
+ ImplBlurContributions( nWidth, aNumberOfContributions, pBlurVector, pWeights, pPixels, pCount);
+
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+
+ // switch coordinates as convolution pass transposes result
+ Bitmap aNewBitmap( Size( nHeight, nWidth ), 24 );
+
+ bool bResult = ImplConvolutionPass( aNewBitmap, nWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+
+ // Cleanup
+ ReleaseAccess( pReadAcc );
+ delete[] pWeights;
+ delete[] pPixels;
+ delete[] pCount;
+
+ if ( !bResult )
+ return bResult;
+
+ // Swap current bitmap with new bitmap
+ ImplAssignWithSize( aNewBitmap );
+
+ // Do vertical filtering
+ ImplBlurContributions(nHeight, aNumberOfContributions, pBlurVector, pWeights, pPixels, pCount );
+
+ pReadAcc = AcquireReadAccess();
+ aNewBitmap = Bitmap( Size( nWidth, nHeight ), 24 );
+ bResult = ImplConvolutionPass( aNewBitmap, nHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+
+ // Cleanup
+ ReleaseAccess( pReadAcc );
+ delete[] pWeights;
+ delete[] pCount;
+ delete[] pPixels;
+ delete[] pBlurVector;
+
+ if ( !bResult )
+ return bResult;
+
+ // Swap current bitmap with new bitmap
+ ImplAssignWithSize( aNewBitmap );
+
+ return true;
+}
+
+// Separable Unsharepn Mask filter is actually a substracted blured
+// image from the original image.
+bool Bitmap::ImplSeparableUnsharpenFilter(const double radius) {
+ const long nWidth = GetSizePixel().Width();
+ const long nHeight = GetSizePixel().Height();
+
+ Bitmap aBlur( *this );
+ aBlur.ImplSeparableBlurFilter(-radius);
+
+ // Amount of unsharpening effect on image - currently set to a fixed value
+ double aAmount = 2.0;
+
+ Bitmap aResultBitmap( Size( nWidth, nHeight ), 24);
+
+ BitmapReadAccess* pReadAccBlur = aBlur.AcquireReadAccess();
+ BitmapReadAccess* pReadAcc = AcquireReadAccess();
+ BitmapWriteAccess* pWriteAcc = aResultBitmap.AcquireWriteAccess();
+
+ BitmapColor aColor, aColorBlur;
+
+ // For all pixels in original image substract pixels values from blured image.
+ for( int x = 0; x < nWidth; x++ )
+ {
+ for( int y = 0; y < nHeight; y++ )
+ {
+ aColorBlur = pReadAccBlur->GetPixel( y , x );
+ if( pReadAccBlur->HasPalette() )
+ {
+ pReadAccBlur->GetPaletteColor( aColorBlur );
+ }
+
+ aColor = pReadAcc->GetPixel( y , x );
+ if( pReadAcc->HasPalette() )
+ {
+ aColor = pReadAcc->GetPaletteColor( aColor );
+ }
+
+ BitmapColor aResultColor(
+ (sal_uInt8) MinMax( aColor.GetRed() + (aColor.GetRed() - aColorBlur.GetRed()) * aAmount, 0, 255 ),
+ (sal_uInt8) MinMax( aColor.GetGreen() + (aColor.GetGreen() - aColorBlur.GetGreen()) * aAmount, 0, 255 ),
+ (sal_uInt8) MinMax( aColor.GetBlue() + (aColor.GetBlue() - aColorBlur.GetBlue()) * aAmount, 0, 255 ) );
+
+ pWriteAcc->SetPixel( y, x, aResultColor );
+ }
+ }
+
+ ReleaseAccess( pWriteAcc );
+ ReleaseAccess( pReadAcc );
+ ReleaseAccess( pReadAccBlur );
+ ImplAssignWithSize ( aResultBitmap );
+ return true;
+}
+
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit c02dd533f5a21b8386b6cfe8fdd9e3f83e7cbc7b
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Fri Jun 15 07:17:36 2012 +0200
Add new Scale modes, simplify convolution calculation.
Convolution calculation now uses 2x transposing horizontal pass
instead of horizontal and vertical which simplifies the code by
reducing code duplication.
Instead of more convolution methods, only one generic method is
used and kernels are now a parameter to the method. For this
Kernel class was introduced with responsibility to calculate
kernel walues and hold kernel specific information.
Besides Lanzcos resampling also Box, Bilinear and Bicubic resampling
was introduced. Box is the simplest and fastest but with still
good quality.
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index 3dbee50..7e6cf3a 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -50,6 +50,9 @@
#define BMP_SCALE_FAST 0x00000001UL
#define BMP_SCALE_INTERPOLATE 0x00000002UL
#define BMP_SCALE_LANCZOS 0x00000003UL
+#define BMP_SCALE_BICUBIC 0x00000004UL
+#define BMP_SCALE_BILINEAR 0x00000005UL
+#define BMP_SCALE_BOX 0x00000006UL
// -----------------------------------------------------------------------------
@@ -158,7 +161,7 @@ class VCL_DLLPUBLIC BmpFilterParam
friend class Animation;
private:
- BmpFilter meFilter;
+ BmpFilter meFilter;
sal_uLong mnProgressStart;
sal_uLong mnProgressEnd;
@@ -213,6 +216,89 @@ public:
}
};
+// --------------------
+// Resample Kernels
+// --------------------
+
+class Kernel
+{
+
+public:
+ Kernel () {}
+ virtual ~Kernel() {}
+
+ virtual double GetWidth() = 0;
+ virtual double Calculate( double x ) = 0;
+};
+
+class Lanczos3Kernel : public Kernel
+{
+
+public:
+ virtual double GetWidth() { return 3.0; }
+ virtual double Calculate (double x)
+ {
+ return (-3.0 <= x && x < 3.0) ? SincFilter(x) * SincFilter( x / 3.0 ) : 0.0;
+ }
+
+ inline double SincFilter(double x)
+ {
+ if (x == 0.0)
+ {
+ return 1.0;
+ }
+ x = x * M_PI;
+ return sin(x) / x;
+ }
+};
+
+class BicubicKernel : public Kernel {
+ virtual double GetWidth() { return 2.0; }
+ virtual double Calculate (double x)
+ {
+ if (x < 0.0)
+ {
+ x = -x;
+ }
+
+ if (x <= 1.0)
+ {
+ return (1.5 * x - 2.5) * x * x + 1.0;
+ }
+ else if (x < 2.0)
+ {
+ return ((-0.5 * x + 2.5) * x - 4) * x + 2;
+ }
+ return 0.0;
+ }
+};
+
+class BilinearKernel : public Kernel {
+ virtual double GetWidth() { return 1.0; }
+ virtual double Calculate (double x)
+ {
+ if (x < 0.0)
+ {
+ x = -x;
+ }
+ if (x < 1.0)
+ {
+ return 1.0-x;
+ }
+ return 0.0;
+ }
+};
+
+class BoxKernel : public Kernel {
+ virtual double GetWidth() { return 0.5; }
+ virtual double Calculate (double x)
+ {
+ if (-0.5 <= x && x < 0.5)
+ return 1.0;
+ return 0.0;
+ }
+};
+
// ----------
// - Bitmap -
// ----------
@@ -277,17 +363,14 @@ public:
SAL_DLLPRIVATE sal_Bool ImplScaleFast( const double& rScaleX, const double& rScaleY );
SAL_DLLPRIVATE sal_Bool ImplScaleInterpolate( const double& rScaleX, const double& rScaleY );
- SAL_DLLPRIVATE bool ImplScaleLanczos( const double& rScaleX, const double& rScaleY );
+ SAL_DLLPRIVATE bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel);
- SAL_DLLPRIVATE void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
- const double aSupport, const int aNumberOfContributions,
- double* pWeights, int* pPixels, int* pCount );
- SAL_DLLPRIVATE bool ImplHorizontalConvolution( Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc,
- int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
- SAL_DLLPRIVATE bool ImplVerticalConvolution( Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc,
- int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
+ SAL_DLLPRIVATE static void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
+ int& aNumberOfContributions, double*& pWeights, int*& pPixels, int*& pCount,
+ Kernel& aKernel );
- SAL_DLLPRIVATE static double ImplLanczosKernel( const double aValue, const double aSupport );
+ SAL_DLLPRIVATE bool ImplConvolutionPass( Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc,
+ int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount );
SAL_DLLPRIVATE sal_Bool ImplMakeMono( sal_uInt8 cThreshold );
SAL_DLLPRIVATE sal_Bool ImplMakeMonoDither();
@@ -305,7 +388,7 @@ public:
long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
long nColors, long nPixels, long& rIndex );
SAL_DLLPRIVATE sal_Bool ImplConvolute3( const long* pMatrix, long nDivisor,
- const BmpFilterParam* pFilterParam, const Link* pProgress );
+ const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplMedianFilter( const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplSobelGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
SAL_DLLPRIVATE sal_Bool ImplEmbossGrey( const BmpFilterParam* pFilterParam, const Link* pProgress );
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index ec458d9..a469681 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -912,13 +912,37 @@ sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) )
{
if( BMP_SCALE_FAST == nScaleFlag )
+ {
bRet = ImplScaleFast( rScaleX, rScaleY );
+ }
else if( BMP_SCALE_INTERPOLATE == nScaleFlag )
+ {
bRet = ImplScaleInterpolate( rScaleX, rScaleY );
+ }
else if( BMP_SCALE_LANCZOS == nScaleFlag )
- bRet = ImplScaleLanczos( rScaleX, rScaleY );
+ {
+ Lanczos3Kernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel);
+ }
+ else if( BMP_SCALE_BICUBIC == nScaleFlag )
+ {
+ BicubicKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
+ else if( BMP_SCALE_BILINEAR == nScaleFlag )
+ {
+ BilinearKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
+ else if( BMP_SCALE_BOX == nScaleFlag )
+ {
+ BoxKernel kernel;
+ bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
+ }
else
- bRet = sal_False;
+ {
+ return false;
+ }
}
else
bRet = sal_True;
@@ -2208,33 +2232,28 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
return bRet;
}
-bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
+bool Bitmap::ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel )
{
- const Size aSizePix( GetSizePixel() );
- const long nWidth = aSizePix.Width();
- const long nHeight = aSizePix.Height();
+ const long nWidth = GetSizePixel().Width();
+ const long nHeight = GetSizePixel().Height();
const long nNewWidth = FRound( nWidth * rScaleX );
const long nNewHeight = FRound( nHeight * rScaleY );
- double aSupport = 3.0; // Sampling radius
-
- // Do horizontal filtering
- double aScale = nNewWidth / (double) nWidth;
- double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
-
- int aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 );
+ bool bResult;
+ BitmapReadAccess* pReadAcc;
+ Bitmap aNewBitmap;
- double* pWeights = new double[ nNewWidth*aNumberOfContributions ];
- int* pPixels = new int[ nNewWidth*aNumberOfContributions ];
- int* pCount = new int[ nNewWidth ];
+ int aNumberOfContributions;
+ double* pWeights;
+ int* pPixels;
+ int* pCount;
- ImplCalculateContributions( nWidth, nNewWidth, aSupport, aNumberOfContributions, pWeights, pPixels, pCount );
-
- BitmapReadAccess* pReadAcc = AcquireReadAccess();
- Bitmap aNewBitmap( Size( nNewWidth, nHeight ), 24);
- bool bResult = ImplHorizontalConvolution( aNewBitmap, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+ // Do horizontal filtering
+ ImplCalculateContributions( nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
+ pReadAcc = AcquireReadAccess();
+ aNewBitmap = Bitmap( Size( nHeight, nNewWidth ), 24);
+ bResult = ImplConvolutionPass( aNewBitmap, nNewWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
- // Cleanup
ReleaseAccess( pReadAcc );
delete[] pWeights;
delete[] pCount;
@@ -2243,26 +2262,15 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
if ( !bResult )
return bResult;
- // Swap current bitmap with new bitmap
+ // Swap Bitmaps
ImplAssignWithSize( aNewBitmap );
// Do vertical filtering
- aScale = nNewHeight / (double) nHeight;
- aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
-
- aNumberOfContributions = (int) ( 2 * aScaledRadius + 1 );
-
- pWeights = new double[ nNewHeight*aNumberOfContributions ];
- pPixels = new int[ nNewHeight*aNumberOfContributions ];
- pCount = new int[ nNewHeight ];
-
- ImplCalculateContributions(nHeight, nNewHeight, aSupport, aNumberOfContributions, pWeights, pPixels, pCount );
-
+ ImplCalculateContributions( nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
pReadAcc = AcquireReadAccess();
aNewBitmap = Bitmap( Size( nNewWidth, nNewHeight ), 24);
- bResult = ImplVerticalConvolution( aNewBitmap, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
+ bResult = ImplConvolutionPass( aNewBitmap, nNewHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
- // Cleanup
ReleaseAccess( pReadAcc );
delete[] pWeights;
delete[] pCount;
@@ -2271,19 +2279,24 @@ bool Bitmap::ImplScaleLanczos( const double& rScaleX, const double& rScaleY )
if ( !bResult )
return bResult;
- // Swap current bitmap with new bitmap
ImplAssignWithSize( aNewBitmap );
return true;
}
-void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, const double aSupport,
- const int aNumberOfContributions, double* pWeights, int* pPixels,
- int* pCount )
+void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, int& aNumberOfContributions,
+ double*& pWeights, int*& pPixels, int*& pCount, Kernel& aKernel)
{
+ const double aSamplingRadius = aKernel.GetWidth();
const double aScale = aDestinationSize / (double) aSourceSize;
- const double aScaledRadius = (aScale <= 1.0) ? aSupport / aScale : aSupport;
- const double aFilterFactor = (aScale <= 1.0) ? aScale : 1.0;
+ const double aScaledRadius = (aScale < 1.0) ? aSamplingRadius / aScale : aSamplingRadius;
+ const double aFilterFactor = (aScale < 1.0) ? aScale : 1.0;
+
+ aNumberOfContributions = (int) ( 2 * ceil(aScaledRadius) + 1 );
+
+ pWeights = new double[ aDestinationSize*aNumberOfContributions ];
+ pPixels = new int[ aDestinationSize*aNumberOfContributions ];
+ pCount = new int[ aDestinationSize ];
double aWeight, aCenter;
int aIndex, aLeft, aRight;
@@ -2295,37 +2308,19 @@ void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDesti
aCurrentCount = 0;
aCenter = i / aScale;
- aLeft = (int) ((aCenter + 0.5) - aScaledRadius );
- aRight = (int) ( aLeft + 2 * aScaledRadius );
+ aLeft = (int) floor(aCenter - aScaledRadius);
+ aRight = (int) ceil (aCenter + aScaledRadius);
for ( int j = aLeft; j <= aRight; j++ )
{
- aWeight = ImplLanczosKernel( (aCenter - j) * aFilterFactor, aSupport );
+ aWeight = aKernel.Calculate( aFilterFactor * ( aCenter - (double) j ) );
- if (aWeight == 0.0)
- {
+ // Reduce calculations with ignoring weights of 0.0
+ if (fabs(aWeight < 0.0001))
continue;
- }
-
- // Mirror edges
- if (j < 0)
- {
- aPixelIndex = -j;
- }
- else if ( j >= aSourceSize )
- {
- aPixelIndex = (aSourceSize - j) + aSourceSize - 1;
- }
- else
- {
- aPixelIndex = j;
- }
- // Edge case for small bitmaps
- if ( aPixelIndex < 0 || aPixelIndex >= aSourceSize )
- {
- aWeight = 0.0;
- }
+ // Handling on edges
+ aPixelIndex = MinMax( j, 0, aSourceSize - 1);
pWeights[ aIndex + aCurrentCount ] = aWeight;
pPixels[ aIndex + aCurrentCount ] = aPixelIndex;
@@ -2336,17 +2331,14 @@ void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDesti
}
}
-bool Bitmap::ImplHorizontalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
+bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
{
BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
if (!pReadAcc || !pWriteAcc)
- {
return false;
- }
const int nHeight = GetSizePixel().Height();
- const int nNewWidth = aNewBitmap.GetSizePixel().Width();
BitmapColor aColor;
double aValueRed, aValueGreen, aValueBlue;
@@ -2355,79 +2347,20 @@ bool Bitmap::ImplHorizontalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pRe
for ( int y = 0; y < nHeight; y++ )
{
- for ( int i = 0; i < nNewWidth; i++ )
+ for ( int x = 0; x < nNewSize; x++ )
{
- aBaseIndex = i * aNumberOfContributions;
- aValueRed = aValueGreen = aValueBlue = 0.0;
- aSum = 0.0;
+ aBaseIndex = x * aNumberOfContributions;
+ aSum = aValueRed = aValueGreen = aValueBlue = 0.0;
- for ( int j=0; j < pCount[i]; j++ )
+ for ( int j=0; j < pCount[x]; j++ )
{
aIndex = aBaseIndex + j;
- aWeight = pWeights[ aIndex ];
- aSum += aWeight;
- if( pReadAcc->HasPalette() )
- {
- aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( y , pPixels[ aIndex ] ) );
- }
- else
- {
- aColor = pReadAcc->GetPixel( y , pPixels[ aIndex ] );
- }
+ aSum += aWeight = pWeights[ aIndex ];
- aValueRed += aWeight * aColor.GetRed();
- aValueGreen += aWeight * aColor.GetGreen();
- aValueBlue += aWeight * aColor.GetBlue();
- }
-
- BitmapColor aResultColor(
- (sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ),
- (sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
- (sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) );
- pWriteAcc->SetPixel( y, i, aResultColor );
- }
- }
- aNewBitmap.ReleaseAccess( pWriteAcc );
- return true;
-}
-
-bool Bitmap::ImplVerticalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
-{
- BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
-
- if (!pReadAcc || !pWriteAcc)
- {
- return false;
- }
-
- const int nWidth = GetSizePixel().Width();
- const int nNewHeight = aNewBitmap.GetSizePixel().Height();
-
- BitmapColor aColor;
- double aValueRed, aValueGreen, aValueBlue;
- double aSum, aWeight;
- int aBaseIndex, aIndex;
- for (int x = 0; x < nWidth; x++)
- {
- for (int i = 0; i < nNewHeight; i++)
- {
- aBaseIndex = i * aNumberOfContributions;
- aSum = 0.0;
- aValueRed = aValueGreen = aValueBlue = 0.0;
-
- for (int j=0; j < pCount[i]; j++)
- {
- aIndex = aBaseIndex + j;
- aWeight = pWeights[ aIndex ];
- aSum += aWeight;
+ aColor = pReadAcc->GetPixel( y, pPixels[ aIndex ] );
if( pReadAcc->HasPalette() )
- {
- aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( pPixels[ aIndex ] , x ) );
- }
- else
- {
- aColor = pReadAcc->GetPixel( pPixels[ aIndex ] , x );
- }
+ aColor = pReadAcc->GetPaletteColor( aColor );
+
aValueRed += aWeight * aColor.GetRed();
aValueGreen += aWeight * aColor.GetGreen();
aValueBlue += aWeight * aColor.GetBlue();
@@ -2437,32 +2370,11 @@ bool Bitmap::ImplVerticalConvolution(Bitmap& aNewBitmap, BitmapReadAccess* pRead
(sal_uInt8) MinMax( aValueRed / aSum, 0, 255 ),
(sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
(sal_uInt8) MinMax( aValueBlue / aSum, 0, 255 ) );
- pWriteAcc->SetPixel( i, x, aResultColor );
+ pWriteAcc->SetPixel( x, y, aResultColor );
}
}
-
aNewBitmap.ReleaseAccess( pWriteAcc );
return true;
}
-double Bitmap::ImplLanczosKernel( const double aValue, const double aSupport ) {
- double x = aValue;
- if (x == 0.0)
- {
- return 1.0;
- }
- if (x < 0.0)
- {
- x = -x;
- }
-
- x *= M_PI;
- if (x < aSupport)
- {
- double x3 = x / 3.0;
- return (sin(x) / x) * sin(x3) / x3;
- }
- return 0.0;
-}
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list