filter/source/msfilter/msdffimp.cxx |   11 ++++++++---
 include/vcl/bitmap.hxx              |    6 +++++-
 include/vcl/bitmapex.hxx            |    7 ++++++-
 include/vcl/gdimtf.hxx              |    2 +-
 vcl/source/gdi/bitmap3.cxx          |   28 +++++++++++++++++++++-------
 vcl/source/gdi/bitmapex.cxx         |    4 ++--
 vcl/source/gdi/gdimtf.cxx           |   25 ++++++++++++++++++-------
 7 files changed, 61 insertions(+), 22 deletions(-)

New commits:
commit b5fd2f9ff7c869065d424aa3b0632549480eb5b6
Author: Luboš Luňák <l.lu...@collabora.com>
Date:   Fri Apr 18 20:46:34 2014 +0200

    handle strange brightness+contrast adjustment from msoffice (fdo#38410)
    
    LO uses basically the formula 
"newpixel=(oldpixel-128)*contrast+128+brightness",
    i.e. contrast is applied first. It looks like there's no "oficial" formula 
for this,
    so a formula that applies brightness first would be ok too. MSO for some 
weird reason
    apparently uses a formula that applies half of brightness before contrast 
and
    half afterwards (insert funny political correctness or compromise joke 
here).
    While the result is the same like with the LO formula if only either 
brightness
    or contrast is adjusted, the result is different if both are involved. Just 
modify
    the image using the MSO algorithm if this is the case.
    
    Conflicts:
        filter/source/msfilter/msdffimp.cxx
        include/vcl/bitmap.hxx
        include/vcl/bitmapex.hxx
        include/vcl/gdimtf.hxx
        vcl/source/gdi/bitmap3.cxx
        vcl/source/gdi/bitmapex.cxx
        vcl/source/gdi/gdimtf.cxx
    
    Change-Id: I55fe8f395832685b90f024cf2f58b0797c1ba588

diff --git a/filter/source/msfilter/msdffimp.cxx 
b/filter/source/msfilter/msdffimp.cxx
index 09f15c0..f37a555 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -3816,7 +3816,12 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& 
rSt, SfxItemSet& rSet, cons
 
             if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( 
eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
             {
-                if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
+                // MSO uses a different algorithm for contrast+brightness, LO 
applies contrast before brightness,
+                // while MSO apparently applies half of brightness before 
contrast and half after. So if only
+                // contrast or brightness need to be altered, the result is 
the same, but if both are involved,
+                // there's no way to map that, so just force a conversion of 
the image.
+                bool needsConversion = nContrast != 0 && nBrightness != 0;
+                if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 && 
!needsConversion )
                 {
                     if ( nBrightness )
                         rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
@@ -3841,7 +3846,7 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, 
SfxItemSet& rSet, cons
                         {
                             BitmapEx    aBitmapEx( aGraf.GetBitmapEx() );
                             if ( nBrightness || nContrast || ( nGamma != 
0x10000 ) )
-                                aBitmapEx.Adjust( nBrightness, 
(sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
+                                aBitmapEx.Adjust( nBrightness, 
(sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, false, true );
                             if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
                                 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
                             else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
@@ -3855,7 +3860,7 @@ SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, 
SfxItemSet& rSet, cons
                         {
                             GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
                             if ( nBrightness || nContrast || ( nGamma != 
0x10000 ) )
-                                aGdiMetaFile.Adjust( nBrightness, 
(sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
+                                aGdiMetaFile.Adjust( nBrightness, 
(sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, false, true );
                             if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
                                 aGdiMetaFile.Convert( 
MTF_CONVERSION_8BIT_GREYS );
                             else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index d555d04e..4759937 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -796,6 +796,9 @@ public:
         If sal_True, invert the channel values with the logical 'not' operator
 
         @return sal_True, if the operation was completed successfully.
+
+        @param msoBrightness
+        Use the same formula for brightness as used by MSOffice.
      */
     sal_Bool                    Adjust( short nLuminancePercent = 0,
                                     short nContrastPercent = 0,
@@ -803,7 +806,8 @@ public:
                                     short nChannelGPercent = 0,
                                     short nChannelBPercent = 0,
                                     double fGamma = 1.0,
-                                    sal_Bool bInvert = sal_False );
+                                    bool bInvert = false,
+                                    bool msoBrightness = false );
 
     /** Apply specified filter to the bitmap
 
diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx
index 00a3c4e..b63c9d5 100644
--- a/include/vcl/bitmapex.hxx
+++ b/include/vcl/bitmapex.hxx
@@ -344,6 +344,10 @@ public:
         If sal_True, invert the channel values with the logical 'not' operator
 
         @return sal_True, if the operation was completed successfully.
+
+        @param msoFormula
+        Use the same formula for brightness as used by MSOffice.
+
      */
     sal_Bool                Adjust( short nLuminancePercent = 0,
                                 short nContrastPercent = 0,
@@ -351,7 +355,8 @@ public:
                                 short nChannelGPercent = 0,
                                 short nChannelBPercent = 0,
                                 double fGamma = 1.0,
-                                sal_Bool bInvert = sal_False );
+                                bool bInvert = false,
+                                bool msoBrightness = false );
 
     /** Apply specified filter to the bitmap
 
diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx
index c790acd..6865001 100644
--- a/include/vcl/gdimtf.hxx
+++ b/include/vcl/gdimtf.hxx
@@ -150,7 +150,7 @@ public:
     void            Adjust( short nLuminancePercent = 0, short 
nContrastPercent = 0,
                             short nChannelRPercent = 0,  short 
nChannelGPercent = 0,
                             short nChannelBPercent = 0,  double fGamma = 1.0,
-                            sal_Bool bInvert = sal_False
+                            bool bInvert = false, bool msoBrightness = false
                     );
 
     void            Convert( MtfConversion eConversion );
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 5b56ae4..354a03b 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -3271,7 +3271,7 @@ sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 
cReduce, sal_uLong nFla
 
 sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
                      short nChannelRPercent, short nChannelGPercent, short 
nChannelBPercent,
-                     double fGamma, sal_Bool bInvert )
+                     double fGamma, bool bInvert, bool msoBrightness )
 {
     sal_Bool bRet = sal_False;
 
@@ -3303,8 +3303,11 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short 
nContrastPercent,
             else
                 fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) 
/ 128.0;
 
-            // total offset = luminance offset + contrast offset
-            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - 
fM * 128.0;
+            if(!msoBrightness)
+                // total offset = luminance offset + contrast offset
+                fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 
- fM * 128.0;
+            else
+                fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55;
 
             // channel offset = channel offset  + total offset
             fROff = nChannelRPercent * 2.55 + fOff;
@@ -3318,10 +3321,21 @@ sal_Bool Bitmap::Adjust( short nLuminancePercent, short 
nContrastPercent,
             // create mapping table
             for( nX = 0L; nX < 256L; nX++ )
             {
-                cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 
0L, 255L );
-                cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 
0L, 255L );
-                cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 
0L, 255L );
-
+                if(!msoBrightness)
+                {
+                    cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff 
), 0L, 255L );
+                    cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff 
), 0L, 255L );
+                    cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff 
), 0L, 255L );
+                }
+                else
+                {
+                    // LO simply uses (in a somewhat optimized form) "newcolor 
= (oldcolor-128)*contrast+brightness+128"
+                    // as the formula, i.e. contrast first, brightness 
afterwards. MSOffice, for whatever weird reason,
+                    // use neither first, but apparently it applies half of 
brightness before contrast and half afterwards.
+                    cMapR[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fROff/2-128) 
* fM + 128 + fROff/2 ), 0L, 255L );
+                    cMapG[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fGOff/2-128) 
* fM + 128 + fGOff/2 ), 0L, 255L );
+                    cMapB[ nX ] = (sal_uInt8) MinMax( FRound( (nX+fBOff/2-128) 
* fM + 128 + fBOff/2 ), 0L, 255L );
+                }
                 if( bGamma )
                 {
                     cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma );
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index f60c583..87564d8 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -633,11 +633,11 @@ sal_Bool BitmapEx::Replace( const Color* pSearchColors, 
const Color* pReplaceCol
 
 sal_Bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
                        short nChannelRPercent, short nChannelGPercent, short 
nChannelBPercent,
-                       double fGamma, sal_Bool bInvert )
+                       double fGamma, bool bInvert, bool msoBrightness )
 {
     return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
                                         nChannelRPercent, nChannelGPercent, 
nChannelBPercent,
-                                        fGamma, bInvert ) : sal_False );
+                                        fGamma, bInvert, msoBrightness ) : 
false );
 }
 
 sal_Bool BitmapEx::Filter( BmpFilter eFilter, const BmpFilterParam* 
pFilterParam, const Link* pProgress )
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 90e691b..17cbb37 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -2175,7 +2175,7 @@ void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc 
pFncCol, const void* pCol
 
 void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
                           short nChannelRPercent, short nChannelGPercent,
-                          short nChannelBPercent, double fGamma, sal_Bool 
bInvert )
+                          short nChannelBPercent, double fGamma, bool bInvert, 
bool msoBrightness )
 {
     // nothing to do? => return quickly
     if( nLuminancePercent || nContrastPercent ||
@@ -2196,8 +2196,11 @@ void GDIMetaFile::Adjust( short nLuminancePercent, short 
nContrastPercent,
         else
             fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 
128.0;
 
-        // total offset = luminance offset + contrast offset
-        fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 
128.0;
+        if(!msoBrightness)
+            // total offset = luminance offset + contrast offset
+            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - 
fM * 128.0;
+        else
+            fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55;
 
         // channel offset = channel offset  + total offset
         fROff = nChannelRPercent * 2.55 + fOff;
@@ -2211,10 +2214,18 @@ void GDIMetaFile::Adjust( short nLuminancePercent, 
short nContrastPercent,
         // create mapping table
         for( long nX = 0L; nX < 256L; nX++ )
         {
-            aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fROff ), 0L, 255L );
-            aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fGOff ), 0L, 255L );
-            aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fBOff ), 0L, 255L );
-
+            if(!msoBrightness)
+            {
+                aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fROff ), 0L, 255L );
+                aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fGOff ), 0L, 255L );
+                aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + 
fBOff ), 0L, 255L );
+            }
+            else
+            {
+                aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( 
(nX+fROff/2-128) * fM + 128 + fROff/2 ), 0L, 255L );
+                aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( 
(nX+fGOff/2-128) * fM + 128 + fGOff/2 ), 0L, 255L );
+                aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( 
(nX+fBOff/2-128) * fM + 128 + fBOff/2 ), 0L, 255L );
+            }
             if( bGamma )
             {
                 aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma );
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to