diff options
-rw-r--r-- | filter/source/msfilter/msdffimp.cxx | 11 | ||||
-rw-r--r-- | include/vcl/bitmap.hxx | 6 | ||||
-rw-r--r-- | include/vcl/bitmapex.hxx | 6 | ||||
-rw-r--r-- | include/vcl/gdimtf.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/bitmap3.cxx | 28 | ||||
-rw-r--r-- | vcl/source/gdi/bitmapex.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/gdimtf.cxx | 25 |
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 ); |