LCOV - code coverage report
Current view: top level - libreoffice/vcl/source/gdi - bitmap3.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 22 1126 2.0 %
Date: 2012-12-27 Functions: 3 28 10.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdlib.h>
      22             : 
      23             : #include <vcl/bmpacc.hxx>
      24             : #include <vcl/octree.hxx>
      25             : #include <vcl/bitmapex.hxx>
      26             : #include <vcl/bitmap.hxx>
      27             : 
      28             : #include <impoct.hxx>
      29             : #include <impvect.hxx>
      30             : #include <math.h>
      31             : 
      32             : // -----------
      33             : // - Defines -
      34             : // -----------
      35             : 
      36             : #define RGB15( _def_cR, _def_cG, _def_cB )  (((sal_uLong)(_def_cR)<<10UL)|((sal_uLong)(_def_cG)<<5UL)|(sal_uLong)(_def_cB))
      37             : #define GAMMA( _def_cVal, _def_InvGamma )   ((sal_uInt8)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
      38             : 
      39             : #define CALC_ERRORS                                                             \
      40             :                         nTemp   = p1T[nX++] >> 12;                              \
      41             :                         nBErr = MinMax( nTemp, 0, 255 );                        \
      42             :                         nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \
      43             :                         nTemp   = p1T[nX++] >> 12;                              \
      44             :                         nGErr = MinMax( nTemp, 0, 255 );                        \
      45             :                         nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \
      46             :                         nTemp   = p1T[nX] >> 12;                                \
      47             :                         nRErr = MinMax( nTemp, 0, 255 );                        \
      48             :                         nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ];
      49             : 
      50             : #define CALC_TABLES3                                        \
      51             :                         p2T[nX++] += FloydError3[nBErr];    \
      52             :                         p2T[nX++] += FloydError3[nGErr];    \
      53             :                         p2T[nX++] += FloydError3[nRErr];
      54             : 
      55             : #define CALC_TABLES5                                        \
      56             :                         p2T[nX++] += FloydError5[nBErr];    \
      57             :                         p2T[nX++] += FloydError5[nGErr];    \
      58             :                         p2T[nX++] += FloydError5[nRErr];
      59             : 
      60             : #define CALC_TABLES7                                        \
      61             :                         p1T[++nX] += FloydError7[nBErr];    \
      62             :                         p2T[nX++] += FloydError1[nBErr];    \
      63             :                         p1T[nX] += FloydError7[nGErr];      \
      64             :                         p2T[nX++] += FloydError1[nGErr];    \
      65             :                         p1T[nX] += FloydError7[nRErr];      \
      66             :                         p2T[nX] += FloydError1[nRErr];
      67             : 
      68             : // -----------
      69             : // - Statics -
      70             : // -----------
      71             : 
      72             : const extern sal_uLong nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 };
      73             : const extern sal_uLong nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 };
      74             : const extern sal_uLong nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 };
      75             : 
      76             : const extern sal_uLong nVCLDitherLut[ 256 ] =
      77             : {
      78             :        0, 49152, 12288, 61440,  3072, 52224, 15360, 64512,   768, 49920, 13056,
      79             :    62208,  3840, 52992, 16128, 65280, 32768, 16384, 45056, 28672, 35840, 19456,
      80             :    48128, 31744, 33536, 17152, 45824, 29440, 36608, 20224, 48896, 32512, 8192,
      81             :    57344,  4096, 53248, 11264, 60416,  7168, 56320,  8960, 58112,  4864, 54016,
      82             :    12032, 61184,  7936, 57088, 40960, 24576, 36864, 20480, 44032, 27648, 39936,
      83             :    23552, 41728, 25344, 37632, 21248, 44800, 28416, 40704, 24320, 2048, 51200,
      84             :    14336, 63488,  1024, 50176, 13312, 62464,  2816, 51968, 15104, 64256,  1792,
      85             :    50944, 14080, 63232, 34816, 18432, 47104, 30720, 33792, 17408, 46080, 29696,
      86             :    35584, 19200, 47872, 31488, 34560, 18176, 46848, 30464, 10240, 59392,  6144,
      87             :    55296,  9216, 58368,  5120, 54272, 11008, 60160,  6912, 56064,  9984, 59136,
      88             :     5888, 55040, 43008, 26624, 38912, 22528, 41984, 25600, 37888, 21504, 43776,
      89             :    27392, 39680, 23296, 42752, 26368, 38656, 22272,   512, 49664, 12800, 61952,
      90             :     3584, 52736, 15872, 65024,   256, 49408, 12544, 61696,  3328, 52480, 15616,
      91             :    64768, 33280, 16896, 45568, 29184, 36352, 19968, 48640, 32256, 33024, 16640,
      92             :    45312, 28928, 36096, 19712, 48384, 32000,  8704, 57856,  4608, 53760, 11776,
      93             :    60928,  7680, 56832,  8448, 57600,  4352, 53504, 11520, 60672,  7424, 56576,
      94             :    41472, 25088, 37376, 20992, 44544, 28160, 40448, 24064, 41216, 24832, 37120,
      95             :    20736, 44288, 27904, 40192, 23808,  2560, 51712, 14848, 64000,  1536, 50688,
      96             :    13824, 62976,  2304, 51456, 14592, 63744,  1280, 50432, 13568, 62720, 35328,
      97             :    18944, 47616, 31232, 34304, 17920, 46592, 30208, 35072, 18688, 47360, 30976,
      98             :    34048, 17664, 46336, 29952, 10752, 59904,  6656, 55808,  9728, 58880,  5632,
      99             :    54784, 10496, 59648,  6400, 55552,  9472, 58624,  5376, 54528, 43520, 27136,
     100             :    39424, 23040, 42496, 26112, 38400, 22016, 43264, 26880, 39168, 22784, 42240,
     101             :    25856, 38144, 21760
     102             : };
     103             : 
     104             : const extern sal_uLong nVCLLut[ 256 ] =
     105             : {
     106             :          0,  1286,  2572,  3858,  5144,  6430,  7716,  9002,
     107             :      10288, 11574, 12860, 14146, 15432, 16718, 18004, 19290,
     108             :      20576, 21862, 23148, 24434, 25720, 27006, 28292, 29578,
     109             :      30864, 32150, 33436, 34722, 36008, 37294, 38580, 39866,
     110             :      41152, 42438, 43724, 45010, 46296, 47582, 48868, 50154,
     111             :      51440, 52726, 54012, 55298, 56584, 57870, 59156, 60442,
     112             :      61728, 63014, 64300, 65586, 66872, 68158, 69444, 70730,
     113             :      72016, 73302, 74588, 75874, 77160, 78446, 79732, 81018,
     114             :      82304, 83590, 84876, 86162, 87448, 88734, 90020, 91306,
     115             :      92592, 93878, 95164, 96450, 97736, 99022,100308,101594,
     116             :     102880,104166,105452,106738,108024,109310,110596,111882,
     117             :     113168,114454,115740,117026,118312,119598,120884,122170,
     118             :     123456,124742,126028,127314,128600,129886,131172,132458,
     119             :     133744,135030,136316,137602,138888,140174,141460,142746,
     120             :     144032,145318,146604,147890,149176,150462,151748,153034,
     121             :     154320,155606,156892,158178,159464,160750,162036,163322,
     122             :     164608,165894,167180,168466,169752,171038,172324,173610,
     123             :     174896,176182,177468,178754,180040,181326,182612,183898,
     124             :     185184,186470,187756,189042,190328,191614,192900,194186,
     125             :     195472,196758,198044,199330,200616,201902,203188,204474,
     126             :     205760,207046,208332,209618,210904,212190,213476,214762,
     127             :     216048,217334,218620,219906,221192,222478,223764,225050,
     128             :     226336,227622,228908,230194,231480,232766,234052,235338,
     129             :     236624,237910,239196,240482,241768,243054,244340,245626,
     130             :     246912,248198,249484,250770,252056,253342,254628,255914,
     131             :     257200,258486,259772,261058,262344,263630,264916,266202,
     132             :     267488,268774,270060,271346,272632,273918,275204,276490,
     133             :     277776,279062,280348,281634,282920,284206,285492,286778,
     134             :     288064,289350,290636,291922,293208,294494,295780,297066,
     135             :     298352,299638,300924,302210,303496,304782,306068,307354,
     136             :     308640,309926,311212,312498,313784,315070,316356,317642,
     137             :     318928,320214,321500,322786,324072,325358,326644,327930
     138             : };
     139             : 
     140             : const long FloydMap[256] =
     141             : {
     142             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     143             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
     144             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     145             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     146             :     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
     147             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     148             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     149             :     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
     150             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     151             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     152             :     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
     153             :     3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     154             :     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     155             :     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
     156             :     4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
     157             :     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
     158             : };
     159             : 
     160             : const long FloydError1[61] =
     161             : {
     162             :     -7680, -7424, -7168, -6912, -6656, -6400, -6144,
     163             :     -5888, -5632, -5376, -5120, -4864, -4608, -4352,
     164             :     -4096, -3840, -3584, -3328, -3072, -2816, -2560,
     165             :     -2304, -2048, -1792, -1536, -1280, -1024, -768,
     166             :     -512, -256, 0, 256, 512, 768, 1024, 1280, 1536,
     167             :     1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584,
     168             :     3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632,
     169             :     5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680
     170             : };
     171             : 
     172             : const long FloydError3[61] =
     173             : {
     174             :     -23040, -22272, -21504, -20736, -19968, -19200,
     175             :     -18432, -17664, -16896, -16128, -15360, -14592,
     176             :     -13824, -13056, -12288, -11520, -10752, -9984,
     177             :     -9216, -8448, -7680, -6912, -6144, -5376, -4608,
     178             :     -3840, -3072, -2304, -1536, -768, 0, 768, 1536,
     179             :     2304, 3072, 3840, 4608, 5376, 6144, 6912, 7680,
     180             :     8448, 9216, 9984, 10752, 11520, 12288, 13056,
     181             :     13824, 14592, 15360, 16128, 16896, 17664, 18432,
     182             :     19200, 19968, 20736, 21504, 22272, 23040
     183             : };
     184             : 
     185             : const long FloydError5[61] =
     186             : {
     187             :     -38400, -37120, -35840, -34560, -33280, -32000,
     188             :     -30720, -29440, -28160, -26880, -25600, -24320,
     189             :     -23040, -21760, -20480, -19200, -17920, -16640,
     190             :     -15360, -14080, -12800, -11520, -10240, -8960,
     191             :     -7680, -6400, -5120, -3840, -2560, -1280,   0,
     192             :     1280, 2560, 3840, 5120, 6400, 7680, 8960, 10240,
     193             :     11520, 12800, 14080, 15360, 16640, 17920, 19200,
     194             :     20480, 21760, 23040, 24320, 25600, 26880, 28160,
     195             :     29440, 30720, 32000, 33280, 34560, 35840, 37120,
     196             :     38400
     197             : };
     198             : 
     199             : const long FloydError7[61] =
     200             : {
     201             :     -53760, -51968, -50176, -48384, -46592, -44800,
     202             :     -43008, -41216, -39424, -37632, -35840, -34048,
     203             :     -32256, -30464, -28672, -26880, -25088, -23296,
     204             :     -21504, -19712, -17920, -16128, -14336, -12544,
     205             :     -10752, -8960, -7168, -5376, -3584, -1792,  0,
     206             :     1792, 3584, 5376, 7168, 8960, 10752, 12544, 14336,
     207             :     16128, 17920, 19712, 21504, 23296, 25088, 26880,
     208             :     28672, 30464, 32256, 34048, 35840, 37632, 39424,
     209             :     41216, 43008, 44800, 46592, 48384, 50176, 51968,
     210             :     53760
     211             : };
     212             : 
     213             : const long FloydIndexMap[6] =
     214             : {
     215             :     -30,  21, 72, 123, 174, 225
     216             : };
     217             : 
     218             : // --------------------------
     219             : // - ImplCreateDitherMatrix -
     220             : // --------------------------
     221             : 
     222           0 : void ImplCreateDitherMatrix( sal_uInt8 (*pDitherMatrix)[16][16] )
     223             : {
     224           0 :     double          fVal = 3.125;
     225           0 :     const double    fVal16 = fVal / 16.;
     226             :     long            i, j, k, l;
     227             :     sal_uInt16          pMtx[ 16 ][ 16 ];
     228           0 :     sal_uInt16          nMax = 0;
     229             :     static sal_uInt8    pMagic[4][4] = { { 0, 14,  3, 13, },
     230             :                                      {11,  5,  8,  6, },
     231             :                                      {12,  2, 15,  1, },
     232             :                                      {7,   9,  4, 10 } };
     233             : 
     234             :     // MagicSquare aufbauen
     235           0 :     for ( i = 0; i < 4; i++ )
     236           0 :        for ( j = 0; j < 4; j++ )
     237           0 :            for ( k = 0; k < 4; k++ )
     238           0 :                 for ( l = 0; l < 4; l++ )
     239           0 :                     nMax = Max ( pMtx[ (k<<2) + i][(l<<2 ) + j] =
     240           0 :                     (sal_uInt16) ( 0.5 + pMagic[i][j]*fVal + pMagic[k][l]*fVal16 ), nMax );
     241             : 
     242             :     // auf Intervall [0;254] skalieren
     243           0 :     for ( i = 0, fVal = 254. / nMax; i < 16; i++ )
     244           0 :         for( j = 0; j < 16; j++ )
     245           0 :             (*pDitherMatrix)[i][j] = (sal_uInt8) ( fVal * pMtx[i][j] );
     246           0 : }
     247             : 
     248             : // ----------
     249             : // - Bitmap -
     250             : // ----------
     251             : 
     252           6 : sal_Bool Bitmap::Convert( BmpConversion eConversion )
     253             : {
     254           6 :     const sal_uInt16    nBitCount = GetBitCount();
     255           6 :     sal_Bool            bRet = sal_False;
     256             : 
     257           6 :     switch( eConversion )
     258             :     {
     259             :         case( BMP_CONVERSION_1BIT_THRESHOLD ):
     260           0 :             bRet = ImplMakeMono( 128 );
     261           0 :         break;
     262             : 
     263             :         case( BMP_CONVERSION_1BIT_MATRIX ):
     264           0 :             bRet = ImplMakeMonoDither();
     265           0 :         break;
     266             : 
     267             :         case( BMP_CONVERSION_4BIT_GREYS ):
     268           0 :             bRet = ImplMakeGreyscales( 16 );
     269           0 :         break;
     270             : 
     271             :         case( BMP_CONVERSION_4BIT_COLORS ):
     272             :         {
     273           0 :             if( nBitCount < 4 )
     274           0 :                 bRet = ImplConvertUp( 4, NULL );
     275           0 :             else if( nBitCount > 4 )
     276           0 :                 bRet = ImplConvertDown( 4, NULL );
     277             :             else
     278           0 :                 bRet = sal_True;
     279             :         }
     280           0 :         break;
     281             : 
     282             :         case( BMP_CONVERSION_4BIT_TRANS ):
     283             :         {
     284           0 :             Color aTrans( BMP_COL_TRANS );
     285             : 
     286           0 :             if( nBitCount < 4 )
     287           0 :                 bRet = ImplConvertUp( 4, &aTrans );
     288             :             else
     289           0 :                 bRet = ImplConvertDown( 4, &aTrans );
     290             :         }
     291           0 :         break;
     292             : 
     293             :         case( BMP_CONVERSION_8BIT_GREYS ):
     294           6 :             bRet = ImplMakeGreyscales( 256 );
     295           6 :         break;
     296             : 
     297             :         case( BMP_CONVERSION_8BIT_COLORS ):
     298             :         {
     299           0 :             if( nBitCount < 8 )
     300           0 :                 bRet = ImplConvertUp( 8 );
     301           0 :             else if( nBitCount > 8 )
     302           0 :                 bRet = ImplConvertDown( 8 );
     303             :             else
     304           0 :                 bRet = sal_True;
     305             :         }
     306           0 :         break;
     307             : 
     308             :         case( BMP_CONVERSION_8BIT_TRANS ):
     309             :         {
     310           0 :             Color aTrans( BMP_COL_TRANS );
     311             : 
     312           0 :             if( nBitCount < 8 )
     313           0 :                 bRet = ImplConvertUp( 8, &aTrans );
     314             :             else
     315           0 :                 bRet = ImplConvertDown( 8, &aTrans );
     316             :         }
     317           0 :         break;
     318             : 
     319             :         case( BMP_CONVERSION_24BIT ):
     320             :         {
     321           0 :             if( nBitCount < 24 )
     322           0 :                 bRet = ImplConvertUp( 24, NULL );
     323             :             else
     324           0 :                 bRet = sal_True;
     325             :         }
     326           0 :         break;
     327             : 
     328             :         case( BMP_CONVERSION_GHOSTED ):
     329           0 :             bRet = ImplConvertGhosted();
     330           0 :         break;
     331             : 
     332             :         default:
     333             :             OSL_FAIL( "Bitmap::Convert(): Unsupported conversion" );
     334           0 :         break;
     335             :     }
     336             : 
     337           6 :     return bRet;
     338             : }
     339             : 
     340           0 : sal_Bool Bitmap::ImplMakeMono( sal_uInt8 cThreshold )
     341             : {
     342           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     343           0 :     sal_Bool                bRet = sal_False;
     344             : 
     345           0 :     if( pReadAcc )
     346             :     {
     347           0 :         Bitmap              aNewBmp( GetSizePixel(), 1 );
     348           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     349             : 
     350           0 :         if( pWriteAcc )
     351             :         {
     352           0 :             const BitmapColor   aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
     353           0 :             const BitmapColor   aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
     354           0 :             const long          nWidth = pWriteAcc->Width();
     355           0 :             const long          nHeight = pWriteAcc->Height();
     356             : 
     357           0 :             if( pReadAcc->HasPalette() )
     358             :             {
     359           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     360             :                 {
     361           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
     362             :                     {
     363           0 :                         if( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >=
     364             :                             cThreshold )
     365             :                         {
     366           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     367             :                         }
     368             :                         else
     369           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     370             :                     }
     371             :                 }
     372             :             }
     373             :             else
     374             :             {
     375           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     376             :                 {
     377           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
     378             :                     {
     379           0 :                         if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >=
     380             :                             cThreshold )
     381             :                         {
     382           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     383             :                         }
     384             :                         else
     385           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     386             :                     }
     387             :                 }
     388             :             }
     389             : 
     390           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
     391           0 :             bRet = sal_True;
     392             :         }
     393             : 
     394           0 :         ReleaseAccess( pReadAcc );
     395             : 
     396           0 :         if( bRet )
     397             :         {
     398           0 :             const MapMode   aMap( maPrefMapMode );
     399           0 :             const Size      aSize( maPrefSize );
     400             : 
     401           0 :             *this = aNewBmp;
     402             : 
     403           0 :             maPrefMapMode = aMap;
     404           0 :             maPrefSize = aSize;
     405           0 :         }
     406             :     }
     407             : 
     408           0 :     return bRet;
     409             : }
     410             : 
     411           0 : sal_Bool Bitmap::ImplMakeMonoDither()
     412             : {
     413           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     414           0 :     sal_Bool                bRet = sal_False;
     415             : 
     416           0 :     if( pReadAcc )
     417             :     {
     418           0 :         Bitmap              aNewBmp( GetSizePixel(), 1 );
     419           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     420             : 
     421           0 :         if( pWriteAcc )
     422             :         {
     423           0 :             const BitmapColor   aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
     424           0 :             const BitmapColor   aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
     425           0 :             const long          nWidth = pWriteAcc->Width();
     426           0 :             const long          nHeight = pWriteAcc->Height();
     427             :             sal_uInt8               pDitherMatrix[ 16 ][ 16 ];
     428             : 
     429           0 :             ImplCreateDitherMatrix( &pDitherMatrix );
     430             : 
     431           0 :             if( pReadAcc->HasPalette() )
     432             :             {
     433           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     434             :                 {
     435           0 :                     for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
     436             :                     {
     437           0 :                         if( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >
     438           0 :                             pDitherMatrix[ nModY ][ nX % 16 ] )
     439             :                         {
     440           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     441             :                         }
     442             :                         else
     443           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     444             :                     }
     445             :                 }
     446             :             }
     447             :             else
     448             :             {
     449           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
     450             :                 {
     451           0 :                     for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ )
     452             :                     {
     453           0 :                         if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >
     454           0 :                             pDitherMatrix[ nModY ][ nX % 16 ]  )
     455             :                         {
     456           0 :                             pWriteAcc->SetPixel( nY, nX, aWhite );
     457             :                         }
     458             :                         else
     459           0 :                             pWriteAcc->SetPixel( nY, nX, aBlack );
     460             :                     }
     461             :                 }
     462             :             }
     463             : 
     464           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
     465           0 :             bRet = sal_True;
     466             :         }
     467             : 
     468           0 :         ReleaseAccess( pReadAcc );
     469             : 
     470           0 :         if( bRet )
     471             :         {
     472           0 :             const MapMode   aMap( maPrefMapMode );
     473           0 :             const Size      aSize( maPrefSize );
     474             : 
     475           0 :             *this = aNewBmp;
     476             : 
     477           0 :             maPrefMapMode = aMap;
     478           0 :             maPrefSize = aSize;
     479           0 :         }
     480             :     }
     481             : 
     482           0 :     return bRet;
     483             : }
     484             : 
     485           6 : sal_Bool Bitmap::ImplMakeGreyscales( sal_uInt16 nGreys )
     486             : {
     487             :     DBG_ASSERT( nGreys == 16 || nGreys == 256, "Only 16 or 256 greyscales are supported!" );
     488             : 
     489           6 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     490           6 :     sal_Bool                bRet = sal_False;
     491             : 
     492           6 :     if( pReadAcc )
     493             :     {
     494           6 :         const BitmapPalette&    rPal = GetGreyPalette( nGreys );
     495           6 :         sal_uLong                   nShift = ( ( nGreys == 16 ) ? 4UL : 0UL );
     496           6 :         sal_Bool                    bPalDiffers = !pReadAcc->HasPalette() || ( rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount() );
     497             : 
     498           6 :         if( !bPalDiffers )
     499           6 :             bPalDiffers = ( (BitmapPalette&) rPal != pReadAcc->GetPalette() );
     500             : 
     501           6 :         if( bPalDiffers )
     502             :         {
     503           0 :             Bitmap              aNewBmp( GetSizePixel(), ( nGreys == 16 ) ? 4 : 8, &rPal );
     504           0 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     505             : 
     506           0 :             if( pWriteAcc )
     507             :             {
     508           0 :                 const long  nWidth = pWriteAcc->Width();
     509           0 :                 const long  nHeight = pWriteAcc->Height();
     510             : 
     511           0 :                 if( pReadAcc->HasPalette() )
     512             :                 {
     513           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     514             :                     {
     515           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     516             :                         {
     517             :                             pWriteAcc->SetPixel( nY, nX,
     518             :                                 (sal_uInt8) ( pReadAcc->GetPaletteColor(
     519           0 :                                     pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift ) );
     520             :                         }
     521             :                     }
     522             :                 }
     523           0 :                 else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR &&
     524           0 :                          pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     525             :                 {
     526           0 :                     nShift += 8;
     527             : 
     528           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     529             :                     {
     530           0 :                         Scanline pReadScan = pReadAcc->GetScanline( nY );
     531           0 :                         Scanline pWriteScan = pWriteAcc->GetScanline( nY );
     532             : 
     533           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     534             :                         {
     535           0 :                             const sal_uLong nB = *pReadScan++;
     536           0 :                             const sal_uLong nG = *pReadScan++;
     537           0 :                             const sal_uLong nR = *pReadScan++;
     538             : 
     539           0 :                             *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
     540             :                         }
     541             :                     }
     542             :                 }
     543           0 :                 else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB &&
     544           0 :                          pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
     545             :                 {
     546           0 :                     nShift += 8;
     547             : 
     548           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     549             :                     {
     550           0 :                         Scanline pReadScan = pReadAcc->GetScanline( nY );
     551           0 :                         Scanline pWriteScan = pWriteAcc->GetScanline( nY );
     552             : 
     553           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     554             :                         {
     555           0 :                             const sal_uLong nR = *pReadScan++;
     556           0 :                             const sal_uLong nG = *pReadScan++;
     557           0 :                             const sal_uLong nB = *pReadScan++;
     558             : 
     559           0 :                             *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift );
     560             :                         }
     561             :                     }
     562             :                 }
     563             :                 else
     564             :                 {
     565           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     566           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     567           0 :                             pWriteAcc->SetPixel( nY, nX, sal::static_int_cast<sal_uInt8>(( pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift) );
     568             :                 }
     569             : 
     570           0 :                 aNewBmp.ReleaseAccess( pWriteAcc );
     571           0 :                 bRet = sal_True;
     572             :             }
     573             : 
     574           0 :             ReleaseAccess( pReadAcc );
     575             : 
     576           0 :             if( bRet )
     577             :             {
     578           0 :                 const MapMode   aMap( maPrefMapMode );
     579           0 :                 const Size      aSize( maPrefSize );
     580             : 
     581           0 :                 *this = aNewBmp;
     582             : 
     583           0 :                 maPrefMapMode = aMap;
     584           0 :                 maPrefSize = aSize;
     585           0 :             }
     586             :         }
     587             :         else
     588             :         {
     589           6 :             ReleaseAccess( pReadAcc );
     590           6 :             bRet = sal_True;
     591             :         }
     592             :     }
     593             : 
     594           6 :     return bRet;
     595             : }
     596             : 
     597           0 : sal_Bool Bitmap::ImplConvertUp( sal_uInt16 nBitCount, Color* pExtColor )
     598             : {
     599             :     DBG_ASSERT( nBitCount > GetBitCount(), "New BitCount must be greater!" );
     600             : 
     601           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     602           0 :     sal_Bool                bRet = sal_False;
     603             : 
     604           0 :     if( pReadAcc )
     605             :     {
     606           0 :         BitmapPalette       aPal;
     607           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, pReadAcc->HasPalette() ? &pReadAcc->GetPalette() : &aPal );
     608           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     609             : 
     610           0 :         if( pWriteAcc )
     611             :         {
     612           0 :             const long  nWidth = pWriteAcc->Width();
     613           0 :             const long  nHeight = pWriteAcc->Height();
     614             : 
     615           0 :             if( pWriteAcc->HasPalette() )
     616             :             {
     617           0 :                 const sal_uInt16            nOldCount = 1 << GetBitCount();
     618           0 :                 const BitmapPalette&    rOldPal = pReadAcc->GetPalette();
     619             : 
     620           0 :                 aPal.SetEntryCount( 1 << nBitCount );
     621             : 
     622           0 :                 for( sal_uInt16 i = 0; i < nOldCount; i++ )
     623           0 :                     aPal[ i ] = rOldPal[ i ];
     624             : 
     625           0 :                 if( pExtColor )
     626           0 :                     aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
     627             : 
     628           0 :                 pWriteAcc->SetPalette( aPal );
     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->GetPixel( nY, nX ) );
     633             :             }
     634             :             else
     635             :             {
     636           0 :                 if( pReadAcc->HasPalette() )
     637             :                 {
     638           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     639           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     640           0 :                             pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ) );
     641             :                 }
     642             :                 else
     643             :                 {
     644           0 :                     for( long nY = 0L; nY < nHeight; nY++ )
     645           0 :                         for( long nX = 0L; nX < nWidth; nX++ )
     646           0 :                             pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) );
     647             :                 }
     648             :             }
     649             : 
     650           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
     651           0 :             bRet = sal_True;
     652             :         }
     653             : 
     654           0 :         ReleaseAccess( pReadAcc );
     655             : 
     656           0 :         if( bRet )
     657             :         {
     658           0 :             const MapMode   aMap( maPrefMapMode );
     659           0 :             const Size      aSize( maPrefSize );
     660             : 
     661           0 :             *this = aNewBmp;
     662             : 
     663           0 :             maPrefMapMode = aMap;
     664           0 :             maPrefSize = aSize;
     665           0 :         }
     666             :     }
     667             : 
     668           0 :     return bRet;
     669             : }
     670             : 
     671           0 : sal_Bool Bitmap::ImplConvertDown( sal_uInt16 nBitCount, Color* pExtColor )
     672             : {
     673             :     DBG_ASSERT( nBitCount <= GetBitCount(), "New BitCount must be lower ( or equal when pExtColor is set )!" );
     674             : 
     675           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     676           0 :     sal_Bool                bRet = sal_False;
     677             : 
     678           0 :     if( pReadAcc )
     679             :     {
     680           0 :         BitmapPalette       aPal;
     681           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, &aPal );
     682           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     683             : 
     684           0 :         if( pWriteAcc )
     685             :         {
     686           0 :             const sal_uInt16    nCount = 1 << nBitCount;
     687           0 :             const long      nWidth = pWriteAcc->Width();
     688           0 :             const long      nWidth1 = nWidth - 1L;
     689           0 :             const long      nHeight = pWriteAcc->Height();
     690           0 :             Octree          aOctree( *pReadAcc, pExtColor ? ( nCount - 1 ) : nCount );
     691           0 :             InverseColorMap aColorMap( aPal = aOctree.GetPalette() );
     692           0 :             BitmapColor     aColor;
     693           0 :             ImpErrorQuad    aErrQuad;
     694           0 :             ImpErrorQuad*   pErrQuad1 = new ImpErrorQuad[ nWidth ];
     695           0 :             ImpErrorQuad*   pErrQuad2 = new ImpErrorQuad[ nWidth ];
     696           0 :             ImpErrorQuad*   pQLine1 = pErrQuad1;
     697           0 :             ImpErrorQuad*   pQLine2 = 0;
     698             :             long            nX, nY;
     699           0 :             long            nYTmp = 0L;
     700             :             sal_uInt8           cIndex;
     701           0 :             sal_Bool            bQ1 = sal_True;
     702             : 
     703           0 :             if( pExtColor )
     704             :             {
     705           0 :                 aPal.SetEntryCount( aPal.GetEntryCount() + 1 );
     706           0 :                 aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor;
     707             :             }
     708             : 
     709             :             // set Black/White always, if we have enough space
     710           0 :             if( aPal.GetEntryCount() < ( nCount - 1 ) )
     711             :             {
     712           0 :                 aPal.SetEntryCount( aPal.GetEntryCount() + 2 );
     713           0 :                 aPal[ aPal.GetEntryCount() - 2 ] = Color( COL_BLACK );
     714           0 :                 aPal[ aPal.GetEntryCount() - 1 ] = Color( COL_WHITE );
     715             :             }
     716             : 
     717           0 :             pWriteAcc->SetPalette( aPal );
     718             : 
     719           0 :             for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ )
     720             :             {
     721           0 :                 for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
     722             :                 {
     723           0 :                     if( pReadAcc->HasPalette() )
     724           0 :                         pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nYTmp, nX ) );
     725             :                     else
     726           0 :                         pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
     727             :                 }
     728             :             }
     729             : 
     730           0 :             for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
     731             :             {
     732             :                 // erstes ZeilenPixel
     733           0 :                 cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ 0 ].ImplGetColor() );
     734           0 :                 pWriteAcc->SetPixel( nY, 0, cIndex );
     735             : 
     736           0 :                 for( nX = 1L; nX < nWidth1; nX++ )
     737             :                 {
     738           0 :                     cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( aColor = pQLine1[ nX ].ImplGetColor() );
     739           0 :                     aErrQuad = ( ImpErrorQuad( aColor ) -= pWriteAcc->GetPaletteColor( cIndex ) );
     740           0 :                     pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
     741           0 :                     pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
     742           0 :                     pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
     743           0 :                     pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
     744           0 :                     pWriteAcc->SetPixel( nY, nX, cIndex );
     745             :                 }
     746             : 
     747             :                 // letztes ZeilenPixel
     748           0 :                 if( nX < nWidth )
     749             :                 {
     750           0 :                     cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ nWidth1 ].ImplGetColor() );
     751           0 :                     pWriteAcc->SetPixel( nY, nX, cIndex );
     752             :                 }
     753             : 
     754             :                 // Zeilenpuffer neu fuellen/kopieren
     755           0 :                 pQLine1 = pQLine2;
     756           0 :                 pQLine2 = ( bQ1 = !bQ1 ) != sal_False ? pErrQuad2 : pErrQuad1;
     757             : 
     758           0 :                 if( nYTmp < nHeight )
     759             :                 {
     760           0 :                     for( nX = 0L; nX < nWidth; nX++ )
     761             :                     {
     762           0 :                         if( pReadAcc->HasPalette() )
     763           0 :                                 pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nYTmp, nX ) );
     764             :                         else
     765           0 :                             pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
     766             :                     }
     767             :                 }
     768             :             }
     769             : 
     770             :             // Zeilenpuffer zerstoeren
     771           0 :             delete[] pErrQuad1;
     772           0 :             delete[] pErrQuad2;
     773             : 
     774           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
     775           0 :             bRet = sal_True;
     776             :         }
     777             : 
     778           0 :         ReleaseAccess( pReadAcc );
     779             : 
     780           0 :         if( bRet )
     781             :         {
     782           0 :             const MapMode   aMap( maPrefMapMode );
     783           0 :             const Size      aSize( maPrefSize );
     784             : 
     785           0 :             *this = aNewBmp;
     786             : 
     787           0 :             maPrefMapMode = aMap;
     788           0 :             maPrefSize = aSize;
     789           0 :         }
     790             :     }
     791             : 
     792           0 :     return bRet;
     793             : }
     794             : 
     795           0 : sal_Bool Bitmap::ImplConvertGhosted()
     796             : {
     797           0 :     Bitmap              aNewBmp;
     798           0 :     BitmapReadAccess*   pR = AcquireReadAccess();
     799           0 :     sal_Bool                bRet = sal_False;
     800             : 
     801           0 :     if( pR )
     802             :     {
     803           0 :         if( pR->HasPalette() )
     804             :         {
     805           0 :             BitmapPalette aNewPal( pR->GetPaletteEntryCount() );
     806             : 
     807           0 :             for( long i = 0, nCount = aNewPal.GetEntryCount(); i < nCount; i++ )
     808             :             {
     809           0 :                 const BitmapColor& rOld = pR->GetPaletteColor( (sal_uInt16) i );
     810           0 :                 aNewPal[ (sal_uInt16) i ] = BitmapColor( ( rOld.GetRed() >> 1 ) | 0x80,
     811           0 :                                                      ( rOld.GetGreen() >> 1 ) | 0x80,
     812           0 :                                                      ( rOld.GetBlue() >> 1 ) | 0x80 );
     813             :             }
     814             : 
     815           0 :             aNewBmp = Bitmap( GetSizePixel(), GetBitCount(), &aNewPal );
     816           0 :             BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
     817             : 
     818           0 :             if( pW )
     819             :             {
     820           0 :                 pW->CopyBuffer( *pR );
     821           0 :                 aNewBmp.ReleaseAccess( pW );
     822           0 :                 bRet = sal_True;
     823           0 :             }
     824             :         }
     825             :         else
     826             :         {
     827           0 :             aNewBmp = Bitmap( GetSizePixel(), 24 );
     828             : 
     829           0 :             BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess();
     830             : 
     831           0 :             if( pW )
     832             :             {
     833           0 :                 const long nWidth = pR->Width(), nHeight = pR->Height();
     834             : 
     835           0 :                 for( long nY = 0; nY < nHeight; nY++ )
     836             :                 {
     837           0 :                     for( long nX = 0; nX < nWidth; nX++ )
     838             :                     {
     839           0 :                         const BitmapColor aOld( pR->GetPixel( nY, nX ) );
     840           0 :                         pW->SetPixel( nY, nX, BitmapColor( ( aOld.GetRed() >> 1 ) | 0x80,
     841           0 :                                                            ( aOld.GetGreen() >> 1 ) | 0x80,
     842           0 :                                                            ( aOld.GetBlue() >> 1 ) | 0x80 ) );
     843             : 
     844           0 :                     }
     845             :                 }
     846             : 
     847           0 :                 aNewBmp.ReleaseAccess( pW );
     848           0 :                 bRet = sal_True;
     849             :             }
     850             :         }
     851             : 
     852           0 :         ReleaseAccess( pR );
     853             :     }
     854             : 
     855           0 :     if( bRet )
     856             :     {
     857           0 :         const MapMode   aMap( maPrefMapMode );
     858           0 :         const Size      aSize( maPrefSize );
     859             : 
     860           0 :         *this = aNewBmp;
     861             : 
     862           0 :         maPrefMapMode = aMap;
     863           0 :         maPrefSize = aSize;
     864             :     }
     865             : 
     866           0 :     return bRet;
     867             : }
     868             : 
     869           0 : sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag )
     870             : {
     871             :     bool bRet;
     872             : 
     873           0 :     if( ( rScaleX != 1.0 ) || ( rScaleY != 1.0 ) )
     874             :     {
     875           0 :         if( BMP_SCALE_FAST == nScaleFlag )
     876             :         {
     877           0 :             bRet = ImplScaleFast( rScaleX, rScaleY );
     878             :         }
     879           0 :         else if( BMP_SCALE_INTERPOLATE == nScaleFlag )
     880             :         {
     881           0 :             bRet = ImplScaleInterpolate( rScaleX, rScaleY );
     882             :         }
     883           0 :         else if( BMP_SCALE_LANCZOS == nScaleFlag )
     884             :         {
     885           0 :             Lanczos3Kernel kernel;
     886           0 :             bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel);
     887             :         }
     888           0 :         else if( BMP_SCALE_BICUBIC == nScaleFlag )
     889             :         {
     890           0 :             BicubicKernel kernel;
     891           0 :             bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     892             :         }
     893           0 :         else if( BMP_SCALE_BILINEAR == nScaleFlag )
     894             :         {
     895           0 :             BilinearKernel kernel;
     896           0 :             bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     897             :         }
     898           0 :         else if( BMP_SCALE_BOX == nScaleFlag )
     899             :         {
     900           0 :             BoxKernel kernel;
     901           0 :             bRet = ImplScaleConvolution( rScaleX, rScaleY, kernel );
     902             :         }
     903             :         else
     904             :         {
     905           0 :             return false;
     906           0 :         }
     907             :     }
     908             :     else
     909           0 :         bRet = true;
     910             : 
     911           0 :     return bRet;
     912             : }
     913             : 
     914           0 : sal_Bool Bitmap::Scale( const Size& rNewSize, sal_uLong nScaleFlag )
     915             : {
     916           0 :     const Size  aSize( GetSizePixel() );
     917             :     bool        bRet;
     918             : 
     919           0 :     if( aSize.Width() && aSize.Height() )
     920             :     {
     921           0 :         bRet = Scale( (double) rNewSize.Width() / aSize.Width(),
     922           0 :                       (double) rNewSize.Height() / aSize.Height(),
     923           0 :                       nScaleFlag );
     924             :     }
     925             :     else
     926           0 :         bRet = sal_True;
     927             : 
     928           0 :     return bRet;
     929             : }
     930             : 
     931           0 : sal_Bool Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY )
     932             : {
     933           0 :     const Size  aSizePix( GetSizePixel() );
     934           0 :     const long  nNewWidth = FRound( aSizePix.Width() * rScaleX );
     935           0 :     const long  nNewHeight = FRound( aSizePix.Height() * rScaleY );
     936           0 :     sal_Bool    bRet = sal_False;
     937             : 
     938           0 :     if( nNewWidth && nNewHeight )
     939             :     {
     940           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
     941             : 
     942           0 :         if(pReadAcc)
     943             :         {
     944           0 :             Bitmap              aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() );
     945           0 :             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
     946             : 
     947           0 :             if( pWriteAcc )
     948             :             {
     949           0 :                 const long  nScanlineSize = pWriteAcc->GetScanlineSize();
     950           0 :                 const long  nNewWidth1 = nNewWidth - 1L;
     951           0 :                 const long  nNewHeight1 = nNewHeight - 1L;
     952           0 :                 const long  nWidth = pReadAcc->Width();
     953           0 :                 const long  nHeight = pReadAcc->Height();
     954           0 :                 long*       pLutX = new long[ nNewWidth ];
     955           0 :                 long*       pLutY = new long[ nNewHeight ];
     956             : 
     957           0 :                 if( nNewWidth1 && nNewHeight1 )
     958             :                 {
     959           0 :                     long        nX, nY, nMapY, nActY = 0L;
     960             : 
     961           0 :                     for( nX = 0L; nX < nNewWidth; nX++ )
     962           0 :                         pLutX[ nX ] = nX * nWidth / nNewWidth;
     963             : 
     964           0 :                     for( nY = 0L; nY < nNewHeight; nY++ )
     965           0 :                         pLutY[ nY ] = nY * nHeight / nNewHeight;
     966             : 
     967           0 :                     while( nActY < nNewHeight )
     968             :                     {
     969           0 :                         nMapY = pLutY[ nActY ];
     970             : 
     971           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
     972           0 :                             pWriteAcc->SetPixel( nActY, nX, pReadAcc->GetPixel( nMapY , pLutX[ nX ] ) );
     973             : 
     974           0 :                         while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) )
     975             :                         {
     976           0 :                             memcpy( pWriteAcc->GetScanline( nActY + 1L ),
     977           0 :                                     pWriteAcc->GetScanline( nActY ), nScanlineSize );
     978           0 :                             nActY++;
     979             :                         }
     980           0 :                         nActY++;
     981             :                     }
     982             : 
     983           0 :                     bRet = sal_True;
     984           0 :                     aNewBmp.ReleaseAccess( pWriteAcc );
     985             :                 }
     986             : 
     987           0 :                 delete[] pLutX;
     988           0 :                 delete[] pLutY;
     989             :             }
     990           0 :             ReleaseAccess( pReadAcc );
     991             : 
     992           0 :             if( bRet )
     993           0 :                 ImplAssignWithSize( aNewBmp );
     994             :         }
     995             :     }
     996             : 
     997           0 :     return bRet;
     998             : }
     999             : 
    1000           0 : sal_Bool Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY )
    1001             : {
    1002           0 :     const Size  aSizePix( GetSizePixel() );
    1003           0 :     const long  nNewWidth = FRound( aSizePix.Width() * rScaleX );
    1004           0 :     const long  nNewHeight = FRound( aSizePix.Height() * rScaleY );
    1005           0 :     sal_Bool        bRet = sal_False;
    1006             : 
    1007           0 :     if( ( nNewWidth > 1L ) && ( nNewHeight > 1L ) )
    1008             :     {
    1009           0 :         BitmapColor         aCol0;
    1010           0 :         BitmapColor         aCol1;
    1011           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1012           0 :         long                nWidth = pReadAcc->Width();
    1013           0 :         long                nHeight = pReadAcc->Height();
    1014           0 :         Bitmap              aNewBmp( Size( nNewWidth, nHeight ), 24 );
    1015           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1016             :         long*               pLutInt;
    1017             :         long*               pLutFrac;
    1018             :         long                nX, nY;
    1019             :         long                lXB0, lXB1, lXG0, lXG1, lXR0, lXR1;
    1020             :         double              fTemp;
    1021             :         long                nTemp;
    1022             : 
    1023           0 :         if( pReadAcc && pWriteAcc )
    1024             :         {
    1025           0 :             const long      nNewWidth1 = nNewWidth - 1L;
    1026           0 :             const long      nWidth1 = pReadAcc->Width() - 1L;
    1027           0 :             const double    fRevScaleX = (double) nWidth1 / nNewWidth1;
    1028             : 
    1029           0 :             pLutInt = new long[ nNewWidth ];
    1030           0 :             pLutFrac = new long[ nNewWidth ];
    1031             : 
    1032           0 :             for( nX = 0L, nTemp = nWidth - 2L; nX < nNewWidth; nX++ )
    1033             :             {
    1034           0 :                 fTemp = nX * fRevScaleX;
    1035           0 :                 pLutInt[ nX ] = MinMax( (long) fTemp, 0, nTemp );
    1036           0 :                 fTemp -= pLutInt[ nX ];
    1037           0 :                 pLutFrac[ nX ] = (long) ( fTemp * 1024. );
    1038             :             }
    1039             : 
    1040           0 :             if( pReadAcc->HasPalette() )
    1041             :             {
    1042           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    1043             :                 {
    1044           0 :                     if( 1 == nWidth )
    1045             :                     {
    1046           0 :                         aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, 0 ) );
    1047             : 
    1048           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
    1049           0 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1050             :                     }
    1051             :                     else
    1052             :                     {
    1053           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
    1054             :                         {
    1055           0 :                             nTemp = pLutInt[ nX ];
    1056             : 
    1057           0 :                             aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nTemp++ ) );
    1058           0 :                             aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nTemp ) );
    1059             : 
    1060           0 :                             nTemp = pLutFrac[ nX ];
    1061             : 
    1062           0 :                             lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1063           0 :                             lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1064           0 :                             lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1065             : 
    1066           0 :                             aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1067           0 :                             aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1068           0 :                             aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1069             : 
    1070           0 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1071             :                         }
    1072             :                     }
    1073             :                 }
    1074             :             }
    1075             :             else
    1076             :             {
    1077           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    1078             :                 {
    1079           0 :                     if( 1 == nWidth )
    1080             :                     {
    1081           0 :                         aCol0 = pReadAcc->GetPixel( nY, 0 );
    1082             : 
    1083           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
    1084           0 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1085             :                     }
    1086             :                     else
    1087             :                     {
    1088           0 :                         for( nX = 0L; nX < nNewWidth; nX++ )
    1089             :                         {
    1090           0 :                             nTemp = pLutInt[ nX ];
    1091             : 
    1092           0 :                             aCol0 = pReadAcc->GetPixel( nY, nTemp++ );
    1093           0 :                             aCol1 = pReadAcc->GetPixel( nY, nTemp );
    1094             : 
    1095           0 :                             nTemp = pLutFrac[ nX ];
    1096             : 
    1097           0 :                             lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1098           0 :                             lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1099           0 :                             lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1100             : 
    1101           0 :                             aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1102           0 :                             aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1103           0 :                             aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1104             : 
    1105           0 :                             pWriteAcc->SetPixel( nY, nX, aCol0 );
    1106             :                         }
    1107             :                     }
    1108             :                 }
    1109             :             }
    1110             : 
    1111           0 :             delete[] pLutInt;
    1112           0 :             delete[] pLutFrac;
    1113           0 :             bRet = sal_True;
    1114             :         }
    1115             : 
    1116           0 :         ReleaseAccess( pReadAcc );
    1117           0 :         aNewBmp.ReleaseAccess( pWriteAcc );
    1118             : 
    1119           0 :         if( bRet )
    1120             :         {
    1121           0 :             bRet = sal_False;
    1122           0 :             ImplAssignWithSize( aNewBmp );
    1123           0 :             pReadAcc = AcquireReadAccess();
    1124           0 :             aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 );
    1125           0 :             pWriteAcc = aNewBmp.AcquireWriteAccess();
    1126             : 
    1127           0 :             if( pReadAcc && pWriteAcc )
    1128             :             {
    1129           0 :                 const long      nNewHeight1 = nNewHeight - 1L;
    1130           0 :                 const long      nHeight1 = pReadAcc->Height() - 1L;
    1131           0 :                 const double    fRevScaleY = (double) nHeight1 / nNewHeight1;
    1132             : 
    1133           0 :                 pLutInt = new long[ nNewHeight ];
    1134           0 :                 pLutFrac = new long[ nNewHeight ];
    1135             : 
    1136           0 :                 for( nY = 0L, nTemp = nHeight - 2L; nY < nNewHeight; nY++ )
    1137             :                 {
    1138           0 :                     fTemp = nY * fRevScaleY;
    1139           0 :                     pLutInt[ nY ] = MinMax( (long) fTemp, 0, nTemp );
    1140           0 :                     fTemp -= pLutInt[ nY ];
    1141           0 :                     pLutFrac[ nY ] = (long) ( fTemp * 1024. );
    1142             :                 }
    1143             : 
    1144           0 :                 if( pReadAcc->HasPalette() )
    1145             :                 {
    1146           0 :                     for( nX = 0L; nX < nNewWidth; nX++ )
    1147             :                     {
    1148           0 :                         if( 1 == nHeight )
    1149             :                         {
    1150           0 :                             aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( 0, nX ) );
    1151             : 
    1152           0 :                             for( nY = 0L; nY < nNewHeight; nY++ )
    1153           0 :                                 pWriteAcc->SetPixel( nY, nX, aCol0 );
    1154             :                         }
    1155             :                         else
    1156             :                         {
    1157           0 :                             for( nY = 0L; nY < nNewHeight; nY++ )
    1158             :                             {
    1159           0 :                                 nTemp = pLutInt[ nY ];
    1160             : 
    1161           0 :                                 aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nTemp++, nX ) );
    1162           0 :                                 aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nTemp, nX ) );
    1163             : 
    1164           0 :                                 nTemp = pLutFrac[ nY ];
    1165             : 
    1166           0 :                                 lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1167           0 :                                 lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1168           0 :                                 lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1169             : 
    1170           0 :                                 aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1171           0 :                                 aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1172           0 :                                 aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1173             : 
    1174           0 :                                 pWriteAcc->SetPixel( nY, nX, aCol0 );
    1175             :                             }
    1176             :                         }
    1177             :                     }
    1178             :                 }
    1179             :                 else
    1180             :                 {
    1181           0 :                     for( nX = 0L; nX < nNewWidth; nX++ )
    1182             :                     {
    1183           0 :                         if( 1 == nHeight )
    1184             :                         {
    1185           0 :                             aCol0 = pReadAcc->GetPixel( 0, nX );
    1186             : 
    1187           0 :                             for( nY = 0L; nY < nNewHeight; nY++ )
    1188           0 :                                 pWriteAcc->SetPixel( nY, nX, aCol0 );
    1189             :                         }
    1190             :                         else
    1191             :                         {
    1192           0 :                             for( nY = 0L; nY < nNewHeight; nY++ )
    1193             :                             {
    1194           0 :                                 nTemp = pLutInt[ nY ];
    1195             : 
    1196           0 :                                 aCol0 = pReadAcc->GetPixel( nTemp++, nX );
    1197           0 :                                 aCol1 = pReadAcc->GetPixel( nTemp, nX );
    1198             : 
    1199           0 :                                 nTemp = pLutFrac[ nY ];
    1200             : 
    1201           0 :                                 lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() );
    1202           0 :                                 lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() );
    1203           0 :                                 lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() );
    1204             : 
    1205           0 :                                 aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) );
    1206           0 :                                 aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) );
    1207           0 :                                 aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) );
    1208             : 
    1209           0 :                                 pWriteAcc->SetPixel( nY, nX, aCol0 );
    1210             :                             }
    1211             :                         }
    1212             :                     }
    1213             :                 }
    1214             : 
    1215           0 :                 delete[] pLutInt;
    1216           0 :                 delete[] pLutFrac;
    1217           0 :                 bRet = sal_True;
    1218             :             }
    1219             : 
    1220           0 :             ReleaseAccess( pReadAcc );
    1221           0 :             aNewBmp.ReleaseAccess( pWriteAcc );
    1222             : 
    1223           0 :             if( bRet )
    1224           0 :                 ImplAssignWithSize( aNewBmp );
    1225           0 :         }
    1226             :     }
    1227             : 
    1228           0 :     if( !bRet )
    1229           0 :         bRet = ImplScaleFast( rScaleX, rScaleY );
    1230             : 
    1231           0 :     return bRet;
    1232             : }
    1233             : 
    1234           0 : sal_Bool Bitmap::Dither( sal_uLong nDitherFlags )
    1235             : {
    1236           0 :     sal_Bool bRet = sal_False;
    1237             : 
    1238           0 :     const Size aSizePix( GetSizePixel() );
    1239             : 
    1240           0 :     if( aSizePix.Width() == 1 || aSizePix.Height() == 1 )
    1241           0 :         bRet = sal_True;
    1242           0 :     else if( nDitherFlags & BMP_DITHER_MATRIX )
    1243           0 :         bRet = ImplDitherMatrix();
    1244           0 :     else if( nDitherFlags & BMP_DITHER_FLOYD )
    1245           0 :         bRet = ImplDitherFloyd();
    1246           0 :     else if( ( nDitherFlags & BMP_DITHER_FLOYD_16 ) && ( GetBitCount() == 24 ) )
    1247           0 :         bRet = ImplDitherFloyd16();
    1248             : 
    1249           0 :     return bRet;
    1250             : }
    1251             : 
    1252           0 : sal_Bool Bitmap::ImplDitherMatrix()
    1253             : {
    1254           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1255           0 :     Bitmap              aNewBmp( GetSizePixel(), 8 );
    1256           0 :     BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1257           0 :     sal_Bool                bRet = sal_False;
    1258             : 
    1259           0 :     if( pReadAcc && pWriteAcc )
    1260             :     {
    1261           0 :         const sal_uLong nWidth = pReadAcc->Width();
    1262           0 :         const sal_uLong nHeight = pReadAcc->Height();
    1263           0 :         BitmapColor aIndex( (sal_uInt8) 0 );
    1264             : 
    1265           0 :         if( pReadAcc->HasPalette() )
    1266             :         {
    1267           0 :             for( sal_uLong nY = 0UL; nY < nHeight; nY++ )
    1268             :             {
    1269           0 :                 for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
    1270             :                 {
    1271           0 :                     const BitmapColor   aCol( pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nX ) ) );
    1272           0 :                     const sal_uLong         nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
    1273           0 :                     const sal_uLong         nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
    1274           0 :                     const sal_uLong         nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
    1275           0 :                     const sal_uLong         nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
    1276             : 
    1277           0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
    1278           0 :                     pWriteAcc->SetPixel( nY, nX, aIndex );
    1279           0 :                 }
    1280             :             }
    1281             :         }
    1282             :         else
    1283             :         {
    1284           0 :             for( sal_uLong nY = 0UL; nY < nHeight; nY++ )
    1285             :             {
    1286           0 :                 for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ )
    1287             :                 {
    1288           0 :                     const BitmapColor   aCol( pReadAcc->GetPixel( nY, nX ) );
    1289           0 :                     const sal_uLong         nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ];
    1290           0 :                     const sal_uLong         nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL;
    1291           0 :                     const sal_uLong         nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL;
    1292           0 :                     const sal_uLong         nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL;
    1293             : 
    1294           0 :                     aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) );
    1295           0 :                     pWriteAcc->SetPixel( nY, nX, aIndex );
    1296           0 :                 }
    1297             :             }
    1298             :         }
    1299             : 
    1300           0 :         bRet = sal_True;
    1301             :     }
    1302             : 
    1303           0 :     ReleaseAccess( pReadAcc );
    1304           0 :     aNewBmp.ReleaseAccess( pWriteAcc );
    1305             : 
    1306           0 :     if( bRet )
    1307             :     {
    1308           0 :         const MapMode   aMap( maPrefMapMode );
    1309           0 :         const Size      aSize( maPrefSize );
    1310             : 
    1311           0 :         *this = aNewBmp;
    1312             : 
    1313           0 :         maPrefMapMode = aMap;
    1314           0 :         maPrefSize = aSize;
    1315             :     }
    1316             : 
    1317           0 :     return bRet;
    1318             : }
    1319             : 
    1320           0 : sal_Bool Bitmap::ImplDitherFloyd()
    1321             : {
    1322           0 :     const Size  aSize( GetSizePixel() );
    1323           0 :     sal_Bool        bRet = sal_False;
    1324             : 
    1325           0 :     if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) )
    1326             :     {
    1327           0 :         BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1328           0 :         Bitmap              aNewBmp( GetSizePixel(), 8 );
    1329           0 :         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1330             : 
    1331           0 :         if( pReadAcc && pWriteAcc )
    1332             :         {
    1333           0 :             BitmapColor aColor;
    1334           0 :             long        nWidth = pReadAcc->Width();
    1335           0 :             long        nWidth1 = nWidth - 1L;
    1336           0 :             long        nHeight = pReadAcc->Height();
    1337             :             long        nX;
    1338           0 :             long        nW = nWidth * 3L;
    1339           0 :             long        nW2 = nW - 3L;
    1340             :             long        nRErr, nGErr, nBErr;
    1341             :             long        nRC, nGC, nBC;
    1342             :             long        nTemp;
    1343             :             long        nZ;
    1344           0 :             long*       p1 = new long[ nW ];
    1345           0 :             long*       p2 = new long[ nW ];
    1346           0 :             long*       p1T = p1;
    1347           0 :             long*       p2T = p2;
    1348             :             long*       pTmp;
    1349           0 :             sal_Bool        bPal = pReadAcc->HasPalette();
    1350             : 
    1351           0 :             pTmp = p2T;
    1352             : 
    1353           0 :             if( bPal )
    1354             :             {
    1355           0 :                 for( nZ = 0; nZ < nWidth; nZ++ )
    1356             :                 {
    1357           0 :                     aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( 0, nZ ) );
    1358             : 
    1359           0 :                     *pTmp++ = (long) aColor.GetBlue() << 12;
    1360           0 :                     *pTmp++ = (long) aColor.GetGreen() << 12;
    1361           0 :                     *pTmp++ = (long) aColor.GetRed() << 12;
    1362             :                 }
    1363             :             }
    1364             :             else
    1365             :             {
    1366           0 :                 for( nZ = 0; nZ < nWidth; nZ++ )
    1367             :                 {
    1368           0 :                     aColor = pReadAcc->GetPixel( 0, nZ );
    1369             : 
    1370           0 :                     *pTmp++ = (long) aColor.GetBlue() << 12;
    1371           0 :                     *pTmp++ = (long) aColor.GetGreen() << 12;
    1372           0 :                     *pTmp++ = (long) aColor.GetRed() << 12;
    1373             :                 }
    1374             :             }
    1375             : 
    1376           0 :             for( long nY = 1, nYAcc = 0L; nY <= nHeight; nY++, nYAcc++ )
    1377             :             {
    1378           0 :                 pTmp = p1T;
    1379           0 :                 p1T = p2T;
    1380           0 :                 p2T = pTmp;
    1381             : 
    1382           0 :                 if( nY < nHeight )
    1383             :                 {
    1384           0 :                     if( bPal )
    1385             :                     {
    1386           0 :                         for( nZ = 0; nZ < nWidth; nZ++ )
    1387             :                         {
    1388           0 :                             aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixel( nY, nZ ) );
    1389             : 
    1390           0 :                             *pTmp++ = (long) aColor.GetBlue() << 12;
    1391           0 :                             *pTmp++ = (long) aColor.GetGreen() << 12;
    1392           0 :                             *pTmp++ = (long) aColor.GetRed() << 12;
    1393             :                         }
    1394             :                     }
    1395             :                     else
    1396             :                     {
    1397           0 :                         for( nZ = 0; nZ < nWidth; nZ++ )
    1398             :                         {
    1399           0 :                             aColor = pReadAcc->GetPixel( nY, nZ );
    1400             : 
    1401           0 :                             *pTmp++ = (long) aColor.GetBlue() << 12;
    1402           0 :                             *pTmp++ = (long) aColor.GetGreen() << 12;
    1403           0 :                             *pTmp++ = (long) aColor.GetRed() << 12;
    1404             :                         }
    1405             :                     }
    1406             :                 }
    1407             : 
    1408             :                 // erstes Pixel gesondert betrachten
    1409           0 :                 nX = 0;
    1410           0 :                 CALC_ERRORS;
    1411           0 :                 CALC_TABLES7;
    1412           0 :                 nX -= 5;
    1413           0 :                 CALC_TABLES5;
    1414           0 :                 pWriteAcc->SetPixel( nYAcc, 0, BitmapColor( (sal_uInt8) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
    1415             : 
    1416             :                 // mittlere Pixel ueber Schleife
    1417             :                 long nXAcc;
    1418           0 :                 for ( nX = 3L, nXAcc = 1L; nX < nW2; nXAcc++ )
    1419             :                 {
    1420           0 :                     CALC_ERRORS;
    1421           0 :                     CALC_TABLES7;
    1422           0 :                     nX -= 8;
    1423           0 :                     CALC_TABLES3;
    1424           0 :                     CALC_TABLES5;
    1425           0 :                     pWriteAcc->SetPixel( nYAcc, nXAcc, BitmapColor( (sal_uInt8) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
    1426             :                 }
    1427             : 
    1428             :                 // letztes Pixel gesondert betrachten
    1429           0 :                 CALC_ERRORS;
    1430           0 :                 nX -= 5;
    1431           0 :                 CALC_TABLES3;
    1432           0 :                 CALC_TABLES5;
    1433           0 :                 pWriteAcc->SetPixel( nYAcc, nWidth1, BitmapColor( (sal_uInt8) ( nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ] ) ) );
    1434             :             }
    1435             : 
    1436           0 :             delete[] p1;
    1437           0 :             delete[] p2;
    1438           0 :             bRet = sal_True;
    1439             :         }
    1440             : 
    1441           0 :         ReleaseAccess( pReadAcc );
    1442           0 :         aNewBmp.ReleaseAccess( pWriteAcc );
    1443             : 
    1444           0 :         if( bRet )
    1445             :         {
    1446           0 :             const MapMode   aMap( maPrefMapMode );
    1447           0 :             const Size      aPrefSize( maPrefSize );
    1448             : 
    1449           0 :             *this = aNewBmp;
    1450             : 
    1451           0 :             maPrefMapMode = aMap;
    1452           0 :             maPrefSize = aPrefSize;
    1453           0 :         }
    1454             :     }
    1455             : 
    1456           0 :     return bRet;
    1457             : }
    1458             : 
    1459           0 : sal_Bool Bitmap::ImplDitherFloyd16()
    1460             : {
    1461           0 :     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
    1462           0 :     Bitmap              aNewBmp( GetSizePixel(), 24 );
    1463           0 :     BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
    1464           0 :     sal_Bool                bRet = sal_False;
    1465             : 
    1466           0 :     if( pReadAcc && pWriteAcc )
    1467             :     {
    1468           0 :         const long      nWidth = pWriteAcc->Width();
    1469           0 :         const long      nWidth1 = nWidth - 1L;
    1470           0 :         const long      nHeight = pWriteAcc->Height();
    1471           0 :         BitmapColor     aColor;
    1472           0 :         BitmapColor     aBestCol;
    1473           0 :         ImpErrorQuad    aErrQuad;
    1474           0 :         ImpErrorQuad*   pErrQuad1 = new ImpErrorQuad[ nWidth ];
    1475           0 :         ImpErrorQuad*   pErrQuad2 = new ImpErrorQuad[ nWidth ];
    1476           0 :         ImpErrorQuad*   pQLine1 = pErrQuad1;
    1477           0 :         ImpErrorQuad*   pQLine2 = 0;
    1478             :         long            nX, nY;
    1479           0 :         long            nYTmp = 0L;
    1480           0 :         sal_Bool            bQ1 = sal_True;
    1481             : 
    1482           0 :         for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ )
    1483           0 :             for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ )
    1484           0 :                 pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
    1485             : 
    1486           0 :         for( nY = 0L; nY < nHeight; nY++, nYTmp++ )
    1487             :         {
    1488             :             // erstes ZeilenPixel
    1489           0 :             aBestCol = pQLine1[ 0 ].ImplGetColor();
    1490           0 :             aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
    1491           0 :             aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
    1492           0 :             aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
    1493           0 :             pWriteAcc->SetPixel( nY, 0, aBestCol );
    1494             : 
    1495           0 :             for( nX = 1L; nX < nWidth1; nX++ )
    1496             :             {
    1497           0 :                 aColor = pQLine1[ nX ].ImplGetColor();
    1498           0 :                 aBestCol.SetRed( ( aColor.GetRed() & 248 ) | 7 );
    1499           0 :                 aBestCol.SetGreen( ( aColor.GetGreen() & 248 ) | 7 );
    1500           0 :                 aBestCol.SetBlue( ( aColor.GetBlue() & 248 ) | 7 );
    1501           0 :                 aErrQuad = ( ImpErrorQuad( aColor ) -= aBestCol );
    1502           0 :                 pQLine1[ ++nX ].ImplAddColorError7( aErrQuad );
    1503           0 :                 pQLine2[ nX-- ].ImplAddColorError1( aErrQuad );
    1504           0 :                 pQLine2[ nX-- ].ImplAddColorError5( aErrQuad );
    1505           0 :                 pQLine2[ nX++ ].ImplAddColorError3( aErrQuad );
    1506           0 :                 pWriteAcc->SetPixel( nY, nX, aBestCol );
    1507             :             }
    1508             : 
    1509             :             // letztes ZeilenPixel
    1510           0 :             aBestCol = pQLine1[ nWidth1 ].ImplGetColor();
    1511           0 :             aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 );
    1512           0 :             aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 );
    1513           0 :             aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 );
    1514           0 :             pWriteAcc->SetPixel( nY, nX, aBestCol );
    1515             : 
    1516             :             // Zeilenpuffer neu fuellen/kopieren
    1517           0 :             pQLine1 = pQLine2;
    1518           0 :             pQLine2 = ( bQ1 = !bQ1 ) != sal_False ? pErrQuad2 : pErrQuad1;
    1519             : 
    1520           0 :             if( nYTmp < nHeight )
    1521           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    1522           0 :                     pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX );
    1523             :         }
    1524             : 
    1525             :         // Zeilenpuffer zerstoeren
    1526           0 :         delete[] pErrQuad1;
    1527           0 :         delete[] pErrQuad2;
    1528           0 :         bRet = sal_True;
    1529             :     }
    1530             : 
    1531           0 :     ReleaseAccess( pReadAcc );
    1532           0 :     aNewBmp.ReleaseAccess( pWriteAcc );
    1533             : 
    1534           0 :     if( bRet )
    1535             :     {
    1536           0 :         const MapMode   aMap( maPrefMapMode );
    1537           0 :         const Size      aSize( maPrefSize );
    1538             : 
    1539           0 :         *this = aNewBmp;
    1540             : 
    1541           0 :         maPrefMapMode = aMap;
    1542           0 :         maPrefSize = aSize;
    1543             :     }
    1544             : 
    1545           0 :     return bRet;
    1546             : }
    1547             : 
    1548           0 : sal_Bool Bitmap::ReduceColors( sal_uInt16 nColorCount, BmpReduce eReduce )
    1549             : {
    1550             :     sal_Bool bRet;
    1551             : 
    1552           0 :     if( GetColorCount() <= (sal_uLong) nColorCount )
    1553           0 :         bRet = sal_True;
    1554           0 :     else if( nColorCount )
    1555             :     {
    1556           0 :         if( BMP_REDUCE_SIMPLE == eReduce )
    1557           0 :             bRet = ImplReduceSimple( nColorCount );
    1558           0 :         else if( BMP_REDUCE_POPULAR == eReduce )
    1559           0 :             bRet = ImplReducePopular( nColorCount );
    1560             :         else
    1561           0 :             bRet = ImplReduceMedian( nColorCount );
    1562             :     }
    1563             :     else
    1564           0 :         bRet = sal_False;
    1565             : 
    1566           0 :     return bRet;
    1567             : }
    1568             : 
    1569           0 : sal_Bool Bitmap::ImplReduceSimple( sal_uInt16 nColorCount )
    1570             : {
    1571           0 :     Bitmap              aNewBmp;
    1572           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    1573           0 :     const sal_uInt16        nColCount = Min( nColorCount, (sal_uInt16) 256 );
    1574             :     sal_uInt16              nBitCount;
    1575           0 :     sal_Bool                bRet = sal_False;
    1576             : 
    1577           0 :     if( nColCount <= 2 )
    1578           0 :         nBitCount = 1;
    1579           0 :     else if( nColCount <= 16 )
    1580           0 :         nBitCount = 4;
    1581             :     else
    1582           0 :         nBitCount = 8;
    1583             : 
    1584           0 :     if( pRAcc )
    1585             :     {
    1586           0 :         Octree                  aOct( *pRAcc, nColCount );
    1587           0 :         const BitmapPalette&    rPal = aOct.GetPalette();
    1588             :         BitmapWriteAccess*      pWAcc;
    1589             : 
    1590           0 :         aNewBmp = Bitmap( GetSizePixel(), nBitCount, &rPal );
    1591           0 :         pWAcc = aNewBmp.AcquireWriteAccess();
    1592             : 
    1593           0 :         if( pWAcc )
    1594             :         {
    1595           0 :             const long nWidth = pRAcc->Width();
    1596           0 :             const long nHeight = pRAcc->Height();
    1597             : 
    1598           0 :             if( pRAcc->HasPalette() )
    1599             :             {
    1600           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    1601           0 :                     for( long nX =0L; nX < nWidth; nX++ )
    1602           0 :                         pWAcc->SetPixel( nY, nX, (sal_uInt8) aOct.GetBestPaletteIndex( pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) ) ) );
    1603             :             }
    1604             :             else
    1605             :             {
    1606           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    1607           0 :                     for( long nX =0L; nX < nWidth; nX++ )
    1608           0 :                         pWAcc->SetPixel( nY, nX, (sal_uInt8) aOct.GetBestPaletteIndex( pRAcc->GetPixel( nY, nX ) ) );
    1609             :             }
    1610             : 
    1611           0 :             aNewBmp.ReleaseAccess( pWAcc );
    1612           0 :             bRet = sal_True;
    1613             :         }
    1614             : 
    1615           0 :         ReleaseAccess( pRAcc );
    1616             :     }
    1617             : 
    1618           0 :     if( bRet )
    1619             :     {
    1620           0 :         const MapMode   aMap( maPrefMapMode );
    1621           0 :         const Size      aSize( maPrefSize );
    1622             : 
    1623           0 :         *this = aNewBmp;
    1624           0 :         maPrefMapMode = aMap;
    1625           0 :         maPrefSize = aSize;
    1626             :     }
    1627             : 
    1628           0 :     return bRet;
    1629             : }
    1630             : 
    1631             : struct PopularColorCount
    1632             : {
    1633             :     sal_uInt32  mnIndex;
    1634             :     sal_uInt32  mnCount;
    1635             : };
    1636             : 
    1637           0 : extern "C" int SAL_CALL ImplPopularCmpFnc( const void* p1, const void* p2 )
    1638             : {
    1639             :     int nRet;
    1640             : 
    1641           0 :     if( ( (PopularColorCount*) p1 )->mnCount < ( (PopularColorCount*) p2 )->mnCount )
    1642           0 :         nRet = 1;
    1643           0 :     else if( ( (PopularColorCount*) p1 )->mnCount == ( (PopularColorCount*) p2 )->mnCount )
    1644           0 :         nRet = 0;
    1645             :     else
    1646           0 :         nRet = -1;
    1647             : 
    1648           0 :     return nRet;
    1649             : }
    1650             : 
    1651           0 : sal_Bool Bitmap::ImplReducePopular( sal_uInt16 nColCount )
    1652             : {
    1653           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    1654             :     sal_uInt16              nBitCount;
    1655           0 :     sal_Bool                bRet = sal_False;
    1656             : 
    1657           0 :     if( nColCount > 256 )
    1658           0 :         nColCount = 256;
    1659             : 
    1660           0 :     if( nColCount < 17 )
    1661           0 :         nBitCount = 4;
    1662             :     else
    1663           0 :         nBitCount = 8;
    1664             : 
    1665           0 :     if( pRAcc )
    1666             :     {
    1667           0 :         const sal_uInt32    nValidBits = 4;
    1668           0 :         const sal_uInt32    nRightShiftBits = 8 - nValidBits;
    1669           0 :         const sal_uInt32    nLeftShiftBits1 = nValidBits;
    1670           0 :         const sal_uInt32    nLeftShiftBits2 = nValidBits << 1;
    1671           0 :         const sal_uInt32    nColorsPerComponent = 1 << nValidBits;
    1672           0 :         const sal_uInt32    nColorOffset = 256 / nColorsPerComponent;
    1673           0 :         const sal_uInt32    nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent;
    1674           0 :         const long          nWidth = pRAcc->Width();
    1675           0 :         const long          nHeight = pRAcc->Height();
    1676           0 :         PopularColorCount*  pCountTable = new PopularColorCount[ nTotalColors ];
    1677             :         long                nX, nY, nR, nG, nB, nIndex;
    1678             : 
    1679           0 :         memset( pCountTable, 0, nTotalColors * sizeof( PopularColorCount ) );
    1680             : 
    1681           0 :         for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
    1682             :         {
    1683           0 :             for( nG = 0; nG < 256; nG += nColorOffset )
    1684             :             {
    1685           0 :                 for( nB = 0; nB < 256; nB += nColorOffset )
    1686             :                 {
    1687           0 :                     pCountTable[ nIndex ].mnIndex = nIndex;
    1688           0 :                     nIndex++;
    1689             :                 }
    1690             :             }
    1691             :         }
    1692             : 
    1693           0 :         if( pRAcc->HasPalette() )
    1694             :         {
    1695           0 :             for( nY = 0L; nY < nHeight; nY++ )
    1696             :             {
    1697           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    1698             :                 {
    1699           0 :                     const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
    1700           0 :                     pCountTable[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    1701           0 :                                  ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    1702           0 :                                  ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
    1703             :                 }
    1704             :             }
    1705             :         }
    1706             :         else
    1707             :         {
    1708           0 :             for( nY = 0L; nY < nHeight; nY++ )
    1709             :             {
    1710           0 :                 for( nX = 0L; nX < nWidth; nX++ )
    1711             :                 {
    1712           0 :                     const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    1713           0 :                     pCountTable[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    1714           0 :                                  ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    1715           0 :                                  ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++;
    1716           0 :                 }
    1717             :             }
    1718             :         }
    1719             : 
    1720           0 :         BitmapPalette aNewPal( nColCount );
    1721             : 
    1722           0 :         qsort( pCountTable, nTotalColors, sizeof( PopularColorCount ), ImplPopularCmpFnc );
    1723             : 
    1724           0 :         for( sal_uInt16 n = 0; n < nColCount; n++ )
    1725             :         {
    1726           0 :             const PopularColorCount& rPop = pCountTable[ n ];
    1727           0 :             aNewPal[ n ] = BitmapColor( (sal_uInt8) ( ( rPop.mnIndex >> nLeftShiftBits2 ) << nRightShiftBits ),
    1728             :                                         (sal_uInt8) ( ( ( rPop.mnIndex >> nLeftShiftBits1 ) & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ),
    1729           0 :                                         (sal_uInt8) ( ( rPop.mnIndex & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ) );
    1730             :         }
    1731             : 
    1732           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount, &aNewPal );
    1733           0 :         BitmapWriteAccess*  pWAcc = aNewBmp.AcquireWriteAccess();
    1734             : 
    1735           0 :         if( pWAcc )
    1736             :         {
    1737           0 :             BitmapColor aDstCol( (sal_uInt8) 0 );
    1738           0 :             sal_uInt8*      pIndexMap = new sal_uInt8[ nTotalColors ];
    1739             : 
    1740           0 :             for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset )
    1741           0 :                 for( nG = 0; nG < 256; nG += nColorOffset )
    1742           0 :                     for( nB = 0; nB < 256; nB += nColorOffset )
    1743           0 :                         pIndexMap[ nIndex++ ] = (sal_uInt8) aNewPal.GetBestIndex( BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB ) );
    1744             : 
    1745           0 :             if( pRAcc->HasPalette() )
    1746             :             {
    1747           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    1748             :                 {
    1749           0 :                     for( nX = 0L; nX < nWidth; nX++ )
    1750             :                     {
    1751           0 :                         const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
    1752           0 :                         aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    1753           0 :                                                      ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    1754           0 :                                                      ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ] );
    1755           0 :                         pWAcc->SetPixel( nY, nX, aDstCol );
    1756             :                     }
    1757             :                 }
    1758             :             }
    1759             :             else
    1760             :             {
    1761           0 :                 for( nY = 0L; nY < nHeight; nY++ )
    1762             :                 {
    1763           0 :                     for( nX = 0L; nX < nWidth; nX++ )
    1764             :                     {
    1765           0 :                         const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    1766           0 :                         aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) |
    1767           0 :                                                      ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) |
    1768           0 :                                                      ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ] );
    1769           0 :                         pWAcc->SetPixel( nY, nX, aDstCol );
    1770           0 :                     }
    1771             :                 }
    1772             :             }
    1773             : 
    1774           0 :             delete[] pIndexMap;
    1775           0 :             aNewBmp.ReleaseAccess( pWAcc );
    1776           0 :             bRet = sal_True;
    1777             :         }
    1778             : 
    1779           0 :         delete[] pCountTable;
    1780           0 :         ReleaseAccess( pRAcc );
    1781             : 
    1782           0 :         if( bRet )
    1783             :         {
    1784           0 :             const MapMode   aMap( maPrefMapMode );
    1785           0 :             const Size      aSize( maPrefSize );
    1786             : 
    1787           0 :             *this = aNewBmp;
    1788           0 :             maPrefMapMode = aMap;
    1789           0 :             maPrefSize = aSize;
    1790           0 :         }
    1791             :     }
    1792             : 
    1793           0 :     return bRet;
    1794             : }
    1795             : 
    1796           0 : sal_Bool Bitmap::ImplReduceMedian( sal_uInt16 nColCount )
    1797             : {
    1798           0 :     BitmapReadAccess*   pRAcc = AcquireReadAccess();
    1799             :     sal_uInt16              nBitCount;
    1800           0 :     sal_Bool                bRet = sal_False;
    1801             : 
    1802           0 :     if( nColCount < 17 )
    1803           0 :         nBitCount = 4;
    1804           0 :     else if( nColCount < 257 )
    1805           0 :         nBitCount = 8;
    1806             :     else
    1807             :     {
    1808             :         OSL_FAIL( "Bitmap::ImplReduceMedian(): invalid color count!" );
    1809           0 :         nBitCount = 8;
    1810           0 :         nColCount = 256;
    1811             :     }
    1812             : 
    1813           0 :     if( pRAcc )
    1814             :     {
    1815           0 :         Bitmap              aNewBmp( GetSizePixel(), nBitCount );
    1816           0 :         BitmapWriteAccess*  pWAcc = aNewBmp.AcquireWriteAccess();
    1817             : 
    1818           0 :         if( pWAcc )
    1819             :         {
    1820           0 :             const sal_uLong nSize = 32768UL * sizeof( sal_uLong );
    1821           0 :             sal_uLong*      pColBuf = (sal_uLong*) rtl_allocateMemory( nSize );
    1822           0 :             const long  nWidth = pWAcc->Width();
    1823           0 :             const long  nHeight = pWAcc->Height();
    1824           0 :             long        nIndex = 0L;
    1825             : 
    1826           0 :             memset( (HPBYTE) pColBuf, 0, nSize );
    1827             : 
    1828             :             // create Buffer
    1829           0 :             if( pRAcc->HasPalette() )
    1830             :             {
    1831           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    1832             :                 {
    1833           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
    1834             :                     {
    1835           0 :                         const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixel( nY, nX ) );
    1836           0 :                         pColBuf[ RGB15( rCol.GetRed() >> 3, rCol.GetGreen() >> 3, rCol.GetBlue() >> 3 ) ]++;
    1837             :                     }
    1838             :                 }
    1839             :             }
    1840             :             else
    1841             :             {
    1842           0 :                 for( long nY = 0L; nY < nHeight; nY++ )
    1843             :                 {
    1844           0 :                     for( long nX = 0L; nX < nWidth; nX++ )
    1845             :                     {
    1846           0 :                         const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) );
    1847           0 :                         pColBuf[ RGB15( aCol.GetRed() >> 3, aCol.GetGreen() >> 3, aCol.GetBlue() >> 3 ) ]++;
    1848           0 :                     }
    1849             :                 }
    1850             :             }
    1851             : 
    1852             :             // create palette via median cut
    1853           0 :             BitmapPalette aPal( pWAcc->GetPaletteEntryCount() );
    1854             :             ImplMedianCut( pColBuf, aPal, 0, 31, 0, 31, 0, 31,
    1855           0 :                            nColCount, nWidth * nHeight, nIndex );
    1856             : 
    1857             :             // do mapping of colors to palette
    1858           0 :             InverseColorMap aMap( aPal );
    1859           0 :             pWAcc->SetPalette( aPal );
    1860           0 :             for( long nY = 0L; nY < nHeight; nY++ )
    1861           0 :                 for( long nX = 0L; nX < nWidth; nX++ )
    1862           0 :                     pWAcc->SetPixel( nY, nX, (sal_uInt8) aMap.GetBestPaletteIndex( pRAcc->GetColor( nY, nX ) ) );
    1863             : 
    1864           0 :             rtl_freeMemory( pColBuf );
    1865           0 :             aNewBmp.ReleaseAccess( pWAcc );
    1866           0 :             bRet = sal_True;
    1867             :         }
    1868             : 
    1869           0 :         ReleaseAccess( pRAcc );
    1870             : 
    1871           0 :         if( bRet )
    1872             :         {
    1873           0 :             const MapMode   aMap( maPrefMapMode );
    1874           0 :             const Size      aSize( maPrefSize );
    1875             : 
    1876           0 :             *this = aNewBmp;
    1877           0 :             maPrefMapMode = aMap;
    1878           0 :             maPrefSize = aSize;
    1879           0 :         }
    1880             :     }
    1881             : 
    1882           0 :     return bRet;
    1883             : }
    1884             : 
    1885           0 : void Bitmap::ImplMedianCut( sal_uLong* pColBuf, BitmapPalette& rPal,
    1886             :                             long nR1, long nR2, long nG1, long nG2, long nB1, long nB2,
    1887             :                             long nColors, long nPixels, long& rIndex )
    1888             : {
    1889           0 :     if( !nPixels )
    1890           0 :         return;
    1891             : 
    1892           0 :     BitmapColor aCol;
    1893           0 :     const long  nRLen = nR2 - nR1;
    1894           0 :     const long  nGLen = nG2 - nG1;
    1895           0 :     const long  nBLen = nB2 - nB1;
    1896           0 :     sal_uLong*      pBuf = pColBuf;
    1897             : 
    1898           0 :     if( !nRLen && !nGLen && !nBLen )
    1899             :     {
    1900           0 :         if( pBuf[ RGB15( nR1, nG1, nB1 ) ] )
    1901             :         {
    1902           0 :             aCol.SetRed( (sal_uInt8) ( nR1 << 3 ) );
    1903           0 :             aCol.SetGreen( (sal_uInt8) ( nG1 << 3 ) );
    1904           0 :             aCol.SetBlue( (sal_uInt8) ( nB1 << 3 ) );
    1905           0 :             rPal[ (sal_uInt16) rIndex++ ] = aCol;
    1906             :         }
    1907             :     }
    1908             :     else
    1909             :     {
    1910           0 :         if( 1 == nColors || 1 == nPixels )
    1911             :         {
    1912           0 :             long nPixSum = 0, nRSum = 0, nGSum = 0, nBSum = 0;
    1913             : 
    1914           0 :             for( long nR = nR1; nR <= nR2; nR++ )
    1915             :             {
    1916           0 :                 for( long nG = nG1; nG <= nG2; nG++ )
    1917             :                 {
    1918           0 :                     for( long nB = nB1; nB <= nB2; nB++ )
    1919             :                     {
    1920           0 :                         nPixSum = pBuf[ RGB15( nR, nG, nB ) ];
    1921             : 
    1922           0 :                         if( nPixSum )
    1923             :                         {
    1924           0 :                             nRSum += nR * nPixSum;
    1925           0 :                             nGSum += nG * nPixSum;
    1926           0 :                             nBSum += nB * nPixSum;
    1927             :                         }
    1928             :                     }
    1929             :                 }
    1930             :             }
    1931             : 
    1932           0 :             aCol.SetRed( (sal_uInt8) ( ( nRSum / nPixels ) << 3 ) );
    1933           0 :             aCol.SetGreen( (sal_uInt8) ( ( nGSum / nPixels ) << 3 ) );
    1934           0 :             aCol.SetBlue( (sal_uInt8) ( ( nBSum / nPixels ) << 3 ) );
    1935           0 :             rPal[ (sal_uInt16) rIndex++ ] = aCol;
    1936             :         }
    1937             :         else
    1938             :         {
    1939           0 :             const long  nTest = ( nPixels >> 1 );
    1940           0 :             long        nPixOld = 0;
    1941           0 :             long        nPixNew = 0;
    1942             : 
    1943           0 :             if( nBLen > nGLen && nBLen > nRLen )
    1944             :             {
    1945           0 :                 long nB = nB1 - 1;
    1946             : 
    1947           0 :                 while( nPixNew < nTest )
    1948             :                 {
    1949           0 :                     nB++, nPixOld = nPixNew;
    1950           0 :                     for( long nR = nR1; nR <= nR2; nR++ )
    1951           0 :                         for( long nG = nG1; nG <= nG2; nG++ )
    1952           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    1953             :                 }
    1954             : 
    1955           0 :                 if( nB < nB2 )
    1956             :                 {
    1957           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB, nColors >> 1, nPixNew, rIndex );
    1958           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB + 1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    1959             :                 }
    1960             :                 else
    1961             :                 {
    1962           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB - 1, nColors >> 1, nPixOld, rIndex );
    1963           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    1964           0 :                 }
    1965             :             }
    1966           0 :             else if( nGLen > nRLen )
    1967             :             {
    1968           0 :                 long nG = nG1 - 1;
    1969             : 
    1970           0 :                 while( nPixNew < nTest )
    1971             :                 {
    1972           0 :                     nG++, nPixOld = nPixNew;
    1973           0 :                     for( long nR = nR1; nR <= nR2; nR++ )
    1974           0 :                         for( long nB = nB1; nB <= nB2; nB++ )
    1975           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    1976             :                 }
    1977             : 
    1978           0 :                 if( nG < nG2 )
    1979             :                 {
    1980           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG, nB1, nB2, nColors >> 1, nPixNew, rIndex );
    1981           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG + 1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    1982             :                 }
    1983             :                 else
    1984             :                 {
    1985           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG - 1, nB1, nB2, nColors >> 1, nPixOld, rIndex );
    1986           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR2, nG, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    1987             :                 }
    1988             :             }
    1989             :             else
    1990             :             {
    1991           0 :                 long nR = nR1 - 1;
    1992             : 
    1993           0 :                 while( nPixNew < nTest )
    1994             :                 {
    1995           0 :                     nR++, nPixOld = nPixNew;
    1996           0 :                     for( long nG = nG1; nG <= nG2; nG++ )
    1997           0 :                         for( long nB = nB1; nB <= nB2; nB++ )
    1998           0 :                             nPixNew += pBuf[ RGB15( nR, nG, nB ) ];
    1999             :                 }
    2000             : 
    2001           0 :                 if( nR < nR2 )
    2002             :                 {
    2003           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR, nG1, nG2, nB1, nB2, nColors >> 1, nPixNew, rIndex );
    2004           0 :                     ImplMedianCut( pBuf, rPal, nR1 + 1, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex );
    2005             :                 }
    2006             :                 else
    2007             :                 {
    2008           0 :                     ImplMedianCut( pBuf, rPal, nR1, nR - 1, nG1, nG2, nB1, nB2, nColors >> 1, nPixOld, rIndex );
    2009           0 :                     ImplMedianCut( pBuf, rPal, nR, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex );
    2010             :                 }
    2011             :             }
    2012             :         }
    2013           0 :     }
    2014             : }
    2015             : 
    2016          35 : sal_Bool Bitmap::Vectorize( PolyPolygon& rPolyPoly, sal_uLong nFlags, const Link* pProgress )
    2017             : {
    2018          35 :     return ImplVectorizer().ImplVectorize( *this, rPolyPoly, nFlags, pProgress );
    2019             : }
    2020             : 
    2021           0 : sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFlags, const Link* pProgress )
    2022             : {
    2023           0 :     return ImplVectorizer().ImplVectorize( *this, rMtf, cReduce, nFlags, pProgress );
    2024             : }
    2025             : 
    2026           0 : sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent,
    2027             :                      short nChannelRPercent, short nChannelGPercent, short nChannelBPercent,
    2028             :                      double fGamma, sal_Bool bInvert )
    2029             : {
    2030           0 :     sal_Bool bRet = sal_False;
    2031             : 
    2032             :     // nothing to do => return quickly
    2033           0 :     if( !nLuminancePercent && !nContrastPercent &&
    2034             :         !nChannelRPercent && !nChannelGPercent && !nChannelBPercent &&
    2035             :         ( fGamma == 1.0 ) && !bInvert )
    2036             :     {
    2037           0 :         bRet = sal_True;
    2038             :     }
    2039             :     else
    2040             :     {
    2041           0 :         BitmapWriteAccess* pAcc = AcquireWriteAccess();
    2042             : 
    2043           0 :         if( pAcc )
    2044             :         {
    2045           0 :             BitmapColor     aCol;
    2046           0 :             const long      nW = pAcc->Width();
    2047           0 :             const long      nH = pAcc->Height();
    2048           0 :             sal_uInt8*          cMapR = new sal_uInt8[ 256 ];
    2049           0 :             sal_uInt8*          cMapG = new sal_uInt8[ 256 ];
    2050           0 :             sal_uInt8*          cMapB = new sal_uInt8[ 256 ];
    2051             :             long            nX, nY;
    2052             :             double          fM, fROff, fGOff, fBOff, fOff;
    2053             : 
    2054             :             // calculate slope
    2055           0 :             if( nContrastPercent >= 0 )
    2056           0 :                 fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) );
    2057             :             else
    2058           0 :                 fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0;
    2059             : 
    2060             :             // total offset = luminance offset + contrast offset
    2061           0 :             fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0;
    2062             : 
    2063             :             // channel offset = channel offset  + total offset
    2064           0 :             fROff = nChannelRPercent * 2.55 + fOff;
    2065           0 :             fGOff = nChannelGPercent * 2.55 + fOff;
    2066           0 :             fBOff = nChannelBPercent * 2.55 + fOff;
    2067             : 
    2068             :             // calculate gamma value
    2069           0 :             fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma );
    2070           0 :             const sal_Bool bGamma = ( fGamma != 1.0 );
    2071             : 
    2072             :             // create mapping table
    2073           0 :             for( nX = 0L; nX < 256L; nX++ )
    2074             :             {
    2075           0 :                 cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L );
    2076           0 :                 cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L );
    2077           0 :                 cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L );
    2078             : 
    2079           0 :                 if( bGamma )
    2080             :                 {
    2081           0 :                     cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma );
    2082           0 :                     cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma );
    2083           0 :                     cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma );
    2084             :                 }
    2085             : 
    2086           0 :                 if( bInvert )
    2087             :                 {
    2088           0 :                     cMapR[ nX ] = ~cMapR[ nX ];
    2089           0 :                     cMapG[ nX ] = ~cMapG[ nX ];
    2090           0 :                     cMapB[ nX ] = ~cMapB[ nX ];
    2091             :                 }
    2092             :             }
    2093             : 
    2094             :             // do modifying
    2095           0 :             if( pAcc->HasPalette() )
    2096             :             {
    2097           0 :                 BitmapColor aNewCol;
    2098             : 
    2099           0 :                 for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ )
    2100             :                 {
    2101           0 :                     const BitmapColor& rCol = pAcc->GetPaletteColor( i );
    2102           0 :                     aNewCol.SetRed( cMapR[ rCol.GetRed() ] );
    2103           0 :                     aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] );
    2104           0 :                     aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] );
    2105           0 :                     pAcc->SetPaletteColor( i, aNewCol );
    2106           0 :                 }
    2107             :             }
    2108           0 :             else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR )
    2109             :             {
    2110           0 :                 for( nY = 0L; nY < nH; nY++ )
    2111             :                 {
    2112           0 :                     Scanline pScan = pAcc->GetScanline( nY );
    2113             : 
    2114           0 :                     for( nX = 0L; nX < nW; nX++ )
    2115             :                     {
    2116           0 :                         *pScan = cMapB[ *pScan ]; pScan++;
    2117           0 :                         *pScan = cMapG[ *pScan ]; pScan++;
    2118           0 :                         *pScan = cMapR[ *pScan ]; pScan++;
    2119             :                     }
    2120             :                 }
    2121             :             }
    2122           0 :             else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB )
    2123             :             {
    2124           0 :                 for( nY = 0L; nY < nH; nY++ )
    2125             :                 {
    2126           0 :                     Scanline pScan = pAcc->GetScanline( nY );
    2127             : 
    2128           0 :                     for( nX = 0L; nX < nW; nX++ )
    2129             :                     {
    2130           0 :                         *pScan = cMapR[ *pScan ]; pScan++;
    2131           0 :                         *pScan = cMapG[ *pScan ]; pScan++;
    2132           0 :                         *pScan = cMapB[ *pScan ]; pScan++;
    2133             :                     }
    2134             :                 }
    2135             :             }
    2136             :             else
    2137             :             {
    2138           0 :                 for( nY = 0L; nY < nH; nY++ )
    2139             :                 {
    2140           0 :                     for( nX = 0L; nX < nW; nX++ )
    2141             :                     {
    2142           0 :                         aCol = pAcc->GetPixel( nY, nX );
    2143           0 :                         aCol.SetRed( cMapR[ aCol.GetRed() ] );
    2144           0 :                         aCol.SetGreen( cMapG[ aCol.GetGreen() ] );
    2145           0 :                         aCol.SetBlue( cMapB[ aCol.GetBlue() ] );
    2146           0 :                         pAcc->SetPixel( nY, nX, aCol );
    2147             :                     }
    2148             :                 }
    2149             :             }
    2150             : 
    2151           0 :             delete[] cMapR;
    2152           0 :             delete[] cMapG;
    2153           0 :             delete[] cMapB;
    2154           0 :             ReleaseAccess( pAcc );
    2155           0 :             bRet = sal_True;
    2156             :         }
    2157             :     }
    2158             : 
    2159           0 :     return bRet;
    2160             : }
    2161             : 
    2162           0 : bool Bitmap::ImplScaleConvolution( const double& rScaleX, const double& rScaleY, Kernel& aKernel )
    2163             : {
    2164           0 :     const long  nWidth = GetSizePixel().Width();
    2165           0 :     const long  nHeight = GetSizePixel().Height();
    2166           0 :     const long  nNewWidth = FRound( nWidth * rScaleX );
    2167           0 :     const long  nNewHeight = FRound( nHeight * rScaleY );
    2168             : 
    2169             :     bool bResult;
    2170             :     BitmapReadAccess* pReadAcc;
    2171           0 :     Bitmap aNewBitmap;
    2172             : 
    2173             :     int aNumberOfContributions;
    2174             :     double* pWeights;
    2175             :     int* pPixels;
    2176             :     int* pCount;
    2177             : 
    2178             :     // Handle negative scales safely cf. other ImplScale methods
    2179           0 :     if( ( nNewWidth < 1L ) || ( nNewHeight < 1L ) )
    2180           0 :         return false;
    2181             : 
    2182             :     // Do horizontal filtering
    2183           0 :     ImplCalculateContributions( nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
    2184           0 :     pReadAcc = AcquireReadAccess();
    2185           0 :     aNewBitmap = Bitmap( Size( nHeight, nNewWidth ), 24);
    2186           0 :     bResult = ImplConvolutionPass( aNewBitmap, nNewWidth, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
    2187             : 
    2188           0 :     ReleaseAccess( pReadAcc );
    2189           0 :     delete[] pWeights;
    2190           0 :     delete[] pCount;
    2191           0 :     delete[] pPixels;
    2192             : 
    2193           0 :     if ( !bResult )
    2194           0 :         return bResult;
    2195             : 
    2196             :     // Swap Bitmaps
    2197           0 :     ImplAssignWithSize( aNewBitmap );
    2198             : 
    2199             :     // Do vertical filtering
    2200           0 :     ImplCalculateContributions( nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel );
    2201           0 :     pReadAcc = AcquireReadAccess();
    2202           0 :     aNewBitmap = Bitmap( Size( nNewWidth, nNewHeight ), 24);
    2203           0 :     bResult = ImplConvolutionPass( aNewBitmap, nNewHeight, pReadAcc, aNumberOfContributions, pWeights, pPixels, pCount );
    2204             : 
    2205           0 :     ReleaseAccess( pReadAcc );
    2206           0 :     delete[] pWeights;
    2207           0 :     delete[] pCount;
    2208           0 :     delete[] pPixels;
    2209             : 
    2210           0 :     if ( !bResult )
    2211           0 :         return bResult;
    2212             : 
    2213           0 :     ImplAssignWithSize( aNewBitmap );
    2214             : 
    2215           0 :     return true;
    2216             : }
    2217             : 
    2218           0 : void Bitmap::ImplCalculateContributions( const int aSourceSize, const int aDestinationSize, int& aNumberOfContributions,
    2219             :                                             double*& pWeights, int*& pPixels, int*& pCount, Kernel& aKernel)
    2220             : {
    2221           0 :     const double aSamplingRadius = aKernel.GetWidth();
    2222           0 :     const double aScale = aDestinationSize / (double) aSourceSize;
    2223           0 :     const double aScaledRadius = (aScale < 1.0) ? aSamplingRadius / aScale : aSamplingRadius;
    2224           0 :     const double aFilterFactor = (aScale < 1.0) ? aScale : 1.0;
    2225             : 
    2226           0 :     aNumberOfContributions  = (int) ( 2 * ceil(aScaledRadius) + 1 );
    2227             : 
    2228           0 :     pWeights = new double[ aDestinationSize*aNumberOfContributions ];
    2229           0 :     pPixels = new int[ aDestinationSize*aNumberOfContributions ];
    2230           0 :     pCount = new int[ aDestinationSize ];
    2231             : 
    2232             :     double aWeight, aCenter;
    2233             :     int aIndex, aLeft, aRight;
    2234             :     int aPixelIndex, aCurrentCount;
    2235             : 
    2236           0 :     for ( int i = 0; i < aDestinationSize; i++ )
    2237             :     {
    2238           0 :         aIndex = i * aNumberOfContributions;
    2239           0 :         aCurrentCount = 0;
    2240           0 :         aCenter = i / aScale;
    2241             : 
    2242           0 :         aLeft  = (int) floor(aCenter - aScaledRadius);
    2243           0 :         aRight = (int) ceil (aCenter + aScaledRadius);
    2244             : 
    2245           0 :         for ( int j = aLeft; j <= aRight; j++ )
    2246             :         {
    2247           0 :             aWeight = aKernel.Calculate( aFilterFactor * ( aCenter - (double) j ) );
    2248             : 
    2249             :             // Reduce calculations with ignoring weights of 0.0
    2250           0 :             if (fabs(aWeight) < 0.0001)
    2251           0 :                 continue;
    2252             : 
    2253             :             // Handling on edges
    2254           0 :             aPixelIndex = MinMax( j, 0, aSourceSize - 1);
    2255             : 
    2256           0 :             pWeights[ aIndex + aCurrentCount ] = aWeight;
    2257           0 :             pPixels[ aIndex + aCurrentCount ] = aPixelIndex;
    2258             : 
    2259           0 :             aCurrentCount++;
    2260             :         }
    2261           0 :         pCount[ i ] = aCurrentCount;
    2262             :     }
    2263           0 : }
    2264             : 
    2265           0 : bool Bitmap::ImplConvolutionPass(Bitmap& aNewBitmap, const int nNewSize, BitmapReadAccess* pReadAcc, int aNumberOfContributions, double* pWeights, int* pPixels, int* pCount)
    2266             : {
    2267           0 :     BitmapWriteAccess* pWriteAcc = aNewBitmap.AcquireWriteAccess();
    2268             : 
    2269           0 :     if (!pReadAcc || !pWriteAcc)
    2270           0 :         return false;
    2271             : 
    2272           0 :     const int nHeight = GetSizePixel().Height();
    2273             : 
    2274           0 :     BitmapColor aColor;
    2275             :     double aValueRed, aValueGreen, aValueBlue;
    2276             :     double aSum, aWeight;
    2277             :     int aBaseIndex, aIndex;
    2278             : 
    2279           0 :     for ( int y = 0; y < nHeight; y++ )
    2280             :     {
    2281           0 :         for ( int x = 0; x < nNewSize; x++ )
    2282             :         {
    2283           0 :             aBaseIndex = x * aNumberOfContributions;
    2284           0 :             aSum = aValueRed = aValueGreen = aValueBlue = 0.0;
    2285             : 
    2286           0 :             for ( int j=0; j < pCount[x]; j++ )
    2287             :             {
    2288           0 :                 aIndex = aBaseIndex + j;
    2289           0 :                 aSum += aWeight = pWeights[ aIndex ];
    2290             : 
    2291           0 :                 aColor = pReadAcc->GetPixel( y, pPixels[ aIndex ] );
    2292           0 :                 if( pReadAcc->HasPalette() )
    2293           0 :                     aColor = pReadAcc->GetPaletteColor( aColor );
    2294             : 
    2295           0 :                 aValueRed   += aWeight * aColor.GetRed();
    2296           0 :                 aValueGreen += aWeight * aColor.GetGreen();
    2297           0 :                 aValueBlue  += aWeight * aColor.GetBlue();
    2298             :             }
    2299             : 
    2300             :             BitmapColor aResultColor(
    2301           0 :                 (sal_uInt8) MinMax( aValueRed   / aSum, 0, 255 ),
    2302           0 :                 (sal_uInt8) MinMax( aValueGreen / aSum, 0, 255 ),
    2303           0 :                 (sal_uInt8) MinMax( aValueBlue  / aSum, 0, 255 ) );
    2304           0 :             pWriteAcc->SetPixel( x, y, aResultColor );
    2305           0 :         }
    2306             :     }
    2307           0 :     aNewBitmap.ReleaseAccess( pWriteAcc );
    2308           0 :     return true;
    2309             : }
    2310             : 
    2311             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10