summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/source/msfilter/msdffimp.cxx11
-rw-r--r--include/vcl/bitmap.hxx6
-rw-r--r--include/vcl/bitmapex.hxx6
-rw-r--r--include/vcl/gdimtf.hxx2
-rw-r--r--vcl/source/gdi/bitmap3.cxx28
-rw-r--r--vcl/source/gdi/bitmapex.cxx4
-rw-r--r--vcl/source/gdi/gdimtf.cxx25
7 files changed, 60 insertions, 22 deletions
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index eb2e91de3053..30d0ec669edd 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -3818,7 +3818,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 ) );
@@ -3843,7 +3848,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, 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 )
@@ -3857,7 +3862,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, 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 9485a5a22b54..222cffae31b0 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -778,6 +778,9 @@ public:
@param bInvert
If true, invert the channel values with the logical 'not' operator
+ @param msoBrightness
+ Use the same formula for brightness as used by MSOffice.
+
@return true, if the operation was completed successfully.
*/
bool Adjust( short nLuminancePercent = 0,
@@ -786,7 +789,8 @@ public:
short nChannelGPercent = 0,
short nChannelBPercent = 0,
double fGamma = 1.0,
- bool bInvert = 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 5fa7c81e7f3b..5571ee41ca5f 100644
--- a/include/vcl/bitmapex.hxx
+++ b/include/vcl/bitmapex.hxx
@@ -348,6 +348,9 @@ public:
@param bInvert
If true, invert the channel values with the logical 'not' operator
+ @param msoFormula
+ Use the same formula for brightness as used by MSOffice.
+
@return true, if the operation was completed successfully.
*/
bool Adjust( short nLuminancePercent = 0,
@@ -356,7 +359,8 @@ public:
short nChannelGPercent = 0,
short nChannelBPercent = 0,
double fGamma = 1.0,
- bool bInvert = 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 0e22e9853320..4d863aa548b3 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,
- bool bInvert = 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 51221ee5873f..5da113f6f10b 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -3215,7 +3215,7 @@ bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFlags,
bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
- double fGamma, bool bInvert )
+ double fGamma, bool bInvert, bool msoBrightness )
{
bool bRet = false;
@@ -3246,8 +3246,11 @@ 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;
@@ -3261,10 +3264,21 @@ bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
// create mapping table
for( long 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 0e41be103957..8a5cd0970c85 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -629,11 +629,11 @@ bool BitmapEx::Replace( const Color* pSearchColors, const Color* pReplaceColors,
bool BitmapEx::Adjust( short nLuminancePercent, short nContrastPercent,
short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
- double fGamma, bool bInvert )
+ double fGamma, bool bInvert, bool msoBrightness )
{
return( !!aBitmap ? aBitmap.Adjust( nLuminancePercent, nContrastPercent,
nChannelRPercent, nChannelGPercent, nChannelBPercent,
- fGamma, bInvert ) : false );
+ fGamma, bInvert, msoBrightness ) : false );
}
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 7aee9fa40665..7107023a2f58 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -2176,7 +2176,7 @@ void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pCol
void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent,
short nChannelRPercent, short nChannelGPercent,
- short nChannelBPercent, double fGamma, bool bInvert )
+ short nChannelBPercent, double fGamma, bool bInvert, bool msoBrightness )
{
// nothing to do? => return quickly
if( nLuminancePercent || nContrastPercent ||
@@ -2197,8 +2197,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;
@@ -2212,10 +2215,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 );