0a6b54b4d3
* docx-brightness-contrast-1.diff * docx-brightness-contrast-2.diff - bnc#875712 - LO-L3: DOC import: picture brigtness/contrast not imported * doc-brightness-contrast.diff - bnc#870240 - LO-L3: pptx import file has text rotated on slide * fix-text-rotation.diff - bnc#870234 - LO-L3: pptx file has text imported as black instead of white * import-gradfill-for-text-colors.diff - bnc#870228 - LO-L3: Text inside the circle is not centered * text-alignment-in-shape.diff - bnc#863021 - LO-L3: Allow setting language for slide or presentation entirely * set-language-in-impress.diff - fix build on openSUSE 12.3: * disable-firebird-unit-test.diff OBS-URL: https://build.opensuse.org/package/show/LibreOffice:Factory/libreoffice?expand=0&rev=154
250 lines
13 KiB
Diff
250 lines
13 KiB
Diff
From 85e088c70aa3cfdd638276a2555b35ed1275c352 Mon Sep 17 00:00:00 2001
|
|
From: Luboš Luňák <l.lunak@collabora.com>
|
|
Date: Fri, 18 Apr 2014 18:46:34 +0000
|
|
Subject: 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
|
|
Reviewed-on: https://gerrit.libreoffice.org/9099
|
|
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
|
|
Tested-by: Miklos Vajna <vmiklos@collabora.co.uk>
|
|
---
|
|
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
|
|
index 63847b3..472e1a5 100644
|
|
--- a/filter/source/msfilter/msdffimp.cxx
|
|
+++ b/filter/source/msfilter/msdffimp.cxx
|
|
@@ -3817,7 +3817,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 ) );
|
|
@@ -3842,7 +3847,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 )
|
|
@@ -3856,7 +3861,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 adf6b63..621fceb 100644
|
|
--- a/include/vcl/bitmap.hxx
|
|
+++ b/include/vcl/bitmap.hxx
|
|
@@ -779,6 +779,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,
|
|
@@ -786,7 +789,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 da23547..8ac6325 100644
|
|
--- a/include/vcl/bitmapex.hxx
|
|
+++ b/include/vcl/bitmapex.hxx
|
|
@@ -343,6 +343,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,
|
|
@@ -350,7 +354,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 8afdc14..d38f863 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 5c4905a..4fbe1b8 100644
|
|
--- a/vcl/source/gdi/bitmap3.cxx
|
|
+++ b/vcl/source/gdi/bitmap3.cxx
|
|
@@ -3250,7 +3250,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;
|
|
|
|
@@ -3282,8 +3282,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;
|
|
@@ -3297,10 +3300,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 6deb1db..98c6b24 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 2e74172..12ad981 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 );
|
|
--
|
|
cgit v0.9.0.2-2-gbebe
|