LCOV - code coverage report
Current view: top level - vcl/source/bitmap - bitmapscalesuper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 283 612 46.2 %
Date: 2015-06-13 12:38:46 Functions: 14 23 60.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <vcl/bmpacc.hxx>
      21             : #include <vcl/bitmapscalesuper.hxx>
      22             : 
      23             : #include <algorithm>
      24             : #include <boost/scoped_array.hpp>
      25             : #include <comphelper/threadpool.hxx>
      26             : 
      27             : namespace {
      28             : 
      29             : #define MAP( cVal0, cVal1, nFrac )  ((sal_uInt8)((((long)(cVal0)<<7L)+nFrac*((long)(cVal1)-(cVal0)))>>7L))
      30             : 
      31        1592 : void generateMap(long nW, long nDstW, bool bHMirr, long* pMapIX, long* pMapFX)
      32             : {
      33        1592 :     const double fRevScaleX = (nDstW > 1L) ? (double) (nW - 1) / (nDstW - 1) : 0.0;
      34             : 
      35        1592 :     long nTemp = nW - 2L;
      36        1592 :     long nTempX = nW - 1L;
      37       75716 :     for (long nX = 0L; nX < nDstW; nX++)
      38             :     {
      39       74124 :         double fTemp = nX * fRevScaleX;
      40       74124 :         if (bHMirr)
      41           0 :             fTemp = nTempX - fTemp;
      42       74124 :         pMapIX[nX] = MinMax((long) fTemp, 0, nTemp);
      43       74124 :         pMapFX[nX] = (long) ((fTemp - pMapIX[nX]) * 128.0);
      44             :     }
      45        1592 : }
      46             : 
      47         796 : struct ScaleContext {
      48             :     BitmapReadAccess  *mpSrc;
      49             :     BitmapWriteAccess *mpDest;
      50             :     long mnSrcW, mnDestW;
      51             :     long mnSrcH, mnDestH;
      52             :     bool mbHMirr, mbVMirr;
      53             :     boost::scoped_array<long> mpMapIX;
      54             :     boost::scoped_array<long> mpMapIY;
      55             :     boost::scoped_array<long> mpMapFX;
      56             :     boost::scoped_array<long> mpMapFY;
      57         796 :     ScaleContext( BitmapReadAccess *pSrc,
      58             :                   BitmapWriteAccess *pDest,
      59             :                   long nSrcW, long nDestW,
      60             :                   long nSrcH, long nDestH,
      61             :                   bool bHMirr, bool bVMirr)
      62             :         : mpSrc( pSrc ), mpDest( pDest )
      63             :         , mnSrcW( nSrcW ), mnDestW( nDestW )
      64             :         , mnSrcH( nSrcH ), mnDestH( nDestH )
      65             :         , mbHMirr( bHMirr ), mbVMirr( bVMirr )
      66         796 :         , mpMapIX( new long[ nDestW ] )
      67         796 :         , mpMapIY( new long[ nDestH ] )
      68         796 :         , mpMapFX( new long[ nDestW ] )
      69        3184 :         , mpMapFY( new long[ nDestH ] )
      70             :     {
      71         796 :         generateMap(nSrcW, nDestW, bHMirr, mpMapIX.get(), mpMapFX.get());
      72         796 :         generateMap(nSrcH, nDestH, bVMirr, mpMapIY.get(), mpMapFY.get());
      73         796 :     }
      74             : };
      75             : 
      76             : #define SCALE_THREAD_STRIP 32
      77             : struct ScaleRangeContext {
      78             :     ScaleContext *mrCtx;
      79             :     long mnStartY, mnEndY;
      80           0 :     ScaleRangeContext( ScaleContext *rCtx, long nStartY )
      81             :         : mrCtx( rCtx ), mnStartY( nStartY ),
      82           0 :           mnEndY( nStartY + SCALE_THREAD_STRIP ) {}
      83             : };
      84             : 
      85             : typedef void (*ScaleRangeFn)(ScaleContext &rCtx, long nStartY, long nEndY);
      86             : 
      87        6131 : class ScaleTask : public comphelper::ThreadTask
      88             : {
      89             :     ScaleRangeFn mpFn;
      90             :     std::vector< ScaleRangeContext > maStrips;
      91             : public:
      92        3069 :     explicit ScaleTask( ScaleRangeFn pFn ) : mpFn( pFn ) {}
      93           0 :     void push( ScaleRangeContext &aRC ) { maStrips.push_back( aRC ); }
      94        3066 :     virtual void doWork() SAL_OVERRIDE
      95             :     {
      96        3066 :         std::vector< ScaleRangeContext >::iterator it;
      97        3066 :         for (it = maStrips.begin(); it != maStrips.end(); ++it)
      98           0 :             mpFn( *(it->mrCtx), it->mnStartY, it->mnEndY );
      99        3068 :     }
     100             : };
     101             : 
     102         335 : void scalePallete8bit(ScaleContext &rCtx, long nStartY, long nEndY)
     103             : {
     104         335 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     105             : 
     106        4064 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     107             :     {
     108        3729 :         long nTempY = rCtx.mpMapIY[ nY ];
     109        3729 :         long nTempFY = rCtx.mpMapFY[ nY ];
     110        3729 :         Scanline pLine0 = rCtx.mpSrc->GetScanline( nTempY );
     111        3729 :         Scanline pLine1 = rCtx.mpSrc->GetScanline( ++nTempY );
     112             : 
     113      115969 :         for(long nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
     114             :         {
     115      112240 :             long nTempX = rCtx.mpMapIX[ nX ];
     116      112240 :             long nTempFX = rCtx.mpMapFX[ nX ];
     117             : 
     118      112240 :             const BitmapColor& rCol0 = rCtx.mpSrc->GetPaletteColor( pLine0[ nTempX ] );
     119      112240 :             const BitmapColor& rCol2 = rCtx.mpSrc->GetPaletteColor( pLine1[ nTempX ] );
     120      112240 :             const BitmapColor& rCol1 = rCtx.mpSrc->GetPaletteColor( pLine0[ ++nTempX ] );
     121      112240 :             const BitmapColor& rCol3 = rCtx.mpSrc->GetPaletteColor( pLine1[ nTempX ] );
     122             : 
     123      112240 :             sal_uInt8 cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTempFX );
     124      112240 :             sal_uInt8 cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTempFX );
     125      112240 :             sal_uInt8 cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTempFX );
     126             : 
     127      112240 :             sal_uInt8 cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTempFX );
     128      112240 :             sal_uInt8 cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTempFX );
     129      112240 :             sal_uInt8 cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTempFX );
     130             : 
     131      112240 :             BitmapColor aColRes( MAP( cR0, cR1, nTempFY ),
     132      112240 :                     MAP( cG0, cG1, nTempFY ),
     133      336720 :                     MAP( cB0, cB1, nTempFY ) );
     134      112240 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     135      112240 :         }
     136             :     }
     137         335 : }
     138             : 
     139           0 : void scalePalleteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
     140             : {
     141           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     142             : 
     143           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     144             :     {
     145           0 :         long nTempY = rCtx.mpMapIY[ nY ];
     146           0 :         long nTempFY = rCtx.mpMapFY[ nY ];
     147             : 
     148           0 :         for( long nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
     149             :         {
     150           0 :             long nTempX = rCtx.mpMapIX[ nX ];
     151           0 :             long nTempFX = rCtx.mpMapFX[ nX ];
     152             : 
     153           0 :             BitmapColor aCol0 = rCtx.mpSrc->GetPaletteColor( rCtx.mpSrc->GetPixelIndex( nTempY, nTempX ) );
     154           0 :             BitmapColor aCol1 = rCtx.mpSrc->GetPaletteColor( rCtx.mpSrc->GetPixelIndex( nTempY, ++nTempX ) );
     155           0 :             sal_uInt8 cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
     156           0 :             sal_uInt8 cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
     157           0 :             sal_uInt8 cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
     158             : 
     159           0 :             aCol1 = rCtx.mpSrc->GetPaletteColor( rCtx.mpSrc->GetPixelIndex( ++nTempY, nTempX ) );
     160           0 :             aCol0 = rCtx.mpSrc->GetPaletteColor( rCtx.mpSrc->GetPixelIndex( nTempY--, --nTempX ) );
     161           0 :             sal_uInt8 cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
     162           0 :             sal_uInt8 cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
     163           0 :             sal_uInt8 cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
     164             : 
     165           0 :             BitmapColor aColRes( MAP( cR0, cR1, nTempFY ),
     166           0 :                     MAP( cG0, cG1, nTempFY ),
     167           0 :                     MAP( cB0, cB1, nTempFY ) );
     168           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     169           0 :         }
     170             :     }
     171           0 : }
     172             : 
     173           0 : void scale24bitBGR(ScaleContext &rCtx, long nStartY, long nEndY)
     174             : {
     175           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     176             : 
     177           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     178             :     {
     179           0 :         long nTempY = rCtx.mpMapIY[ nY ];
     180           0 :         long nTempFY = rCtx.mpMapFY[ nY ];
     181           0 :         Scanline pLine0 = rCtx.mpSrc->GetScanline( nTempY );
     182           0 :         Scanline pLine1 = rCtx.mpSrc->GetScanline( ++nTempY );
     183             : 
     184           0 :         for( long nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
     185             :         {
     186           0 :             long nOff = 3L * rCtx.mpMapIX[ nX ];
     187           0 :             long nTempFX = rCtx.mpMapFX[ nX ];
     188             : 
     189           0 :             Scanline pTmp0 = pLine0 + nOff ;
     190           0 :             Scanline pTmp1 = pTmp0 + 3L;
     191           0 :             sal_uInt8 cB0 = MAP( *pTmp0, *pTmp1, nTempFX );
     192           0 :             pTmp0++; pTmp1++;
     193           0 :             sal_uInt8 cG0 = MAP( *pTmp0, *pTmp1, nTempFX );
     194           0 :             pTmp0++; pTmp1++;
     195           0 :             sal_uInt8 cR0 = MAP( *pTmp0, *pTmp1, nTempFX );
     196             : 
     197           0 :             pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
     198           0 :             sal_uInt8 cB1 = MAP( *pTmp0, *pTmp1, nTempFX );
     199           0 :             pTmp0++; pTmp1++;
     200           0 :             sal_uInt8 cG1 = MAP( *pTmp0, *pTmp1, nTempFX );
     201           0 :             pTmp0++; pTmp1++;
     202           0 :             sal_uInt8 cR1 = MAP( *pTmp0, *pTmp1, nTempFX );
     203             : 
     204           0 :             BitmapColor aColRes( MAP( cR0, cR1, nTempFY ),
     205           0 :                     MAP( cG0, cG1, nTempFY ),
     206           0 :                     MAP( cB0, cB1, nTempFY ) );
     207           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     208           0 :         }
     209             :     }
     210           0 : }
     211             : 
     212           0 : void scale24bitRGB(ScaleContext &rCtx, long nStartY, long nEndY)
     213             : {
     214           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     215             : 
     216           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     217             :     {
     218           0 :         long nTempY = rCtx.mpMapIY[ nY ];
     219           0 :         long nTempFY = rCtx.mpMapFY[ nY ];
     220           0 :         Scanline pLine0 = rCtx.mpSrc->GetScanline( nTempY );
     221           0 :         Scanline pLine1 = rCtx.mpSrc->GetScanline( ++nTempY );
     222             : 
     223           0 :         for( long nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
     224             :         {
     225           0 :             long nOff = 3L * rCtx.mpMapIX[ nX ];
     226           0 :             long nTempFX = rCtx.mpMapFX[ nX ];
     227             : 
     228           0 :             Scanline pTmp0 = pLine0 + nOff;
     229           0 :             Scanline pTmp1 = pTmp0 + 3L;
     230           0 :             sal_uInt8 cR0 = MAP( *pTmp0, *pTmp1, nTempFX );
     231           0 :             pTmp0++; pTmp1++;
     232           0 :             sal_uInt8 cG0 = MAP( *pTmp0, *pTmp1, nTempFX );
     233           0 :             pTmp0++; pTmp1++;
     234           0 :             sal_uInt8 cB0 = MAP( *pTmp0, *pTmp1, nTempFX );
     235             : 
     236           0 :             pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
     237           0 :             sal_uInt8 cR1 = MAP( *pTmp0, *pTmp1, nTempFX );
     238           0 :             pTmp0++; pTmp1++;
     239           0 :             sal_uInt8 cG1 = MAP( *pTmp0, *pTmp1, nTempFX );
     240           0 :             pTmp0++; pTmp1++;
     241           0 :             sal_uInt8 cB1 = MAP( *pTmp0, *pTmp1, nTempFX );
     242             : 
     243           0 :             BitmapColor aColRes( MAP( cR0, cR1, nTempFY ),
     244           0 :                     MAP( cG0, cG1, nTempFY ),
     245           0 :                     MAP( cB0, cB1, nTempFY ) );
     246           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     247           0 :         }
     248             :     }
     249           0 : }
     250             : 
     251         346 : void scaleNonPalleteGeneral(ScaleContext &rCtx, long nStartY, long nEndY)
     252             : {
     253         346 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     254             : 
     255       10251 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     256             :     {
     257        9905 :         long nTempY = rCtx.mpMapIY[ nY ];
     258        9905 :         long nTempFY = rCtx.mpMapFY[ nY ];
     259             : 
     260     3685881 :         for( long nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
     261             :         {
     262     3675976 :             long nTempX = rCtx.mpMapIX[ nX ];
     263     3675976 :             long nTempFX = rCtx.mpMapFX[ nX ];
     264             : 
     265     3675976 :             BitmapColor aCol0 = rCtx.mpSrc->GetPixel( nTempY, nTempX );
     266     7351952 :             BitmapColor aCol1 = rCtx.mpSrc->GetPixel( nTempY, ++nTempX );
     267     3675976 :             sal_uInt8 cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
     268     3675976 :             sal_uInt8 cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
     269     3675976 :             sal_uInt8 cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
     270             : 
     271     3675976 :             aCol1 = rCtx.mpSrc->GetPixel( ++nTempY, nTempX );
     272     3675976 :             aCol0 = rCtx.mpSrc->GetPixel( nTempY--, --nTempX );
     273     3675976 :             sal_uInt8 cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
     274     3675976 :             sal_uInt8 cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
     275     3675976 :             sal_uInt8 cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
     276             : 
     277     3675976 :             BitmapColor aColRes( MAP( cR0, cR1, nTempFY ),
     278     3675976 :                     MAP( cG0, cG1, nTempFY ),
     279    14703904 :                     MAP( cB0, cB1, nTempFY ) );
     280     3675976 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     281     3675976 :         }
     282             :     }
     283         346 : }
     284             : 
     285           3 : void scalePallete8bit2(ScaleContext &rCtx, long nStartY, long nEndY)
     286             : {
     287           3 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     288           3 :     const long nMax = 1 << 7L;
     289             : 
     290         426 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     291             :     {
     292         423 :         long nTop = rCtx.mbVMirr ? ( nY + 1 ) : nY;
     293         423 :         long nBottom = rCtx.mbVMirr ? nY : ( nY + 1 ) ;
     294             : 
     295             :         long nLineStart, nLineRange;
     296         423 :         if( nY == nEndY )
     297             :         {
     298           3 :             nLineStart = rCtx.mpMapIY[ nY ];
     299           3 :             nLineRange = 0;
     300             :         }
     301             :         else
     302             :         {
     303         420 :             nLineStart = rCtx.mpMapIY[ nTop ] ;
     304         420 :             nLineRange = ( rCtx.mpMapIY[ nBottom ] == rCtx.mpMapIY[ nTop ] ) ? 1 :( rCtx.mpMapIY[ nBottom ] - rCtx.mpMapIY[ nTop ] );
     305             :         }
     306             : 
     307       60066 :         for( long nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
     308             :         {
     309       59643 :             long nLeft = rCtx.mbHMirr ? ( nX + 1 ) : nX;
     310       59643 :             long nRight = rCtx.mbHMirr ? nX : ( nX + 1 ) ;
     311             : 
     312             :             long nRowStart;
     313             :             long nRowRange;
     314       59643 :             if( nX == nEndX )
     315             :             {
     316         423 :                 nRowStart = rCtx.mpMapIX[ nX ];
     317         423 :                 nRowRange = 0;
     318             :             }
     319             :             else
     320             :             {
     321       59220 :                 nRowStart = rCtx.mpMapIX[ nLeft ];
     322       59220 :                 nRowRange = ( rCtx.mpMapIX[ nRight ] == rCtx.mpMapIX[ nLeft ] )? 1 : ( rCtx.mpMapIX[ nRight ] - rCtx.mpMapIX[ nLeft ] );
     323             :             }
     324             : 
     325       59643 :             long nSumR = 0;
     326       59643 :             long nSumG = 0;
     327       59643 :             long nSumB = 0;
     328       59643 :             long nTotalWeightY = 0;
     329             : 
     330      225459 :             for(long i = 0; i<= nLineRange; i++)
     331             :             {
     332      165816 :                 Scanline pTmpY = rCtx.mpSrc->GetScanline( nLineStart + i );
     333      165816 :                 long nSumRowR = 0;
     334      165816 :                 long nSumRowG = 0;
     335      165816 :                 long nSumRowB = 0;
     336      165816 :                 long nTotalWeightX = 0;
     337             : 
     338      626808 :                 for(long j = 0; j <= nRowRange; j++)
     339             :                 {
     340      460992 :                     const BitmapColor& rCol = rCtx.mpSrc->GetPaletteColor( pTmpY[ nRowStart + j ] );
     341             : 
     342      460992 :                     if(nX == nEndX )
     343             :                     {
     344        1176 :                         nSumRowB += rCol.GetBlue() << 7L;
     345        1176 :                         nSumRowG += rCol.GetGreen() << 7L;
     346        1176 :                         nSumRowR += rCol.GetRed() << 7L;
     347        1176 :                         nTotalWeightX += 1 << 7L;
     348             :                     }
     349      459816 :                     else if( j == 0 )
     350             :                     {
     351      164640 :                         long nWeightX = (nMax- rCtx.mpMapFX[ nLeft ]) ;
     352      164640 :                         nSumRowB += ( nWeightX *rCol.GetBlue()) ;
     353      164640 :                         nSumRowG += ( nWeightX *rCol.GetGreen()) ;
     354      164640 :                         nSumRowR += ( nWeightX *rCol.GetRed()) ;
     355      164640 :                         nTotalWeightX += nWeightX;
     356             :                     }
     357      295176 :                     else if ( nRowRange == j )
     358             :                     {
     359      164640 :                         long nWeightX = rCtx.mpMapFX[ nRight ] ;
     360      164640 :                         nSumRowB += ( nWeightX *rCol.GetBlue() );
     361      164640 :                         nSumRowG += ( nWeightX *rCol.GetGreen() );
     362      164640 :                         nSumRowR += ( nWeightX *rCol.GetRed() );
     363      164640 :                         nTotalWeightX += nWeightX;
     364             :                     }
     365             :                     else
     366             :                     {
     367      130536 :                         nSumRowB += rCol.GetBlue() << 7L;
     368      130536 :                         nSumRowG += rCol.GetGreen() << 7L;
     369      130536 :                         nSumRowR += rCol.GetRed() << 7L;
     370      130536 :                         nTotalWeightX += 1 << 7L;
     371             :                     }
     372             :                 }
     373             : 
     374      165816 :                 long nWeightY = nMax;
     375      165816 :                 if( nY == nEndY )
     376         423 :                     nWeightY = nMax;
     377      165393 :                 else if( i == 0 )
     378       59220 :                     nWeightY = nMax - rCtx.mpMapFY[ nTop ];
     379      106173 :                 else if( nLineRange == 1 )
     380       12267 :                     nWeightY = rCtx.mpMapFY[ nTop ];
     381       93906 :                 else if ( nLineRange == i )
     382       46953 :                     nWeightY = rCtx.mpMapFY[ nBottom ];
     383             : 
     384      165816 :                 if (nTotalWeightX)
     385             :                 {
     386      165816 :                     nSumRowB /= nTotalWeightX;
     387      165816 :                     nSumRowG /= nTotalWeightX;
     388      165816 :                     nSumRowR /= nTotalWeightX;
     389             :                 }
     390             : 
     391      165816 :                 nSumB += nWeightY * nSumRowB;
     392      165816 :                 nSumG += nWeightY * nSumRowG;
     393      165816 :                 nSumR += nWeightY * nSumRowR;
     394      165816 :                 nTotalWeightY += nWeightY;
     395             :             }
     396             : 
     397       59643 :             if (nTotalWeightY)
     398             :             {
     399       59643 :                 nSumR /= nTotalWeightY;
     400       59643 :                 nSumG /= nTotalWeightY;
     401       59643 :                 nSumB /= nTotalWeightY;
     402             :             }
     403             : 
     404       59643 :             BitmapColor aColRes((sal_uInt8)nSumR, (sal_uInt8)nSumG, (sal_uInt8)nSumB);
     405       59643 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     406       59643 :         }
     407             :     }
     408           3 : }
     409             : 
     410           0 : void scalePalleteGeneral2(ScaleContext &rCtx, long nStartY, long nEndY)
     411             : {
     412           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     413           0 :     const long nMax = 1 << 7L;
     414             : 
     415           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     416             :     {
     417           0 :         long nTop = rCtx.mbVMirr ? ( nY + 1 ) : nY;
     418           0 :         long nBottom = rCtx.mbVMirr ? nY : ( nY + 1 ) ;
     419             : 
     420             :         long nLineStart, nLineRange;
     421           0 :         if( nY ==nEndY )
     422             :         {
     423           0 :             nLineStart = rCtx.mpMapIY[ nY ];
     424           0 :             nLineRange = 0;
     425             :         }
     426             :         else
     427             :         {
     428           0 :             nLineStart = rCtx.mpMapIY[ nTop ] ;
     429           0 :             nLineRange = ( rCtx.mpMapIY[ nBottom ] == rCtx.mpMapIY[ nTop ] ) ? 1 :( rCtx.mpMapIY[ nBottom ] - rCtx.mpMapIY[ nTop ] );
     430             :         }
     431             : 
     432           0 :         for( long nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
     433             :         {
     434           0 :             long nLeft = rCtx.mbHMirr ? ( nX + 1 ) : nX;
     435           0 :             long nRight = rCtx.mbHMirr ? nX : ( nX + 1 ) ;
     436             : 
     437             :             long nRowStart, nRowRange;
     438           0 :             if( nX == nEndX )
     439             :             {
     440           0 :                 nRowStart = rCtx.mpMapIX[ nX ];
     441           0 :                 nRowRange = 0;
     442             :             }
     443             :             else
     444             :             {
     445           0 :                 nRowStart = rCtx.mpMapIX[ nLeft ];
     446           0 :                 nRowRange = ( rCtx.mpMapIX[ nRight ] == rCtx.mpMapIX[ nLeft ] )? 1 : ( rCtx.mpMapIX[ nRight ] - rCtx.mpMapIX[ nLeft ] );
     447             :             }
     448             : 
     449           0 :             long nSumR = 0;
     450           0 :             long nSumG = 0;
     451           0 :             long nSumB = 0;
     452           0 :             long nTotalWeightY = 0;
     453             : 
     454           0 :             for(long i = 0; i<= nLineRange; i++)
     455             :             {
     456           0 :                 long nSumRowR = 0;
     457           0 :                 long nSumRowG = 0;
     458           0 :                 long nSumRowB = 0;
     459           0 :                 long nTotalWeightX = 0;
     460             : 
     461           0 :                 for(long j = 0; j <= nRowRange; j++)
     462             :                 {
     463           0 :                     BitmapColor aCol0 = rCtx.mpSrc->GetPaletteColor ( rCtx.mpSrc->GetPixelIndex( nLineStart + i, nRowStart + j ) );
     464             : 
     465           0 :                     if(nX == nEndX )
     466             :                     {
     467             : 
     468           0 :                         nSumRowB += aCol0.GetBlue() << 7L;
     469           0 :                         nSumRowG += aCol0.GetGreen() << 7L;
     470           0 :                         nSumRowR += aCol0.GetRed() << 7L;
     471           0 :                         nTotalWeightX += 1 << 7L;
     472             :                     }
     473           0 :                     else if( j == 0 )
     474             :                     {
     475             : 
     476           0 :                         long nWeightX = (nMax- rCtx.mpMapFX[ nLeft ]) ;
     477           0 :                         nSumRowB += ( nWeightX *aCol0.GetBlue()) ;
     478           0 :                         nSumRowG += ( nWeightX *aCol0.GetGreen()) ;
     479           0 :                         nSumRowR += ( nWeightX *aCol0.GetRed()) ;
     480           0 :                         nTotalWeightX += nWeightX;
     481             :                     }
     482           0 :                     else if ( nRowRange == j )
     483             :                     {
     484             : 
     485           0 :                         long nWeightX = rCtx.mpMapFX[ nRight ] ;
     486           0 :                         nSumRowB += ( nWeightX *aCol0.GetBlue() );
     487           0 :                         nSumRowG += ( nWeightX *aCol0.GetGreen() );
     488           0 :                         nSumRowR += ( nWeightX *aCol0.GetRed() );
     489           0 :                         nTotalWeightX += nWeightX;
     490             :                     }
     491             :                     else
     492             :                     {
     493             : 
     494           0 :                         nSumRowB += aCol0.GetBlue() << 7L;
     495           0 :                         nSumRowG += aCol0.GetGreen() << 7L;
     496           0 :                         nSumRowR += aCol0.GetRed() << 7L;
     497           0 :                         nTotalWeightX += 1 << 7L;
     498             :                     }
     499           0 :                 }
     500             : 
     501           0 :                 long nWeightY = nMax;
     502           0 :                 if( nY == nEndY )
     503           0 :                     nWeightY = nMax;
     504           0 :                 else if( i == 0 )
     505           0 :                     nWeightY = nMax - rCtx.mpMapFY[ nTop ];
     506           0 :                 else if( nLineRange == 1 )
     507           0 :                     nWeightY = rCtx.mpMapFY[ nTop ];
     508           0 :                 else if ( nLineRange == i )
     509           0 :                     nWeightY = rCtx.mpMapFY[ nBottom ];
     510             : 
     511           0 :                 if (nTotalWeightX)
     512             :                 {
     513           0 :                     nSumRowB /= nTotalWeightX;
     514           0 :                     nSumRowG /= nTotalWeightX;
     515           0 :                     nSumRowR /= nTotalWeightX;
     516             :                 }
     517             : 
     518           0 :                 nSumB += nWeightY * nSumRowB;
     519           0 :                 nSumG += nWeightY * nSumRowG;
     520           0 :                 nSumR += nWeightY * nSumRowR;
     521           0 :                 nTotalWeightY += nWeightY;
     522             :             }
     523             : 
     524           0 :             if (nTotalWeightY)
     525             :             {
     526           0 :                 nSumR /= nTotalWeightY;
     527           0 :                 nSumG /= nTotalWeightY;
     528           0 :                 nSumB /= nTotalWeightY;
     529             :             }
     530             : 
     531           0 :             BitmapColor aColRes((sal_uInt8)nSumR, (sal_uInt8)nSumG, (sal_uInt8)nSumB);
     532           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     533           0 :         }
     534             :     }
     535           0 : }
     536             : 
     537           0 : void scale24bitBGR2(ScaleContext &rCtx, long nStartY, long nEndY)
     538             : {
     539           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     540           0 :     const long nMax = 1 << 7L;
     541             : 
     542           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     543             :     {
     544           0 :         long nTop = rCtx.mbVMirr ? ( nY + 1 ) : nY;
     545           0 :         long nBottom = rCtx.mbVMirr ? nY : ( nY + 1 ) ;
     546             : 
     547             :         long nLineStart;
     548             :         long nLineRange;
     549           0 :         if( nY ==nEndY )
     550             :         {
     551           0 :             nLineStart = rCtx.mpMapIY[ nY ];
     552           0 :             nLineRange = 0;
     553             :         }
     554             :         else
     555             :         {
     556           0 :             nLineStart = rCtx.mpMapIY[ nTop ] ;
     557           0 :             nLineRange = ( rCtx.mpMapIY[ nBottom ] == rCtx.mpMapIY[ nTop ] ) ? 1 :( rCtx.mpMapIY[ nBottom ] - rCtx.mpMapIY[ nTop ] );
     558             :         }
     559             : 
     560           0 :         for( long nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
     561             :         {
     562           0 :             long nLeft = rCtx.mbHMirr ? ( nX + 1 ) : nX;
     563           0 :             long nRight = rCtx.mbHMirr ? nX : ( nX + 1 ) ;
     564             : 
     565             :             long nRowStart;
     566             :             long nRowRange;
     567           0 :             if( nX == nEndX )
     568             :             {
     569           0 :                 nRowStart = rCtx.mpMapIX[ nX ];
     570           0 :                 nRowRange = 0;
     571             :             }
     572             :             else
     573             :             {
     574           0 :                 nRowStart = rCtx.mpMapIX[ nLeft ];
     575           0 :                 nRowRange = ( rCtx.mpMapIX[ nRight ] == rCtx.mpMapIX[ nLeft ] )? 1 : ( rCtx.mpMapIX[ nRight ] - rCtx.mpMapIX[ nLeft ] );
     576             :             }
     577             : 
     578           0 :             long nSumR = 0;
     579           0 :             long nSumG = 0;
     580           0 :             long nSumB = 0;
     581           0 :             long nTotalWeightY = 0;
     582             : 
     583           0 :             for(long i = 0; i<= nLineRange; i++)
     584             :             {
     585           0 :                 Scanline pTmpY = rCtx.mpSrc->GetScanline( nLineStart + i );
     586           0 :                 Scanline pTmpX = pTmpY + 3L * nRowStart;
     587           0 :                 long nSumRowR = 0;
     588           0 :                 long nSumRowG = 0;
     589           0 :                 long nSumRowB = 0;
     590           0 :                 long nTotalWeightX = 0;
     591             : 
     592           0 :                 for(long j = 0; j <= nRowRange; j++)
     593             :                 {
     594           0 :                     if(nX == nEndX )
     595             :                     {
     596           0 :                         nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
     597           0 :                         nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
     598           0 :                         nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
     599           0 :                         nTotalWeightX += 1 << 7L;
     600             :                     }
     601           0 :                     else if( j == 0 )
     602             :                     {
     603           0 :                         long nWeightX = (nMax- rCtx.mpMapFX[ nLeft ]) ;
     604           0 :                         nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++;
     605           0 :                         nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++;
     606           0 :                         nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++;
     607           0 :                         nTotalWeightX += nWeightX;
     608             :                     }
     609           0 :                     else if ( nRowRange == j )
     610             :                     {
     611           0 :                         long nWeightX = rCtx.mpMapFX[ nRight ] ;
     612           0 :                         nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++;
     613           0 :                         nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++;
     614           0 :                         nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++;
     615           0 :                         nTotalWeightX += nWeightX;
     616             :                     }
     617             :                     else
     618             :                     {
     619           0 :                         nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
     620           0 :                         nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
     621           0 :                         nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
     622           0 :                         nTotalWeightX += 1 << 7L;
     623             :                     }
     624             :                 }
     625             : 
     626           0 :                 long nWeightY = nMax;
     627           0 :                 if( nY == nEndY )
     628           0 :                     nWeightY = nMax;
     629           0 :                 else if( i == 0 )
     630           0 :                     nWeightY = nMax - rCtx.mpMapFY[ nTop ];
     631           0 :                 else if( nLineRange == 1 )
     632           0 :                     nWeightY = rCtx.mpMapFY[ nTop ];
     633           0 :                 else if ( nLineRange == i )
     634           0 :                     nWeightY = rCtx.mpMapFY[ nBottom ];
     635             : 
     636           0 :                 if (nTotalWeightX)
     637             :                 {
     638           0 :                     nSumRowB /= nTotalWeightX;
     639           0 :                     nSumRowG /= nTotalWeightX;
     640           0 :                     nSumRowR /= nTotalWeightX;
     641             :                 }
     642           0 :                 nSumB += nWeightY * nSumRowB;
     643           0 :                 nSumG += nWeightY * nSumRowG;
     644           0 :                 nSumR += nWeightY * nSumRowR;
     645           0 :                 nTotalWeightY += nWeightY;
     646             :             }
     647             : 
     648           0 :             if (nTotalWeightY)
     649             :             {
     650           0 :                 nSumR /= nTotalWeightY;
     651           0 :                 nSumG /= nTotalWeightY;
     652           0 :                 nSumB /= nTotalWeightY;
     653             :             }
     654           0 :             BitmapColor aColRes((sal_uInt8)nSumR, (sal_uInt8)nSumG, (sal_uInt8)nSumB);
     655           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     656           0 :         }
     657             :     }
     658           0 : }
     659             : 
     660           0 : void scale24bitRGB2(ScaleContext &rCtx, long nStartY, long nEndY)
     661             : {
     662           0 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     663           0 :     const long nMax = 1 << 7L;
     664             : 
     665           0 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     666             :     {
     667           0 :         long nTop = rCtx.mbVMirr ? ( nY + 1 ) : nY;
     668           0 :         long nBottom = rCtx.mbVMirr ? nY : ( nY + 1 ) ;
     669             : 
     670             :         long nLineStart, nLineRange;
     671           0 :         if( nY ==nEndY )
     672             :         {
     673           0 :             nLineStart = rCtx.mpMapIY[ nY ];
     674           0 :             nLineRange = 0;
     675             :         }
     676             :         else
     677             :         {
     678           0 :             nLineStart = rCtx.mpMapIY[ nTop ] ;
     679           0 :             nLineRange = ( rCtx.mpMapIY[ nBottom ] == rCtx.mpMapIY[ nTop ] ) ? 1 :( rCtx.mpMapIY[ nBottom ] - rCtx.mpMapIY[ nTop ] );
     680             :         }
     681             : 
     682           0 :         for( long nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
     683             :         {
     684           0 :             long nLeft = rCtx.mbHMirr ? ( nX + 1 ) : nX;
     685           0 :             long nRight = rCtx.mbHMirr ? nX : ( nX + 1 ) ;
     686             : 
     687             :             long nRowStart, nRowRange;
     688           0 :             if( nX == nEndX )
     689             :             {
     690           0 :                 nRowStart = rCtx.mpMapIX[ nX ];
     691           0 :                 nRowRange = 0;
     692             :             }
     693             :             else
     694             :             {
     695           0 :                 nRowStart = rCtx.mpMapIX[ nLeft ];
     696           0 :                 nRowRange = ( rCtx.mpMapIX[ nRight ] == rCtx.mpMapIX[ nLeft ] )? 1 : ( rCtx.mpMapIX[ nRight ] - rCtx.mpMapIX[ nLeft ] );
     697             :             }
     698             : 
     699           0 :             long nSumR = 0;
     700           0 :             long nSumG = 0;
     701           0 :             long nSumB = 0;
     702           0 :             long nTotalWeightY = 0;
     703             : 
     704           0 :             for(long i = 0; i<= nLineRange; i++)
     705             :             {
     706           0 :                 Scanline pTmpY = rCtx.mpSrc->GetScanline( nLineStart + i );
     707           0 :                 Scanline pTmpX = pTmpY + 3L * nRowStart;
     708           0 :                 long nSumRowR = 0;
     709           0 :                 long nSumRowG = 0;
     710           0 :                 long nSumRowB = 0;
     711           0 :                 long nTotalWeightX = 0;
     712             : 
     713           0 :                 for(long j = 0; j <= nRowRange; j++)
     714             :                 {
     715           0 :                     if(nX == nEndX )
     716             :                     {
     717           0 :                         nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
     718           0 :                         nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
     719           0 :                         nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
     720           0 :                         nTotalWeightX += 1 << 7L;
     721             :                     }
     722           0 :                     else if( j == 0 )
     723             :                     {
     724           0 :                         long nWeightX = (nMax- rCtx.mpMapFX[ nLeft ]) ;
     725           0 :                         nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++;
     726           0 :                         nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++;
     727           0 :                         nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++;
     728           0 :                         nTotalWeightX += nWeightX;
     729             :                     }
     730           0 :                     else if ( nRowRange == j )
     731             :                     {
     732           0 :                         long nWeightX = rCtx.mpMapFX[ nRight ] ;
     733           0 :                         nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++;
     734           0 :                         nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++;
     735           0 :                         nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++;
     736           0 :                         nTotalWeightX += nWeightX;
     737             :                     }
     738             :                     else
     739             :                     {
     740           0 :                         nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
     741           0 :                         nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
     742           0 :                         nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
     743           0 :                         nTotalWeightX += 1 << 7L;
     744             :                     }
     745             :                 }
     746             : 
     747           0 :                 long nWeightY = nMax;
     748           0 :                 if( nY == nEndY )
     749           0 :                     nWeightY = nMax;
     750           0 :                 else if( i == 0 )
     751           0 :                     nWeightY = nMax - rCtx.mpMapFY[ nTop ];
     752           0 :                 else if( nLineRange == 1 )
     753           0 :                     nWeightY = rCtx.mpMapFY[ nTop ];
     754           0 :                 else if ( nLineRange == i )
     755           0 :                     nWeightY = rCtx.mpMapFY[ nBottom ];
     756             : 
     757           0 :                 if (nTotalWeightX)
     758             :                 {
     759           0 :                     nSumRowB /= nTotalWeightX;
     760           0 :                     nSumRowG /= nTotalWeightX;
     761           0 :                     nSumRowR /= nTotalWeightX;
     762             :                 }
     763           0 :                 nSumB += nWeightY * nSumRowB;
     764           0 :                 nSumG += nWeightY * nSumRowG;
     765           0 :                 nSumR += nWeightY * nSumRowR;
     766           0 :                 nTotalWeightY += nWeightY;
     767             :             }
     768             : 
     769           0 :             if (nTotalWeightY)
     770             :             {
     771           0 :                 nSumR /= nTotalWeightY;
     772           0 :                 nSumG /= nTotalWeightY;
     773           0 :                 nSumB /= nTotalWeightY;
     774             :             }
     775           0 :             BitmapColor aColRes((sal_uInt8)nSumR, (sal_uInt8)nSumG, (sal_uInt8)nSumB);
     776           0 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     777           0 :         }
     778             :     }
     779           0 : }
     780             : 
     781         112 : void scaleNonPalleteGeneral2(ScaleContext &rCtx, long nStartY, long nEndY)
     782             : {
     783         112 :     const long nStartX = 0, nEndX = rCtx.mnDestW - 1L;
     784         112 :     const long nMax = 1 << 7L;
     785             : 
     786       23330 :     for( long nY = nStartY; nY <= nEndY; nY++ )
     787             :     {
     788       23218 :         long nTop = rCtx.mbVMirr ? ( nY + 1 ) : nY;
     789       23218 :         long nBottom = rCtx.mbVMirr ? nY : ( nY + 1 ) ;
     790             : 
     791             :         long nLineStart, nLineRange;
     792       23218 :         if( nY ==nEndY )
     793             :         {
     794         112 :             nLineStart = rCtx.mpMapIY[ nY ];
     795         112 :             nLineRange = 0;
     796             :         }
     797             :         else
     798             :         {
     799       23106 :             nLineStart = rCtx.mpMapIY[ nTop ] ;
     800       23106 :             nLineRange = ( rCtx.mpMapIY[ nBottom ] == rCtx.mpMapIY[ nTop ] ) ? 1 :( rCtx.mpMapIY[ nBottom ] - rCtx.mpMapIY[ nTop ] );
     801             :         }
     802             : 
     803     4663999 :         for( long nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
     804             :         {
     805     4640781 :             long nLeft = rCtx.mbHMirr ? ( nX + 1 ) : nX;
     806     4640781 :             long nRight = rCtx.mbHMirr ? nX : ( nX + 1 ) ;
     807             : 
     808             :             long nRowStart, nRowRange;
     809     4640781 :             if( nX == nEndX )
     810             :             {
     811       23218 :                 nRowStart = rCtx.mpMapIX[ nX ];
     812       23218 :                 nRowRange = 0;
     813             :             }
     814             :             else
     815             :             {
     816     4617563 :                 nRowStart = rCtx.mpMapIX[ nLeft ];
     817     4617563 :                 nRowRange = ( rCtx.mpMapIX[ nRight ] == rCtx.mpMapIX[ nLeft ] )? 1 : ( rCtx.mpMapIX[ nRight ] - rCtx.mpMapIX[ nLeft ] );
     818             :             }
     819             : 
     820     4640781 :             long nSumR = 0;
     821     4640781 :             long nSumG = 0;
     822     4640781 :             long nSumB = 0;
     823     4640781 :             long nTotalWeightY = 0;
     824             : 
     825    26036392 :             for(long i = 0; i<= nLineRange; i++)
     826             :             {
     827    21395611 :                 long nSumRowR = 0;
     828    21395611 :                 long nSumRowG = 0;
     829    21395611 :                 long nSumRowB = 0;
     830    21395611 :                 long nTotalWeightX = 0;
     831             : 
     832   123532924 :                 for(long j = 0; j <= nRowRange; j++)
     833             :                 {
     834   102137313 :                     BitmapColor aCol0 = rCtx.mpSrc->GetPixel( nLineStart + i, nRowStart + j );
     835             : 
     836   102137313 :                     if(nX == nEndX )
     837             :                     {
     838             : 
     839      112100 :                         nSumRowB += aCol0.GetBlue() << 7L;
     840      112100 :                         nSumRowG += aCol0.GetGreen() << 7L;
     841      112100 :                         nSumRowR += aCol0.GetRed() << 7L;
     842      112100 :                         nTotalWeightX += 1 << 7L;
     843             :                     }
     844   102025213 :                     else if( j == 0 )
     845             :                     {
     846             : 
     847    21283511 :                         long nWeightX = (nMax- rCtx.mpMapFX[ nLeft ]) ;
     848    21283511 :                         nSumRowB += ( nWeightX *aCol0.GetBlue()) ;
     849    21283511 :                         nSumRowG += ( nWeightX *aCol0.GetGreen()) ;
     850    21283511 :                         nSumRowR += ( nWeightX *aCol0.GetRed()) ;
     851    21283511 :                         nTotalWeightX += nWeightX;
     852             :                     }
     853    80741702 :                     else if ( nRowRange == j )
     854             :                     {
     855             : 
     856    21283511 :                         long nWeightX = rCtx.mpMapFX[ nRight ] ;
     857    21283511 :                         nSumRowB += ( nWeightX *aCol0.GetBlue() );
     858    21283511 :                         nSumRowG += ( nWeightX *aCol0.GetGreen() );
     859    21283511 :                         nSumRowR += ( nWeightX *aCol0.GetRed() );
     860    21283511 :                         nTotalWeightX += nWeightX;
     861             :                     }
     862             :                     else
     863             :                     {
     864    59458191 :                         nSumRowB += aCol0.GetBlue() << 7L;
     865    59458191 :                         nSumRowG += aCol0.GetGreen() << 7L;
     866    59458191 :                         nSumRowR += aCol0.GetRed() << 7L;
     867    59458191 :                         nTotalWeightX += 1 << 7L;
     868             :                     }
     869   102137313 :                 }
     870             : 
     871    21395611 :                 long nWeightY = nMax;
     872    21395611 :                 if( nY == nEndY )
     873       20797 :                     nWeightY = nMax;
     874    21374814 :                 else if( i == 0 )
     875     4619984 :                     nWeightY = nMax - rCtx.mpMapFY[ nTop ];
     876    16754830 :                 else if( nLineRange == 1 )
     877           0 :                     nWeightY = rCtx.mpMapFY[ nTop ];
     878    16754830 :                 else if ( nLineRange == i )
     879     4619984 :                     nWeightY = rCtx.mpMapFY[ nBottom ];
     880             : 
     881    21395611 :                 if (nTotalWeightX)
     882             :                 {
     883    21395611 :                     nSumRowB /= nTotalWeightX;
     884    21395611 :                     nSumRowG /= nTotalWeightX;
     885    21395611 :                     nSumRowR /= nTotalWeightX;
     886             :                 }
     887             : 
     888    21395611 :                 nSumB += nWeightY * nSumRowB;
     889    21395611 :                 nSumG += nWeightY * nSumRowG;
     890    21395611 :                 nSumR += nWeightY * nSumRowR;
     891    21395611 :                 nTotalWeightY += nWeightY;
     892             :             }
     893             : 
     894     4640781 :             if (nTotalWeightY)
     895             :             {
     896     4640781 :                 nSumR /= nTotalWeightY;
     897     4640781 :                 nSumG /= nTotalWeightY;
     898     4640781 :                 nSumB /= nTotalWeightY;
     899             :             }
     900             : 
     901     4640781 :             BitmapColor aColRes((sal_uInt8)nSumR, (sal_uInt8)nSumG, (sal_uInt8)nSumB);
     902     4640781 :             rCtx.mpDest->SetPixel( nY, nXDst++, aColRes );
     903     4640781 :         }
     904             :     }
     905         112 : }
     906             : 
     907             : } // end anonymous namespace
     908             : 
     909         796 : BitmapScaleSuper::BitmapScaleSuper(const double& rScaleX, const double& rScaleY) :
     910             :     mrScaleX(rScaleX),
     911         796 :     mrScaleY(rScaleY)
     912         796 : {}
     913             : 
     914         796 : BitmapScaleSuper::~BitmapScaleSuper()
     915         796 : {}
     916             : 
     917         796 : bool BitmapScaleSuper::filter(Bitmap& rBitmap)
     918             : {
     919         796 :     bool bRet = false;
     920             : 
     921         796 :     const Size aSizePix(rBitmap.GetSizePixel());
     922             : 
     923         796 :     bool bHMirr = mrScaleX < 0;
     924         796 :     bool bVMirr = mrScaleY < 0;
     925             : 
     926         796 :     double fScaleX = std::fabs(mrScaleX);
     927         796 :     double fScaleY = std::fabs(mrScaleY);
     928             : 
     929         796 :     const long nDstW = FRound(aSizePix.Width()  * fScaleX);
     930         796 :     const long nDstH = FRound(aSizePix.Height() * fScaleY);
     931             : 
     932         796 :     const double fScaleThresh = 0.6;
     933             : 
     934         796 :     if (nDstW <= 1L || nDstH <= 1L)
     935           0 :         return false;
     936             : 
     937         796 :     Bitmap::ScopedReadAccess pReadAccess(rBitmap);
     938             : 
     939        1592 :     Bitmap aOutBmp(Size(nDstW, nDstH), 24);
     940        1592 :     Bitmap::ScopedWriteAccess pWriteAccess(aOutBmp);
     941             : 
     942         796 :     const long nStartY = 0;
     943         796 :     const long nEndY   = nDstH - 1L;
     944             : 
     945         796 :     if (pReadAccess && pWriteAccess)
     946             :     {
     947             :         ScaleRangeFn pScaleRangeFn;
     948             :         ScaleContext aContext( pReadAccess.get(),
     949             :                                pWriteAccess.get(),
     950         796 :                                pReadAccess->Width(),
     951         796 :                                pWriteAccess->Width(),
     952         796 :                                pReadAccess->Height(),
     953         796 :                                pWriteAccess->Height(),
     954        3980 :                                bVMirr, bHMirr );
     955             : 
     956         796 :         bool bScaleUp = fScaleX >= fScaleThresh && fScaleY >= fScaleThresh;
     957         796 :         if( pReadAccess->HasPalette() )
     958             :         {
     959         338 :             switch( pReadAccess->GetScanlineFormat() )
     960             :             {
     961             :             case BMP_FORMAT_8BIT_PAL:
     962         338 :                 pScaleRangeFn = bScaleUp ? scalePallete8bit : scalePallete8bit2;
     963         338 :                 break;
     964             :             default:
     965             :                 pScaleRangeFn = bScaleUp ? scalePalleteGeneral
     966           0 :                                         : scalePalleteGeneral2;
     967           0 :                 break;
     968             :             }
     969             :         }
     970             :         else
     971             :         {
     972         458 :             switch( pReadAccess->GetScanlineFormat() )
     973             :             {
     974             :             case BMP_FORMAT_24BIT_TC_BGR:
     975           0 :                 pScaleRangeFn = bScaleUp ? scale24bitBGR : scale24bitBGR2;
     976           0 :                 break;
     977             :             case BMP_FORMAT_24BIT_TC_RGB:
     978           0 :                 pScaleRangeFn = bScaleUp ? scale24bitRGB : scale24bitRGB2;
     979           0 :                 break;
     980             :             default:
     981             :                 pScaleRangeFn = bScaleUp ? scaleNonPalleteGeneral
     982         458 :                                         : scaleNonPalleteGeneral2;
     983         458 :                 break;
     984             :             }
     985             :         }
     986             : 
     987             :         // We want to thread - only if there is a lot of work to do:
     988             :         // We work hard when there is a large destination image, or
     989             :         // A large source image.
     990         796 :         bool bHorizontalWork = pReadAccess->Width() > 512 || pWriteAccess->Width() > 512;
     991             : 
     992         796 :         static bool bDisableThreadedScaling = getenv ("VCL_NO_THREAD_SCALE");
     993         796 :         if ( bDisableThreadedScaling || !bHorizontalWork ||
     994             :              nEndY - nStartY < SCALE_THREAD_STRIP )
     995             :         {
     996             :             SAL_INFO("vcl.gdi", "Scale in main thread");
     997         697 :             pScaleRangeFn( aContext, nStartY, nEndY );
     998             :         }
     999             :         else
    1000             :         {
    1001             :             // partition and queue work
    1002          99 :             comphelper::ThreadPool &rShared = comphelper::ThreadPool::getSharedOptimalPool();
    1003          99 :             sal_uInt32 nThreads = rShared.getWorkerCount();
    1004             :             assert( nThreads > 0 );
    1005          99 :             sal_uInt32 nStrips = ((nEndY - nStartY) + SCALE_THREAD_STRIP - 1) / SCALE_THREAD_STRIP;
    1006          99 :             sal_uInt32 nStripsPerThread = nStrips / nThreads;
    1007             :             SAL_INFO("vcl.gdi", "Scale in " << nStrips << " strips " << nStripsPerThread << " per thread we have " << nThreads << " CPU threads ");
    1008          99 :             long nStripY = nStartY;
    1009        3168 :             for ( sal_uInt32 t = 0; t < nThreads - 1; t++ )
    1010             :             {
    1011        3069 :                 ScaleTask *pTask = new ScaleTask( pScaleRangeFn );
    1012        3069 :                 for ( sal_uInt32 j = 0; j < nStripsPerThread; j++ )
    1013             :                 {
    1014           0 :                     ScaleRangeContext aRC( &aContext, nStripY );
    1015           0 :                     pTask->push( aRC );
    1016           0 :                     nStripY += SCALE_THREAD_STRIP;
    1017             :                 }
    1018        3069 :                 rShared.pushTask( pTask );
    1019             :             }
    1020             :             // finish any remaining bits here
    1021          99 :             pScaleRangeFn( aContext, nStripY, nEndY );
    1022             : 
    1023          99 :             rShared.waitUntilEmpty();
    1024             :             SAL_INFO("vcl.gdi", "All threaded scaling tasks complete");
    1025             :         }
    1026             : 
    1027         796 :         bRet = true;
    1028             :     }
    1029             : 
    1030         796 :     if( bRet )
    1031             :     {
    1032         796 :         rBitmap.AdaptBitCount(aOutBmp);
    1033         796 :         rBitmap = aOutBmp;
    1034             :     }
    1035             : 
    1036        1592 :     return bRet;
    1037             : }
    1038             : 
    1039             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11