From 0ff04e11c0e79a2969774c21df8e0d5822b54e08 Mon Sep 17 00:00:00 2001 From: Norbert Thiebaud Date: Mon, 18 Feb 2013 19:32:34 -0600 Subject: fdo#60719 : fix crash on scaling bmp with target/source width/height = 1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Tested-by: Arnaud Versini Reviewed-by: Tomaž Vajngerl Tested-by: Tomaž Vajngerl Reviewed-by: Norbert Thiebaud Reviewed-on: https://gerrit.libreoffice.org/2248 Reviewed-by: Petr Mladek Tested-by: Petr Mladek --- svtools/source/graphic/grfmgr2.cxx | 94 ++++++++++++++++++++++++++++---------- 1 file 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++ ) -- cgit v1.2.3