LCOV - code coverage report
Current view: top level - vcl/source/gdi - bitmap3.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1755 0.0 %
Date: 2014-04-14 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10