LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - bitmap3.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 676 1720 39.3 %
Date: 2013-07-09 Functions: 19 35 54.3 %
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             : 
      21             : #include <stdlib.h>
      22             : 
      23             : #include <vcl/bmpacc.hxx>
      24             : #include <vcl/octree.hxx>
      25             : #include <vcl/bitmapex.hxx>
      26             : #include <vcl/bitmap.hxx>
      27             : 
      28             : #include <impoct.hxx>
      29             : #include <impvect.hxx>
      30             : #include <math.h>
      31             : 
      32             : #define RGB15( _def_cR, _def_cG, _def_cB )  (((sal_uLong)(_def_cR)<<10UL)|((sal_uLong)(_def_cG)<<5UL)|(sal_uLong)(_def_cB))
      33             : #define GAMMA( _def_cVal, _def_InvGamma )   ((sal_uInt8)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
      34             : #define MAP( cVal0, cVal1, nFrac )  ((sal_uInt8)((((long)(cVal0)<<7L)+nFrac*((long)(cVal1)-(cVal0)))>>7L))
      35             : 
      36             : #define CALC_ERRORS                                                             \
      37             :                         nTemp   = p1T[nX++] >> 12;                              \
      38             :                         nBErr = MinMax( nTemp, 0, 255 );                        \
      39             :                         nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \
      40             :                         nTemp   = p1T[nX++] >> 12;                              \
      41             :                         nGErr = MinMax( nTemp, 0, 255 );                        \
      42             :                         nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \
      43             :                         nTemp   = p1T[nX] >> 12;                                \
      44             :                         nRErr = MinMax( nTemp, 0, 255 );                        \
      45             :                         nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];
      46             : 
      47             : #define CALC_TABLES3                                        \
      48             :                         p2T[nX++] += FloydError3[nBErr];    \
      49             :                         p2T[nX++] += FloydError3[nGErr];    \
      50             :                         p2T[nX++] += FloydError3[nRErr];
      51             : 
      52             : #define CALC_TABLES5                                        \
      53             :                         p2T[nX++] += FloydError5[nBErr];    \
      54             :                         p2T[nX++] += FloydError5[nGErr];    \
      55             :                         p2T[nX++] += FloydError5[nRErr];
      56             : 
      57             : #define CALC_TABLES7                                        \
      58             :                         p1T[++nX] += FloydError7[nBErr];    \
      59             :                         p2T[nX++] += FloydError1[nBErr];    \
      60             :                         p1T[nX] += FloydError7[nGErr];      \
      61             :                         p2T[nX++] += FloydError1[nGErr];    \
      62             :                         p1T[nX] += FloydError7[nRErr];      \
      63             :                         p2T[nX] += FloydError1[nRErr];
      64             : 
      65             : const extern sal_uLong nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 };
      66             : const extern sal_uLong nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 };
      67             : const extern sal_uLong nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 };
      68             : 
      69             : const extern sal_uLong nVCLDitherLut[ 256 ] =
      70             : {
      71             :        0, 49152, 12288, 61440,  3072, 52224, 15360, 64512,   768, 49920, 13056,
      72             :    62208,  3840, 52992, 16128, 65280, 32768, 16384, 45056, 28672, 35840, 19456,
      73             :    48128, 31744, 33536, 17152, 45824, 29440, 36608, 20224, 48896, 32512, 8192,
      74             :    57344,  4096, 53248, 11264, 60416,  7168, 56320,  8960, 58112,  4864, 54016,
      75             :    12032, 61184,  7936, 57088, 40960, 24576, 36864, 20480, 44032, 27648, 39936,
      76             :    23552, 41728, 25344, 37632, 21248, 44800, 28416, 40704, 24320, 2048, 51200,
      77             :    14336, 63488,  1024, 50176, 13312, 62464,  2816, 51968, 15104, 64256,  1792,
      78             :    50944, 14080, 63232, 34816, 18432, 47104, 30720, 33792, 17408, 46080, 29696,
      79             :    35584, 19200, 47872, 31488, 34560, 18176, 46848, 30464, 10240, 59392,  6144,
      80             :    55296,  9216, 58368,  5120, 54272, 11008, 60160,  6912, 56064,  9984, 59136,
      81             :     5888, 55040, 43008, 26624, 38912, 22528, 41984, 25600, 37888, 21504, 43776,
      82             :    27392, 39680, 23296, 42752, 26368, 38656, 22272,   512, 49664, 12800, 61952,
      83             :     3584, 52736, 15872, 65024,   256, 49408, 12544, 61696,  3328, 52480, 15616,
      84             :    64768, 33280, 16896, 45568, 29184, 36352, 19968, 48640, 32256, 33024, 16640,
      85             :    45312, 28928, 36096, 19712, 48384, 32000,  8704, 57856,  4608, 53760, 11776,
      86             :    60928,  7680, 56832,  8448, 57600,  4352, 53504, 11520, 60672,  7424, 56576,
      87             :    41472, 25088, 37376, 20992, 44544, 28160, 40448, 24064, 41216, 24832, 37120,
      88             :    20736, 44288, 27904, 40192, 23808,  2560, 51712, 14848, 64000,  1536, 50688,
      89             :    13824, 62976,  2304, 51456, 14592, 63744,  1280, 50432, 13568, 62720, 35328,
      90             :    18944, 47616, 31232, 34304, 17920, 46592, 30208, 35072, 18688, 47360, 30976,
      91             :    34048, 17664, 46336, 29952, 10752, 59904,  6656, 55808,  9728, 58880,  5632,
      92             :    54784, 10496, 59648,  6400, 55552,  9472, 58624,  5376, 54528, 43520, 27136,
      93             :    39424, 23040, 42496, 26112, 38400, 22016, 43264, 26880, 39168, 22784, 42240,
      94             :    25856, 38144, 21760
      95             : };
      96             : 
      97             : const extern sal_uLong nVCLLut[ 256 ] =
      98             : {
      99             :          0,  1286,  2572,  3858,  5144,  6430,  7716,  9002,
     100             :      10288, 11574, 12860, 14146, 15432, 16718, 18004, 19290,
     101             :      20576, 21862, 23148, 24434, 25720, 27006, 28292, 29578,
     102             :      30864, 32150, 33436, 34722, 36008, 37294, 38580, 39866,
     103             :      41152, 42438, 43724, 45010, 46296, 47582, 48868, 50154,
     104             :      51440, 52726, 54012, 55298, 56584, 57870, 59156, 60442,
     105             :      61728, 63014, 64300, 65586, 66872, 68158, 69444, 70730,
     106             :      72016, 73302, 74588, 75874, 77160, 78446, 79732, 81018,
     107             :      82304, 83590, 84876, 86162, 87448, 88734, 90020, 91306,
     108             :      92592, 93878, 95164, 96450, 97736, 99022,100308,101594,
     109             :     102880,104166,105452,106738,108024,109310,110596,111882,
     110             :     113168,114454,115740,117026,118312,119598,120884,122170,
     111             :     123456,124742,126028,127314,128600,129886,131172,132458,
     112             :     133744,135030,136316,137602,138888,140174,141460,142746,
     113             :     144032,145318,146604,147890,149176,150462,151748,153034,
     114             :     154320,155606,156892,158178,159464,160750,162036,163322,
     115             :     164608,165894,167180,168466,169752,171038,172324,173610,
     116             :     174896,176182,177468,178754,180040,181326,182612,183898,
     117             :     185184,186470,187756,189042,190328,191614,192900,194186,
     118             :     195472,196758,198044,199330,200616,201902,203188,204474,
     119             :     205760,207046,208332,209618,210904,212190,213476,214762,
     120             :     216048,217334,218620,219906,221192,222478,223764,225050,
     121             :     226336,227622,228908,230194,231480,232766,234052,235338,
     122             :     236624,237910,239196,240482,241768,243054,244340,245626,
     123             :     246912,248198,249484,250770,252056,253342,254628,255914,
     124             :     257200,258486,259772,261058,262344,263630,264916,266202,
     125             :     267488,268774,270060,271346,272632,273918,275204,276490,
     126             :     277776,279062,280348,281634,282920,284206,285492,286778,
     127             :     288064,289350,290636,291922,293208,294494,295780,297066,
     128             :     298352,299638,300924,302210,303496,304782,306068,307354,
     129             :     308640,309926,311212,312498,313784,315070,316356,317642,
     130             :     318928,320214,321500,322786,324072,325358,326644,327930
     131             : };
     132             : 
     133             : const long FloydMap[256] =
     134             : {
     135             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     136             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
     137             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     138             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     139             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
     140             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     141             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     142             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     143             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     144             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     145             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     146             :     3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     147             :     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     148             :     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     149             :     4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
     150             :     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
     151             : };
     152             : 
     153             : const long FloydError1[61] =
     154             : {
     155             :     -7680, -7424, -7168, -6912, -6656, -6400, -6144,
     156             :     -5888, -5632, -5376, -5120, -4864, -4608, -4352,
     157             :     -4096, -3840, -3584, -3328, -3072, -2816, -2560,
     158             :     -2304, -2048, -1792, -1536, -1280, -1024, -768,
     159             :     -512, -256, 0, 256, 512, 768, 1024, 1280, 1536,
     160             :     1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584,
     161             :     3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632,
     162             :     5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680
     163             : };
     164             : 
     165             : const long FloydError3[61] =
     166             : {
     167             :     -23040, -22272, -21504, -20736, -19968, -19200,
     168             :     -18432, -17664, -16896, -16128, -15360, -14592,
     169             :     -13824, -13056, -12288, -11520, -10752, -9984,
     170             :     -9216, -8448, -7680, -6912, -6144, -5376, -4608,
     171             :     -3840, -3072, -2304, -1536, -768, 0, 768, 1536,
     172             :     2304, 3072, 3840, 4608, 5376, 6144, 6912, 7680,
     173             :     8448, 9216, 9984, 10752, 11520, 12288, 13056,
     174             :     13824, 14592, 15360, 16128, 16896, 17664, 18432,
     175             :     19200, 19968, 20736, 21504, 22272, 23040
     176             : };
     177             : 
     178             : const long FloydError5[61] =
     179             : {
     180             :     -38400, -37120, -35840, -34560, -33280, -32000,
     181             :     -30720, -29440, -28160, -26880, -25600, -24320,
     182             :     -23040, -21760, -20480, -19200, -17920, -16640,
     183             :     -15360, -14080, -12800, -11520, -10240, -8960,
     184             :     -7680, -6400, -5120, -3840, -2560, -1280,   0,
     185             :     1280, 2560, 3840, 5120, 6400, 7680, 8960, 10240,
     186             :     11520, 12800, 14080, 15360, 16640, 17920, 19200,
     187             :     20480, 21760, 23040, 24320, 25600, 26880, 28160,
     188             :     29440, 30720, 32000, 33280, 34560, 35840, 37120,
     189             :     38400
     190             : };
     191             : 
     192             : const long FloydError7[61] =
     193             : {
     194             :     -53760, -51968, -50176, -48384, -46592, -44800,
     195             :     -43008, -41216, -39424, -37632, -35840, -34048,
     196             :     -32256, -30464, -28672, -26880, -25088, -23296,
     197             :     -21504, -19712, -17920, -16128, -14336, -12544,
     198             :     -10752, -8960, -7168, -5376, -3584, -1792,  0,
     199             :     1792, 3584, 5376, 7168, 8960, 10752, 12544, 14336,
     200             :     16128, 17920, 19712, 21504, 23296, 25088, 26880,
     201             :     28672, 30464, 32256, 34048, 35840, 37632, 39424,
     202             :     41216, 43008, 44800, 46592, 48384, 50176, 51968,
     203             :     53760
     204             : };
     205             : 
     206             : const long FloydIndexMap[6] =
     207             : {
     208             :     -30,  21, 72, 123, 174, 225
     209             : };
     210             : 
     211           0 : void ImplCreateDitherMatrix( sal_uInt8 (*pDitherMatrix)[16][16] )
     212             : {
     213           0 :     double          fVal = 3.125;
     214           0 :     const double    fVal16 = fVal / 16.;
     215             :     long            i, j, k, l;
     216             :     sal_uInt16          pMtx[ 16 ][ 16 ];
     217           0 :     sal_uInt16          nMax = 0;
     218             :     static const sal_uInt8 pMagic[4][4] = { { 0, 14,  3, 13, },
     219             :                                      {11,  5,  8,  6, },
     220             :                                      {12,  2, 15,  1, },
     221             :                                      {7,   9,  4, 10 } };
     222             : 
     223             :     // Build MagicSquare
     224           0 :     for ( i = 0; i < 4; i++ )
     225           0 :        for ( j = 0; j < 4; j++ )
     226           0 :            for ( k = 0; k < 4; k++ )
     227           0 :                 for ( l = 0; l < 4; l++ )
     228           0 :                     nMax = std::max ( pMtx[ (k<<2) + i][(l<<2 ) + j] =
     229           0 :                     (sal_uInt16) ( 0.5 + pMagic[i][j]*fVal + pMagic[k][l]*fVal16 ), nMax );
     230             : 
     231             :     // Scale to interval [0;254]
     232           0 :     for ( i = 0, fVal = 254. / nMax; i < 16; i++ )
     233           0 :         for( j = 0; j < 16; j++ )
     234           0 :             (*pDitherMatrix)[i][j] = (sal_uInt8) ( fVal * pMtx[i][j] );
     235           0 : }
     236             : 
     237      124017 : sal_Bool Bitmap::Convert( BmpConversion eConversion )
     238             : {
     239      124017 :     const sal_uInt16    nBitCount = GetBitCount();
     240      124017 :     sal_Bool            bRet = sal_False;
     241             : 
     242      124017 :     switch( eConversion )
     243             :     {
     244             :         case( BMP_CONVERSION_1BIT_THRESHOLD ):
     245           0 :             bRet = ImplMakeMono( 128 );
     246           0 :         break;
     247             : 
     248             :         case( BMP_CONVERSION_1BIT_MATRIX ):
     249           0 :             bRet = ImplMakeMonoDither();
     250           0 :         break;
     251             : 
     252             :         case( BMP_CONVERSION_4BIT_GREYS ):
     253           0 :             bRet = ImplMakeGreyscales( 16 );
     254           0 :         break;
     255             : 
     256             :         case( BMP_CONVERSION_4BIT_COLORS ):
     257             :         {
     258           0 :             if( nBitCount < 4 )
     259           0 :                 bRet = ImplConvertUp( 4, NULL );
     260           0 :             else if( nBitCount > 4 )
     261           0 :                 bRet = ImplConvertDown( 4, NULL );
     262             :             else
     263           0 :                 bRet = sal_True;
     264             :         }
     265           0 :         break;
     266             : 
     267             :         case( BMP_CONVERSION_4BIT_TRANS ):
     268             :         {
     269           0 :             Color aTrans( BMP_COL_TRANS );
     270             : 
     271           0 :             if( nBitCount < 4 )
     272           0 :                 bRet = ImplConvertUp( 4, &aTrans );
     273             :             else
     274           0 :                 bRet = ImplConvertDown( 4, &aTrans );
     275             :         }
     276           0 :         break;
     277             : 
     278             :         case( BMP_CONVERSION_8BIT_GREYS ):
     279      123516 :             bRet = ImplMakeGreyscales( 256 );
     280      123516 :         break;
     281             : 
     282             :         case( BMP_CONVERSION_8BIT_COLORS ):
     283             :         {
     284         469 :             if( nBitCount < 8 )
     285           0 :                 bRet = ImplConvertUp( 8 );
     286         469 :             else if( nBitCount > 8 )
     287         469 :                 bRet = ImplConvertDown( 8 );
     288             :             else
     289           0 :                 bRet = sal_True;
     290             :         }
     291         469 :         break;
     292             : 
     293             :         case( BMP_CONVERSION_8BIT_TRANS ):
     294             :         {
     295           0 :             Color aTrans( BMP_COL_TRANS );
     296             : 
     297           0 :             if( nBitCount < 8 )
     298           0 :                 bRet = ImplConvertUp( 8, &aTrans );
     299             :             else
     300           0 :                 bRet = ImplConvertDown( 8, &aTrans );
     301             :         }
     302           0 :         break;
     303             : 
     304             :         case( BMP_CONVERSION_24BIT ):
     305             :         {
     306          32 :             if( nBitCount < 24 )
     307          32 :                 bRet = ImplConvertUp( 24, NULL );
     308             :             else
     309           0 :                 bRet = sal_True;
     310             :         }
     311          32 :         break;
     312             : 
     313             :         case( BMP_CONVERSION_GHOSTED ):
     314           0 :             bRet = ImplConvertGhosted();
     315           0 :         break;
     316             : 
     317             :         default:
     318             :             OSL_FAIL( "Bitmap::Convert(): Unsupported conversion" );
     319           0 :         break;
     320             :     }
     321             : 
     322      124017 :     return bRet;
     323             : }
     324             : 
     325           9 : sal_Bool Bitmap::ImplMakeMono( sal_uInt8 cThreshold )
     326             : {
     327           9 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     328           9 :     sal_Bool                bRet = sal_False;
     329             : 
     330           9 :     if( pReadAcc )
     331             :     {
     332           9 :         Bitmap              aNewBmp( GetSizePixel(), 1 );
     333           9 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     334             : 
     335           9 :         if( pWriteAcc )
     336             :         {
     337           9 :             const BitmapColor   aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
     338          18 :             const BitmapColor   aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
     339           9 :             const long          nWidth = pWriteAcc->Width();
     340           9 :             const long          nHeight = pWriteAcc->Height();
     341             : 
     342           9 :             if( pReadAcc->HasPalette() )
     343             :             {
     344          58 :                 for( long nY = 0L; nY < nHeight; nY++ )
     345             :                 {
     346       12496 :                     for( long nX = 0L; nX < nWidth; nX++ )
     347             :                     {
     348       12440 :                         const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX );
     349       12440 :                         if( pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >=
     350             :                             cThreshold )
     351             :                         {
     352        6218 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     353             :                         }
     354             :                         else
     355        6222 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     356             :                     }
     357             :                 }
     358             :             }
     359             :             else
     360             :             {
     361         102 :                 for( long nY = 0L; nY < nHeight; nY++ )
     362             :                 {
     363        4133 :                     for( long nX = 0L; nX < nWidth; nX++ )
     364             :                     {
     365        4038 :                         if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >=
     366             :                             cThreshold )
     367             :                         {
     368         524 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     369             :                         }
     370             :                         else
     371        3514 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     372             :                     }
     373             :                 }
     374             :             }
     375             : 
     376           9 :             aNewBmp.ReleaseAccess( pWriteAcc );
     377          18 :             bRet = sal_True;
     378             :         }
     379             : 
     380           9 :         ReleaseAccess( pReadAcc );
     381             : 
     382           9 :         if( bRet )
     383             :         {
     384           9 :             const MapMode   aMap( maPrefMapMode );
     385           9 :             const Size      aSize( maPrefSize );
     386             : 
     387           9 :             *this = aNewBmp;
     388             : 
     389           9 :             maPrefMapMode = aMap;
     390           9 :             maPrefSize = aSize;
     391           9 :         }
     392             :     }
     393             : 
     394           9 :     return bRet;
     395             : }
     396             : 
     397           0 : sal_Bool Bitmap::ImplMakeMonoDither()
     398             : {
     399           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     400           0 :     sal_Bool                bRet = sal_False;
     401             : 
     402           0 :     if( pReadAcc )
     403             :     {
     404           0 :         Bitmap              aNewBmp( GetSizePixel(), 1 );
     405           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     406             : 
     407           0 :         if( pWriteAcc )
     408             :         {
     409           0 :             const BitmapColor   aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
     410           0 :             const BitmapColor   aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
     411           0 :             const long          nWidth = pWriteAcc->Width();
     412           0 :             const long          nHeight = pWriteAcc->Height();
     413             :             sal_uInt8               pDitherMatrix[ 16 ][ 16 ];
     414             : 
     415           0 :             ImplCreateDitherMatrix( &pDitherMatrix );
     416             : 
     417           0 :             if( pReadAcc->HasPalette() )
     418             :             {
     419           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     420             :                 {
     421           0 :                     for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
     422             :                     {
     423           0 :                         const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX );
     424           0 :                         if( pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >
     425           0 :                             pDitherMatrix[ nModY ][ nX % 16 ] )
     426             :                         {
     427           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     428             :                         }
     429             :                         else
     430           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     431             :                     }
     432             :                 }
     433             :             }
     434             :             else
     435             :             {
     436           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     437             :                 {
     438           0 :                     for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
     439             :                     {
     440           0 :                         if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >
     441           0 :                             pDitherMatrix[ nModY ][ nX % 16 ]  )
     442             :                         {
     443           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     444             :                         }
     445             :                         else
     446           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     447             :                     }
     448             :                 }
     449             :             }
     450             : 
     451           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
     452           0 :             bRet = sal_True;
     453             :         }
     454             : 
     455           0 :         ReleaseAccess( pReadAcc );
     456             : 
     457           0 :         if( bRet )
     458             :         {
     459           0 :             const MapMode   aMap( maPrefMapMode );
     460           0 :             const Size      aSize( maPrefSize );
     461             : 
     462           0 :             *this = aNewBmp;
     463             : 
     464           0 :             maPrefMapMode = aMap;
     465           0 :             maPrefSize = aSize;
     466           0 :         }
     467             :     }
     468             : 
     469           0 :     return bRet;
     470             : }
     471             : 
     472      123516 : sal_Bool Bitmap::ImplMakeGreyscales( sal_uInt16 nGreys )
     473             : {
     474             :     DBG_ASSERT( nGreys == 16 || nGreys == 256, "Only 16 or 256 greyscales are supported!" );
     475             : 
     476      123516 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     477      123516 :     sal_Bool                bRet = sal_False;
     478             : 
     479      123516 :     if( pReadAcc )
     480             :     {
     481      123516 :         const BitmapPalette&    rPal = GetGreyPalette( nGreys );
     482      123516 :         sal_uLong                   nShift = ( ( nGreys == 16 ) ? 4UL : 0UL );
     483      123516 :         bool                    bPalDiffers = !pReadAcc->HasPalette() || ( rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount() );
     484             : 
     485      123516 :         if( !bPalDiffers )
     486      116483 :             bPalDiffers = ( (BitmapPalette&) rPal != pReadAcc->GetPalette() );
     487             : 
     488      123516 :         if( bPalDiffers )
     489             :         {
     490        7033 :             Bitmap              aNewBmp( GetSizePixel(), ( nGreys == 16 ) ? 4 : 8, &rPal );
     491        7033 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     492             : 
     493        7033 :             if( pWriteAcc )
     494             :             {
     495        7033 :                 const long  nWidth = pWriteAcc->Width();
     496        7033 :                 const long  nHeight = pWriteAcc->Height();
     497             : 
     498        7033 :                 if( pReadAcc->HasPalette() )
     499             :                 {
     500           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     501             :                     {
     502           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     503             :                         {
     504           0 :                             const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX );
     505             :                             pWriteAcc->SetPixelIndex( nY, nX,
     506           0 :                                 (pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >> nShift) );
     507             :                         }
     508             :                     }
     509             :                 }
     510       14066 :                 else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR &&
     511        7033 :                          pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     512             :                 {
     513        7033 :                     nShift += 8;
     514             : 
     515      733102 :                     for( long nY = 0L; nY < nHeight; nY++ )
     516             :                     {
     517      726069 :                         Scanline pReadScan = pReadAcc->GetScanline( nY );
     518      726069 :                         Scanline pWriteScan = pWriteAcc->GetScanline( nY );
     519             : 
     520   109801854 :                         for( long nX = 0L; nX < nWidth; nX++ )
     521             :                         {
     522   109075785 :                             const sal_uLong nB = *pReadScan++;
     523   109075785 :                             const sal_uLong nG = *pReadScan++;
     524   109075785 :                             const sal_uLong nR = *pReadScan++;
     525             : 
     526   109075785 :                             *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
     527             :                         }
     528             :                     }
     529             :                 }
     530           0 :                 else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB &&
     531           0 :                          pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     532             :                 {
     533           0 :                     nShift += 8;
     534             : 
     535           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     536             :                     {
     537           0 :                         Scanline pReadScan = pReadAcc->GetScanline( nY );
     538           0 :                         Scanline pWriteScan = pWriteAcc->GetScanline( nY );
     539             : 
     540           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     541             :                         {
     542           0 :                             const sal_uLong nR = *pReadScan++;
     543           0 :                             const sal_uLong nG = *pReadScan++;
     544           0 :                             const sal_uLong nB = *pReadScan++;
     545             : 
     546           0 :                             *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
     547             :                         }
     548             :                     }
     549             :                 }
     550             :                 else
     551             :                 {
     552           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     553           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     554           0 :                             pWriteAcc->SetPixelIndex( nY, nX, (pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift );
     555             :                 }
     556             : 
     557        7033 :                 aNewBmp.ReleaseAccess( pWriteAcc );
     558        7033 :                 bRet = sal_True;
     559             :             }
     560             : 
     561        7033 :             ReleaseAccess( pReadAcc );
     562             : 
     563        7033 :             if( bRet )
     564             :             {
     565        7033 :                 const MapMode   aMap( maPrefMapMode );
     566        7033 :                 const Size      aSize( maPrefSize );
     567             : 
     568        7033 :                 *this = aNewBmp;
     569             : 
     570        7033 :                 maPrefMapMode = aMap;
     571        7033 :                 maPrefSize = aSize;
     572        7033 :             }
     573             :         }
     574             :         else
     575             :         {
     576      116483 :             ReleaseAccess( pReadAcc );
     577      116483 :             bRet = sal_True;
     578             :         }
     579             :     }
     580             : 
     581      123516 :     return bRet;
     582             : }
     583             : 
     584          32 : sal_Bool Bitmap::ImplConvertUp( sal_uInt16 nBitCount, Color* pExtColor )
     585             : {
     586             :     DBG_ASSERT( nBitCount > GetBitCount(), "New BitCount must be greater!" );
     587             : 
     588          32 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     589          32 :     sal_Bool                bRet = sal_False;
     590             : 
     591          32 :     if( pReadAcc )
     592             :     {
     593          32 :         BitmapPalette       aPal;
     594          64 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, pReadAcc->HasPalette() ? &pReadAcc->GetPalette() : &aPal );
     595          32 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     596             : 
     597          32 :         if( pWriteAcc )
     598             :         {
     599          32 :             const long  nWidth = pWriteAcc->Width();
     600          32 :             const long  nHeight = pWriteAcc->Height();
     601             : 
     602          32 :             if( pWriteAcc->HasPalette() )
     603             :             {
     604           0 :                 const sal_uInt16            nOldCount = 1 << GetBitCount();
     605           0 :                 const BitmapPalette&    rOldPal = pReadAcc->GetPalette();
     606             : 
     607           0 :                 aPal.SetEntryCount( 1 << nBitCount );
     608             : 
     609           0 :                 for( sal_uInt16 i = 0; i < nOldCount; i++ )
     610           0 :                     aPal[ i ] = rOldPal[ i ];
     611             : 
     612           0 :                 if( pExtColor )
     613           0 :                     aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
     614             : 
     615           0 :                 pWriteAcc->SetPalette( aPal );
     616             : 
     617           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     618           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
     619           0 :                         pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) );
     620             :             }
     621             :             else
     622             :             {
     623          32 :                 if( pReadAcc->HasPalette() )
     624             :                 {
     625         373 :                     for( long nY = 0L; nY < nHeight; nY++ )
     626        5046 :                         for( long nX = 0L; nX < nWidth; nX++ )
     627        4705 :                             pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) ) );
     628             :                 }
     629             :                 else
     630             :                 {
     631           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     632           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     633           0 :                             pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) );
     634             :                 }
     635             :             }
     636             : 
     637          32 :             aNewBmp.ReleaseAccess( pWriteAcc );
     638          32 :             bRet = sal_True;
     639             :         }
     640             : 
     641          32 :         ReleaseAccess( pReadAcc );
     642             : 
     643          32 :         if( bRet )
     644             :         {
     645          32 :             const MapMode   aMap( maPrefMapMode );
     646          32 :             const Size      aSize( maPrefSize );
     647             : 
     648          32 :             *this = aNewBmp;
     649             : 
     650          32 :             maPrefMapMode = aMap;
     651          32 :             maPrefSize = aSize;
     652          32 :         }
     653             :     }
     654             : 
     655          32 :     return bRet;
     656             : }
     657             : 
     658         469 : sal_Bool Bitmap::ImplConvertDown( sal_uInt16 nBitCount, Color* pExtColor )
     659             : {
     660             :     DBG_ASSERT( nBitCount <= GetBitCount(), "New BitCount must be lower ( or equal when pExtColor is set )!" );
     661             : 
     662         469 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     663         469 :     sal_Bool                bRet = sal_False;
     664             : 
     665         469 :     if( pReadAcc )
     666             :     {
     667         469 :         BitmapPalette       aPal;
     668         938 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, &aPal );
     669         469 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     670             : 
     671         469 :         if( pWriteAcc )
     672             :         {
     673         469 :             const sal_uInt16    nCount = 1 << nBitCount;
     674         469 :             const long      nWidth = pWriteAcc->Width();
     675         469 :             const long      nWidth1 = nWidth - 1L;
     676         469 :             const long      nHeight = pWriteAcc->Height();
     677         469 :             Octree          aOctree( *pReadAcc, pExtColor ? ( nCount - 1 ) : nCount );
     678         938 :             InverseColorMap aColorMap( aPal = aOctree.GetPalette() );
     679         938 :             BitmapColor     aColor;
     680         469 :             ImpErrorQuad    aErrQuad;
     681         469 :             ImpErrorQuad*   pErrQuad1 = new ImpErrorQuad[ nWidth ];
     682         469 :             ImpErrorQuad*   pErrQuad2 = new ImpErrorQuad[ nWidth ];
     683         469 :             ImpErrorQuad*   pQLine1 = pErrQuad1;
     684         469 :             ImpErrorQuad*   pQLine2 = 0;
     685             :             long            nX, nY;
     686         469 :             long            nYTmp = 0L;
     687             :             sal_uInt8           cIndex;
     688         469 :             bool            bQ1 = true;
     689             : 
     690         469 :             if( pExtColor )
     691             :             {
     692           0 :                 aPal.SetEntryCount( aPal.GetEntryCount() + 1 );
     693           0 :                 aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
     694             :             }
     695             : 
     696             :             // set Black/White always, if we have enough space
     697         469 :             if( aPal.GetEntryCount() < ( nCount - 1 ) )
     698             :             {
     699         334 :                 aPal.SetEntryCount( aPal.GetEntryCount() + 2 );
     700         334 :                 aPal[ aPal.GetEntryCount() - 2 ] = Color( COL_BLACK );
     701         334 :                 aPal[ aPal.GetEntryCount() - 1 ] = Color( COL_WHITE );
     702             :             }
     703             : 
     704         469 :             pWriteAcc->SetPalette( aPal );
     705             : 
     706        1407 :             for( nY = 0L; nY < std::min( nHeight, 2L ); nY++, nYTmp++ )
     707             :             {
     708       71734 :                 for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
     709             :                 {
     710       70796 :                     if( pReadAcc->HasPalette() )
     711           0 :                         pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nYTmp, nX ) );
     712             :                     else
     713       70796 :                         pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
     714             :                 }
     715             :             }
     716             : 
     717       32879 :             for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
     718             :             {
     719             :                 // first pixel in the line
     720       32410 :                 cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ 0 ].ImplGetColor() );
     721       32410 :                 pWriteAcc->SetPixelIndex( nY, 0, cIndex );
     722             : 
     723     2497179 :                 for( nX = 1L; nX < nWidth1; nX++ )
     724             :                 {
     725     2464769 :                     cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( aColor = pQLine1[ nX ].ImplGetColor() );
     726     2464769 :                     aErrQuad = ( ImpErrorQuad( aColor ) -= pWriteAcc->GetPaletteColor( cIndex ) );
     727     2464769 :                     pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
     728     2464769 :                     pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
     729     2464769 :                     pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
     730     2464769 :                     pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
     731     2464769 :                     pWriteAcc->SetPixelIndex( nY, nX, cIndex );
     732             :                 }
     733             : 
     734             :                 // Last RowPixel
     735       32410 :                 if( nX < nWidth )
     736             :                 {
     737       32410 :                     cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ nWidth1 ].ImplGetColor() );
     738       32410 :                     pWriteAcc->SetPixelIndex( nY, nX, cIndex );
     739             :                 }
     740             : 
     741             :                 // Refill/copy row buffer
     742       32410 :                 pQLine1 = pQLine2;
     743       32410 :                 pQLine2 = ( bQ1 = !bQ1 ) ? pErrQuad2 : pErrQuad1;
     744             : 
     745       32410 :                 if( nYTmp < nHeight )
     746             :                 {
     747     2490265 :                     for( nX = 0L; nX < nWidth; nX++ )
     748             :                     {
     749     2458793 :                         if( pReadAcc->HasPalette() )
     750           0 :                             pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nYTmp, nX ) );
     751             :                         else
     752     2458793 :                             pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
     753             :                     }
     754             :                 }
     755             :             }
     756             : 
     757             :             // Delete row buffer
     758         469 :             delete[] pErrQuad1;
     759         469 :             delete[] pErrQuad2;
     760             : 
     761         469 :             aNewBmp.ReleaseAccess( pWriteAcc );
     762         938 :             bRet = sal_True;
     763             :         }
     764             : 
     765         469 :         ReleaseAccess( pReadAcc );
     766             : 
     767         469 :         if( bRet )
     768             :         {
     769         469 :             const MapMode   aMap( maPrefMapMode );
     770         469 :             const Size      aSize( maPrefSize );
     771             : 
     772         469 :             *this = aNewBmp;
     773             : 
     774         469 :             maPrefMapMode = aMap;
     775         469 :             maPrefSize = aSize;
     776         469 :         }
     777             :     }
     778             : 
     779         469 :     return bRet;
     780             : }
     781             : 
     782           0 : sal_Bool Bitmap::ImplConvertGhosted()
     783             : {
     784           0 :     Bitmap              aNewBmp;
     785           0 :     BitmapReadAccess*   pR = AcquireReadAccess();
     786           0 :     sal_Bool                bRet = sal_False;
     787             : 
     788           0 :     if( pR )
     789             :     {
     790           0 :         if( pR->HasPalette() )
     791             :         {
     792           0 :             BitmapPalette aNewPal( pR->GetPaletteEntryCount() );
     793             : 
     794           0 :             for( long i = 0, nCount = aNewPal.GetEntryCount(); i < nCount; i++ )
     795             :             {
     796           0 :                 const BitmapColor& rOld = pR->GetPaletteColor( (sal_uInt16) i );
     797           0 :                 aNewPal[ (sal_uInt16) i ] = BitmapColor( ( rOld.GetRed() >> 1 ) | 0x80,
     798           0 :                                                      ( rOld.GetGreen() >> 1 ) | 0x80,
     799           0 :                                                      ( rOld.GetBlue() >> 1 ) | 0x80 );
     800             :             }
     801             : 
     802           0 :             aNewBmp = Bitmap( GetSizePixel(), GetBitCount(), &aNewPal );
     803           0 :             BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
     804             : 
     805           0 :             if( pW )
     806             :             {
     807           0 :                 pW->CopyBuffer( *pR );
     808           0 :                 aNewBmp.ReleaseAccess( pW );
     809           0 :                 bRet = sal_True;
     810           0 :             }
     811             :         }
     812             :         else
     813             :         {
     814           0 :             aNewBmp = Bitmap( GetSizePixel(), 24 );
     815             : 
     816           0 :             BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
     817             : 
     818           0 :             if( pW )
     819             :             {
     820           0 :                 const long nWidth = pR->Width(), nHeight = pR->Height();
     821             : 
     822           0 :                 for( long nY = 0; nY < nHeight; nY++ )
     823             :                 {
     824           0 :                     for( long nX = 0; nX < nWidth; nX++ )
     825             :                     {
     826           0 :                         const BitmapColor aOld( pR->GetPixel( nY, nX ) );
     827           0 :                         pW->SetPixel( nY, nX, BitmapColor( ( aOld.GetRed() >> 1 ) | 0x80,
     828           0 :                                                            ( aOld.GetGreen() >> 1 ) | 0x80,
     829           0 :                                                            ( aOld.GetBlue() >> 1 ) | 0x80 ) );
     830             : 
     831           0 :                     }
     832             :                 }
     833             : 
     834           0 :                 aNewBmp.ReleaseAccess( pW );
     835           0 :                 bRet = sal_True;
     836             :             }
     837             :         }
     838             : 
     839           0 :         ReleaseAccess( pR );
     840             :     }
     841             : 
     842           0 :     if( bRet )
     843             :     {
     844           0 :         const MapMode   aMap( maPrefMapMode );
     845           0 :         const Size      aSize( maPrefSize );
     846             : 
     847           0 :         *this = aNewBmp;
     848             : 
     849           0 :         maPrefMapMode = aMap;
     850           0 :         maPrefSize = aSize;
     851             :     }
     852             : 
     853           0 :     return bRet;
     854             : }
     855             : 
     856       49393 : sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
     857             : {
     858       49393 :     bool bRetval(false);
     859             : 
     860             : #ifdef DBG_UTIL
     861             :     const sal_uInt16 nStartCount(GetBitCount());
     862             : #endif
     863             : 
     864       49393 :     if(basegfx::fTools::equalZero(rScaleX) || basegfx::fTools::equalZero(rScaleY))
     865             :     {
     866             :         // no scale
     867           0 :         bRetval = true;
     868             :     }
     869             : 
     870       49393 :     if(basegfx::fTools::equal(rScaleX, 1.0) && basegfx::fTools::equal(rScaleY, 1.0))
     871             :     {
     872             :         // no scale
     873           0 :         bRetval = true;
     874             :     }
     875             : 
     876       49393 :     switch(nScaleFlag)
     877             :     {
     878             :         case BMP_SCALE_NONE :
     879             :         {
     880           0 :             bRetval = false;
     881           0 :             break;
     882             :         }
     883             :         case BMP_SCALE_FAST :
     884             :         {
     885           1 :             bRetval = ImplScaleFast( rScaleX, rScaleY );
     886           1 :             break;
     887             :         }
     888             :         case BMP_SCALE_INTERPOLATE :
     889             :         {
     890         124 :             bRetval = ImplScaleInterpolate( rScaleX, rScaleY );
     891         124 :             break;
     892             :         }
     893             :         case BMP_SCALE_SUPER :
     894             :         {
     895       48113 :             if(GetSizePixel().Width() < 2 || GetSizePixel().Height() < 2)
     896             :             {
     897             :                 // fallback to ImplScaleFast
     898       47374 :                 bRetval = ImplScaleFast( rScaleX, rScaleY );
     899             :             }
     900             :             else
     901             :             {
     902             :                 // #i121233# use method from symphony
     903         739 :                 bRetval = ImplScaleSuper( rScaleX, rScaleY );
     904             :             }
     905       48113 :             break;
     906             :         }
     907             :         case BMP_SCALE_LANCZOS :
     908             :         {
     909        1152 :             const Lanczos3Kernel kernel;
     910             : 
     911        1152 :             bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     912        1152 :             break;
     913             :         }
     914             :         case BMP_SCALE_BICUBIC :
     915             :         {
     916           1 :             const BicubicKernel kernel;
     917             : 
     918           1 :             bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     919           1 :             break;
     920             :         }
     921             :         case BMP_SCALE_BILINEAR :
     922             :         {
     923           1 :             const BilinearKernel kernel;
     924             : 
     925           1 :             bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     926           1 :             break;
     927             :         }
     928             :         case BMP_SCALE_BOX :
     929             :         {
     930           1 :             const BoxKernel kernel;
     931             : 
     932           1 :             bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     933           1 :             break;
     934             :         }
     935             :     }
     936             : 
     937             : #ifdef DBG_UTIL
     938             :     if(bRetval && nStartCount != GetBitCount())
     939             :     {
     940             :         OSL_ENSURE(false, "Bitmap::Scale has changed the ColorDepth, this should *not* happen (!)");
     941             :     }
     942             : #endif
     943             : 
     944       49393 :     return bRetval;
     945             : }
     946             : 
     947             : // ------------------------------------------------------------------------
     948             : 
     949         869 : sal_Bool Bitmap::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
     950             : {
     951         869 :     const Size  aSize( GetSizePixel() );
     952             :     bool        bRet;
     953             : 
     954         869 :     if( aSize.Width() && aSize.Height() )
     955             :     {
     956         869 :         bRet = Scale( (double) rNewSize.Width() / aSize.Width(),
     957         869 :                       (double) rNewSize.Height() / aSize.Height(),
     958        1738 :                       nScaleFlag );
     959             :     }
     960             :     else
     961           0 :         bRet = sal_True;
     962             : 
     963         869 :     return bRet;
     964             : }
     965             : 
     966             : // ------------------------------------------------------------------------
     967             : 
     968          68 : void Bitmap::AdaptBitCount(Bitmap& rNew) const
     969             : {
     970          68 :     ImplAdaptBitCount(rNew);
     971          68 : }
     972             : 
     973             : // ------------------------------------------------------------------------
     974             : 
     975        2086 : void Bitmap::ImplAdaptBitCount(Bitmap& rNew) const
     976             : {
     977             :     // aNew is the result of some operation; adapt it's BitCount to the original (this)
     978        2086 :     if(GetBitCount() != rNew.GetBitCount())
     979             :     {
     980         543 :         switch(GetBitCount())
     981             :         {
     982             :             case 1:
     983             :             {
     984           0 :                 rNew.Convert(BMP_CONVERSION_1BIT_THRESHOLD);
     985           0 :                 break;
     986             :             }
     987             :             case 4:
     988             :             {
     989           0 :                 if(HasGreyPalette())
     990             :                 {
     991           0 :                     rNew.Convert(BMP_CONVERSION_4BIT_GREYS);
     992             :                 }
     993             :                 else
     994             :                 {
     995           0 :                     rNew.Convert(BMP_CONVERSION_4BIT_COLORS);
     996             :                 }
     997           0 :                 break;
     998             :             }
     999             :             case 8:
    1000             :             {
    1001         543 :                 if(HasGreyPalette())
    1002             :                 {
    1003         542 :                     rNew.Convert(BMP_CONVERSION_8BIT_GREYS);
    1004             :                 }
    1005             :                 else
    1006             :                 {
    1007           1 :                     rNew.Convert(BMP_CONVERSION_8BIT_COLORS);
    1008             :                 }
    1009         543 :                 break;
    1010             :             }
    1011             :             case 24:
    1012             :             {
    1013           0 :                 rNew.Convert(BMP_CONVERSION_24BIT);
    1014           0 :                 break;
    1015             :             }
    1016             :             default:
    1017             :             {
    1018             :                 OSL_ENSURE(false, "BitDepth adaption failed (!)");
    1019           0 :                 break;
    1020             :             }
    1021             :         }
    1022             :     }
    1023        2086 : }
    1024             : 
    1025       47375 : sal_Bool Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY )
    1026             : {
    1027       47375 :     const Size  aSizePix( GetSizePixel() );
    1028       47375 :     const long  nNewWidth = FRound( aSizePix.Width() * rScaleX );
    1029       47375 :     const long  nNewHeight = FRound( aSizePix.Height() * rScaleY );
    1030       47375 :     sal_Bool    bRet = sal_False;
    1031             : 
    1032       47375 :     if( nNewWidth && nNewHeight )
    1033             :     {
    1034       47375 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1035             : 
    1036       47375 :         if(pReadAcc)
    1037             :         {
    1038       47375 :             Bitmap              aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() );
    1039       47375 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1040             : 
    1041       47375 :             if( pWriteAcc )
    1042             :             {
    1043       47375 :                 const long  nScanlineSize = pWriteAcc->GetScanlineSize();
    1044       47375 :                 const long  nNewWidth1 = nNewWidth - 1L;
    1045       47375 :                 const long  nNewHeight1 = nNewHeight - 1L;
    1046       47375 :                 const long  nWidth = pReadAcc->Width();
    1047       47375 :                 const long  nHeight = pReadAcc->Height();
    1048       47375 :                 long*       pLutX = new long[ nNewWidth ];
    1049       47375 :                 long*       pLutY = new long[ nNewHeight ];
    1050             : 
    1051       47375 :                 if( nNewWidth1 && nNewHeight1 )
    1052             :                 {
    1053       47375 :                     long        nX, nY, nMapY, nActY = 0L;
    1054             : 
    1055    17948499 :                     for( nX = 0L; nX < nNewWidth; nX++ )
    1056    17901124 :                         pLutX[ nX ] = nX * nWidth / nNewWidth;
    1057             : 
    1058    25307162 :                     for( nY = 0L; nY < nNewHeight; nY++ )
    1059    25259787 :                         pLutY[ nY ] = nY * nHeight / nNewHeight;
    1060             : 
    1061      306387 :                     while( nActY < nNewHeight )
    1062             :                     {
    1063      211637 :                         nMapY = pLutY[ nActY ];
    1064             : 
    1065   141921217 :                         for( nX = 0L; nX < nNewWidth; nX++ )
    1066   141709580 :                             pWriteAcc->SetPixel( nActY, nX, pReadAcc->GetPixel( nMapY , pLutX[ nX ] ) );
    1067             : 
    1068    25471424 :                         while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) )
    1069             :                         {
    1070    25048150 :                             memcpy( pWriteAcc->GetScanline( nActY + 1L ),
    1071    50096300 :                                     pWriteAcc->GetScanline( nActY ), nScanlineSize );
    1072    25048150 :                             nActY++;
    1073             :                         }
    1074      211637 :                         nActY++;
    1075             :                     }
    1076             : 
    1077       47375 :                     bRet = sal_True;
    1078       47375 :                     aNewBmp.ReleaseAccess( pWriteAcc );
    1079             :                 }
    1080             : 
    1081       47375 :                 delete[] pLutX;
    1082       47375 :                 delete[] pLutY;
    1083             :             }
    1084       47375 :             ReleaseAccess( pReadAcc );
    1085             : 
    1086       47375 :             if( bRet )
    1087       47375 :                 ImplAssignWithSize( aNewBmp );
    1088             :         }
    1089             :     }
    1090             : 
    1091       47375 :     return bRet;
    1092             : }
    1093             : 
    1094         124 : sal_Bool Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY )
    1095             : {
    1096         124 :     const Size  aSizePix( GetSizePixel() );
    1097         124 :     const long  nNewWidth = FRound( aSizePix.Width() * rScaleX );
    1098         124 :     const long  nNewHeight = FRound( aSizePix.Height() * rScaleY );
    1099         124 :     sal_Bool        bRet = sal_False;
    1100             : 
    1101         124 :     if( ( nNewWidth > 1L ) && ( nNewHeight > 1L ) )
    1102             :     {
    1103         124 :         BitmapColor         aCol0;
    1104         248 :         BitmapColor         aCol1;
    1105         124 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1106         124 :         long                nWidth = pReadAcc->Width();
    1107         124 :         long                nHeight = pReadAcc->Height();
    1108         248 :         Bitmap              aNewBmp( Size( nNewWidth, nHeight ), 24 );
    1109         124 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1110             :         long*               pLutInt;
    1111             :         long*               pLutFrac;
    1112             :         long                nX, nY;
    1113             :         long                lXB0, lXB1, lXG0, lXG1, lXR0, lXR1;
    1114             :         double              fTemp;
    1115             :         long                nTemp;
    1116             : 
    1117         124 :         if( pReadAcc && pWriteAcc )
    1118             :         {
    1119         124 :             const long      nNewWidth1 = nNewWidth - 1L;
    1120         124 :             const long      nWidth1 = pReadAcc->Width() - 1L;
    1121         124 :             const double    fRevScaleX = (double) nWidth1 / nNewWidth1;
    1122             : 
    1123         124 :             pLutInt = new long[ nNewWidth ];
    1124         124 :             pLutFrac = new long[ nNewWidth ];
    1125             : 
    1126        1557 :             for( nX = 0L, nTemp = nWidth - 2L; nX < nNewWidth; nX++ )
    1127             :             {
    1128        1433 :                 fTemp = nX * fRevScaleX;
    1129        1433 :                 pLutInt[ nX ] = MinMax( (long) fTemp, 0, nTemp );
    1130        1433 :                 fTemp -= pLutInt[ nX ];
    1131        1433 :                 pLutFrac[ nX ] = (long) ( fTemp * 1024. );
    1132             :             }
    1133             : 
    1134        1517 :             for( nY = 0L; nY < nHeight; nY++ )
    1135             :             {
    1136        1393 :                 if( 1 == nWidth )
    1137             :                 {
    1138           0 :                     if( pReadAcc->HasPalette() )
    1139             :                     {
    1140           0 :                         aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, 0 ) );
    1141             :                     }
    1142             :                     else
    1143             :                     {
    1144           0 :                         aCol0 = pReadAcc->GetPixel( nY, 0 );
    1145             :                     }
    1146             : 
    1147           0 :                     for( nX = 0L; nX < nNewWidth; nX++ )
    1148             :                     {
    1149           0 :                         pWriteAcc->SetPixel( nY, nX, aCol0 );
    1150             :                     }
    1151             :                 }
    1152             :                 else
    1153             :                 {
    1154       44937 :                     for( nX = 0L; nX < nNewWidth; nX++ )
    1155             :                     {
    1156       43544 :                         nTemp = pLutInt[ nX ];
    1157             : 
    1158       43544 :                         if( pReadAcc->HasPalette() )
    1159             :                         {
    1160           0 :                             aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp++ ) );
    1161           0 :                             aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp ) );
    1162             :                         }
    1163             :                         else
    1164             :                         {
    1165       43544 :                             aCol0 = pReadAcc->GetPixel( nY, nTemp++ );
    1166       43544 :                             aCol1 = pReadAcc->GetPixel( nY, nTemp );
    1167             :                         }
    1168             : 
    1169       43544 :                         nTemp = pLutFrac[ nX ];
    1170             : 
    1171       43544 :                         lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1172       43544 :                         lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1173       43544 :                         lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1174             : 
    1175       43544 :                         aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1176       43544 :                         aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1177       43544 :                         aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1178             : 
    1179       43544 :                         pWriteAcc->SetPixel( nY, nX, aCol0 );
    1180             :                     }
    1181             :                 }
    1182             :             }
    1183             : 
    1184         124 :             delete[] pLutInt;
    1185         124 :             delete[] pLutFrac;
    1186         124 :             bRet = sal_True;
    1187             :         }
    1188             : 
    1189         124 :         ReleaseAccess( pReadAcc );
    1190         124 :         aNewBmp.ReleaseAccess( pWriteAcc );
    1191             : 
    1192         124 :         if( bRet )
    1193             :         {
    1194         124 :             bRet = sal_False;
    1195         124 :             const Bitmap aOriginal(*this);
    1196         124 :             *this = aNewBmp;
    1197         124 :             aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 );
    1198         124 :             pReadAcc = AcquireReadAccess();
    1199         124 :             pWriteAcc = aNewBmp.AcquireWriteAccess();
    1200             : 
    1201         124 :             if( pReadAcc && pWriteAcc )
    1202             :             {
    1203         124 :                 const long      nNewHeight1 = nNewHeight - 1L;
    1204         124 :                 const long      nHeight1 = pReadAcc->Height() - 1L;
    1205         124 :                 const double    fRevScaleY = (double) nHeight1 / nNewHeight1;
    1206             : 
    1207         124 :                 pLutInt = new long[ nNewHeight ];
    1208         124 :                 pLutFrac = new long[ nNewHeight ];
    1209             : 
    1210        1679 :                 for( nY = 0L, nTemp = nHeight - 2L; nY < nNewHeight; nY++ )
    1211             :                 {
    1212        1555 :                     fTemp = nY * fRevScaleY;
    1213        1555 :                     pLutInt[ nY ] = MinMax( (long) fTemp, 0, nTemp );
    1214        1555 :                     fTemp -= pLutInt[ nY ];
    1215        1555 :                     pLutFrac[ nY ] = (long) ( fTemp * 1024. );
    1216             :                 }
    1217             : 
    1218             :                 // after 1st step, bitmap *is* 24bit format (see above)
    1219             :                 OSL_ENSURE(!pReadAcc->HasPalette(), "OOps, somehow ImplScaleInterpolate in-between format has palette, should not happen (!)");
    1220             : 
    1221        1557 :                 for( nX = 0L; nX < nNewWidth; nX++ )
    1222             :                 {
    1223        1433 :                     if( 1 == nHeight )
    1224             :                     {
    1225           0 :                         aCol0 = pReadAcc->GetPixel( 0, nX );
    1226             : 
    1227           0 :                         for( nY = 0L; nY < nNewHeight; nY++ )
    1228             :                         {
    1229           0 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1230             :                         }
    1231             :                     }
    1232             :                     else
    1233             :                     {
    1234       23989 :                         for( nY = 0L; nY < nNewHeight; nY++ )
    1235             :                         {
    1236       22556 :                             nTemp = pLutInt[ nY ];
    1237             : 
    1238       22556 :                             aCol0 = pReadAcc->GetPixel( nTemp++, nX );
    1239       22556 :                             aCol1 = pReadAcc->GetPixel( nTemp, nX );
    1240             : 
    1241       22556 :                             nTemp = pLutFrac[ nY ];
    1242             : 
    1243       22556 :                             lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1244       22556 :                             lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1245       22556 :                             lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1246             : 
    1247       22556 :                             aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1248       22556 :                             aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1249       22556 :                             aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1250             : 
    1251       22556 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1252             :                         }
    1253             :                     }
    1254             :                 }
    1255             : 
    1256         124 :                 delete[] pLutInt;
    1257         124 :                 delete[] pLutFrac;
    1258         124 :                 bRet = sal_True;
    1259             :             }
    1260             : 
    1261         124 :             ReleaseAccess( pReadAcc );
    1262         124 :             aNewBmp.ReleaseAccess( pWriteAcc );
    1263             : 
    1264         124 :             if( bRet )
    1265             :             {
    1266         124 :                 aOriginal.ImplAdaptBitCount(aNewBmp);
    1267         124 :                 *this = aNewBmp;
    1268         124 :             }
    1269         124 :         }
    1270             :     }
    1271             : 
    1272         124 :     if( !bRet )
    1273             :     {
    1274           0 :         bRet = ImplScaleFast( rScaleX, rScaleY );
    1275             :     }
    1276             : 
    1277         124 :     return bRet;
    1278             : }
    1279             : 
    1280             : // #i121233# Added BMP_SCALE_SUPER from symphony code
    1281             : 
    1282         739 : sal_Bool Bitmap::ImplScaleSuper(
    1283             :     const double& rScaleX,
    1284             :     const double& rScaleY )
    1285             : {
    1286         739 :     const Size  aSizePix( GetSizePixel() );
    1287         739 :     bool   bHMirr = ( rScaleX < 0 );
    1288         739 :     bool   bVMirr = ( rScaleY < 0 );
    1289         739 :     double scaleX = bHMirr ? -rScaleX : rScaleX;
    1290         739 :     double scaleY = bVMirr ? -rScaleY : rScaleY;
    1291         739 :     const long  nDstW = FRound( aSizePix.Width() * scaleX );
    1292         739 :     const long  nDstH = FRound( aSizePix.Height() * scaleY );
    1293         739 :     const double fScaleThresh = 0.6;
    1294         739 :     bool bRet = false;
    1295             : 
    1296         739 :     if( ( nDstW > 1L ) && ( nDstH > 1L ) )
    1297             :     {
    1298        1478 :         BitmapColor         aCol0, aCol1, aColRes;
    1299         739 :         BitmapReadAccess*   pAcc = AcquireReadAccess();
    1300        1478 :         Bitmap              aOutBmp( Size( nDstW, nDstH ), 24 );
    1301         739 :         BitmapWriteAccess*  pWAcc = aOutBmp.AcquireWriteAccess();
    1302         739 :         long*               pMapIX = new long[ nDstW ];
    1303         739 :         long*               pMapIY = new long[ nDstH ];
    1304         739 :         long*               pMapFX = new long[ nDstW ];
    1305         739 :         long*               pMapFY = new long[ nDstH ];
    1306             :         long                nX, nY, nXDst, nYDst;;
    1307             :         double              fTemp;
    1308             :         long                nTemp , nTempX, nTempY, nTempFX, nTempFY;
    1309             :         sal_uInt8           cR0, cG0, cB0, cR1, cG1, cB1;
    1310         739 :         long                nStartX = 0 , nStartY = 0;
    1311         739 :         long                nEndX = nDstW - 1L;
    1312         739 :         long                nEndY = nDstH - 1L;
    1313         739 :         long                nMax = 1 << 7L;
    1314             : 
    1315         739 :         if( pAcc && pWAcc )
    1316             :         {
    1317         739 :             long                nW = pAcc->Width() ;
    1318         739 :             long                nH = pAcc->Height() ;
    1319         739 :             const double    fRevScaleX = ( nDstW > 1L ) ? ( (double) ( nW - 1 ) / ( nDstW - 1 ) ) : 0.0;
    1320         739 :             const double    fRevScaleY = ( nDstH > 1L ) ? ( (double) ( nH - 1 ) / ( nDstH - 1 ) ) : 0.0;
    1321             : 
    1322             :             // create horizontal mapping table
    1323       58313 :             for( nX = 0L, nTempX = nW - 1L, nTemp = nW - 2L; nX < nDstW; nX++ )
    1324             :             {
    1325       57574 :                 fTemp = nX * fRevScaleX;
    1326             : 
    1327       57574 :                 if( bHMirr )
    1328           0 :                     fTemp = nTempX - fTemp;
    1329             : 
    1330       57574 :                 pMapFX[ nX ] = (long) ( ( fTemp - ( pMapIX[ nX ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. );
    1331             :             }
    1332             : 
    1333             :             // create vertical mapping table
    1334       10796 :             for( nY = 0L, nTempY = nH - 1L, nTemp = nH - 2L; nY < nDstH; nY++ )
    1335             :             {
    1336       10057 :                 fTemp = nY * fRevScaleY;
    1337             : 
    1338       10057 :                 if( bVMirr )
    1339           0 :                     fTemp = nTempY - fTemp;
    1340             : 
    1341       10057 :                 pMapFY[ nY ] = (long) ( ( fTemp - ( pMapIY[ nY ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. );
    1342             :             }
    1343             : 
    1344         739 :             if( pAcc->HasPalette() )
    1345             :             {
    1346           2 :                 if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
    1347             :                 {
    1348           2 :                     if( scaleX >= fScaleThresh && scaleY >= fScaleThresh )
    1349             :                     {
    1350             :                         Scanline pLine0, pLine1;
    1351             : 
    1352        1144 :                         for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1353             :                         {
    1354        1142 :                             nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ];
    1355        1142 :                             pLine0 = pAcc->GetScanline( nTempY );
    1356        1142 :                             pLine1 = pAcc->GetScanline( ++nTempY );
    1357             : 
    1358      328896 :                             for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
    1359             :                             {
    1360      327754 :                                 nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ];
    1361             : 
    1362      327754 :                                 const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTempX ] );
    1363      327754 :                                 const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTempX ] );
    1364      327754 :                                 const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTempX ] );
    1365      327754 :                                 const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTempX ] );
    1366             : 
    1367      327754 :                                 cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTempFX );
    1368      327754 :                                 cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTempFX );
    1369      327754 :                                 cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTempFX );
    1370             : 
    1371      327754 :                                 cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTempFX );
    1372      327754 :                                 cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTempFX );
    1373      327754 :                                 cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTempFX );
    1374             : 
    1375      327754 :                                 aColRes.SetRed( MAP( cR0, cR1, nTempFY ) );
    1376      327754 :                                 aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) );
    1377      327754 :                                 aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) );
    1378      327754 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1379             :                             }
    1380           2 :                         }
    1381             :                     }
    1382             :                     else
    1383             :                     {
    1384             :                         Scanline    pTmpY;
    1385             :                         long        nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ;
    1386             :                         long        nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ;
    1387             :                         long        nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY;
    1388             : 
    1389           0 :                         for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1390             :                         {
    1391           0 :                             nTop = bVMirr ? ( nY + 1 ) : nY;
    1392           0 :                             nBottom = bVMirr ? nY : ( nY + 1 ) ;
    1393             : 
    1394           0 :                             if( nY ==nEndY )
    1395             :                             {
    1396           0 :                                 nLineStart = pMapIY[ nY ];
    1397           0 :                                 nLineRange = 0;
    1398             :                             }
    1399             :                             else
    1400             :                             {
    1401           0 :                                 nLineStart = pMapIY[ nTop ] ;
    1402           0 :                                 nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] );
    1403             :                             }
    1404             : 
    1405           0 :                             for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
    1406             :                             {
    1407           0 :                                 nLeft = bHMirr ? ( nX + 1 ) : nX;
    1408           0 :                                 nRight = bHMirr ? nX : ( nX + 1 ) ;
    1409             : 
    1410           0 :                                 if( nX == nEndX )
    1411             :                                 {
    1412           0 :                                     nRowStart = pMapIX[ nX ];
    1413           0 :                                     nRowRange = 0;
    1414             :                                 }
    1415             :                                 else
    1416             :                                 {
    1417           0 :                                     nRowStart = pMapIX[ nLeft ];
    1418           0 :                                     nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] );
    1419             :                                 }
    1420             : 
    1421           0 :                                 nSumR = nSumG = nSumB = 0;
    1422           0 :                                 nTotalWeightY = 0;
    1423             : 
    1424           0 :                                 for(int i = 0; i<= nLineRange; i++)
    1425             :                                 {
    1426           0 :                                     pTmpY = pAcc->GetScanline( nLineStart + i );
    1427           0 :                                     nSumRowR = nSumRowG = nSumRowB = 0;
    1428           0 :                                     nTotalWeightX = 0;
    1429             : 
    1430           0 :                                     for(int j = 0; j <= nRowRange; j++)
    1431             :                                     {
    1432           0 :                                         const BitmapColor& rCol = pAcc->GetPaletteColor( pTmpY[ nRowStart + j ] );
    1433             : 
    1434           0 :                                         if(nX == nEndX )
    1435             :                                         {
    1436           0 :                                             nSumRowB += rCol.GetBlue() << 7L;
    1437           0 :                                             nSumRowG += rCol.GetGreen() << 7L;
    1438           0 :                                             nSumRowR += rCol.GetRed() << 7L;
    1439           0 :                                             nTotalWeightX += 1 << 7L;
    1440             :                                         }
    1441           0 :                                         else if( j == 0 )
    1442             :                                         {
    1443           0 :                                             nWeightX = (nMax- pMapFX[ nLeft ]) ;
    1444           0 :                                             nSumRowB += ( nWeightX *rCol.GetBlue()) ;
    1445           0 :                                             nSumRowG += ( nWeightX *rCol.GetGreen()) ;
    1446           0 :                                             nSumRowR += ( nWeightX *rCol.GetRed()) ;
    1447           0 :                                             nTotalWeightX += nWeightX;
    1448             :                                         }
    1449           0 :                                         else if ( nRowRange == j )
    1450             :                                         {
    1451           0 :                                             nWeightX = pMapFX[ nRight ] ;
    1452           0 :                                             nSumRowB += ( nWeightX *rCol.GetBlue() );
    1453           0 :                                             nSumRowG += ( nWeightX *rCol.GetGreen() );
    1454           0 :                                             nSumRowR += ( nWeightX *rCol.GetRed() );
    1455           0 :                                             nTotalWeightX += nWeightX;
    1456             :                                         }
    1457             :                                         else
    1458             :                                         {
    1459           0 :                                             nSumRowB += rCol.GetBlue() << 7L;
    1460           0 :                                             nSumRowG += rCol.GetGreen() << 7L;
    1461           0 :                                             nSumRowR += rCol.GetRed() << 7L;
    1462           0 :                                             nTotalWeightX += 1 << 7L;
    1463             :                                         }
    1464             :                                     }
    1465             : 
    1466           0 :                                     if( nY == nEndY )
    1467           0 :                                         nWeightY = nMax;
    1468           0 :                                     else if( i == 0 )
    1469           0 :                                         nWeightY = nMax - pMapFY[ nTop ];
    1470           0 :                                     else if( nLineRange == 1 )
    1471           0 :                                         nWeightY = pMapFY[ nTop ];
    1472           0 :                                     else if ( nLineRange == i )
    1473           0 :                                         nWeightY = pMapFY[ nBottom ];
    1474             :                                     else
    1475           0 :                                         nWeightY = nMax;
    1476             : 
    1477           0 :                                     nSumB += nWeightY * ( nSumRowB / nTotalWeightX );
    1478           0 :                                     nSumG += nWeightY * ( nSumRowG / nTotalWeightX );
    1479           0 :                                     nSumR += nWeightY * ( nSumRowR / nTotalWeightX );
    1480           0 :                                     nTotalWeightY += nWeightY;
    1481             :                                 }
    1482             : 
    1483           0 :                                 aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) ));
    1484           0 :                                 aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) ));
    1485           0 :                                 aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) ));
    1486           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1487             : 
    1488             :                             }
    1489             :                         }
    1490             :                     }
    1491             :                 }
    1492             :                 else
    1493             :                 {
    1494           0 :                     if( scaleX >= fScaleThresh && scaleY >= fScaleThresh )
    1495             :                     {
    1496           0 :                         for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1497             :                         {
    1498           0 :                             nTempY = pMapIY[ nY ], nTempFY = pMapFY[ nY ];
    1499             : 
    1500           0 :                             for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
    1501             :                             {
    1502           0 :                                 nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ];
    1503             : 
    1504           0 :                                 aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, nTempX ) );
    1505           0 :                                 aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, ++nTempX ) );
    1506           0 :                                 cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
    1507           0 :                                 cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
    1508           0 :                                 cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
    1509             : 
    1510           0 :                                 aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( ++nTempY, nTempX ) );
    1511           0 :                                 aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY--, --nTempX ) );
    1512           0 :                                 cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
    1513           0 :                                 cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
    1514           0 :                                 cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
    1515             : 
    1516           0 :                                 aColRes.SetRed( MAP( cR0, cR1, nTempFY ) );
    1517           0 :                                 aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) );
    1518           0 :                                 aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) );
    1519           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1520             :                             }
    1521             :                         }
    1522             : 
    1523             :                     }
    1524             :                     else
    1525             :                     {
    1526             :                         long        nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ;
    1527             :                         long        nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ;
    1528             :                         long        nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY;
    1529             : 
    1530           0 :                         for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1531             :                         {
    1532           0 :                             nTop = bVMirr ? ( nY + 1 ) : nY;
    1533           0 :                             nBottom = bVMirr ? nY : ( nY + 1 ) ;
    1534             : 
    1535           0 :                             if( nY ==nEndY )
    1536             :                             {
    1537           0 :                                 nLineStart = pMapIY[ nY ];
    1538           0 :                                 nLineRange = 0;
    1539             :                             }
    1540             :                             else
    1541             :                             {
    1542           0 :                                 nLineStart = pMapIY[ nTop ] ;
    1543           0 :                                 nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] );
    1544             :                             }
    1545             : 
    1546           0 :                             for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
    1547             :                             {
    1548           0 :                                 nLeft = bHMirr ? ( nX + 1 ) : nX;
    1549           0 :                                 nRight = bHMirr ? nX : ( nX + 1 ) ;
    1550             : 
    1551           0 :                                 if( nX == nEndX )
    1552             :                                 {
    1553           0 :                                     nRowStart = pMapIX[ nX ];
    1554           0 :                                     nRowRange = 0;
    1555             :                                 }
    1556             :                                 else
    1557             :                                 {
    1558           0 :                                     nRowStart = pMapIX[ nLeft ];
    1559           0 :                                     nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] );
    1560             :                                 }
    1561             : 
    1562           0 :                                 nSumR = nSumG = nSumB = 0;
    1563           0 :                                 nTotalWeightY = 0;
    1564             : 
    1565           0 :                                 for(int i = 0; i<= nLineRange; i++)
    1566             :                                 {
    1567           0 :                                     nSumRowR = nSumRowG = nSumRowB = 0;
    1568           0 :                                     nTotalWeightX = 0;
    1569             : 
    1570           0 :                                     for(int j = 0; j <= nRowRange; j++)
    1571             :                                     {
    1572           0 :                                         aCol0 = pAcc->GetPaletteColor ( pAcc->GetPixelIndex( nLineStart + i, nRowStart + j ) );
    1573             : 
    1574           0 :                                         if(nX == nEndX )
    1575             :                                         {
    1576             : 
    1577           0 :                                             nSumRowB += aCol0.GetBlue() << 7L;
    1578           0 :                                             nSumRowG += aCol0.GetGreen() << 7L;
    1579           0 :                                             nSumRowR += aCol0.GetRed() << 7L;
    1580           0 :                                             nTotalWeightX += 1 << 7L;
    1581             :                                         }
    1582           0 :                                         else if( j == 0 )
    1583             :                                         {
    1584             : 
    1585           0 :                                             nWeightX = (nMax- pMapFX[ nLeft ]) ;
    1586           0 :                                             nSumRowB += ( nWeightX *aCol0.GetBlue()) ;
    1587           0 :                                             nSumRowG += ( nWeightX *aCol0.GetGreen()) ;
    1588           0 :                                             nSumRowR += ( nWeightX *aCol0.GetRed()) ;
    1589           0 :                                             nTotalWeightX += nWeightX;
    1590             :                                         }
    1591           0 :                                         else if ( nRowRange == j )
    1592             :                                         {
    1593             : 
    1594           0 :                                             nWeightX = pMapFX[ nRight ] ;
    1595           0 :                                             nSumRowB += ( nWeightX *aCol0.GetBlue() );
    1596           0 :                                             nSumRowG += ( nWeightX *aCol0.GetGreen() );
    1597           0 :                                             nSumRowR += ( nWeightX *aCol0.GetRed() );
    1598           0 :                                             nTotalWeightX += nWeightX;
    1599             :                                         }
    1600             :                                         else
    1601             :                                         {
    1602             : 
    1603           0 :                                             nSumRowB += aCol0.GetBlue() << 7L;
    1604           0 :                                             nSumRowG += aCol0.GetGreen() << 7L;
    1605           0 :                                             nSumRowR += aCol0.GetRed() << 7L;
    1606           0 :                                             nTotalWeightX += 1 << 7L;
    1607             :                                         }
    1608             :                                     }
    1609             : 
    1610           0 :                                     if( nY == nEndY )
    1611           0 :                                         nWeightY = nMax;
    1612           0 :                                     else if( i == 0 )
    1613           0 :                                         nWeightY = nMax - pMapFY[ nTop ];
    1614           0 :                                     else if( nLineRange == 1 )
    1615           0 :                                         nWeightY = pMapFY[ nTop ];
    1616           0 :                                     else if ( nLineRange == i )
    1617           0 :                                         nWeightY = pMapFY[ nBottom ];
    1618             :                                     else
    1619           0 :                                         nWeightY = nMax;
    1620             : 
    1621           0 :                                     nSumB += nWeightY * ( nSumRowB / nTotalWeightX );
    1622           0 :                                     nSumG += nWeightY * ( nSumRowG / nTotalWeightX );
    1623           0 :                                     nSumR += nWeightY * ( nSumRowR / nTotalWeightX );
    1624           0 :                                     nTotalWeightY += nWeightY;
    1625             :                                 }
    1626             : 
    1627           0 :                                 aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) ));
    1628           0 :                                 aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) ));
    1629           0 :                                 aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) ));
    1630           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1631             :                             }
    1632             :                         }
    1633             :                     }
    1634             :                 }
    1635             :             }
    1636             :             else
    1637             :             {
    1638         737 :                 if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
    1639             :                 {
    1640         737 :                     if( scaleX >= fScaleThresh && scaleY >= fScaleThresh )
    1641             :                     {
    1642             :                         Scanline    pLine0, pLine1, pTmp0, pTmp1;
    1643             :                         long        nOff;
    1644             : 
    1645         788 :                         for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1646             :                         {
    1647         784 :                             nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ];
    1648         784 :                             pLine0 = pAcc->GetScanline( nTempY );
    1649         784 :                             pLine1 = pAcc->GetScanline( ++nTempY );
    1650             : 
    1651      109760 :                             for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
    1652             :                             {
    1653      108976 :                                 nOff = 3L * ( nTempX = pMapIX[ nX ] );
    1654      108976 :                                 nTempFX = pMapFX[ nX ];
    1655             : 
    1656      108976 :                                 pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
    1657      108976 :                                 cB0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1658      108976 :                                 cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1659      108976 :                                 cR0 = MAP( *pTmp0, *pTmp1, nTempFX );
    1660             : 
    1661      108976 :                                 pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
    1662      108976 :                                 cB1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1663      108976 :                                 cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1664      108976 :                                 cR1 = MAP( *pTmp0, *pTmp1, nTempFX );
    1665             : 
    1666      108976 :                                 aColRes.SetRed( MAP( cR0, cR1, nTempFY ) );
    1667      108976 :                                 aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) );
    1668      108976 :                                 aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) );
    1669      108976 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1670             :                             }
    1671           4 :                         }
    1672             :                     }
    1673             :                     else
    1674             :                     {
    1675             :                         Scanline    pTmpY, pTmpX;
    1676             :                         long        nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ;
    1677             :                         long        nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ;
    1678             :                         long        nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY;
    1679             : 
    1680        8864 :                         for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1681             :                         {
    1682        8131 :                             nTop = bVMirr ? ( nY + 1 ) : nY;
    1683        8131 :                             nBottom = bVMirr ? nY : ( nY + 1 ) ;
    1684             : 
    1685        8131 :                             if( nY ==nEndY )
    1686             :                             {
    1687         733 :                                 nLineStart = pMapIY[ nY ];
    1688         733 :                                 nLineRange = 0;
    1689             :                             }
    1690             :                             else
    1691             :                             {
    1692        7398 :                                 nLineStart = pMapIY[ nTop ] ;
    1693        7398 :                                 nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] );
    1694             :                             }
    1695             : 
    1696      634455 :                             for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
    1697             :                             {
    1698      626324 :                                 nLeft = bHMirr ? ( nX + 1 ) : nX;
    1699      626324 :                                 nRight = bHMirr ? nX : ( nX + 1 ) ;
    1700             : 
    1701      626324 :                                 if( nX == nEndX  )
    1702             :                                 {
    1703        8131 :                                     nRowStart = pMapIX[ nX ];
    1704        8131 :                                     nRowRange = 0;
    1705             :                                 }
    1706             :                                 else
    1707             :                                 {
    1708      618193 :                                     nRowStart = pMapIX[ nLeft ];
    1709      618193 :                                     nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] );
    1710             :                                 }
    1711             : 
    1712      626324 :                                 nSumR = nSumG = nSumB = 0;
    1713      626324 :                                 nTotalWeightY = 0;
    1714             : 
    1715     2412488 :                                 for(int i = 0; i<= nLineRange; i++)
    1716             :                                 {
    1717     1786164 :                                     pTmpY = pAcc->GetScanline( nLineStart + i );
    1718     1786164 :                                     pTmpX = pTmpY + 3L * nRowStart;
    1719     1786164 :                                     nSumRowR = nSumRowG = nSumRowB = 0;
    1720     1786164 :                                     nTotalWeightX = 0;
    1721             : 
    1722     7243950 :                                     for(int j = 0; j <= nRowRange; j++)
    1723             :                                     {
    1724     5457786 :                                         if(nX == nEndX )
    1725             :                                         {
    1726       23178 :                                             nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
    1727       23178 :                                             nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
    1728       23178 :                                             nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
    1729       23178 :                                             nTotalWeightX += 1 << 7L;
    1730             :                                         }
    1731     5434608 :                                         else if( j == 0 )
    1732             :                                         {
    1733     1762986 :                                             nWeightX = (nMax- pMapFX[ nLeft ]) ;
    1734     1762986 :                                             nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1735     1762986 :                                             nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1736     1762986 :                                             nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1737     1762986 :                                             nTotalWeightX += nWeightX;
    1738             :                                         }
    1739     3671622 :                                         else if ( nRowRange == j )
    1740             :                                         {
    1741     1762986 :                                             nWeightX = pMapFX[ nRight ] ;
    1742     1762986 :                                             nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++;
    1743     1762986 :                                             nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++;
    1744     1762986 :                                             nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++;
    1745     1762986 :                                             nTotalWeightX += nWeightX;
    1746             :                                         }
    1747             :                                         else
    1748             :                                         {
    1749     1908636 :                                             nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
    1750     1908636 :                                             nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
    1751     1908636 :                                             nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
    1752     1908636 :                                             nTotalWeightX += 1 << 7L;
    1753             :                                         }
    1754             :                                     }
    1755             : 
    1756     1786164 :                                     if( nY == nEndY )
    1757       56444 :                                         nWeightY = nMax;
    1758     1729720 :                                     else if( i == 0 )
    1759      569880 :                                         nWeightY = nMax - pMapFY[ nTop ];
    1760     1159840 :                                     else if( nLineRange == 1 )
    1761           0 :                                         nWeightY = pMapFY[ nTop ];
    1762     1159840 :                                     else if ( nLineRange == i )
    1763      569880 :                                         nWeightY = pMapFY[ nBottom ];
    1764             :                                     else
    1765      589960 :                                         nWeightY = nMax;
    1766             : 
    1767     1786164 :                                     nSumB += nWeightY * ( nSumRowB / nTotalWeightX );
    1768     1786164 :                                     nSumG += nWeightY * ( nSumRowG / nTotalWeightX );
    1769     1786164 :                                     nSumR += nWeightY * ( nSumRowR / nTotalWeightX );
    1770     1786164 :                                     nTotalWeightY += nWeightY;
    1771             :                                 }
    1772             : 
    1773      626324 :                                 aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) ));
    1774      626324 :                                 aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) ));
    1775      626324 :                                 aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) ));
    1776      626324 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1777             : 
    1778             :                             }
    1779             :                         }
    1780             :                     }
    1781             :                 }
    1782           0 :                 else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
    1783             :                 {
    1784           0 :                     if( scaleX >= fScaleThresh && scaleY >= fScaleThresh )
    1785             :                     {
    1786             :                         Scanline    pLine0, pLine1, pTmp0, pTmp1;
    1787             :                         long        nOff;
    1788             : 
    1789           0 :                         for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1790             :                         {
    1791           0 :                             nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ];
    1792           0 :                             pLine0 = pAcc->GetScanline( nTempY );
    1793           0 :                             pLine1 = pAcc->GetScanline( ++nTempY );
    1794             : 
    1795           0 :                             for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
    1796             :                             {
    1797           0 :                                 nOff = 3L * ( nTempX = pMapIX[ nX ] );
    1798           0 :                                 nTempFX = pMapFX[ nX ];
    1799             : 
    1800           0 :                                 pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L;
    1801           0 :                                 cR0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1802           0 :                                 cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1803           0 :                                 cB0 = MAP( *pTmp0, *pTmp1, nTempFX );
    1804             : 
    1805           0 :                                 pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L;
    1806           0 :                                 cR1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1807           0 :                                 cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++;
    1808           0 :                                 cB1 = MAP( *pTmp0, *pTmp1, nTempFX );
    1809             : 
    1810           0 :                                 aColRes.SetRed( MAP( cR0, cR1, nTempFY ) );
    1811           0 :                                 aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) );
    1812           0 :                                 aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) );
    1813           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1814             :                             }
    1815           0 :                         }
    1816             :                     }
    1817             :                     else
    1818             :                     {
    1819             :                         Scanline    pTmpY, pTmpX;
    1820             :                         long        nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ;
    1821             :                         long        nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ;
    1822             :                         long        nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY;
    1823             : 
    1824           0 :                         for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1825             :                         {
    1826           0 :                             nTop = bVMirr ? ( nY + 1 ) : nY;
    1827           0 :                             nBottom = bVMirr ? nY : ( nY + 1 ) ;
    1828             : 
    1829           0 :                             if( nY ==nEndY )
    1830             :                             {
    1831           0 :                                 nLineStart = pMapIY[ nY ];
    1832           0 :                                 nLineRange = 0;
    1833             :                             }
    1834             :                             else
    1835             :                             {
    1836           0 :                                 nLineStart = pMapIY[ nTop ] ;
    1837           0 :                                 nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] );
    1838             :                             }
    1839             : 
    1840           0 :                             for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
    1841             :                             {
    1842           0 :                                 nLeft = bHMirr ? ( nX + 1 ) : nX;
    1843           0 :                                 nRight = bHMirr ? nX : ( nX + 1 ) ;
    1844             : 
    1845           0 :                                 if( nX == nEndX )
    1846             :                                 {
    1847           0 :                                     nRowStart = pMapIX[ nX ];
    1848           0 :                                     nRowRange = 0;
    1849             :                                 }
    1850             :                                 else
    1851             :                                 {
    1852           0 :                                     nRowStart = pMapIX[ nLeft ];
    1853           0 :                                     nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] );
    1854             :                                 }
    1855             : 
    1856           0 :                                 nSumR = nSumG = nSumB = 0;
    1857           0 :                                 nTotalWeightY = 0;
    1858             : 
    1859           0 :                                 for(int i = 0; i<= nLineRange; i++)
    1860             :                                 {
    1861           0 :                                     pTmpY = pAcc->GetScanline( nLineStart + i );
    1862           0 :                                     pTmpX = pTmpY + 3L * nRowStart;
    1863           0 :                                     nSumRowR = nSumRowG = nSumRowB = 0;
    1864           0 :                                     nTotalWeightX = 0;
    1865             : 
    1866           0 :                                     for(int j = 0; j <= nRowRange; j++)
    1867             :                                     {
    1868           0 :                                         if(nX == nEndX )
    1869             :                                         {
    1870           0 :                                             nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
    1871           0 :                                             nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
    1872           0 :                                             nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
    1873           0 :                                             nTotalWeightX += 1 << 7L;
    1874             :                                         }
    1875           0 :                                         else if( j == 0 )
    1876             :                                         {
    1877           0 :                                             nWeightX = (nMax- pMapFX[ nLeft ]) ;
    1878           0 :                                             nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1879           0 :                                             nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1880           0 :                                             nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++;
    1881           0 :                                             nTotalWeightX += nWeightX;
    1882             :                                         }
    1883           0 :                                         else if ( nRowRange == j )
    1884             :                                         {
    1885           0 :                                             nWeightX = pMapFX[ nRight ] ;
    1886           0 :                                             nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++;
    1887           0 :                                             nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++;
    1888           0 :                                             nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++;
    1889           0 :                                             nTotalWeightX += nWeightX;
    1890             :                                         }
    1891             :                                         else
    1892             :                                         {
    1893           0 :                                             nSumRowR += ( *pTmpX ) << 7L;pTmpX++;
    1894           0 :                                             nSumRowG += ( *pTmpX ) << 7L;pTmpX++;
    1895           0 :                                             nSumRowB += ( *pTmpX ) << 7L;pTmpX++;
    1896           0 :                                             nTotalWeightX += 1 << 7L;
    1897             :                                         }
    1898             :                                     }
    1899             : 
    1900           0 :                                     if( nY == nEndY )
    1901           0 :                                         nWeightY = nMax;
    1902           0 :                                     else if( i == 0 )
    1903           0 :                                         nWeightY = nMax - pMapFY[ nTop ];
    1904           0 :                                     else if( nLineRange == 1 )
    1905           0 :                                         nWeightY = pMapFY[ nTop ];
    1906           0 :                                     else if ( nLineRange == i )
    1907           0 :                                         nWeightY = pMapFY[ nBottom ];
    1908             :                                     else
    1909           0 :                                         nWeightY = nMax;
    1910             : 
    1911           0 :                                     nSumB += nWeightY * ( nSumRowB / nTotalWeightX );
    1912           0 :                                     nSumG += nWeightY * ( nSumRowG / nTotalWeightX );
    1913           0 :                                     nSumR += nWeightY * ( nSumRowR / nTotalWeightX );
    1914           0 :                                     nTotalWeightY += nWeightY;
    1915             :                                 }
    1916             : 
    1917           0 :                                 aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) ));
    1918           0 :                                 aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) ));
    1919           0 :                                 aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) ));
    1920           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1921             : 
    1922             :                             }
    1923             :                         }
    1924             :                     }
    1925             :                 }
    1926             :                 else
    1927             :                 {
    1928           0 :                     if( scaleX >= fScaleThresh && scaleY >= fScaleThresh )
    1929             :                     {
    1930           0 :                         for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1931             :                         {
    1932           0 :                             nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ];
    1933             : 
    1934           0 :                             for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ )
    1935             :                             {
    1936           0 :                                 nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ];
    1937             : 
    1938           0 :                                 aCol0 = pAcc->GetPixel( nTempY, nTempX );
    1939           0 :                                 aCol1 = pAcc->GetPixel( nTempY, ++nTempX );
    1940           0 :                                 cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
    1941           0 :                                 cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
    1942           0 :                                 cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
    1943             : 
    1944           0 :                                 aCol1 = pAcc->GetPixel( ++nTempY, nTempX );
    1945           0 :                                 aCol0 = pAcc->GetPixel( nTempY--, --nTempX );
    1946           0 :                                 cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX );
    1947           0 :                                 cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX );
    1948           0 :                                 cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX );
    1949             : 
    1950           0 :                                 aColRes.SetRed( MAP( cR0, cR1, nTempFY ) );
    1951           0 :                                 aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) );
    1952           0 :                                 aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) );
    1953           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    1954             :                             }
    1955             :                         }
    1956             :                     }
    1957             :                     else
    1958             :                     {
    1959             :                         long        nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ;
    1960             :                         long        nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ;
    1961             :                         long        nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY;
    1962             : 
    1963           0 :                         for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ )
    1964             :                         {
    1965           0 :                             nTop = bVMirr ? ( nY + 1 ) : nY;
    1966           0 :                             nBottom = bVMirr ? nY : ( nY + 1 ) ;
    1967             : 
    1968           0 :                             if( nY ==nEndY )
    1969             :                             {
    1970           0 :                                 nLineStart = pMapIY[ nY ];
    1971           0 :                                 nLineRange = 0;
    1972             :                             }
    1973             :                             else
    1974             :                             {
    1975           0 :                                 nLineStart = pMapIY[ nTop ] ;
    1976           0 :                                 nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] );
    1977             :                             }
    1978             : 
    1979           0 :                             for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ )
    1980             :                             {
    1981           0 :                                 nLeft = bHMirr ? ( nX + 1 ) : nX;
    1982           0 :                                 nRight = bHMirr ? nX : ( nX + 1 ) ;
    1983             : 
    1984           0 :                                 if( nX == nEndX )
    1985             :                                 {
    1986           0 :                                     nRowStart = pMapIX[ nX ];
    1987           0 :                                     nRowRange = 0;
    1988             :                                 }
    1989             :                                 else
    1990             :                                 {
    1991           0 :                                     nRowStart = pMapIX[ nLeft ];
    1992           0 :                                     nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] );
    1993             :                                 }
    1994             : 
    1995           0 :                                 nSumR = nSumG = nSumB = 0;
    1996           0 :                                 nTotalWeightY = 0;
    1997             : 
    1998           0 :                                 for(int i = 0; i<= nLineRange; i++)
    1999             :                                 {
    2000           0 :                                     nSumRowR = nSumRowG = nSumRowB = 0;
    2001           0 :                                     nTotalWeightX = 0;
    2002             : 
    2003           0 :                                     for(int j = 0; j <= nRowRange; j++)
    2004             :                                     {
    2005           0 :                                         aCol0 = pAcc->GetPixel( nLineStart + i, nRowStart + j );
    2006             : 
    2007           0 :                                         if(nX == nEndX )
    2008             :                                         {
    2009             : 
    2010           0 :                                             nSumRowB += aCol0.GetBlue() << 7L;
    2011           0 :                                             nSumRowG += aCol0.GetGreen() << 7L;
    2012           0 :                                             nSumRowR += aCol0.GetRed() << 7L;
    2013           0 :                                             nTotalWeightX += 1 << 7L;
    2014             :                                         }
    2015           0 :                                         else if( j == 0 )
    2016             :                                         {
    2017             : 
    2018           0 :                                             nWeightX = (nMax- pMapFX[ nLeft ]) ;
    2019           0 :                                             nSumRowB += ( nWeightX *aCol0.GetBlue()) ;
    2020           0 :                                             nSumRowG += ( nWeightX *aCol0.GetGreen()) ;
    2021           0 :                                             nSumRowR += ( nWeightX *aCol0.GetRed()) ;
    2022           0 :                                             nTotalWeightX += nWeightX;
    2023             :                                         }
    2024           0 :                                         else if ( nRowRange == j )
    2025             :                                         {
    2026             : 
    2027           0 :                                             nWeightX = pMapFX[ nRight ] ;
    2028           0 :                                             nSumRowB += ( nWeightX *aCol0.GetBlue() );
    2029           0 :                                             nSumRowG += ( nWeightX *aCol0.GetGreen() );
    2030           0 :                                             nSumRowR += ( nWeightX *aCol0.GetRed() );
    2031           0 :                                             nTotalWeightX += nWeightX;
    2032             :                                         }
    2033             :                                         else
    2034             :                                         {
    2035           0 :                                             nSumRowB += aCol0.GetBlue() << 7L;
    2036           0 :                                             nSumRowG += aCol0.GetGreen() << 7L;
    2037           0 :                                             nSumRowR += aCol0.GetRed() << 7L;
    2038           0 :                                             nTotalWeightX += 1 << 7L;
    2039             :                                         }
    2040             :                                     }
    2041             : 
    2042           0 :                                     if( nY == nEndY )
    2043           0 :                                         nWeightY = nMax;
    2044           0 :                                     else if( i == 0 )
    2045           0 :                                         nWeightY = nMax - pMapFY[ nTop ];
    2046           0 :                                     else if( nLineRange == 1 )
    2047           0 :                                         nWeightY = pMapFY[ nTop ];
    2048           0 :                                     else if ( nLineRange == i )
    2049           0 :                                         nWeightY = pMapFY[ nBottom ];
    2050             :                                     else
    2051           0 :                                         nWeightY = nMax;
    2052             : 
    2053           0 :                                     nSumB += nWeightY * ( nSumRowB / nTotalWeightX );
    2054           0 :                                     nSumG += nWeightY * ( nSumRowG / nTotalWeightX );
    2055           0 :                                     nSumR += nWeightY * ( nSumRowR / nTotalWeightX );
    2056           0 :                                     nTotalWeightY += nWeightY;
    2057             :                                 }
    2058             : 
    2059           0 :                                 aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) ));
    2060           0 :                                 aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) ));
    2061           0 :                                 aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) ));
    2062           0 :                                 pWAcc->SetPixel( nYDst, nXDst++, aColRes );
    2063             : 
    2064             :                             }
    2065             :                         }
    2066             :                     }
    2067             :                 }
    2068             :             }
    2069             : 
    2070         739 :             bRet = true;
    2071             :         }
    2072             : 
    2073         739 :         delete[] pMapIX;
    2074         739 :         delete[] pMapIY;
    2075         739 :         delete[] pMapFX;
    2076         739 :         delete[] pMapFY;
    2077             : 
    2078         739 :         if(pAcc)
    2079             :         {
    2080         739 :             ReleaseAccess( pAcc );
    2081             :         }
    2082         739 :         if(pWAcc)
    2083             :         {
    2084         739 :             aOutBmp.ReleaseAccess( pWAcc );
    2085             :         }
    2086         739 :         if( bRet )
    2087             :         {
    2088         739 :             ImplAdaptBitCount(aOutBmp);
    2089         739 :             ImplAssignWithSize(aOutBmp);
    2090             :         }
    2091             : 
    2092         739 :         if( !bRet )
    2093         739 :             bRet = ImplScaleFast( scaleX, scaleY );
    2094             :     }
    2095             : 
    2096         739 :     return bRet;
    2097             : }
    2098             : 
    2099             : //-----------------------------------------------------------------------------------
    2100             : 
    2101             : namespace
    2102             : {
    2103        2204 :     void ImplCalculateContributions(
    2104             :         const sal_uInt32 aSourceSize,
    2105             :         const sal_uInt32 aDestinationSize,
    2106             :         sal_uInt32& aNumberOfContributions,
    2107             :         double*& pWeights,
    2108             :         sal_uInt32*& pPixels,
    2109             :         sal_uInt32*& pCount,
    2110             :         const Kernel& aKernel)
    2111             :     {
    2112        2204 :         const double fSamplingRadius(aKernel.GetWidth());
    2113        2204 :         const double fScale(aDestinationSize / static_cast< double >(aSourceSize));
    2114        2204 :         const double fScaledRadius((fScale < 1.0) ? fSamplingRadius / fScale : fSamplingRadius);
    2115        2204 :         const double fFilterFactor((fScale < 1.0) ? fScale : 1.0);
    2116             : 
    2117        2204 :         aNumberOfContributions = (static_cast< sal_uInt32 >(fabs(ceil(fScaledRadius))) * 2) + 1;
    2118        2204 :         const sal_uInt32 nAllocSize(aDestinationSize * aNumberOfContributions);
    2119        2204 :         pWeights = new double[nAllocSize];
    2120        2204 :         pPixels = new sal_uInt32[nAllocSize];
    2121        2204 :         pCount = new sal_uInt32[aDestinationSize];
    2122             : 
    2123      207401 :         for(sal_uInt32 i(0); i < aDestinationSize; i++)
    2124             :         {
    2125      205197 :             const sal_uInt32 aIndex(i * aNumberOfContributions);
    2126      205197 :             const double aCenter(i / fScale);
    2127      205197 :             const sal_Int32 aLeft(static_cast< sal_Int32 >(floor(aCenter - fScaledRadius)));
    2128      205197 :             const sal_Int32 aRight(static_cast< sal_Int32 >(ceil(aCenter + fScaledRadius)));
    2129      205197 :             sal_uInt32 aCurrentCount(0);
    2130             : 
    2131     4470681 :             for(sal_Int32 j(aLeft); j <= aRight; j++)
    2132             :             {
    2133     4265484 :                 const double aWeight(aKernel.Calculate(fFilterFactor * (aCenter - static_cast< double>(j))));
    2134             : 
    2135             :                 // Reduce calculations with ignoring weights of 0.0
    2136     4265484 :                 if(fabs(aWeight) < 0.0001)
    2137             :                 {
    2138      662083 :                     continue;
    2139             :                 }
    2140             : 
    2141             :                 // Handling on edges
    2142     3603401 :                 const sal_uInt32 aPixelIndex(MinMax(j, 0, aSourceSize - 1));
    2143     3603401 :                 const sal_uInt32 nIndex(aIndex + aCurrentCount);
    2144             : 
    2145     3603401 :                 pWeights[nIndex] = aWeight;
    2146     3603401 :                 pPixels[nIndex] = aPixelIndex;
    2147             : 
    2148     3603401 :                 aCurrentCount++;
    2149             :             }
    2150             : 
    2151      205197 :             pCount[i] = aCurrentCount;
    2152             :         }
    2153        2204 :     }
    2154             : 
    2155        1123 :     sal_Bool ImplScaleConvolutionHor(
    2156             :         Bitmap& rSource,
    2157             :         Bitmap& rTarget,
    2158             :         const double& rScaleX,
    2159             :         const Kernel& aKernel)
    2160             :     {
    2161             :         // Do horizontal filtering
    2162             :         OSL_ENSURE(rScaleX > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)");
    2163        1123 :         const sal_uInt32 nWidth(rSource.GetSizePixel().Width());
    2164        1123 :         const sal_uInt32 nNewWidth(FRound(nWidth * rScaleX));
    2165             : 
    2166        1123 :         if(nWidth == nNewWidth)
    2167             :         {
    2168           0 :             return true;
    2169             :         }
    2170             : 
    2171        1123 :         BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess();
    2172             : 
    2173        1123 :         if(pReadAcc)
    2174             :         {
    2175        1123 :             double* pWeights = 0;
    2176        1123 :             sal_uInt32* pPixels = 0;
    2177        1123 :             sal_uInt32* pCount = 0;
    2178        1123 :             sal_uInt32 aNumberOfContributions(0);
    2179             : 
    2180        1123 :             const sal_uInt32 nHeight(rSource.GetSizePixel().Height());
    2181        1123 :             ImplCalculateContributions(nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel);
    2182        1123 :             rTarget = Bitmap(Size(nNewWidth, nHeight), 24);
    2183        1123 :             BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess();
    2184        1123 :             bool bResult(0 != pWriteAcc);
    2185             : 
    2186        1123 :             if(bResult)
    2187             :             {
    2188      180427 :                 for(sal_uInt32 y(0); y < nHeight; y++)
    2189             :                 {
    2190    17475570 :                     for(sal_uInt32 x(0); x < nNewWidth; x++)
    2191             :                     {
    2192    17296266 :                         const sal_uInt32 aBaseIndex(x * aNumberOfContributions);
    2193    17296266 :                         double aSum(0.0);
    2194    17296266 :                         double aValueRed(0.0);
    2195    17296266 :                         double aValueGreen(0.0);
    2196    17296266 :                         double aValueBlue(0.0);
    2197             : 
    2198   343521168 :                         for(sal_uInt32 j(0); j < pCount[x]; j++)
    2199             :                         {
    2200   326224902 :                             const sal_uInt32 aIndex(aBaseIndex + j);
    2201   326224902 :                             const double aWeight(pWeights[aIndex]);
    2202   326224902 :                             BitmapColor aColor;
    2203             : 
    2204   326224902 :                             aSum += aWeight;
    2205             : 
    2206   326224902 :                             if(pReadAcc->HasPalette())
    2207             :                             {
    2208   113838885 :                                 aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(y, pPixels[aIndex]));
    2209             :                             }
    2210             :                             else
    2211             :                             {
    2212   212386017 :                                 aColor = pReadAcc->GetPixel(y, pPixels[aIndex]);
    2213             :                             }
    2214             : 
    2215   326224902 :                             aValueRed += aWeight * aColor.GetRed();
    2216   326224902 :                             aValueGreen += aWeight * aColor.GetGreen();
    2217   326224902 :                             aValueBlue += aWeight * aColor.GetBlue();
    2218   326224902 :                         }
    2219             : 
    2220             :                         const BitmapColor aResultColor(
    2221    17296266 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)),
    2222    17296266 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)),
    2223    51888798 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255)));
    2224             : 
    2225    17296266 :                         pWriteAcc->SetPixel(y, x, aResultColor);
    2226    17296266 :                     }
    2227             :                 }
    2228             : 
    2229        1123 :                 rTarget.ReleaseAccess(pWriteAcc);
    2230             :             }
    2231             : 
    2232        1123 :             rSource.ReleaseAccess(pReadAcc);
    2233        1123 :             delete[] pWeights;
    2234        1123 :             delete[] pCount;
    2235        1123 :             delete[] pPixels;
    2236             : 
    2237        1123 :             if(bResult)
    2238             :             {
    2239        1123 :                 return true;
    2240             :             }
    2241             :         }
    2242             : 
    2243           0 :         return false;
    2244             :     }
    2245             : 
    2246        1081 :     bool ImplScaleConvolutionVer(
    2247             :         Bitmap& rSource,
    2248             :         Bitmap& rTarget,
    2249             :         const double& rScaleY,
    2250             :         const Kernel& aKernel)
    2251             :     {
    2252             :         // Do vertical filtering
    2253             :         OSL_ENSURE(rScaleY > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)");
    2254        1081 :         const sal_uInt32 nHeight(rSource.GetSizePixel().Height());
    2255        1081 :         const sal_uInt32 nNewHeight(FRound(nHeight * rScaleY));
    2256             : 
    2257        1081 :         if(nHeight == nNewHeight)
    2258             :         {
    2259           0 :             return true;
    2260             :         }
    2261             : 
    2262        1081 :         BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess();
    2263             : 
    2264        1081 :         if(pReadAcc)
    2265             :         {
    2266        1081 :             double* pWeights = 0;
    2267        1081 :             sal_uInt32* pPixels = 0;
    2268        1081 :             sal_uInt32* pCount = 0;
    2269        1081 :             sal_uInt32 aNumberOfContributions(0);
    2270             : 
    2271        1081 :             const sal_uInt32 nWidth(rSource.GetSizePixel().Width());
    2272        1081 :             ImplCalculateContributions(nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel);
    2273        1081 :             rTarget = Bitmap(Size(nWidth, nNewHeight), 24);
    2274        1081 :             BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess();
    2275        1081 :             bool bResult(0 != pWriteAcc);
    2276             : 
    2277        1081 :             if(pWriteAcc)
    2278             :             {
    2279      273425 :                 for(sal_uInt32 x(0); x < nWidth; x++)
    2280             :                 {
    2281    23241832 :                     for(sal_uInt32 y(0); y < nNewHeight; y++)
    2282             :                     {
    2283    22969488 :                         const sal_uInt32 aBaseIndex(y * aNumberOfContributions);
    2284    22969488 :                         double aSum(0.0);
    2285    22969488 :                         double aValueRed(0.0);
    2286    22969488 :                         double aValueGreen(0.0);
    2287    22969488 :                         double aValueBlue(0.0);
    2288             : 
    2289   549222304 :                         for(sal_uInt32 j(0); j < pCount[y]; j++)
    2290             :                         {
    2291   526252816 :                             const sal_uInt32 aIndex(aBaseIndex + j);
    2292   526252816 :                             const double aWeight(pWeights[aIndex]);
    2293   526252816 :                             BitmapColor aColor;
    2294             : 
    2295   526252816 :                             aSum += aWeight;
    2296             : 
    2297   526252816 :                             if(pReadAcc->HasPalette())
    2298             :                             {
    2299   215449326 :                                 aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(pPixels[aIndex], x));
    2300             :                             }
    2301             :                             else
    2302             :                             {
    2303   310803490 :                                 aColor = pReadAcc->GetPixel(pPixels[aIndex], x);
    2304             :                             }
    2305             : 
    2306   526252816 :                             aValueRed += aWeight * aColor.GetRed();
    2307   526252816 :                             aValueGreen += aWeight * aColor.GetGreen();
    2308   526252816 :                             aValueBlue += aWeight * aColor.GetBlue();
    2309   526252816 :                         }
    2310             : 
    2311             :                         const BitmapColor aResultColor(
    2312    22969488 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)),
    2313    22969488 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)),
    2314    68908464 :                             static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255)));
    2315             : 
    2316    22969488 :                         if(pWriteAcc->HasPalette())
    2317             :                         {
    2318           0 :                             pWriteAcc->SetPixelIndex(y, x, static_cast< sal_uInt8 >(pWriteAcc->GetBestPaletteIndex(aResultColor)));
    2319             :                         }
    2320             :                         else
    2321             :                         {
    2322    22969488 :                             pWriteAcc->SetPixel(y, x, aResultColor);
    2323             :                         }
    2324    22969488 :                     }
    2325             :                 }
    2326             :             }
    2327             : 
    2328        1081 :             rTarget.ReleaseAccess(pWriteAcc);
    2329        1081 :             rSource.ReleaseAccess(pReadAcc);
    2330             : 
    2331        1081 :             delete[] pWeights;
    2332        1081 :             delete[] pCount;
    2333        1081 :             delete[] pPixels;
    2334             : 
    2335        1081 :             if(bResult)
    2336             :             {
    2337        1081 :                 return true;
    2338             :             }
    2339             :         }
    2340             : 
    2341           0 :         return false;
    2342             :     }
    2343             : }
    2344             : 
    2345             : // #i121233# Added BMP_SCALE_LANCZOS, BMP_SCALE_BICUBIC, BMP_SCALE_BILINEAR and
    2346             : // BMP_SCALE_BOX derived from the original commit from Tomas Vajngerl (see
    2347             : // bugzilla task for deitails) Thanks!
    2348        1155 : sal_Bool Bitmap::ImplScaleConvolution(
    2349             :     const double& rScaleX,
    2350             :     const double& rScaleY,
    2351             :     const Kernel& aKernel)
    2352             : {
    2353        1155 :     const bool bMirrorHor(rScaleX < 0.0);
    2354        1155 :     const bool bMirrorVer(rScaleY < 0.0);
    2355        1155 :     const double fScaleX(bMirrorHor ? -rScaleX : rScaleX);
    2356        1155 :     const double fScaleY(bMirrorVer ? -rScaleY : rScaleY);
    2357        1155 :     const sal_uInt32 nWidth(GetSizePixel().Width());
    2358        1155 :     const sal_uInt32 nHeight(GetSizePixel().Height());
    2359        1155 :     const sal_uInt32 nNewWidth(FRound(nWidth * fScaleX));
    2360        1155 :     const sal_uInt32 nNewHeight(FRound(nHeight * fScaleY));
    2361        1155 :     const bool bScaleHor(nWidth != nNewWidth);
    2362        1155 :     const bool bScaleVer(nHeight != nNewHeight);
    2363        1155 :     const bool bMirror(bMirrorHor || bMirrorVer);
    2364             : 
    2365        1155 :     if(!bMirror && !bScaleHor && !bScaleVer)
    2366             :     {
    2367           0 :         return true;
    2368             :     }
    2369             : 
    2370        1155 :     bool bResult(true);
    2371        1155 :     sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE);
    2372        1155 :     bool bMirrorAfter(false);
    2373             : 
    2374        1155 :     if(bMirror)
    2375             :     {
    2376           0 :         if(bMirrorHor)
    2377             :         {
    2378           0 :             nMirrorFlags |= BMP_MIRROR_HORZ;
    2379             :         }
    2380             : 
    2381           0 :         if(bMirrorVer)
    2382             :         {
    2383           0 :             nMirrorFlags |= BMP_MIRROR_VERT;
    2384             :         }
    2385             : 
    2386           0 :         const sal_uInt32 nStartSize(nWidth * nHeight);
    2387           0 :         const sal_uInt32 nEndSize(nNewWidth * nNewHeight);
    2388             : 
    2389           0 :         bMirrorAfter = nStartSize > nEndSize;
    2390             : 
    2391           0 :         if(!bMirrorAfter)
    2392             :         {
    2393           0 :             bResult = Mirror(nMirrorFlags);
    2394             :         }
    2395             :     }
    2396             : 
    2397        1155 :     Bitmap aResult;
    2398             : 
    2399        1155 :     if(bResult)
    2400             :     {
    2401        1155 :         const sal_uInt32 nInBetweenSizeHorFirst(nHeight * nNewWidth);
    2402        1155 :         const sal_uInt32 nInBetweenSizeVerFirst(nNewHeight * nWidth);
    2403        1155 :         Bitmap aSource(*this);
    2404             : 
    2405        1155 :         if(nInBetweenSizeHorFirst < nInBetweenSizeVerFirst)
    2406             :         {
    2407         322 :             if(bScaleHor)
    2408             :             {
    2409         322 :                 bResult = ImplScaleConvolutionHor(aSource, aResult, fScaleX, aKernel);
    2410             :             }
    2411             : 
    2412         322 :             if(bResult && bScaleVer)
    2413             :             {
    2414         248 :                 if(bScaleHor)
    2415             :                 {
    2416             :                     // copy partial result, independent of color depth
    2417         248 :                     aSource = aResult;
    2418             :                 }
    2419             : 
    2420         248 :                 bResult = ImplScaleConvolutionVer(aSource, aResult, fScaleY, aKernel);
    2421             :             }
    2422             :         }
    2423             :         else
    2424             :         {
    2425         833 :             if(bScaleVer)
    2426             :             {
    2427         833 :                 bResult = ImplScaleConvolutionVer(aSource, aResult, fScaleY, aKernel);
    2428             :             }
    2429             : 
    2430         833 :             if(bResult && bScaleHor)
    2431             :             {
    2432         801 :                 if(bScaleVer)
    2433             :                 {
    2434             :                     // copy partial result, independent of color depth
    2435         801 :                     aSource = aResult;
    2436             :                 }
    2437             : 
    2438         801 :                 bResult = ImplScaleConvolutionHor(aSource, aResult, fScaleX, aKernel);
    2439             :             }
    2440        1155 :         }
    2441             :     }
    2442             : 
    2443        1155 :     if(bResult && bMirrorAfter)
    2444             :     {
    2445           0 :         bResult = aResult.Mirror(nMirrorFlags);
    2446             :     }
    2447             : 
    2448        1155 :     if(bResult)
    2449             :     {
    2450        1155 :         ImplAdaptBitCount(aResult);
    2451        1155 :         *this = aResult;
    2452             :     }
    2453             : 
    2454        1155 :     return bResult;
    2455             : }
    2456             : 
    2457             : // ------------------------------------------------------------------------
    2458             : 
    2459           0 : sal_Bool Bitmap::Dither( sal_uLong nDitherFlags )
    2460             : {
    2461           0 :     sal_Bool bRet = sal_False;
    2462             : 
    2463           0 :     const Size aSizePix( GetSizePixel() );
    2464             : 
    2465           0 :     if( aSizePix.Width() == 1 || aSizePix.Height() == 1 )
    2466           0 :         bRet = sal_True;
    2467           0 :     else if( nDitherFlags & BMP_DITHER_MATRIX )
    2468           0 :         bRet = ImplDitherMatrix();
    2469           0 :     else if( nDitherFlags & BMP_DITHER_FLOYD )
    2470           0 :         bRet = ImplDitherFloyd();
    2471           0 :     else if( ( nDitherFlags & BMP_DITHER_FLOYD_16 ) && ( GetBitCount() == 24 ) )
    2472           0 :         bRet = ImplDitherFloyd16();
    2473             : 
    2474           0 :     return bRet;
    2475             : }
    2476             : 
    2477           0 : sal_Bool Bitmap::ImplDitherMatrix()
    2478             : {
    2479           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    2480           0 :     Bitmap              aNewBmp( GetSizePixel(), 8 );
    2481           0 :     BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    2482           0 :     sal_Bool                bRet = sal_False;
    2483             : 
    2484           0 :     if( pReadAcc && pWriteAcc )
    2485             :     {
    2486           0 :         const sal_uLong nWidth = pReadAcc->Width();
    2487           0 :         const sal_uLong nHeight = pReadAcc->Height();
    2488           0 :         BitmapColor aIndex( (sal_uInt8) 0 );
    2489             : 
    2490           0 :         if( pReadAcc->HasPalette() )
    2491             :         {
    2492           0 :             for( sal_uLong nY = 0UL; nY < nHeight; nY++ )
    2493             :             {
    2494           0 :                 for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
    2495             :                 {
    2496           0 :                     const BitmapColor   aCol( pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) ) );
    2497           0 :                     const sal_uLong         nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
    2498           0 :                     const sal_uLong         nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
    2499           0 :                     const sal_uLong         nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
    2500           0 :                     const sal_uLong         nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
    2501             : 
    2502           0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
    2503           0 :                     pWriteAcc->SetPixel( nY, nX, aIndex );
    2504           0 :                 }
    2505             :             }
    2506             :         }
    2507             :         else
    2508             :         {
    2509           0 :             for( sal_uLong nY = 0UL; nY < nHeight; nY++ )
    2510             :             {
    2511           0 :                 for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
    2512             :                 {
    2513           0 :                     const BitmapColor   aCol( pReadAcc->GetPixel( nY, nX ) );
    2514           0 :                     const sal_uLong         nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
    2515           0 :                     const sal_uLong         nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
    2516           0 :                     const sal_uLong         nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
    2517           0 :                     const sal_uLong         nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
    2518             : 
    2519           0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
    2520           0 :                     pWriteAcc->SetPixel( nY, nX, aIndex );
    2521           0 :                 }
    2522             :             }
    2523             :         }
    2524             : 
    2525           0 :         bRet = sal_True;
    2526             :     }
    2527             : 
    2528           0 :     ReleaseAccess( pReadAcc );
    2529           0 :     aNewBmp.ReleaseAccess( pWriteAcc );
    2530             : 
    2531           0 :     if( bRet )
    2532             :     {
    2533           0 :         const MapMode   aMap( maPrefMapMode );
    2534           0 :         const Size      aSize( maPrefSize );
    2535             : 
    2536           0 :         *this = aNewBmp;
    2537             : 
    2538           0 :         maPrefMapMode = aMap;
    2539           0 :         maPrefSize = aSize;
    2540             :     }
    2541             : 
    2542           0 :     return bRet;
    2543             : }
    2544             : 
    2545           0 : sal_Bool Bitmap::ImplDitherFloyd()
    2546             : {
    2547           0 :     const Size  aSize( GetSizePixel() );
    2548           0 :     sal_Bool        bRet = sal_False;
    2549             : 
    2550           0 :     if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) )
    2551             :     {
    2552           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    2553           0 :         Bitmap              aNewBmp( GetSizePixel(), 8 );
    2554           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    2555             : 
    2556           0 :         if( pReadAcc && pWriteAcc )
    2557             :         {
    2558           0 :             BitmapColor aColor;
    2559           0 :             long        nWidth = pReadAcc->Width();
    2560           0 :             long        nWidth1 = nWidth - 1L;
    2561           0 :             long        nHeight = pReadAcc->Height();
    2562             :             long        nX;
    2563           0 :             long        nW = nWidth * 3L;
    2564           0 :             long        nW2 = nW - 3L;
    2565             :             long        nRErr, nGErr, nBErr;
    2566             :             long        nRC, nGC, nBC;
    2567             :             long        nTemp;
    2568             :             long        nZ;
    2569           0 :             long*       p1 = new long[ nW ];
    2570           0 :             long*       p2 = new long[ nW ];
    2571           0 :             long*       p1T = p1;
    2572           0 :             long*       p2T = p2;
    2573             :             long*       pTmp;
    2574           0 :             sal_Bool        bPal = pReadAcc->HasPalette();
    2575             : 
    2576           0 :             pTmp = p2T;
    2577             : 
    2578           0 :             if( bPal )
    2579             :             {
    2580           0 :                 for( nZ = 0; nZ < nWidth; nZ++ )
    2581             :                 {
    2582           0 :                     aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( 0, nZ ) );
    2583             : 
    2584           0 :                     *pTmp++ = (long) aColor.GetBlue() << 12;
    2585           0 :                     *pTmp++ = (long) aColor.GetGreen() << 12;
    2586           0 :                     *pTmp++ = (long) aColor.GetRed() << 12;
    2587             :                 }
    2588             :             }
    2589             :             else
    2590             :             {
    2591           0 :                 for( nZ = 0; nZ < nWidth; nZ++ )
    2592             :                 {
    2593           0 :                     aColor = pReadAcc->GetPixel( 0, nZ );
    2594             : 
    2595           0 :                     *pTmp++ = (long) aColor.GetBlue() << 12;
    2596           0 :                     *pTmp++ = (long) aColor.GetGreen() << 12;
    2597           0 :                     *pTmp++ = (long) aColor.GetRed() << 12;
    2598             :                 }
    2599             :             }
    2600             : 
    2601           0 :             for( long nY = 1, nYAcc = 0L; nY <= nHeight; nY++, nYAcc++ )
    2602             :             {
    2603           0 :                 pTmp = p1T;
    2604           0 :                 p1T = p2T;
    2605           0 :                 p2T = pTmp;
    2606             : 
    2607           0 :                 if( nY < nHeight )
    2608             :                 {
    2609           0 :                     if( bPal )
    2610             :                     {
    2611           0 :                         for( nZ = 0; nZ < nWidth; nZ++ )
    2612             :                         {
    2613           0 :                             aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nZ ) );
    2614             : 
    2615           0 :                             *pTmp++ = (long) aColor.GetBlue() << 12;
    2616           0 :                             *pTmp++ = (long) aColor.GetGreen() << 12;
    2617           0 :                             *pTmp++ = (long) aColor.GetRed() << 12;
    2618             :                         }
    2619             :                     }
    2620             :                     else
    2621             :                     {
    2622           0 :                         for( nZ = 0; nZ < nWidth; nZ++ )
    2623             :                         {
    2624           0 :                             aColor = pReadAcc->GetPixel( nY, nZ );
    2625             : 
    2626           0 :                             *pTmp++ = (long) aColor.GetBlue() << 12;
    2627           0 :                             *pTmp++ = (long) aColor.GetGreen() << 12;
    2628           0 :                             *pTmp++ = (long) aColor.GetRed() << 12;
    2629             :                         }
    2630             :                     }
    2631             :                 }
    2632             : 
    2633             :                 // Examine first Pixel separately
    2634           0 :                 nX = 0;
    2635           0 :                 CALC_ERRORS;
    2636           0 :                 CALC_TABLES7;
    2637           0 :                 nX -= 5;
    2638           0 :                 CALC_TABLES5;
    2639           0 :                 pWriteAcc->SetPixelIndex( nYAcc, 0, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) );
    2640             : 
    2641             :                 // Get middle Pixels using a loop
    2642             :                 long nXAcc;
    2643           0 :                 for ( nX = 3L, nXAcc = 1L; nX < nW2; nXAcc++ )
    2644             :                 {
    2645           0 :                     CALC_ERRORS;
    2646           0 :                     CALC_TABLES7;
    2647           0 :                     nX -= 8;
    2648           0 :                     CALC_TABLES3;
    2649           0 :                     CALC_TABLES5;
    2650           0 :                     pWriteAcc->SetPixelIndex( nYAcc, nXAcc, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) );
    2651             :                 }
    2652             : 
    2653             :                 // Treat last Pixel separately
    2654           0 :                 CALC_ERRORS;
    2655           0 :                 nX -= 5;
    2656           0 :                 CALC_TABLES3;
    2657           0 :                 CALC_TABLES5;
    2658           0 :                 pWriteAcc->SetPixelIndex( nYAcc, nWidth1, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) );
    2659             :             }
    2660             : 
    2661           0 :             delete[] p1;
    2662           0 :             delete[] p2;
    2663           0 :             bRet = sal_True;
    2664             :         }
    2665             : 
    2666           0 :         ReleaseAccess( pReadAcc );
    2667           0 :         aNewBmp.ReleaseAccess( pWriteAcc );
    2668             : 
    2669           0 :         if( bRet )
    2670             :         {
    2671           0 :             const MapMode   aMap( maPrefMapMode );
    2672           0 :             const Size      aPrefSize( maPrefSize );
    2673             : 
    2674           0 :             *this = aNewBmp;
    2675             : 
    2676           0 :             maPrefMapMode = aMap;
    2677           0 :             maPrefSize = aPrefSize;
    2678           0 :         }
    2679             :     }
    2680             : 
    2681           0 :     return bRet;
    2682             : }
    2683             : 
    2684           0 : sal_Bool Bitmap::ImplDitherFloyd16()
    2685             : {
    2686           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    2687           0 :     Bitmap              aNewBmp( GetSizePixel(), 24 );
    2688           0 :     BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    2689           0 :     sal_Bool                bRet = sal_False;
    2690             : 
    2691           0 :     if( pReadAcc && pWriteAcc )
    2692             :     {
    2693           0 :         const long      nWidth = pWriteAcc->Width();
    2694           0 :         const long      nWidth1 = nWidth - 1L;
    2695           0 :         const long      nHeight = pWriteAcc->Height();
    2696           0 :         BitmapColor     aColor;
    2697           0 :         BitmapColor     aBestCol;
    2698           0 :         ImpErrorQuad    aErrQuad;
    2699           0 :         ImpErrorQuad*   pErrQuad1 = new ImpErrorQuad[ nWidth ];
    2700           0 :         ImpErrorQuad*   pErrQuad2 = new ImpErrorQuad[ nWidth ];
    2701           0 :         ImpErrorQuad*   pQLine1 = pErrQuad1;
    2702           0 :         ImpErrorQuad*   pQLine2 = 0;
    2703             :         long            nX, nY;
    2704           0 :         long            nYTmp = 0L;
    2705           0 :         bool            bQ1 = true;
    2706             : 
    2707           0 :         for( nY = 0L; nY < std::min( nHeight, 2L ); nY++, nYTmp++ )
    2708           0 :             for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
    2709           0 :                 pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
    2710             : 
    2711           0 :         for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
    2712             :         {
    2713             :             // First RowPixel
    2714           0 :             aBestCol = pQLine1[ 0 ].ImplGetColor();
    2715           0 :             aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
    2716           0 :             aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
    2717           0 :             aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
    2718           0 :             pWriteAcc->SetPixel( nY, 0, aBestCol );
    2719             : 
    2720           0 :             for( nX = 1L; nX < nWidth1; nX++ )
    2721             :             {
    2722           0 :                 aColor = pQLine1[ nX ].ImplGetColor();
    2723           0 :                 aBestCol.SetRed( ( aColor.GetRed() & 248 ) | 7 );
    2724           0 :                 aBestCol.SetGreen( ( aColor.GetGreen() & 248 ) | 7 );
    2725           0 :                 aBestCol.SetBlue( ( aColor.GetBlue() & 248 ) | 7 );
    2726           0 :                 aErrQuad = ( ImpErrorQuad( aColor ) -= aBestCol );
    2727           0 :                 pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
    2728           0 :                 pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
    2729           0 :                 pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
    2730           0 :                 pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
    2731           0 :                 pWriteAcc->SetPixel( nY, nX, aBestCol );
    2732             :             }
    2733             : 
    2734             :             // Last RowPixel
    2735           0 :             aBestCol = pQLine1[ nWidth1 ].ImplGetColor();
    2736           0 :             aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
    2737           0 :             aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
    2738           0 :             aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
    2739           0 :             pWriteAcc->SetPixel( nY, nX, aBestCol );
    2740             : 
    2741             :             // Refill/copy row buffer
    2742           0 :             pQLine1 = pQLine2;
    2743           0 :             pQLine2 = ( bQ1 = !bQ1 ) ? pErrQuad2 : pErrQuad1;
    2744             : 
    2745           0 :             if( nYTmp < nHeight )
    2746           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    2747           0 :                     pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
    2748             :         }
    2749             : 
    2750             :         // Destroy row buffer
    2751           0 :         delete[] pErrQuad1;
    2752           0 :         delete[] pErrQuad2;
    2753           0 :         bRet = sal_True;
    2754             :     }
    2755             : 
    2756           0 :     ReleaseAccess( pReadAcc );
    2757           0 :     aNewBmp.ReleaseAccess( pWriteAcc );
    2758             : 
    2759           0 :     if( bRet )
    2760             :     {
    2761           0 :         const MapMode   aMap( maPrefMapMode );
    2762           0 :         const Size      aSize( maPrefSize );
    2763             : 
    2764           0 :         *this = aNewBmp;
    2765             : 
    2766           0 :         maPrefMapMode = aMap;
    2767           0 :         maPrefSize = aSize;
    2768             :     }
    2769             : 
    2770           0 :     return bRet;
    2771             : }
    2772             : 
    2773           0 : sal_Bool Bitmap::ReduceColors( sal_uInt16 nColorCount, BmpReduce eReduce )
    2774             : {
    2775             :     sal_Bool bRet;
    2776             : 
    2777           0 :     if( GetColorCount() <= (sal_uLong) nColorCount )
    2778           0 :         bRet = sal_True;
    2779           0 :     else if( nColorCount )
    2780             :     {
    2781           0 :         if( BMP_REDUCE_SIMPLE == eReduce )
    2782           0 :             bRet = ImplReduceSimple( nColorCount );
    2783           0 :         else if( BMP_REDUCE_POPULAR == eReduce )
    2784           0 :             bRet = ImplReducePopular( nColorCount );
    2785             :         else
    2786           0 :             bRet = ImplReduceMedian( nColorCount );
    2787             :     }
    2788             :     else
    2789           0 :         bRet = sal_False;
    2790             : 
    2791           0 :     return bRet;
    2792             : }
    2793             : 
    2794           0 : sal_Bool Bitmap::ImplReduceSimple( sal_uInt16 nColorCount )
    2795             : {
    2796           0 :     Bitmap              aNewBmp;
    2797           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    2798           0 :     const sal_uInt16        nColCount = std::min( nColorCount, (sal_uInt16) 256 );
    2799             :     sal_uInt16              nBitCount;
    2800           0 :     sal_Bool                bRet = sal_False;
    2801             : 
    2802           0 :     if( nColCount <= 2 )
    2803           0 :         nBitCount = 1;
    2804           0 :     else if( nColCount <= 16 )
    2805           0 :         nBitCount = 4;
    2806             :     else
    2807           0 :         nBitCount = 8;
    2808             : 
    2809           0 :     if( pRAcc )
    2810             :     {
    2811           0 :         Octree                  aOct( *pRAcc, nColCount );
    2812           0 :         const BitmapPalette&    rPal = aOct.GetPalette();
    2813             :         BitmapWriteAccess*      pWAcc;
    2814             : 
    2815           0 :         aNewBmp = Bitmap( GetSizePixel(), nBitCount, &rPal );
    2816           0 :         pWAcc = aNewBmp.AcquireWriteAccess();
    2817             : 
    2818           0 :         if( pWAcc )
    2819             :         {
    2820           0 :             const long nWidth = pRAcc->Width();
    2821           0 :             const long nHeight = pRAcc->Height();
    2822             : 
    2823           0 :             if( pRAcc->HasPalette() )
    2824             :             {
    2825           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    2826           0 :                     for( long nX =0L; nX < nWidth; nX++ )
    2827           0 :                         pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ))) );
    2828             :             }
    2829             :             else
    2830             :             {
    2831           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    2832           0 :                     for( long nX =0L; nX < nWidth; nX++ )
    2833           0 :                         pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPixel( nY, nX ) )) );
    2834             :             }
    2835             : 
    2836           0 :             aNewBmp.ReleaseAccess( pWAcc );
    2837           0 :             bRet = sal_True;
    2838             :         }
    2839             : 
    2840           0 :         ReleaseAccess( pRAcc );
    2841             :     }
    2842             : 
    2843           0 :     if( bRet )
    2844             :     {
    2845           0 :         const MapMode   aMap( maPrefMapMode );
    2846           0 :         const Size      aSize( maPrefSize );
    2847             : 
    2848           0 :         *this = aNewBmp;
    2849           0 :         maPrefMapMode = aMap;
    2850           0 :         maPrefSize = aSize;
    2851             :     }
    2852             : 
    2853           0 :     return bRet;
    2854             : }
    2855             : 
    2856             : struct PopularColorCount
    2857             : {
    2858             :     sal_uInt32  mnIndex;
    2859             :     sal_uInt32  mnCount;
    2860             : };
    2861             : 
    2862           0 : extern "C" int SAL_CALL ImplPopularCmpFnc( const void* p1, const void* p2 )
    2863             : {
    2864             :     int nRet;
    2865             : 
    2866           0 :     if( ( (PopularColorCount*) p1 )->mnCount < ( (PopularColorCount*) p2 )->mnCount )
    2867           0 :         nRet = 1;
    2868           0 :     else if( ( (PopularColorCount*) p1 )->mnCount == ( (PopularColorCount*) p2 )->mnCount )
    2869           0 :         nRet = 0;
    2870             :     else
    2871           0 :         nRet = -1;
    2872             : 
    2873           0 :     return nRet;
    2874             : }
    2875             : 
    2876           0 : sal_Bool Bitmap::ImplReducePopular( sal_uInt16 nColCount )
    2877             : {
    2878           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    2879             :     sal_uInt16              nBitCount;
    2880           0 :     sal_Bool                bRet = sal_False;
    2881             : 
    2882           0 :     if( nColCount > 256 )
    2883           0 :         nColCount = 256;
    2884             : 
    2885           0 :     if( nColCount < 17 )
    2886           0 :         nBitCount = 4;
    2887             :     else
    2888           0 :         nBitCount = 8;
    2889             : 
    2890           0 :     if( pRAcc )
    2891             :     {
    2892           0 :         const sal_uInt32    nValidBits = 4;
    2893           0 :         const sal_uInt32    nRightShiftBits = 8 - nValidBits;
    2894           0 :         const sal_uInt32    nLeftShiftBits1 = nValidBits;
    2895           0 :         const sal_uInt32    nLeftShiftBits2 = nValidBits << 1;
    2896           0 :         const sal_uInt32    nColorsPerComponent = 1 << nValidBits;
    2897           0 :         const sal_uInt32    nColorOffset = 256 / nColorsPerComponent;
    2898           0 :         const sal_uInt32    nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent;
    2899           0 :         const long          nWidth = pRAcc->Width();
    2900           0 :         const long          nHeight = pRAcc->Height();
    2901           0 :         PopularColorCount*  pCountTable = new PopularColorCount[ nTotalColors ];
    2902             :         long                nX, nY, nR, nG, nB, nIndex;
    2903             : 
    2904           0 :         memset( pCountTable, 0, nTotalColors * sizeof( PopularColorCount ) );
    2905             : 
    2906           0 :         for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
    2907             :         {
    2908           0 :             for( nG = 0; nG < 256; nG += nColorOffset )
    2909             :             {
    2910           0 :                 for( nB = 0; nB < 256; nB += nColorOffset )
    2911             :                 {
    2912           0 :                     pCountTable[ nIndex ].mnIndex = nIndex;
    2913           0 :                     nIndex++;
    2914             :                 }
    2915             :             }
    2916             :         }
    2917             : 
    2918           0 :         if( pRAcc->HasPalette() )
    2919             :         {
    2920           0 :             for( nY = 0L; nY < nHeight; nY++ )
    2921             :             {
    2922           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    2923             :                 {
    2924           0 :                     const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) );
    2925           0 :                     pCountTable[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    2926           0 :                                  ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    2927           0 :                                  ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
    2928             :                 }
    2929             :             }
    2930             :         }
    2931             :         else
    2932             :         {
    2933           0 :             for( nY = 0L; nY < nHeight; nY++ )
    2934             :             {
    2935           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    2936             :                 {
    2937           0 :                     const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    2938           0 :                     pCountTable[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    2939           0 :                                  ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    2940           0 :                                  ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
    2941           0 :                 }
    2942             :             }
    2943             :         }
    2944             : 
    2945           0 :         BitmapPalette aNewPal( nColCount );
    2946             : 
    2947           0 :         qsort( pCountTable, nTotalColors, sizeof( PopularColorCount ), ImplPopularCmpFnc );
    2948             : 
    2949           0 :         for( sal_uInt16 n = 0; n < nColCount; n++ )
    2950             :         {
    2951           0 :             const PopularColorCount& rPop = pCountTable[ n ];
    2952           0 :             aNewPal[ n ] = BitmapColor( (sal_uInt8) ( ( rPop.mnIndex >> nLeftShiftBits2 ) << nRightShiftBits ),
    2953             :                                         (sal_uInt8) ( ( ( rPop.mnIndex >> nLeftShiftBits1 ) & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ),
    2954           0 :                                         (sal_uInt8) ( ( rPop.mnIndex & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ) );
    2955             :         }
    2956             : 
    2957           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, &aNewPal );
    2958           0 :         BitmapWriteAccess*  pWAcc = aNewBmp.AcquireWriteAccess();
    2959             : 
    2960           0 :         if( pWAcc )
    2961             :         {
    2962           0 :             BitmapColor aDstCol( (sal_uInt8) 0 );
    2963           0 :             sal_uInt8*      pIndexMap = new sal_uInt8[ nTotalColors ];
    2964             : 
    2965           0 :             for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
    2966           0 :                 for( nG = 0; nG < 256; nG += nColorOffset )
    2967           0 :                     for( nB = 0; nB < 256; nB += nColorOffset )
    2968           0 :                         pIndexMap[ nIndex++ ] = (sal_uInt8) aNewPal.GetBestIndex( BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB ) );
    2969             : 
    2970           0 :             if( pRAcc->HasPalette() )
    2971             :             {
    2972           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    2973             :                 {
    2974           0 :                     for( nX = 0L; nX < nWidth; nX++ )
    2975             :                     {
    2976           0 :                         const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) );
    2977           0 :                         aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    2978           0 :                                                      ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    2979           0 :                                                      ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ] );
    2980           0 :                         pWAcc->SetPixel( nY, nX, aDstCol );
    2981             :                     }
    2982             :                 }
    2983             :             }
    2984             :             else
    2985             :             {
    2986           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    2987             :                 {
    2988           0 :                     for( nX = 0L; nX < nWidth; nX++ )
    2989             :                     {
    2990           0 :                         const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    2991           0 :                         aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    2992           0 :                                                      ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    2993           0 :                                                      ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ] );
    2994           0 :                         pWAcc->SetPixel( nY, nX, aDstCol );
    2995           0 :                     }
    2996             :                 }
    2997             :             }
    2998             : 
    2999           0 :             delete[] pIndexMap;
    3000           0 :             aNewBmp.ReleaseAccess( pWAcc );
    3001           0 :             bRet = sal_True;
    3002             :         }
    3003             : 
    3004           0 :         delete[] pCountTable;
    3005           0 :         ReleaseAccess( pRAcc );
    3006             : 
    3007           0 :         if( bRet )
    3008             :         {
    3009           0 :             const MapMode   aMap( maPrefMapMode );
    3010           0 :             const Size      aSize( maPrefSize );
    3011             : 
    3012           0 :             *this = aNewBmp;
    3013           0 :             maPrefMapMode = aMap;
    3014           0 :             maPrefSize = aSize;
    3015           0 :         }
    3016             :     }
    3017             : 
    3018           0 :     return bRet;
    3019             : }
    3020             : 
    3021           0 : sal_Bool Bitmap::ImplReduceMedian( sal_uInt16 nColCount )
    3022             : {
    3023           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    3024             :     sal_uInt16              nBitCount;
    3025           0 :     sal_Bool                bRet = sal_False;
    3026             : 
    3027           0 :     if( nColCount < 17 )
    3028           0 :         nBitCount = 4;
    3029           0 :     else if( nColCount < 257 )
    3030           0 :         nBitCount = 8;
    3031             :     else
    3032             :     {
    3033             :         OSL_FAIL( "Bitmap::ImplReduceMedian(): invalid color count!" );
    3034           0 :         nBitCount = 8;
    3035           0 :         nColCount = 256;
    3036             :     }
    3037             : 
    3038           0 :     if( pRAcc )
    3039             :     {
    3040           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount );
    3041           0 :         BitmapWriteAccess*  pWAcc = aNewBmp.AcquireWriteAccess();
    3042             : 
    3043           0 :         if( pWAcc )
    3044             :         {
    3045           0 :             const sal_uLong nSize = 32768UL * sizeof( sal_uLong );
    3046           0 :             sal_uLong*      pColBuf = (sal_uLong*) rtl_allocateMemory( nSize );
    3047           0 :             const long  nWidth = pWAcc->Width();
    3048           0 :             const long  nHeight = pWAcc->Height();
    3049           0 :             long        nIndex = 0L;
    3050             : 
    3051           0 :             memset( (HPBYTE) pColBuf, 0, nSize );
    3052             : 
    3053             :             // create Buffer
    3054           0 :             if( pRAcc->HasPalette() )
    3055             :             {
    3056           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    3057             :                 {
    3058           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
    3059             :                     {
    3060           0 :                         const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) );
    3061           0 :                         pColBuf[ RGB15( rCol.GetRed() >> 3, rCol.GetGreen() >> 3, rCol.GetBlue() >> 3 ) ]++;
    3062             :                     }
    3063             :                 }
    3064             :             }
    3065             :             else
    3066             :             {
    3067           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    3068             :                 {
    3069           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
    3070             :                     {
    3071           0 :                         const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    3072           0 :                         pColBuf[ RGB15( aCol.GetRed() >> 3, aCol.GetGreen() >> 3, aCol.GetBlue() >> 3 ) ]++;
    3073           0 :                     }
    3074             :                 }
    3075             :             }
    3076             : 
    3077             :             // create palette via median cut
    3078           0 :             BitmapPalette aPal( pWAcc->GetPaletteEntryCount() );
    3079             :             ImplMedianCut( pColBuf, aPal, 0, 31, 0, 31, 0, 31,
    3080           0 :                            nColCount, nWidth * nHeight, nIndex );
    3081             : 
    3082             :             // do mapping of colors to palette
    3083           0 :             InverseColorMap aMap( aPal );
    3084           0 :             pWAcc->SetPalette( aPal );
    3085           0 :             for( long nY = 0L; nY < nHeight; nY++ )
    3086           0 :                 for( long nX = 0L; nX < nWidth; nX++ )
    3087           0 :                     pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>( aMap.GetBestPaletteIndex( pRAcc->GetColor( nY, nX ) )) );
    3088             : 
    3089           0 :             rtl_freeMemory( pColBuf );
    3090           0 :             aNewBmp.ReleaseAccess( pWAcc );
    3091           0 :             bRet = sal_True;
    3092             :         }
    3093             : 
    3094           0 :         ReleaseAccess( pRAcc );
    3095             : 
    3096           0 :         if( bRet )
    3097             :         {
    3098           0 :             const MapMode   aMap( maPrefMapMode );
    3099           0 :             const Size      aSize( maPrefSize );
    3100             : 
    3101           0 :             *this = aNewBmp;
    3102           0 :             maPrefMapMode = aMap;
    3103           0 :             maPrefSize = aSize;
    3104           0 :         }
    3105             :     }
    3106             : 
    3107           0 :     return bRet;
    3108             : }
    3109             : 
    3110           0 : void Bitmap::ImplMedianCut( sal_uLong* pColBuf, BitmapPalette& rPal,
    3111             :                             long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
    3112             :                             long nColors, long nPixels, long& rIndex )
    3113             : {
    3114           0 :     if( !nPixels )
    3115           0 :         return;
    3116             : 
    3117           0 :     BitmapColor aCol;
    3118           0 :     const long  nRLen = nR2 - nR1;
    3119           0 :     const long  nGLen = nG2 - nG1;
    3120           0 :     const long  nBLen = nB2 - nB1;
    3121           0 :     sal_uLong*      pBuf = pColBuf;
    3122             : 
    3123           0 :     if( !nRLen && !nGLen && !nBLen )
    3124             :     {
    3125           0 :         if( pBuf[ RGB15( nR1, nG1, nB1 ) ] )
    3126             :         {
    3127           0 :             aCol.SetRed( (sal_uInt8) ( nR1 << 3 ) );
    3128           0 :             aCol.SetGreen( (sal_uInt8) ( nG1 << 3 ) );
    3129           0 :             aCol.SetBlue( (sal_uInt8) ( nB1 << 3 ) );
    3130           0 :             rPal[ (sal_uInt16) rIndex++ ] = aCol;
    3131             :         }
    3132             :     }
    3133             :     else
    3134             :     {
    3135           0 :         if( 1 == nColors || 1 == nPixels )
    3136             :         {
    3137           0 :             long nPixSum = 0, nRSum = 0, nGSum = 0, nBSum = 0;
    3138             : 
    3139           0 :             for( long nR = nR1; nR <= nR2; nR++ )
    3140             :             {
    3141           0 :                 for( long nG = nG1; nG <= nG2; nG++ )
    3142             :                 {
    3143           0 :                     for( long nB = nB1; nB <= nB2; nB++ )
    3144             :                     {
    3145           0 :                         nPixSum = pBuf[ RGB15( nR, nG, nB ) ];
    3146             : 
    3147           0 :                         if( nPixSum )
    3148             :                         {
    3149           0 :                             nRSum += nR * nPixSum;
    3150           0 :                             nGSum += nG * nPixSum;
    3151           0 :                             nBSum += nB * nPixSum;
    3152             :                         }
    3153             :                     }
    3154             :                 }
    3155             :             }
    3156             : 
    3157           0 :             aCol.SetRed( (sal_uInt8) ( ( nRSum / nPixels ) << 3 ) );
    3158           0 :             aCol.SetGreen( (sal_uInt8) ( ( nGSum / nPixels ) << 3 ) );
    3159           0 :             aCol.SetBlue( (sal_uInt8) ( ( nBSum / nPixels ) << 3 ) );
    3160           0 :             rPal[ (sal_uInt16) rIndex++ ] = aCol;
    3161             :         }
    3162             :         else
    3163             :         {
    3164           0 :             const long  nTest = ( nPixels >> 1 );
    3165           0 :             long        nPixOld = 0;
    3166           0 :             long        nPixNew = 0;
    3167             : 
    3168           0 :             if( nBLen > nGLen && nBLen > nRLen )
    3169             :             {
    3170           0 :                 long nB = nB1 - 1;
    3171             : 
    3172           0 :                 while( nPixNew < nTest )
    3173             :                 {
    3174           0 :                     nB++, nPixOld = nPixNew;
    3175           0 :                     for( long nR = nR1; nR <= nR2; nR++ )
    3176           0 :                         for( long nG = nG1; nG <= nG2; nG++ )
    3177           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    3178             :                 }
    3179             : 
    3180           0 :                 if( nB < nB2 )
    3181             :                 {
    3182           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB, nColors >> 1, nPixNew, rIndex );
    3183           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB + 1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    3184             :                 }
    3185             :                 else
    3186             :                 {
    3187           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB - 1, nColors >> 1, nPixOld, rIndex );
    3188           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    3189           0 :                 }
    3190             :             }
    3191           0 :             else if( nGLen > nRLen )
    3192             :             {
    3193           0 :                 long nG = nG1 - 1;
    3194             : 
    3195           0 :                 while( nPixNew < nTest )
    3196             :                 {
    3197           0 :                     nG++, nPixOld = nPixNew;
    3198           0 :                     for( long nR = nR1; nR <= nR2; nR++ )
    3199           0 :                         for( long nB = nB1; nB <= nB2; nB++ )
    3200           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    3201             :                 }
    3202             : 
    3203           0 :                 if( nG < nG2 )
    3204             :                 {
    3205           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG, nB1, nB2, nColors >> 1, nPixNew, rIndex );
    3206           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG + 1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    3207             :                 }
    3208             :                 else
    3209             :                 {
    3210           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG - 1, nB1, nB2, nColors >> 1, nPixOld, rIndex );
    3211           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    3212             :                 }
    3213             :             }
    3214             :             else
    3215             :             {
    3216           0 :                 long nR = nR1 - 1;
    3217             : 
    3218           0 :                 while( nPixNew < nTest )
    3219             :                 {
    3220           0 :                     nR++, nPixOld = nPixNew;
    3221           0 :                     for( long nG = nG1; nG <= nG2; nG++ )
    3222           0 :                         for( long nB = nB1; nB <= nB2; nB++ )
    3223           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    3224             :                 }
    3225             : 
    3226           0 :                 if( nR < nR2 )
    3227             :                 {
    3228           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR, nG1, nG2, nB1, nB2, nColors >> 1, nPixNew, rIndex );
    3229           0 :                     ImplMedianCut( pBuf, rPal, nR1 + 1, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    3230             :                 }
    3231             :                 else
    3232             :                 {
    3233           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR - 1, nG1, nG2, nB1, nB2, nColors >> 1, nPixOld, rIndex );
    3234           0 :                     ImplMedianCut( pBuf, rPal, nR, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    3235             :                 }
    3236             :             }
    3237             :         }
    3238           0 :     }
    3239             : }
    3240             : 
    3241           2 : sal_Bool Bitmap::Vectorize( PolyPolygon& rPolyPoly, sal_uLong nFlags, const Link* pProgress )
    3242             : {
    3243           2 :     return ImplVectorizer().ImplVectorize( *this, rPolyPoly, nFlags, pProgress );
    3244             : }
    3245             : 
    3246           0 : sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFlags, const Link* pProgress )
    3247             : {
    3248           0 :     return ImplVectorizer().ImplVectorize( *this, rMtf, cReduce, nFlags, pProgress );
    3249             : }
    3250             : 
    3251           0 : sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
    3252             :                      short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
    3253             :                      double fGamma, sal_Bool bInvert )
    3254             : {
    3255           0 :     sal_Bool bRet = sal_False;
    3256             : 
    3257             :     // nothing to do => return quickly
    3258           0 :     if( !nLuminancePercent && !nContrastPercent &&
    3259           0 :         !nChannelRPercent && !nChannelGPercent && !nChannelBPercent &&
    3260           0 :         ( fGamma == 1.0 ) && !bInvert )
    3261             :     {
    3262           0 :         bRet = sal_True;
    3263             :     }
    3264             :     else
    3265             :     {
    3266           0 :         BitmapWriteAccess* pAcc = AcquireWriteAccess();
    3267             : 
    3268           0 :         if( pAcc )
    3269             :         {
    3270           0 :             BitmapColor     aCol;
    3271           0 :             const long      nW = pAcc->Width();
    3272           0 :             const long      nH = pAcc->Height();
    3273           0 :             sal_uInt8*          cMapR = new sal_uInt8[ 256 ];
    3274           0 :             sal_uInt8*          cMapG = new sal_uInt8[ 256 ];
    3275           0 :             sal_uInt8*          cMapB = new sal_uInt8[ 256 ];
    3276             :             long            nX, nY;
    3277             :             double          fM, fROff, fGOff, fBOff, fOff;
    3278             : 
    3279             :             // calculate slope
    3280           0 :             if( nContrastPercent >= 0 )
    3281           0 :                 fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) );
    3282             :             else
    3283           0 :                 fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
    3284             : 
    3285             :             // total offset = luminance offset + contrast offset
    3286           0 :             fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
    3287             : 
    3288             :             // channel offset = channel offset  + total offset
    3289           0 :             fROff = nChannelRPercent * 2.55 + fOff;
    3290           0 :             fGOff = nChannelGPercent * 2.55 + fOff;
    3291           0 :             fBOff = nChannelBPercent * 2.55 + fOff;
    3292             : 
    3293             :             // calculate gamma value
    3294           0 :             fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
    3295           0 :             const bool bGamma = ( fGamma != 1.0 );
    3296             : 
    3297             :             // create mapping table
    3298           0 :             for( nX = 0L; nX < 256L; nX++ )
    3299             :             {
    3300           0 :                 cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
    3301           0 :                 cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
    3302           0 :                 cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
    3303             : 
    3304           0 :                 if( bGamma )
    3305             :                 {
    3306           0 :                     cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma );
    3307           0 :                     cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma );
    3308           0 :                     cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma );
    3309             :                 }
    3310             : 
    3311           0 :                 if( bInvert )
    3312             :                 {
    3313           0 :                     cMapR[ nX ] = ~cMapR[ nX ];
    3314           0 :                     cMapG[ nX ] = ~cMapG[ nX ];
    3315           0 :                     cMapB[ nX ] = ~cMapB[ nX ];
    3316             :                 }
    3317             :             }
    3318             : 
    3319             :             // do modifying
    3320           0 :             if( pAcc->HasPalette() )
    3321             :             {
    3322           0 :                 BitmapColor aNewCol;
    3323             : 
    3324           0 :                 for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
    3325             :                 {
    3326           0 :                     const BitmapColor& rCol = pAcc->GetPaletteColor( i );
    3327           0 :                     aNewCol.SetRed( cMapR[ rCol.GetRed() ] );
    3328           0 :                     aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] );
    3329           0 :                     aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] );
    3330           0 :                     pAcc->SetPaletteColor( i, aNewCol );
    3331           0 :                 }
    3332             :             }
    3333           0 :             else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
    3334             :             {
    3335           0 :                 for( nY = 0L; nY < nH; nY++ )
    3336             :                 {
    3337           0 :                     Scanline pScan = pAcc->GetScanline( nY );
    3338             : 
    3339           0 :                     for( nX = 0L; nX < nW; nX++ )
    3340             :                     {
    3341           0 :                         *pScan = cMapB[ *pScan ]; pScan++;
    3342           0 :                         *pScan = cMapG[ *pScan ]; pScan++;
    3343           0 :                         *pScan = cMapR[ *pScan ]; pScan++;
    3344             :                     }
    3345             :                 }
    3346             :             }
    3347           0 :             else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
    3348             :             {
    3349           0 :                 for( nY = 0L; nY < nH; nY++ )
    3350             :                 {
    3351           0 :                     Scanline pScan = pAcc->GetScanline( nY );
    3352             : 
    3353           0 :                     for( nX = 0L; nX < nW; nX++ )
    3354             :                     {
    3355           0 :                         *pScan = cMapR[ *pScan ]; pScan++;
    3356           0 :                         *pScan = cMapG[ *pScan ]; pScan++;
    3357           0 :                         *pScan = cMapB[ *pScan ]; pScan++;
    3358             :                     }
    3359             :                 }
    3360             :             }
    3361             :             else
    3362             :             {
    3363           0 :                 for( nY = 0L; nY < nH; nY++ )
    3364             :                 {
    3365           0 :                     for( nX = 0L; nX < nW; nX++ )
    3366             :                     {
    3367           0 :                         aCol = pAcc->GetPixel( nY, nX );
    3368           0 :                         aCol.SetRed( cMapR[ aCol.GetRed() ] );
    3369           0 :                         aCol.SetGreen( cMapG[ aCol.GetGreen() ] );
    3370           0 :                         aCol.SetBlue( cMapB[ aCol.GetBlue() ] );
    3371           0 :                         pAcc->SetPixel( nY, nX, aCol );
    3372             :                     }
    3373             :                 }
    3374             :             }
    3375             : 
    3376           0 :             delete[] cMapR;
    3377           0 :             delete[] cMapG;
    3378           0 :             delete[] cMapB;
    3379           0 :             ReleaseAccess( pAcc );
    3380           0 :             bRet = sal_True;
    3381             :         }
    3382             :     }
    3383             : 
    3384           0 :     return bRet;
    3385             : }
    3386             : 
    3387           0 : bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
    3388             : {
    3389           0 :     BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
    3390             : 
    3391           0 :     if (!pReadAcc || !pWriteAcc)
    3392           0 :         return false;
    3393             : 
    3394           0 :     const int nHeight = GetSizePixel().Height();
    3395             : 
    3396           0 :     BitmapColor aColor;
    3397             :     double aValueRed, aValueGreen, aValueBlue;
    3398             :     double aSum, aWeight;
    3399             :     int aBaseIndex, aIndex;
    3400             : 
    3401           0 :     for ( int y = 0; y < nHeight; y++ )
    3402             :     {
    3403           0 :         for ( int x = 0; x < nNewSize; x++ )
    3404             :         {
    3405           0 :             aBaseIndex = x * aNumberOfContributions;
    3406           0 :             aSum = aValueRed = aValueGreen = aValueBlue = 0.0;
    3407             : 
    3408           0 :             for ( int j=0; j < pCount[x]; j++ )
    3409             :             {
    3410           0 :                 aIndex = aBaseIndex + j;
    3411           0 :                 aSum += aWeight = pWeights[ aIndex ];
    3412             : 
    3413           0 :                 aColor = pReadAcc->GetColor( y, pPixels[ aIndex ] );
    3414             : 
    3415           0 :                 aValueRed   += aWeight * aColor.GetRed();
    3416           0 :                 aValueGreen += aWeight * aColor.GetGreen();
    3417           0 :                 aValueBlue  += aWeight * aColor.GetBlue();
    3418             :             }
    3419             : 
    3420             :             BitmapColor aResultColor(
    3421           0 :                 (sal_uInt8) MinMax( aValueRed   / aSum, 0, 255 ),
    3422           0 :                 (sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
    3423           0 :                 (sal_uInt8) MinMax( aValueBlue  / aSum, 0, 255 ) );
    3424           0 :             pWriteAcc->SetPixel( x, y, aResultColor );
    3425           0 :         }
    3426             :     }
    3427           0 :     aNewBitmap.ReleaseAccess( pWriteAcc );
    3428           0 :     return true;
    3429         465 : }
    3430             : 
    3431             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10