[Libreoffice-commits] .: 2 commits - svtools/source svx/inc svx/source vcl/inc vcl/source
Tomaž Vajngerl
tvajngerl at kemper.freedesktop.org
Tue Jul 24 13:17:44 PDT 2012
svtools/source/graphic/grfmgr2.cxx | 137 ++++-----
svx/inc/svx/compressgraphicdialog.hxx | 6
svx/source/dialog/compressgraphicdialog.cxx | 101 +++---
vcl/inc/vcl/bitmap.hxx | 112 ++++---
vcl/inc/vcl/bitmapex.hxx | 5
vcl/source/gdi/bitmap3.cxx | 406 +++++++++++++++++++++++++++-
vcl/source/gdi/bitmapex.cxx | 42 ++
7 files changed, 629 insertions(+), 180 deletions(-)
New commits:
commit 53d51dbee6d4037c4cfc3fa743de8dac76da48c6
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Tue Jul 24 22:01:18 2012 +0200
One pass scale, rotate and crop using bilinear filtering and averaging.
With this commit I reintroduce one pass scale, rotate and crop that
was located in grfmgr2.cxx (now in Bitmap class) and was used for
preparing bitmaps for displaying on screen. By default the combination
of two filters is used: bilinear, which is a similar algorithm than
the "old" one, but with the same result, and averaging algorithm. Bilinear
filtering is used for bitmap enlarging and shrinking till factor 0.6. Below
this bilinear gives bad results because of limited sampling. For such cases
averaging is used which is a simple algorithm for shrinking. In averaging
the algorithm calculates the average of samples which result is the new
pixel. Currently both algorithms are not optimised.
One pass scale, rotate and crop should only be used for displaying of
images.
Change-Id: I5a1330b58a7cbb6fde8546e16c3e8c140afca565
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index f072f77..f3b6a07 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -44,7 +44,6 @@
// - defines -
// -----------
-#define MAP( cVal0, cVal1, nFrac ) ((sal_uInt8)((((long)(cVal0)<<20L)+nFrac*((long)(cVal1)-(cVal0)))>>20L))
#define WATERMARK_LUM_OFFSET 50
#define WATERMARK_CON_OFFSET -70
@@ -267,14 +266,16 @@ sal_Bool GraphicManager::ImplDraw( OutputDevice* pOut, const Point& rPt,
sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
const Point& rPoint, const Size& rSize,
- const BitmapEx& rBitmapEx, const GraphicAttr& rAttr,
- const sal_uLong nFlags, BitmapEx* pBmpEx )
+ const BitmapEx& rBitmapEx, const GraphicAttr& rAttributes,
+ const sal_uLong nFlags, BitmapEx* pResultBitmapEx )
{
bool bRet = false;
Point aOutPointInPixels;
Size aOutSizeInPixels;
- int nRotation = rAttr.GetRotation() % 3600;
- Size aUnrotatedSizeInPixels( pOutputDevice->LogicToPixel( rSize ) );
+ int nRotation = rAttributes.GetRotation() % 3600;
+
+ Point aUnrotatedPointInPixels( pOutputDevice->LogicToPixel( rPoint ) );
+ Size aUnrotatedSizeInPixels( pOutputDevice->LogicToPixel( rSize ) );
BitmapEx aBitmapEx( rBitmapEx );
@@ -283,69 +284,70 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
if( nRotation )
{
- Polygon aRotationPolygon( Rectangle( rPoint, rSize ) );
- aRotationPolygon.Rotate( rPoint, nRotation );
- const Rectangle aRotationBoundRectangle( aRotationPolygon.GetBoundRect() );
- aOutPointInPixels = pOutputDevice->LogicToPixel( aRotationBoundRectangle.TopLeft() );
- aOutSizeInPixels = pOutputDevice->LogicToPixel( aRotationBoundRectangle.GetSize() );
-
- // rotate the image before further processing
- aBitmapEx.Rotate( nRotation, COL_TRANSPARENT );
+ Polygon aPoly( Rectangle( rPoint, rSize ) );
+ aPoly.Rotate( rPoint, nRotation );
+ const Rectangle aRotationBoundRect( aPoly.GetBoundRect() );
+ aOutPointInPixels = pOutputDevice->LogicToPixel( aRotationBoundRect.TopLeft() );
+ aOutSizeInPixels = pOutputDevice->LogicToPixel( aRotationBoundRect.GetSize() );
}
else
{
- aOutPointInPixels = pOutputDevice->LogicToPixel( rPoint );
+ aOutPointInPixels = aUnrotatedPointInPixels;
aOutSizeInPixels = aUnrotatedSizeInPixels;
}
- Point aOutPoint;
- Size aOutSize;
- const Size& rBitmapSizePixels = rBitmapEx.GetSizePixel();
- long nStartX(-1), nStartY(-1), nEndX(-1), nEndY(-1);
- bool isHorizontalMirrored = ( rAttr.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
- bool isVerticalMirrored = ( rAttr.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
+ Point aOutPoint;
+ Size aOutSize;
+
+ const Size& rBitmapSizePixels = rBitmapEx.GetSizePixel();
+ Rectangle aCropRectangle(-1, -1, -1, -1);
+ bool isHorizontalMirrored = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_HORZ ) != 0;
+ bool isVerticalMirrored = ( rAttributes.GetMirrorFlags() & BMP_MIRROR_VERT ) != 0;
- Rectangle aBmpRect( aOutPointInPixels, aOutSizeInPixels );
+ Rectangle aBitmapRectangle( aOutPointInPixels, aOutSizeInPixels );
// calculate output sizes
- if( !pBmpEx )
+ if( !pResultBitmapEx )
{
- Point aPoint;
- Rectangle aOutRect( aPoint, pOutputDevice->GetOutputSizePixel() );
+ Rectangle aOutRect( Point(), pOutputDevice->GetOutputSizePixel() );
if( pOutputDevice->GetOutDevType() == OUTDEV_WINDOW )
{
- const Region aPaintRgn( ( (Window*) pOutputDevice )->GetPaintRegion() );
- if( !aPaintRgn.IsNull() )
+ const Region aPaintRegion( ( (Window*) pOutputDevice )->GetPaintRegion() );
+
+ if( !aPaintRegion.IsNull() )
{
- aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRgn.GetBoundRect() ) );
+ aOutRect.Intersection( pOutputDevice->LogicToPixel( aPaintRegion.GetBoundRect() ) );
}
}
- aOutRect.Intersection( aBmpRect );
+ aOutRect.Intersection( aBitmapRectangle );
if( !aOutRect.IsEmpty() )
{
aOutPoint = pOutputDevice->PixelToLogic( aOutRect.TopLeft() );
- aOutSize = pOutputDevice->PixelToLogic( aOutRect.GetSize() );
- nStartX = aOutRect.Left() - aBmpRect.Left();
- nStartY = aOutRect.Top() - aBmpRect.Top();
- nEndX = aOutRect.Right() - aBmpRect.Left();
- nEndY = aOutRect.Bottom() - aBmpRect.Top();
+ aOutSize = pOutputDevice->PixelToLogic( aOutRect.GetSize() );
+
+ aCropRectangle = Rectangle(
+ aOutRect.Left() - aBitmapRectangle.Left(),
+ aOutRect.Top() - aBitmapRectangle.Top(),
+ aOutRect.Right() - aBitmapRectangle.Left(),
+ aOutRect.Bottom() - aBitmapRectangle.Top() );
+
}
- else
- nStartX = -1L; // invalid
}
else
{
aOutPoint = pOutputDevice->PixelToLogic( aOutPointInPixels );
- aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
- nStartX = nStartY = 0;
- nEndX = aOutSizeInPixels.Width() - 1L;
- nEndY = aOutSizeInPixels.Height() - 1L;
+ aOutSize = pOutputDevice->PixelToLogic( aOutSizeInPixels );
+
+ aCropRectangle = Rectangle(
+ 0, 0,
+ aOutSizeInPixels.Width() - 1,
+ aOutSizeInPixels.Height() - 1 );
}
- if( nStartX < 0L )
+ if( aCropRectangle.GetWidth() <= 0 && aCropRectangle.GetHeight() <= 0)
return false;
// do transformation
@@ -365,43 +367,44 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
else
{
// calculate scaling factors
- double fScaleX = aBmpRect.GetWidth() / (double) aBitmapEx.GetSizePixel().Width();
- double fScaleY = aBmpRect.GetHeight() / (double) aBitmapEx.GetSizePixel().Height();
-
- // calculate crop regions on original non-scaled bitmap
- long nOriginalStartX = nStartX / fScaleX;
- long nOriginalEndX = nEndX / fScaleX;
- long nOriginalStartY = nStartY / fScaleY;
- long nOriginalEndY = nEndY / fScaleY;
-
- Size aScaleSize( nEndX - nStartX + 1, nEndY - nStartY + 1 );
-
- // crop the bitmap, so we deal with a smaller bitmap
- // todo: join crop and scale step into one step on Bitmap to decrease processing
- bRet = aBitmapEx.Crop( Rectangle( nOriginalStartX, nOriginalStartY, nOriginalEndX, nOriginalEndY ) );
+ double fScaleX = aUnrotatedSizeInPixels.Width() / (double) rBitmapSizePixels.Width();
+ double fScaleY = aUnrotatedSizeInPixels.Height() / (double) rBitmapSizePixels.Height();
// mirror the image - this should not impact the picture dimenstions
if( isHorizontalMirrored || isVerticalMirrored )
- bRet = aBitmapEx.Mirror( rAttr.GetMirrorFlags() );
+ bRet = aBitmapEx.Mirror( rAttributes.GetMirrorFlags() );
// depending on the flags, scale the image to the desired proportions
// use FAST scale if no smooth scale is desired
- if( !( nFlags & GRFMGR_DRAW_SMOOTHSCALE ))
- bRet = aBitmapEx.Scale( aScaleSize, BMP_SCALE_FAST );
- else
- bRet = aBitmapEx.Scale( aScaleSize );
+ if( nFlags & GRFMGR_DRAW_SMOOTHSCALE)
+ {
+ Polygon aPoly( Rectangle( Point(), aUnrotatedSizeInPixels) );
+ aPoly.Rotate( Point(), nRotation );
+ Rectangle aNewBound( aPoly.GetBoundRect() );
+ Rectangle aCropRectangle2 (
+ aCropRectangle.Left() + aNewBound.Left(),
+ aCropRectangle.Top() + aNewBound.Top(),
+ aCropRectangle.Right() + aNewBound.Left(),
+ aCropRectangle.Bottom() + aNewBound.Top());
+
+ bRet = aBitmapEx.ScaleCropRotate( fScaleX, fScaleY, aCropRectangle2, nRotation, COL_TRANSPARENT );
+ }
}
if( bRet )
{
// attribute adjustment if neccessary
- if( rAttr.IsSpecialDrawMode() || rAttr.IsAdjusted() || rAttr.IsTransparent() )
- ImplAdjust( aBitmapEx, rAttr, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+ if( rAttributes.IsSpecialDrawMode()
+ || rAttributes.IsAdjusted()
+ || rAttributes.IsTransparent() )
+ {
+ ImplAdjust( aBitmapEx, rAttributes, ADJUSTMENT_DRAWMODE | ADJUSTMENT_COLORS | ADJUSTMENT_TRANSPARENCY );
+ }
// OutDev adjustment if neccessary
- if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER &&
- pOutputDevice->GetBitCount() <= 8 &&
- aBitmapEx.GetBitCount() >= 8 )
+ if( pOutputDevice->GetOutDevType() != OUTDEV_PRINTER
+ && pOutputDevice->GetBitCount() <= 8
+ && aBitmapEx.GetBitCount() >= 8 )
{
aBitmapEx.Dither( BMP_DITHER_MATRIX );
}
@@ -410,12 +413,12 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOutputDevice,
// create output
if( bRet )
{
- if( pBmpEx )
+ if( pResultBitmapEx )
{
- if( !rAttr.IsTransparent() && !aBitmapEx.IsAlpha() )
+ if( !rAttributes.IsTransparent() && !aBitmapEx.IsAlpha() )
aBitmapEx = BitmapEx( aBitmapEx.GetBitmap().CreateDisplayBitmap( pOutputDevice ), aBitmapEx.GetMask() );
- *pBmpEx = aBitmapEx;
+ *pResultBitmapEx = aBitmapEx;
}
pOutputDevice->DrawBitmapEx( aOutPoint, aOutSize, aBitmapEx);
}
diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx
index 5c2832e..e1e489f 100644
--- a/vcl/inc/vcl/bitmap.hxx
+++ b/vcl/inc/vcl/bitmap.hxx
@@ -343,10 +343,9 @@ class VCL_DLLPUBLIC Bitmap
{
private:
- ImpBitmap* mpImpBmp;
- MapMode maPrefMapMode;
- Size maPrefSize;
-
+ ImpBitmap* mpImpBmp;
+ MapMode maPrefMapMode;
+ Size maPrefSize;
public:
@@ -356,59 +355,63 @@ public:
SAL_DLLPRIVATE void ImplSetImpBitmap( ImpBitmap* pImpBmp );
SAL_DLLPRIVATE void ImplAssignWithSize( const Bitmap& rBitmap );
- SAL_DLLPRIVATE static sal_Bool ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bMSOFormat = sal_False );
- SAL_DLLPRIVATE static sal_Bool ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset );
- SAL_DLLPRIVATE static sal_Bool ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bMSOFormat = sal_False );
- SAL_DLLPRIVATE static sal_Bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad );
- SAL_DLLPRIVATE static sal_Bool ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown );
- SAL_DLLPRIVATE sal_Bool ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const;
- SAL_DLLPRIVATE static sal_Bool ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc );
- SAL_DLLPRIVATE static sal_Bool ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc );
- SAL_DLLPRIVATE static sal_Bool ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
- sal_uLong nCompression, sal_uInt32& rImageSize );
+ SAL_DLLPRIVATE static sal_Bool ImplReadDIB( SvStream& rIStm, Bitmap& rBmp, sal_uLong nOffset, sal_Bool bMSOFormat = sal_False );
+ SAL_DLLPRIVATE static sal_Bool ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset );
+ SAL_DLLPRIVATE static sal_Bool ImplReadDIBInfoHeader( SvStream& rIStm, DIBInfoHeader& rHeader, sal_Bool& bTopDown, sal_Bool bMSOFormat = sal_False );
+ SAL_DLLPRIVATE static sal_Bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, sal_Bool bQuad );
+ SAL_DLLPRIVATE static sal_Bool ImplReadDIBBits( SvStream& rIStm, DIBInfoHeader& rHeader, BitmapWriteAccess& rAcc, sal_Bool bTopDown );
+ SAL_DLLPRIVATE sal_Bool ImplWriteDIB( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bCompressed ) const;
+ SAL_DLLPRIVATE static sal_Bool ImplWriteDIBFileHeader( SvStream& rOStm, BitmapReadAccess& rAcc );
+ SAL_DLLPRIVATE static sal_Bool ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc );
+ SAL_DLLPRIVATE static sal_Bool ImplWriteDIBBits( SvStream& rOStm, BitmapReadAccess& rAcc,
+ sal_uLong nCompression, sal_uInt32& rImageSize );
SAL_DLLPRIVATE static void ImplDecodeRLE( sal_uInt8* pBuffer, DIBInfoHeader& rHeader,
- BitmapWriteAccess& rAcc, sal_Bool bRLE4 );
- SAL_DLLPRIVATE static sal_Bool ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 );
-
- 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 ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel);
-
- SAL_DLLPRIVATE static void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
+ BitmapWriteAccess& rAcc, sal_Bool bRLE4 );
+ SAL_DLLPRIVATE static sal_Bool ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, sal_Bool bRLE4 );
+
+ 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 ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel);
+ SAL_DLLPRIVATE bool ImplTransformAveraging( const double& rScaleX, const double& rScaleY,
+ const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor );
+ SAL_DLLPRIVATE bool ImplTransformBilinearFiltering( const double& rScaleX, const double& rScaleY,
+ const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor );
+
+ SAL_DLLPRIVATE static void ImplCalculateContributions( const int aSourceSize, const int aDestinationSize,
int& aNumberOfContributions, double*& pWeights, int*& pPixels, int*& pCount,
Kernel& aKernel );
- SAL_DLLPRIVATE bool ImplConvolutionPass( Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc,
+ 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();
- SAL_DLLPRIVATE sal_Bool ImplMakeGreyscales( sal_uInt16 nGreyscales );
- SAL_DLLPRIVATE sal_Bool ImplConvertUp( sal_uInt16 nBitCount, Color* pExtColor = NULL );
- SAL_DLLPRIVATE sal_Bool ImplConvertDown( sal_uInt16 nBitCount, Color* pExtColor = NULL );
- SAL_DLLPRIVATE sal_Bool ImplConvertGhosted();
- SAL_DLLPRIVATE sal_Bool ImplDitherMatrix();
- SAL_DLLPRIVATE sal_Bool ImplDitherFloyd();
- SAL_DLLPRIVATE sal_Bool ImplDitherFloyd16();
- SAL_DLLPRIVATE sal_Bool ImplReduceSimple( sal_uInt16 nColorCount );
- SAL_DLLPRIVATE sal_Bool ImplReducePopular( sal_uInt16 nColorCount );
- SAL_DLLPRIVATE sal_Bool ImplReduceMedian( sal_uInt16 nColorCount );
+ SAL_DLLPRIVATE sal_Bool ImplMakeMono( sal_uInt8 cThreshold );
+ SAL_DLLPRIVATE sal_Bool ImplMakeMonoDither();
+ SAL_DLLPRIVATE sal_Bool ImplMakeGreyscales( sal_uInt16 nGreyscales );
+ SAL_DLLPRIVATE sal_Bool ImplConvertUp( sal_uInt16 nBitCount, Color* pExtColor = NULL );
+ SAL_DLLPRIVATE sal_Bool ImplConvertDown( sal_uInt16 nBitCount, Color* pExtColor = NULL );
+ SAL_DLLPRIVATE sal_Bool ImplConvertGhosted();
+ SAL_DLLPRIVATE sal_Bool ImplDitherMatrix();
+ SAL_DLLPRIVATE sal_Bool ImplDitherFloyd();
+ SAL_DLLPRIVATE sal_Bool ImplDitherFloyd16();
+ SAL_DLLPRIVATE sal_Bool ImplReduceSimple( sal_uInt16 nColorCount );
+ SAL_DLLPRIVATE sal_Bool ImplReducePopular( sal_uInt16 nColorCount );
+ SAL_DLLPRIVATE sal_Bool ImplReduceMedian( sal_uInt16 nColorCount );
SAL_DLLPRIVATE void ImplMedianCut( sal_uLong* pColBuf, BitmapPalette& rPal,
- 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,
+ 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 );
- 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 );
- SAL_DLLPRIVATE sal_Bool ImplSolarize( const BmpFilterParam* pFilterParam, const Link* pProgress );
- SAL_DLLPRIVATE sal_Bool ImplSepia( const BmpFilterParam* pFilterParam, const Link* pProgress );
- 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,
+ 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 );
+ SAL_DLLPRIVATE sal_Bool ImplSolarize( const BmpFilterParam* pFilterParam, const Link* pProgress );
+ SAL_DLLPRIVATE sal_Bool ImplSepia( const BmpFilterParam* pFilterParam, const Link* pProgress );
+ 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:
@@ -633,8 +636,7 @@ public:
@return sal_True, if the operation was completed successfully.
*/
- sal_Bool Scale( const Size& rNewSize,
- sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+ sal_Bool Scale( const Size& rNewSize, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
/** Scale the bitmap
@@ -646,8 +648,12 @@ public:
@return sal_True, if the operation was completed successfully.
*/
- sal_Bool Scale( const double& rScaleX, const double& rScaleY,
- sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+ sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+
+ /** Scale, crop and rotate the bitmap */
+ sal_Bool ScaleCropRotate(
+ const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
/** Rotate bitmap by the specified angle
diff --git a/vcl/inc/vcl/bitmapex.hxx b/vcl/inc/vcl/bitmapex.hxx
index 845981a..a29c271 100644
--- a/vcl/inc/vcl/bitmapex.hxx
+++ b/vcl/inc/vcl/bitmapex.hxx
@@ -268,6 +268,11 @@ public:
*/
sal_Bool Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+ /** Scale, crop and rotate the bitmap */
+ sal_Bool ScaleCropRotate(
+ const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong nScaleFlag = BMP_SCALE_DEFAULT );
+
/** Rotate bitmap by the specified angle
@param nAngle10
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 4bef165..b1a028c 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -907,7 +907,7 @@ sal_Bool Bitmap::ImplConvertGhosted()
sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag )
{
- sal_Bool bRet;
+ bool bRet;
if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) )
{
@@ -945,7 +945,7 @@ sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong
}
}
else
- bRet = sal_True;
+ bRet = true;
return bRet;
}
@@ -955,7 +955,7 @@ sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong
sal_Bool Bitmap::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
{
const Size aSize( GetSizePixel() );
- sal_Bool bRet;
+ bool bRet;
if( aSize.Width() && aSize.Height() )
{
@@ -2377,4 +2377,404 @@ bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapR
return true;
}
+sal_Bool Bitmap::ScaleCropRotate(
+ const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong /* nScaleFlag */ )
+{
+ bool bRet;
+
+ if ( rScaleY < 0.6 && rScaleX < 0.6 )
+ {
+ bRet = ImplTransformAveraging( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
+ }
+ else
+ {
+ bRet = ImplTransformBilinearFiltering( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor);
+ }
+
+ return bRet;
+}
+
+// Scaling algorithm best for shrinking below factor 0.5 where algorithms with limited sampling range show bad results (bilinear, bicubic).
+// The algoritm determines the sampling range for one pixel and calculates the average of samples which is the resulting pixel.
+bool Bitmap::ImplTransformAveraging( const double& rScaleX, const double& rScaleY, const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor )
+{
+ const Size aSizePix( GetSizePixel() );
+
+ const int nStartX = rRotatedRectangle.Left();
+ const int nStartY = rRotatedRectangle.Top();
+ const int nEndX = rRotatedRectangle.Right();
+ const int nEndY = rRotatedRectangle.Bottom();
+
+ const int nTargetWidth = rRotatedRectangle.GetWidth();
+ const int nTargetHeight = rRotatedRectangle.GetHeight();
+
+ const int nOriginWidth = aSizePix.Width();
+ const int nOriginHeight = aSizePix.Height();
+
+ const int nScaledWidth = FRound( nOriginWidth * rScaleX );
+ const int nScaledHeight = FRound( nOriginHeight * rScaleY );
+
+ const double aReverseScaleX = 1.0 / rScaleX;
+ const double aReverseScaleY = 1.0 / rScaleY;
+
+ const double fCosAngle = cos( nAngle10 * F_PI1800 );
+ const double fSinAngle = sin( nAngle10 * F_PI1800 );
+
+ if( nTargetWidth <= 1L || nTargetHeight <= 1L )
+ return false;
+
+ BitmapColor aColor, aResultColor;
+
+ Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
+
+ BitmapReadAccess* pReadAccess = AcquireReadAccess();
+ BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
+
+ if( !pReadAccess || !pWriteAccess )
+ return false;
+
+ const BitmapColor aFillColor( pWriteAccess->GetBestMatchingColor( rFillColor ) );
+
+ int x, y, xOut, yOut;
+ int aCount;
+ double aSumRed, aSumGreen, aSumBlue;
+
+ for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
+ {
+ for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
+ {
+ double unrotatedX = fCosAngle * x - fSinAngle * y;
+ double unrotatedY = fSinAngle * x + fCosAngle * y;
+
+ if ( unrotatedX < 0
+ || unrotatedX >= nScaledWidth
+ || unrotatedY < 0
+ || unrotatedY >= nScaledHeight)
+ {
+ pWriteAccess->SetPixel( yOut, xOut, aFillColor );
+ }
+ else
+ {
+ double dYStart = ((unrotatedY + 0.5) * aReverseScaleY) - 0.5;
+ double dYEnd = ((unrotatedY + 1.5) * aReverseScaleY) - 0.5;
+
+ int yStart = MinMax( dYStart, 0, nOriginHeight - 1);
+ int yEnd = MinMax( dYEnd, 0, nOriginHeight - 1);
+
+ double dXStart = ((unrotatedX + 0.5) * aReverseScaleX) - 0.5;
+ double dXEnd = ((unrotatedX + 1.5) * aReverseScaleX) - 0.5;
+
+ int xStart = MinMax( dXStart, 0, nOriginWidth - 1);
+ int xEnd = MinMax( dXEnd, 0, nOriginWidth - 1);
+
+ aSumRed = aSumGreen = aSumBlue = 0.0;
+ aCount = 0;
+
+ for (int yIn = yStart; yIn <= yEnd; yIn++)
+ {
+ for (int xIn = xStart; xIn <= xEnd; xIn++)
+ {
+ aColor = pReadAccess->GetPixel( yIn, xIn );
+
+ if( pReadAccess->HasPalette() )
+ aColor = pReadAccess->GetPaletteColor( aColor );
+
+ aSumRed += aColor.GetRed();
+ aSumGreen += aColor.GetGreen();
+ aSumBlue += aColor.GetBlue();
+
+ aCount++;
+ }
+ }
+
+ aResultColor.SetRed( MinMax( aSumRed / aCount, 0, 255) );
+ aResultColor.SetGreen( MinMax( aSumGreen / aCount, 0, 255) );
+ aResultColor.SetBlue( MinMax( aSumBlue / aCount, 0, 255) );
+
+ pWriteAccess->SetPixel( yOut, xOut, aResultColor );
+ }
+ }
+ }
+
+ ReleaseAccess( pReadAccess );
+ aOutBmp.ReleaseAccess( pWriteAccess );
+ ImplAssignWithSize( aOutBmp );
+
+ return true;
+}
+
+// Bilinear filtering used for shrinking and enlarging the source bitmap. Filtering is also used for rotation.
+// Filtering shows bad results at shrinking for a factor less than 0.5 because of limited sampling.
+bool Bitmap::ImplTransformBilinearFiltering( const double& rScaleX, const double& rScaleY, const Rectangle& rRotatedRectangle, const long nAngle10, const Color& rFillColor )
+{
+ const Size aSizePix( GetSizePixel() );
+
+ const int nOriginWidth = aSizePix.Width();
+ const int nOriginHeight = aSizePix.Height();
+
+ const int nScaledWidth = FRound( aSizePix.Width() * rScaleX );
+ const int nScaledHeight = FRound( aSizePix.Height() * rScaleY );
+
+ const int nStartX = rRotatedRectangle.Left();
+ const int nStartY = rRotatedRectangle.Top();
+ const int nEndX = rRotatedRectangle.Right();
+ const int nEndY = rRotatedRectangle.Bottom();
+
+ const int nTargetWidth = rRotatedRectangle.GetWidth();
+ const int nTargetHeight = rRotatedRectangle.GetHeight();
+
+ const double fCosAngle = cos( nAngle10 * F_PI1800 );
+ const double fSinAngle = sin( nAngle10 * F_PI1800 );
+
+ Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
+
+ BitmapReadAccess* pReadAccess = AcquireReadAccess();
+ BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
+
+ if( !pReadAccess || !pWriteAccess )
+ return false;
+
+ const BitmapColor aFillColor( pWriteAccess->GetBestMatchingColor( rFillColor ) );
+
+ double aReverseScaleX = 1.0 / rScaleX;
+ double aReverseScaleY = 1.0 / rScaleY;
+
+ BitmapColor aColor00, aColor01, aColor10, aColor11, aResultColor;
+
+ int x, y, xOut, yOut;
+
+ for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
+ {
+ for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
+ {
+ double unrotatedX = fCosAngle * x - fSinAngle * y;
+ double unrotatedY = fSinAngle * x + fCosAngle * y;
+
+ if ( unrotatedX < 0
+ || unrotatedX >= nScaledWidth
+ || unrotatedY < 0
+ || unrotatedY >= nScaledHeight)
+ {
+ pWriteAccess->SetPixel( yOut, xOut, aFillColor );
+ }
+ else
+ {
+ double sy0 = ((unrotatedY + 0.5) * aReverseScaleY) - 0.5;
+
+ int y0 = MinMax( floor( sy0 ), 0, nOriginHeight - 1);
+ int y1 = MinMax( y0 + 1, 0, nOriginHeight - 1);
+
+ double sx0 = ((unrotatedX + 0.5) * aReverseScaleX) - 0.5;
+ int x0 = MinMax( floor( sx0 ), 0, nOriginWidth - 1);
+ int x1 = MinMax( x0 + 1, 0, nOriginWidth - 1);
+
+ aColor00 = pReadAccess->GetPixel( y0, x0 );
+ aColor01 = pReadAccess->GetPixel( y1, x0 );
+ aColor10 = pReadAccess->GetPixel( y0, x1 );
+ aColor11 = pReadAccess->GetPixel( y1, x1 );
+
+ if( pReadAccess->HasPalette() )
+ {
+ aColor00 = pReadAccess->GetPaletteColor( aColor00 );
+ aColor01 = pReadAccess->GetPaletteColor( aColor01 );
+ aColor10 = pReadAccess->GetPaletteColor( aColor10 );
+ aColor11 = pReadAccess->GetPaletteColor( aColor11 );
+ }
+
+ double fx0 = sx0 - x0;
+ double fy0 = sy0 - y0;
+ double fx1 = 1.0 - fx0;
+ double fy1 = 1.0 - fy0;
+
+ double w00 = fx1 * fy1;
+ double w01 = fx1 * fy0;
+ double w10 = fx0 * fy1;
+ double w11 = fx0 * fy0;
+
+ double red = aColor00.GetRed() * w00 + aColor10.GetRed() * w10 + aColor01.GetRed() * w01 + aColor11.GetRed() * w11;
+ double green = aColor00.GetGreen() * w00 + aColor10.GetGreen() * w10 + aColor01.GetGreen() * w01 + aColor11.GetGreen() * w11;
+ double blue = aColor00.GetBlue() * w00 + aColor10.GetBlue() * w10 + aColor01.GetBlue() * w01 + aColor11.GetBlue() * w11;
+
+ aResultColor.SetRed( MinMax(red, 0, 255) );
+ aResultColor.SetGreen( MinMax(green, 0, 255) );
+ aResultColor.SetBlue( MinMax(blue, 0, 255) );
+
+ pWriteAccess->SetPixel( yOut, xOut, aResultColor );
+ }
+ }
+ }
+
+ ReleaseAccess( pReadAccess );
+ aOutBmp.ReleaseAccess( pWriteAccess );
+ ImplAssignWithSize( aOutBmp );
+
+ return true;
+}
+
+/*bool Bitmap::ImplScaleSuperFast( const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel )
+{
+ const Size aSizePix( GetSizePixel() );
+
+ const int nOriginWidth = aSizePix.Width();
+ const int nOriginHeight = aSizePix.Height();
+
+ const int nStartX = rRectPixel.Left();
+ const int nStartY = rRectPixel.Top();
+ const int nEndX = rRectPixel.Right();
+ const int nEndY = rRectPixel.Bottom();
+
+ const int nTargetWidth = rRectPixel.GetWidth();
+ const int nTargetHeight = rRectPixel.GetHeight();
+
+ BitmapColor aColor00, aColor01, aColor10, aColor11, aResultColor;
+
+ Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
+
+ BitmapReadAccess* pReadAccess = AcquireReadAccess();
+ BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
+
+ if( !pReadAccess || !pWriteAccess )
+ return false;
+
+ double aReverseScaleX = 1.0 / rScaleX;
+ double aReverseScaleY = 1.0 / rScaleY;
+
+ int x, y, xOut, yOut;
+
+ for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
+ {
+ double sy0 = ((y + 0.5) * aReverseScaleY) - 0.5;
+
+ int y0 = MinMax( floor( sy0 ), 0, nOriginHeight - 1);
+ int y1 = MinMax( y0 + 1, 0, nOriginHeight - 1);
+
+ for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
+ {
+ double sx0 = ((x + 0.5) * aReverseScaleX) - 0.5;
+ int x0 = MinMax( floor( sx0 ), 0, nOriginWidth - 1);
+ int x1 = MinMax( x0 + 1, 0, nOriginWidth - 1);
+
+ aColor00 = pReadAccess->GetPixel( y0, x0 );
+ aColor01 = pReadAccess->GetPixel( y1, x0 );
+ aColor10 = pReadAccess->GetPixel( y0, x1 );
+ aColor11 = pReadAccess->GetPixel( y1, x1 );
+
+ if( pReadAccess->HasPalette() )
+ {
+ aColor00 = pReadAccess->GetPaletteColor( aColor00 );
+ aColor01 = pReadAccess->GetPaletteColor( aColor01 );
+ aColor10 = pReadAccess->GetPaletteColor( aColor10 );
+ aColor11 = pReadAccess->GetPaletteColor( aColor11 );
+ }
+
+ double fx0 = sx0 - x0;
+ double fy0 = sy0 - y0;
+ double fx1 = 1.0 - fx0;
+ double fy1 = 1.0 - fy0;
+
+ double w00 = fx1 * fy1;
+ double w01 = fx1 * fy0;
+ double w10 = fx0 * fy1;
+ double w11 = fx0 * fy0;
+
+ double red = aColor00.GetRed() * w00 + aColor10.GetRed() * w10 + aColor01.GetRed() * w01 + aColor11.GetRed() * w11;
+ double green = aColor00.GetGreen() * w00 + aColor10.GetGreen() * w10 + aColor01.GetGreen() * w01 + aColor11.GetGreen() * w11;
+ double blue = aColor00.GetBlue() * w00 + aColor10.GetBlue() * w10 + aColor01.GetBlue() * w01 + aColor11.GetBlue() * w11;
+
+ aResultColor.SetRed( MinMax(red, 0, 255) );
+ aResultColor.SetGreen( MinMax(green, 0, 255) );
+ aResultColor.SetBlue( MinMax(blue, 0, 255) );
+
+ pWriteAccess->SetPixel( yOut, xOut, aResultColor );
+ }
+ }
+
+ ReleaseAccess( pReadAccess );
+ aOutBmp.ReleaseAccess( pWriteAccess );
+ ImplAssignWithSize( aOutBmp );
+
+ return true;
+}
+bool Bitmap::ImplScaleSuper( const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, const long nAngle10, const Color& rFillColor )
+{
+ Rectangle aRect( rRectPixel );
+
+ const int nStartX = aRect.Left();
+ const int nStartY = aRect.Top();
+ const int nEndX = aRect.Right();
+ const int nEndY = aRect.Bottom();
+
+ const int nTargetWidth = aRect.GetWidth();
+ const int nTargetHeight = aRect.GetHeight();
+
+ const int nOriginWidth = GetSizePixel().Width();
+ const int nOriginHeight = GetSizePixel().Height();
+
+ const double aReverseScaleX = 1.0 / rScaleX;
+ const double aReverseScaleY = 1.0 / rScaleY;
+
+ if( nTargetWidth <= 1L || nTargetHeight <= 1L )
+ return false;
+
+ BitmapColor aColor, aResultColor;
+
+ Bitmap aOutBmp( Size( nTargetWidth, nTargetHeight ), 24 );
+
+ BitmapReadAccess* pReadAccess = AcquireReadAccess();
+ BitmapWriteAccess* pWriteAccess = aOutBmp.AcquireWriteAccess();
+
+ if( !pReadAccess || !pWriteAccess )
+ return false;
+
+ int x, y, xOut, yOut;
+ int aCount;
+ double aSumRed, aSumGreen, aSumBlue;
+
+ for( y = nStartY, yOut = 0; y <= nEndY; y++, yOut++ )
+ {
+ int yStart = MinMax( floor( y * aReverseScaleY ), 0, nOriginHeight - 1);
+ int yEnd = MinMax( floor( (y+1) * aReverseScaleY ), 0, nOriginHeight - 1);
+
+ for( x = nStartX, xOut = 0; x <= nEndX; x++, xOut++ )
+ {
+ int xStart = MinMax( floor( x * aReverseScaleX ), 0, nOriginWidth - 1);
+ int xEnd = MinMax( floor( (x+1) * aReverseScaleX ), 0, nOriginWidth - 1);
+
+ aSumRed = aSumGreen = aSumBlue = 0.0;
+ aCount = 0;
+
+ for (int yIn = yStart; yIn < yEnd; yIn++)
+ {
+ for (int xIn = xStart; xIn < xEnd; xIn++)
+ {
+ aColor = pReadAccess->GetPixel( yIn, xIn );
+
+ if( pReadAccess->HasPalette() )
+ aColor = pReadAccess->GetPaletteColor( aColor );
+
+ aSumRed += aColor.GetRed();
+ aSumGreen += aColor.GetGreen();
+ aSumBlue += aColor.GetBlue();
+
+ aCount++;
+ }
+ }
+
+ aResultColor.SetRed( MinMax(aSumRed / aCount, 0, 255) );
+ aResultColor.SetGreen( MinMax(aSumGreen / aCount, 0, 255) );
+ aResultColor.SetBlue( MinMax(aSumBlue / aCount, 0, 255) );
+
+ pWriteAccess->SetPixel( yOut, xOut, aResultColor );
+ }
+ }
+
+ ReleaseAccess( pReadAccess );
+ aOutBmp.ReleaseAccess( pWriteAccess );
+ ImplAssignWithSize( aOutBmp );
+
+ return true;
+}
+*/
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index d1d4262..e9a3ab4 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -443,7 +443,47 @@ sal_Bool BitmapEx::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
return bRet;
}
-// ------------------------------------------------------------------
+sal_Bool BitmapEx::ScaleCropRotate(
+ const double& rScaleX, const double& rScaleY, const Rectangle& rRectPixel, long nAngle10,
+ const Color& rFillColor, sal_uLong nScaleFlag )
+{
+ sal_Bool bRet = sal_False;
+
+ if( !!aBitmap )
+ {
+ const sal_Bool bTransRotate = ( Color( COL_TRANSPARENT ) == rFillColor );
+
+ if( bTransRotate )
+ {
+ if( eTransparent == TRANSPARENT_COLOR )
+ {
+ bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, aTransparentColor, nScaleFlag );
+ }
+ else
+ {
+ bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_BLACK, nScaleFlag );
+ if( eTransparent == TRANSPARENT_NONE )
+ {
+ aMask = Bitmap( aBitmapSize, 1 );
+ aMask.Erase( COL_BLACK );
+ eTransparent = TRANSPARENT_BITMAP;
+ }
+
+ if( bRet && !!aMask )
+ aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
+ }
+ }
+ else
+ {
+ bRet = aBitmap.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, rFillColor, nScaleFlag );
+
+ if( bRet && ( eTransparent == TRANSPARENT_BITMAP ) && !!aMask )
+ aMask.ScaleCropRotate( rScaleX, rScaleY, rRectPixel, nAngle10, COL_WHITE, nScaleFlag );
+ }
+ }
+
+ return bRet;
+}
sal_Bool BitmapEx::Rotate( long nAngle10, const Color& rFillColor )
{
commit 963cababc65c945412963f7d66578b544d5f720b
Author: Tomaž Vajngerl <quikee at gmail.com>
Date: Tue Jul 24 20:21:22 2012 +0200
Simplify compression and remove code duplication in CompressGraphicDialog
Change-Id: Ia9e3bab09eef6e1055f1fd689373ab65310ea7e3
diff --git a/svx/inc/svx/compressgraphicdialog.hxx b/svx/inc/svx/compressgraphicdialog.hxx
index bf93e62..d535b98 100644
--- a/svx/inc/svx/compressgraphicdialog.hxx
+++ b/svx/inc/svx/compressgraphicdialog.hxx
@@ -80,6 +80,12 @@ private:
void UpdateNewHeightMF();
void UpdateResolutionLB();
+ void Compress(SvStream& aStream);
+
+
+ double GetViewWidthInch();
+ double GetViewHeightInch();
+
public:
CompressGraphicsDialog( Window* pParent, const Graphic& rGraphic, const Size& rViewSize100mm, SfxBindings& rBindings );
virtual ~CompressGraphicsDialog();
diff --git a/svx/source/dialog/compressgraphicdialog.cxx b/svx/source/dialog/compressgraphicdialog.cxx
index bc6afa6..547d51c 100644
--- a/svx/source/dialog/compressgraphicdialog.cxx
+++ b/svx/source/dialog/compressgraphicdialog.cxx
@@ -129,8 +129,7 @@ void CompressGraphicsDialog::Update()
String aViewSizeString;
- int aValX = aPixelSize.Width() * 100 / MetricField::ConvertValue(m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH);
- //int aValY = aPixelSize.Height() * 100 / MetricField::ConvertValue(m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH);
+ int aValX = (int) (aPixelSize.Width() / GetViewWidthInch());
aViewSizeString += GetUnitString( m_aViewSize100mm.Width(), eFieldUnit, cSep );
aViewSizeString += String( " x " ) ;
@@ -156,13 +155,13 @@ void CompressGraphicsDialog::Update()
void CompressGraphicsDialog::UpdateNewWidthMF()
{
- int nPixelX = (sal_Int32)((double)MetricField::ConvertValue(m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH) / 100 * m_dResolution );
+ int nPixelX = (sal_Int32)( GetViewWidthInch() * m_dResolution );
m_aMFNewWidth.SetText( UniString::CreateFromInt32( nPixelX ) );
}
void CompressGraphicsDialog::UpdateNewHeightMF()
{
- int nPixelY = (sal_Int32)((double)MetricField::ConvertValue(m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH) / 100 * m_dResolution );
+ int nPixelY = (sal_Int32)( GetViewHeightInch() * m_dResolution );
m_aMFNewHeight.SetText( UniString::CreateFromInt32( nPixelY ) );
}
@@ -171,11 +170,46 @@ void CompressGraphicsDialog::UpdateResolutionLB()
m_aResolutionLB.SetText( UniString::CreateFromInt32( (sal_Int32) m_dResolution ) );
}
+double CompressGraphicsDialog::GetViewWidthInch()
+{
+ return (double) MetricField::ConvertValue(m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0;
+}
+
+double CompressGraphicsDialog::GetViewHeightInch()
+{
+ return (double) MetricField::ConvertValue(m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0;
+}
+
+void CompressGraphicsDialog::Compress(SvStream& aStream)
+{
+ long nPixelX = (long)( GetViewWidthInch() * m_dResolution );
+ long nPixelY = (long)( GetViewHeightInch() * m_dResolution );
+
+ BitmapEx bitmap = m_aGraphic.GetBitmapEx();
+ if ( m_aReduceResolutionCB.IsChecked() )
+ {
+ bitmap.Scale( Size( nPixelX, nPixelY ), BMP_SCALE_BEST );
+ }
+ Graphic aScaledGraphic = Graphic( bitmap );
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+
+ Sequence< PropertyValue > aFilterData( 3 );
+ aFilterData[ 0 ].Name = "Interlaced";
+ aFilterData[ 0 ].Value <<= (sal_Int32) 0;
+ aFilterData[ 1 ].Name = "Compression";
+ aFilterData[ 1 ].Value <<= (sal_Int32) m_aCompressionMF.GetValue();
+ aFilterData[ 2 ].Name = "Quality";
+ aFilterData[ 2 ].Value <<= (sal_Int32) m_aQualityMF.GetValue();
+
+ String aGraphicFormatName = m_aLosslessRB.IsChecked() ? String( "png" ) : String( "jpg" );
+
+ sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( aGraphicFormatName );
+ rFilter.ExportGraphic( aScaledGraphic, String( "test" ), aStream, nFilterFormat, &aFilterData );
+}
+
IMPL_LINK_NOARG( CompressGraphicsDialog, NewWidthModifiedHdl )
{
- int aNewPixelWidth = m_aMFNewWidth.GetValue();
- double aViewWidthInch = (double) MetricField::ConvertValue(m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH) / 100;
- m_dResolution = aNewPixelWidth / aViewWidthInch;
+ m_dResolution = m_aMFNewWidth.GetValue() / GetViewWidthInch();
UpdateNewHeightMF();
UpdateResolutionLB();
@@ -186,9 +220,7 @@ IMPL_LINK_NOARG( CompressGraphicsDialog, NewWidthModifiedHdl )
IMPL_LINK_NOARG( CompressGraphicsDialog, NewHeightModifiedHdl )
{
- int aNewPixelHeight = m_aMFNewHeight.GetValue();
- double aViewHeightInch = (double) MetricField::ConvertValue(m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH) / 100;
- m_dResolution = aNewPixelHeight / aViewHeightInch;
+ m_dResolution = m_aMFNewHeight.GetValue() / GetViewHeightInch();
UpdateNewWidthMF();
UpdateResolutionLB();
@@ -233,32 +265,9 @@ IMPL_LINK_NOARG( CompressGraphicsDialog, CalculateClickHdl )
if ( m_dResolution > 0 )
{
- long nPixelX = (long)((double) MetricField::ConvertValue(m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0 * m_dResolution );
- long nPixelY = (long)((double) MetricField::ConvertValue(m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0 * m_dResolution );
-
- BitmapEx bitmap = m_aGraphic.GetBitmapEx();
- if ( m_aReduceResolutionCB.IsChecked() )
- {
- bitmap.Scale( Size( nPixelX, nPixelY ), BMP_SCALE_BEST );
- }
- Graphic aScaledGraphic = Graphic( bitmap );
- GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
-
- Sequence< PropertyValue > aFilterData( 3 );
- aFilterData[ 0 ].Name = "Interlaced";
- aFilterData[ 0 ].Value <<= (sal_Int32) 0;
- aFilterData[ 1 ].Name = "Compression";
- aFilterData[ 1 ].Value <<= (sal_Int32) m_aCompressionMF.GetValue();
- aFilterData[ 2 ].Name = "Quality";
- aFilterData[ 2 ].Value <<= (sal_Int32) m_aQualityMF.GetValue();
-
SvMemoryStream aMemStream;
aMemStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
-
- String aGraphicFormatName = m_aLosslessRB.IsChecked() ? String( "png" ) : String( "jpg" );
-
- sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( aGraphicFormatName );
- rFilter.ExportGraphic( aScaledGraphic, String( "test" ), aMemStream, nFilterFormat, &aFilterData );
+ Compress( aMemStream );
aMemStream.Seek( STREAM_SEEK_TO_END );
aSize = aMemStream.Tell();
}
@@ -277,33 +286,13 @@ Graphic CompressGraphicsDialog::GetCompressedGraphic()
{
if ( m_dResolution > 0 )
{
- long nPixelX = (long)((double) MetricField::ConvertValue( m_aViewSize100mm.Width(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0 * m_dResolution );
- long nPixelY = (long)((double) MetricField::ConvertValue( m_aViewSize100mm.Height(), 2, MAP_100TH_MM, FUNIT_INCH) / 100.0 * m_dResolution );
-
- BitmapEx bitmap = m_aGraphic.GetBitmapEx();
- bitmap.Scale(Size(nPixelX, nPixelY), BMP_SCALE_BEST);
- Graphic aScaledGraphic = Graphic (bitmap);
GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
-
- Sequence< PropertyValue > aFilterData( 3 );
- aFilterData[ 0 ].Name = "Interlaced";
- aFilterData[ 0 ].Value <<= (sal_Int32) 0;
- aFilterData[ 1 ].Name = "Compression";
- aFilterData[ 1 ].Value <<= (sal_Int32) m_aCompressionMF.GetValue();
- aFilterData[ 2 ].Name = "Quality";
- aFilterData[ 2 ].Value <<= (sal_Int32) m_aQualityMF.GetValue();
-
+ Graphic aResultGraphic = Graphic ();
SvMemoryStream aMemStream;
aMemStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
- Graphic aResultGraphic = Graphic ();
-
- String aGraphicFormatName = m_aLosslessRB.IsChecked() ? String( "png" ) : String( "jpg" );
-
- sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName(aGraphicFormatName );
- rFilter.ExportGraphic( aScaledGraphic, String("test"), aMemStream, nFilterFormat, &aFilterData );
+ Compress( aMemStream );
aMemStream.Seek( STREAM_SEEK_TO_BEGIN );
rFilter.ImportGraphic( aResultGraphic, String("test"), aMemStream );
-
return aResultGraphic;
}
return m_aGraphic;
More information about the Libreoffice-commits
mailing list