summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNorbert Thiebaud <nthiebaud@gmail.com>2013-02-18 19:32:34 -0600
committerPetr Mladek <pmladek@suse.cz>2013-02-19 11:05:20 +0000
commit0ff04e11c0e79a2969774c21df8e0d5822b54e08 (patch)
treec55bd7ff8c2f844a38f371870e33ef6879ee1213
parentf68b89cbfd76e43a701f8457a3a97c87be74758a (diff)
fdo#60719 : fix crash on scaling bmp with target/source width/height = 1
The rendering is quite ugly compared to the same pdf opened with pdf reader. but at least it does not crash anymore. The function ImplCreateRotatedScaled seems quite sub-optimal for one thing it is called even when there is no rotation and still bother with doing a lot of work to 'rotate' things. It was assuming Width and Height > 1 for both the source and the target The patch tries to 'hide' the misery... but I'm not convinced that this is 'right'. Change-Id: I9aec5eb6655ea3678aa018ae5928dabb8058bec6 Reviewed-on: https://gerrit.libreoffice.org/2195 Reviewed-by: Arnaud Versini <arnaud.versini@gmail.com> Tested-by: Arnaud Versini <arnaud.versini@gmail.com> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Tomaž Vajngerl <quikee@gmail.com> Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/2248 Reviewed-by: Petr Mladek <pmladek@suse.cz> Tested-by: Petr Mladek <pmladek@suse.cz>
-rw-r--r--svtools/source/graphic/grfmgr2.cxx94
1 files changed, 71 insertions, 23 deletions
diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx
index 4aeccf991b66..88a6ce84dac7 100644
--- a/svtools/source/graphic/grfmgr2.cxx
+++ b/svtools/source/graphic/grfmgr2.cxx
@@ -276,38 +276,88 @@ sal_Bool ImplCreateRotatedScaled( const BitmapEx& rBmpEx, const GraphicAttr& rAt
long* pMapIY = new long[ aUnrotatedHeight ];
long* pMapFY = new long[ aUnrotatedHeight ];
- const double fScaleX = ( aUnrotatedWidth - 1 ) / (double) ( aBitmapWidth - 1 );
- const double fScaleY = ( aUnrotatedHeight - 1 ) / (double) ( aBitmapHeight - 1 );
-
- const double fRevScaleX = 1.0 / fScaleX;
- const double fRevScaleY = 1.0 / fScaleY;
+ double fRevScaleX;
+ double fRevScaleY;
+ bool scaleByAveraging = false;
int x,y;
- // create horizontal mapping table
- for( x = 0, nTmpX = aBitmapWidth - 1L, nTmp = aBitmapWidth - 2L; x < aUnrotatedWidth; x++ )
+ if(aBitmapWidth > 1 && aUnrotatedWidth > 1)
{
- fTmp = x * fRevScaleX;
+ fRevScaleX = (double) ( aBitmapWidth - 1 ) / (double)( aUnrotatedWidth - 1 );
+ // create horizontal mapping table
+ for( x = 0, nTmpX = aBitmapWidth - 1L, nTmp = aBitmapWidth - 2L >= 0 ? aBitmapWidth -2L : 0L; x < aUnrotatedWidth; x++ )
+ {
+ fTmp = x * fRevScaleX;
- if( bHMirr )
- fTmp = nTmpX - fTmp;
+ if( bHMirr )
+ fTmp = nTmpX - fTmp;
- pMapIX[ x ] = MinMax( fTmp, 0, nTmp );
- pMapFX[ x ] = (long) ( ( fTmp - pMapIX[ x ] ) * 1048576.0 );
+ pMapIX[ x ] = MinMax( fTmp, 0, nTmp );
+ pMapFX[ x ] = (long) ( ( fTmp - pMapIX[ x ] ) * 1048576.0 );
+ }
+ scaleByAveraging |= fRevScaleX > 5.0/3.0;
}
+ else
+ {
+ if(aBitmapWidth == 1)
+ {
+ fRevScaleX = 1.0 / (double)( aUnrotatedWidth );
+ for ( x = 0; x < aUnrotatedWidth ; x++)
+ {
+ pMapIX[x] = 0;
+ pMapFX[x] = 0.5;
+ }
+ scaleByAveraging = true;
+ }
+ else
+ {
+ fRevScaleX = (double) aBitmapWidth / (double)( aUnrotatedWidth);
+ fTmp = (double)aBitmapWidth / 2.0;
- // create vertical mapping table
- for( y = 0, nTmpY = aBitmapHeight - 1L, nTmp = aBitmapHeight - 2L; y < aUnrotatedHeight; y++ )
+ pMapIX[ 0 ] = (long)fTmp;
+ pMapFX[ 0 ] = (long)( ( fTmp - pMapIX[ 0 ] ) * 1048576.0 );
+ scaleByAveraging = true;
+ }
+ }
+ if(aBitmapHeight > 1 && aUnrotatedHeight > 1)
{
- fTmp = y * fRevScaleY;
+ fRevScaleY = (double) ( aBitmapHeight - 1 ) / (double)( aUnrotatedHeight - 1 );
+ // create vertical mapping table
+ for( y = 0, nTmpY = aBitmapHeight - 1L, nTmp = aBitmapHeight - 2L >= 0 ? aBitmapHeight - 2L : 0L; y < aUnrotatedHeight; y++ )
+ {
+ fTmp = y * fRevScaleY;
- if( bVMirr )
- fTmp = nTmpY - fTmp;
+ if( bVMirr )
+ fTmp = nTmpY - fTmp;
- pMapIY[ y ] = MinMax( fTmp, 0, nTmp );
- pMapFY[ y ] = (long) ( ( fTmp - pMapIY[ y ] ) * 1048576.0 );
+ pMapIY[ y ] = MinMax( fTmp, 0, nTmp );
+ pMapFY[ y ] = (long) ( ( fTmp - pMapIY[ y ] ) * 1048576.0 );
+ }
+ scaleByAveraging |= fRevScaleY > 5.0/3.0;
}
+ else
+ {
+ if(aBitmapHeight == 1)
+ {
+ fRevScaleY = 1.0 / (double)( aUnrotatedHeight);
+ for ( y = 0; y < aUnrotatedHeight ; y++)
+ {
+ pMapIY[y] = 0;
+ pMapFY[y] = 0.5;
+ }
+ scaleByAveraging = true;
+ }
+ else
+ {
+ fRevScaleY = (double) aBitmapHeight / (double)( aUnrotatedHeight);
+ fTmp = (double)aBitmapHeight / 2.0;
+ pMapIY[ 0 ] = (long)fTmp;
+ pMapFY[ 0 ] = (long)( ( fTmp - pMapIY[ 0 ] ) * 1048576.0 );
+ scaleByAveraging = true;
+ }
+ }
Bitmap aBmp( rBmpEx.GetBitmap() );
Bitmap aOutBmp;
@@ -330,8 +380,6 @@ sal_Bool ImplCreateRotatedScaled( const BitmapEx& rBmpEx, const GraphicAttr& rAt
aPoly.Rotate( Point(), nRot10 );
Rectangle aNewBound( aPoly.GetBoundRect() );
- bool scaleByAveraging = fScaleX < 0.6 || fScaleY < 0.6;
-
// create horizontal mapping table
for( x = 0, nTmpX = aNewBound.Left() + nStartX; x < aTargetWidth; x++ )
{
@@ -696,11 +744,11 @@ sal_Bool ImplCreateRotatedScaled( const BitmapEx& rBmpEx, const GraphicAttr& rAt
// create new horizontal mapping table
for( nX = 0UL; nX < aUnrotatedWidth; nX++ )
- pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576. );
+ pMapLX[ nX ] = FRound( (double) pMapIX[ nX ] + pMapFX[ nX ] / 1048576.0 );
// create new vertical mapping table
for( nY = 0UL; nY < aUnrotatedHeight; nY++ )
- pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576. );
+ pMapLY[ nY ] = FRound( (double) pMapIY[ nY ] + pMapFY[ nY ] / 1048576.0 );
// do mask rotation
for( nY = 0; nY < aTargetHeight; nY++ )