[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