19f62ea84SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 39f62ea84SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 49f62ea84SAndrew Rist * or more contributor license agreements. See the NOTICE file 59f62ea84SAndrew Rist * distributed with this work for additional information 69f62ea84SAndrew Rist * regarding copyright ownership. The ASF licenses this file 79f62ea84SAndrew Rist * to you under the Apache License, Version 2.0 (the 89f62ea84SAndrew Rist * "License"); you may not use this file except in compliance 99f62ea84SAndrew Rist * with the License. You may obtain a copy of the License at 109f62ea84SAndrew Rist * 119f62ea84SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 129f62ea84SAndrew Rist * 139f62ea84SAndrew Rist * Unless required by applicable law or agreed to in writing, 149f62ea84SAndrew Rist * software distributed under the License is distributed on an 159f62ea84SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169f62ea84SAndrew Rist * KIND, either express or implied. See the License for the 179f62ea84SAndrew Rist * specific language governing permissions and limitations 189f62ea84SAndrew Rist * under the License. 199f62ea84SAndrew Rist * 209f62ea84SAndrew Rist *************************************************************/ 219f62ea84SAndrew Rist 229f62ea84SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_vcl.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <stdlib.h> 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <vcl/bmpacc.hxx> 30cdf0e10cSrcweir #include <vcl/octree.hxx> 31cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 32cdf0e10cSrcweir #include <vcl/bitmap.hxx> 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <impoct.hxx> 35cdf0e10cSrcweir #include <impvect.hxx> 36cdf0e10cSrcweir 37cdf0e10cSrcweir // ----------- 38cdf0e10cSrcweir // - Defines - 39cdf0e10cSrcweir // ----------- 40cdf0e10cSrcweir 41cdf0e10cSrcweir #define RGB15( _def_cR, _def_cG, _def_cB ) (((sal_uLong)(_def_cR)<<10UL)|((sal_uLong)(_def_cG)<<5UL)|(sal_uLong)(_def_cB)) 42cdf0e10cSrcweir #define GAMMA( _def_cVal, _def_InvGamma ) ((sal_uInt8)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L)) 4337ab0f2dSArmin Le Grand #define MAP( cVal0, cVal1, nFrac ) ((sal_uInt8)((((long)(cVal0)<<7L)+nFrac*((long)(cVal1)-(cVal0)))>>7L)) 44cdf0e10cSrcweir 45cdf0e10cSrcweir #define CALC_ERRORS \ 46cdf0e10cSrcweir nTemp = p1T[nX++] >> 12; \ 47cdf0e10cSrcweir nBErr = MinMax( nTemp, 0, 255 ); \ 48cdf0e10cSrcweir nBErr = nBErr - FloydIndexMap[ nBC = FloydMap[nBErr] ]; \ 49cdf0e10cSrcweir nTemp = p1T[nX++] >> 12; \ 50cdf0e10cSrcweir nGErr = MinMax( nTemp, 0, 255 ); \ 51cdf0e10cSrcweir nGErr = nGErr - FloydIndexMap[ nGC = FloydMap[nGErr] ]; \ 52cdf0e10cSrcweir nTemp = p1T[nX] >> 12; \ 53cdf0e10cSrcweir nRErr = MinMax( nTemp, 0, 255 ); \ 54cdf0e10cSrcweir nRErr = nRErr - FloydIndexMap[ nRC = FloydMap[nRErr] ]; 55cdf0e10cSrcweir 56cdf0e10cSrcweir #define CALC_TABLES3 \ 57cdf0e10cSrcweir p2T[nX++] += FloydError3[nBErr]; \ 58cdf0e10cSrcweir p2T[nX++] += FloydError3[nGErr]; \ 59cdf0e10cSrcweir p2T[nX++] += FloydError3[nRErr]; 60cdf0e10cSrcweir 61cdf0e10cSrcweir #define CALC_TABLES5 \ 62cdf0e10cSrcweir p2T[nX++] += FloydError5[nBErr]; \ 63cdf0e10cSrcweir p2T[nX++] += FloydError5[nGErr]; \ 64cdf0e10cSrcweir p2T[nX++] += FloydError5[nRErr]; 65cdf0e10cSrcweir 66cdf0e10cSrcweir #define CALC_TABLES7 \ 67cdf0e10cSrcweir p1T[++nX] += FloydError7[nBErr]; \ 68cdf0e10cSrcweir p2T[nX++] += FloydError1[nBErr]; \ 69cdf0e10cSrcweir p1T[nX] += FloydError7[nGErr]; \ 70cdf0e10cSrcweir p2T[nX++] += FloydError1[nGErr]; \ 71cdf0e10cSrcweir p1T[nX] += FloydError7[nRErr]; \ 72cdf0e10cSrcweir p2T[nX] += FloydError1[nRErr]; 73cdf0e10cSrcweir 74cdf0e10cSrcweir // ----------- 75cdf0e10cSrcweir // - Statics - 76cdf0e10cSrcweir // ----------- 77cdf0e10cSrcweir 78cdf0e10cSrcweir sal_uLong nVCLRLut[ 6 ] = { 16, 17, 18, 19, 20, 21 }; 79cdf0e10cSrcweir sal_uLong nVCLGLut[ 6 ] = { 0, 6, 12, 18, 24, 30 }; 80cdf0e10cSrcweir sal_uLong nVCLBLut[ 6 ] = { 0, 36, 72, 108, 144, 180 }; 81cdf0e10cSrcweir 82cdf0e10cSrcweir // ------------------------------------------------------------------------ 83cdf0e10cSrcweir 84cdf0e10cSrcweir sal_uLong nVCLDitherLut[ 256 ] = 85cdf0e10cSrcweir { 86cdf0e10cSrcweir 0, 49152, 12288, 61440, 3072, 52224, 15360, 64512, 768, 49920, 13056, 87cdf0e10cSrcweir 62208, 3840, 52992, 16128, 65280, 32768, 16384, 45056, 28672, 35840, 19456, 88cdf0e10cSrcweir 48128, 31744, 33536, 17152, 45824, 29440, 36608, 20224, 48896, 32512, 8192, 89cdf0e10cSrcweir 57344, 4096, 53248, 11264, 60416, 7168, 56320, 8960, 58112, 4864, 54016, 90cdf0e10cSrcweir 12032, 61184, 7936, 57088, 40960, 24576, 36864, 20480, 44032, 27648, 39936, 91cdf0e10cSrcweir 23552, 41728, 25344, 37632, 21248, 44800, 28416, 40704, 24320, 2048, 51200, 92cdf0e10cSrcweir 14336, 63488, 1024, 50176, 13312, 62464, 2816, 51968, 15104, 64256, 1792, 93cdf0e10cSrcweir 50944, 14080, 63232, 34816, 18432, 47104, 30720, 33792, 17408, 46080, 29696, 94cdf0e10cSrcweir 35584, 19200, 47872, 31488, 34560, 18176, 46848, 30464, 10240, 59392, 6144, 95cdf0e10cSrcweir 55296, 9216, 58368, 5120, 54272, 11008, 60160, 6912, 56064, 9984, 59136, 96cdf0e10cSrcweir 5888, 55040, 43008, 26624, 38912, 22528, 41984, 25600, 37888, 21504, 43776, 97cdf0e10cSrcweir 27392, 39680, 23296, 42752, 26368, 38656, 22272, 512, 49664, 12800, 61952, 98cdf0e10cSrcweir 3584, 52736, 15872, 65024, 256, 49408, 12544, 61696, 3328, 52480, 15616, 99cdf0e10cSrcweir 64768, 33280, 16896, 45568, 29184, 36352, 19968, 48640, 32256, 33024, 16640, 100cdf0e10cSrcweir 45312, 28928, 36096, 19712, 48384, 32000, 8704, 57856, 4608, 53760, 11776, 101cdf0e10cSrcweir 60928, 7680, 56832, 8448, 57600, 4352, 53504, 11520, 60672, 7424, 56576, 102cdf0e10cSrcweir 41472, 25088, 37376, 20992, 44544, 28160, 40448, 24064, 41216, 24832, 37120, 103cdf0e10cSrcweir 20736, 44288, 27904, 40192, 23808, 2560, 51712, 14848, 64000, 1536, 50688, 104cdf0e10cSrcweir 13824, 62976, 2304, 51456, 14592, 63744, 1280, 50432, 13568, 62720, 35328, 105cdf0e10cSrcweir 18944, 47616, 31232, 34304, 17920, 46592, 30208, 35072, 18688, 47360, 30976, 106cdf0e10cSrcweir 34048, 17664, 46336, 29952, 10752, 59904, 6656, 55808, 9728, 58880, 5632, 107cdf0e10cSrcweir 54784, 10496, 59648, 6400, 55552, 9472, 58624, 5376, 54528, 43520, 27136, 108cdf0e10cSrcweir 39424, 23040, 42496, 26112, 38400, 22016, 43264, 26880, 39168, 22784, 42240, 109cdf0e10cSrcweir 25856, 38144, 21760 110cdf0e10cSrcweir }; 111cdf0e10cSrcweir 112cdf0e10cSrcweir // ------------------------------------------------------------------------ 113cdf0e10cSrcweir 114cdf0e10cSrcweir sal_uLong nVCLLut[ 256 ] = 115cdf0e10cSrcweir { 116cdf0e10cSrcweir 0, 1286, 2572, 3858, 5144, 6430, 7716, 9002, 117cdf0e10cSrcweir 10288, 11574, 12860, 14146, 15432, 16718, 18004, 19290, 118cdf0e10cSrcweir 20576, 21862, 23148, 24434, 25720, 27006, 28292, 29578, 119cdf0e10cSrcweir 30864, 32150, 33436, 34722, 36008, 37294, 38580, 39866, 120cdf0e10cSrcweir 41152, 42438, 43724, 45010, 46296, 47582, 48868, 50154, 121cdf0e10cSrcweir 51440, 52726, 54012, 55298, 56584, 57870, 59156, 60442, 122cdf0e10cSrcweir 61728, 63014, 64300, 65586, 66872, 68158, 69444, 70730, 123cdf0e10cSrcweir 72016, 73302, 74588, 75874, 77160, 78446, 79732, 81018, 124cdf0e10cSrcweir 82304, 83590, 84876, 86162, 87448, 88734, 90020, 91306, 125cdf0e10cSrcweir 92592, 93878, 95164, 96450, 97736, 99022,100308,101594, 126cdf0e10cSrcweir 102880,104166,105452,106738,108024,109310,110596,111882, 127cdf0e10cSrcweir 113168,114454,115740,117026,118312,119598,120884,122170, 128cdf0e10cSrcweir 123456,124742,126028,127314,128600,129886,131172,132458, 129cdf0e10cSrcweir 133744,135030,136316,137602,138888,140174,141460,142746, 130cdf0e10cSrcweir 144032,145318,146604,147890,149176,150462,151748,153034, 131cdf0e10cSrcweir 154320,155606,156892,158178,159464,160750,162036,163322, 132cdf0e10cSrcweir 164608,165894,167180,168466,169752,171038,172324,173610, 133cdf0e10cSrcweir 174896,176182,177468,178754,180040,181326,182612,183898, 134cdf0e10cSrcweir 185184,186470,187756,189042,190328,191614,192900,194186, 135cdf0e10cSrcweir 195472,196758,198044,199330,200616,201902,203188,204474, 136cdf0e10cSrcweir 205760,207046,208332,209618,210904,212190,213476,214762, 137cdf0e10cSrcweir 216048,217334,218620,219906,221192,222478,223764,225050, 138cdf0e10cSrcweir 226336,227622,228908,230194,231480,232766,234052,235338, 139cdf0e10cSrcweir 236624,237910,239196,240482,241768,243054,244340,245626, 140cdf0e10cSrcweir 246912,248198,249484,250770,252056,253342,254628,255914, 141cdf0e10cSrcweir 257200,258486,259772,261058,262344,263630,264916,266202, 142cdf0e10cSrcweir 267488,268774,270060,271346,272632,273918,275204,276490, 143cdf0e10cSrcweir 277776,279062,280348,281634,282920,284206,285492,286778, 144cdf0e10cSrcweir 288064,289350,290636,291922,293208,294494,295780,297066, 145cdf0e10cSrcweir 298352,299638,300924,302210,303496,304782,306068,307354, 146cdf0e10cSrcweir 308640,309926,311212,312498,313784,315070,316356,317642, 147cdf0e10cSrcweir 318928,320214,321500,322786,324072,325358,326644,327930 148cdf0e10cSrcweir }; 149cdf0e10cSrcweir 150cdf0e10cSrcweir // ------------------------------------------------------------------------ 151cdf0e10cSrcweir 152cdf0e10cSrcweir long FloydMap[256] = 153cdf0e10cSrcweir { 154cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155cdf0e10cSrcweir 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 156cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 157cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 158cdf0e10cSrcweir 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 159cdf0e10cSrcweir 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 160cdf0e10cSrcweir 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 161cdf0e10cSrcweir 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 162cdf0e10cSrcweir 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 163cdf0e10cSrcweir 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 164cdf0e10cSrcweir 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 165cdf0e10cSrcweir 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 166cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 167cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 168cdf0e10cSrcweir 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 169cdf0e10cSrcweir 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 170cdf0e10cSrcweir }; 171cdf0e10cSrcweir 172cdf0e10cSrcweir // ------------------------------------------------------------------------ 173cdf0e10cSrcweir 174cdf0e10cSrcweir long FloydError1[61] = 175cdf0e10cSrcweir { 176cdf0e10cSrcweir -7680, -7424, -7168, -6912, -6656, -6400, -6144, 177cdf0e10cSrcweir -5888, -5632, -5376, -5120, -4864, -4608, -4352, 178cdf0e10cSrcweir -4096, -3840, -3584, -3328, -3072, -2816, -2560, 179cdf0e10cSrcweir -2304, -2048, -1792, -1536, -1280, -1024, -768, 180cdf0e10cSrcweir -512, -256, 0, 256, 512, 768, 1024, 1280, 1536, 181cdf0e10cSrcweir 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 182cdf0e10cSrcweir 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5632, 183cdf0e10cSrcweir 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680 184cdf0e10cSrcweir }; 185cdf0e10cSrcweir 186cdf0e10cSrcweir // ------------------------------------------------------------------------ 187cdf0e10cSrcweir 188cdf0e10cSrcweir long FloydError3[61] = 189cdf0e10cSrcweir { 190cdf0e10cSrcweir -23040, -22272, -21504, -20736, -19968, -19200, 191cdf0e10cSrcweir -18432, -17664, -16896, -16128, -15360, -14592, 192cdf0e10cSrcweir -13824, -13056, -12288, -11520, -10752, -9984, 193cdf0e10cSrcweir -9216, -8448, -7680, -6912, -6144, -5376, -4608, 194cdf0e10cSrcweir -3840, -3072, -2304, -1536, -768, 0, 768, 1536, 195cdf0e10cSrcweir 2304, 3072, 3840, 4608, 5376, 6144, 6912, 7680, 196cdf0e10cSrcweir 8448, 9216, 9984, 10752, 11520, 12288, 13056, 197cdf0e10cSrcweir 13824, 14592, 15360, 16128, 16896, 17664, 18432, 198cdf0e10cSrcweir 19200, 19968, 20736, 21504, 22272, 23040 199cdf0e10cSrcweir }; 200cdf0e10cSrcweir 201cdf0e10cSrcweir // ------------------------------------------------------------------------ 202cdf0e10cSrcweir 203cdf0e10cSrcweir long FloydError5[61] = 204cdf0e10cSrcweir { 205cdf0e10cSrcweir -38400, -37120, -35840, -34560, -33280, -32000, 206cdf0e10cSrcweir -30720, -29440, -28160, -26880, -25600, -24320, 207cdf0e10cSrcweir -23040, -21760, -20480, -19200, -17920, -16640, 208cdf0e10cSrcweir -15360, -14080, -12800, -11520, -10240, -8960, 209cdf0e10cSrcweir -7680, -6400, -5120, -3840, -2560, -1280, 0, 210cdf0e10cSrcweir 1280, 2560, 3840, 5120, 6400, 7680, 8960, 10240, 211cdf0e10cSrcweir 11520, 12800, 14080, 15360, 16640, 17920, 19200, 212cdf0e10cSrcweir 20480, 21760, 23040, 24320, 25600, 26880, 28160, 213cdf0e10cSrcweir 29440, 30720, 32000, 33280, 34560, 35840, 37120, 214cdf0e10cSrcweir 38400 215cdf0e10cSrcweir }; 216cdf0e10cSrcweir 217cdf0e10cSrcweir // ------------------------------------------------------------------------ 218cdf0e10cSrcweir 219cdf0e10cSrcweir long FloydError7[61] = 220cdf0e10cSrcweir { 221cdf0e10cSrcweir -53760, -51968, -50176, -48384, -46592, -44800, 222cdf0e10cSrcweir -43008, -41216, -39424, -37632, -35840, -34048, 223cdf0e10cSrcweir -32256, -30464, -28672, -26880, -25088, -23296, 224cdf0e10cSrcweir -21504, -19712, -17920, -16128, -14336, -12544, 225cdf0e10cSrcweir -10752, -8960, -7168, -5376, -3584, -1792, 0, 226cdf0e10cSrcweir 1792, 3584, 5376, 7168, 8960, 10752, 12544, 14336, 227cdf0e10cSrcweir 16128, 17920, 19712, 21504, 23296, 25088, 26880, 228cdf0e10cSrcweir 28672, 30464, 32256, 34048, 35840, 37632, 39424, 229cdf0e10cSrcweir 41216, 43008, 44800, 46592, 48384, 50176, 51968, 230cdf0e10cSrcweir 53760 231cdf0e10cSrcweir }; 232cdf0e10cSrcweir 233cdf0e10cSrcweir // ------------------------------------------------------------------------ 234cdf0e10cSrcweir 235cdf0e10cSrcweir long FloydIndexMap[6] = 236cdf0e10cSrcweir { 237cdf0e10cSrcweir -30, 21, 72, 123, 174, 225 238cdf0e10cSrcweir }; 239cdf0e10cSrcweir 240cdf0e10cSrcweir // -------------------------- 241cdf0e10cSrcweir // - ImplCreateDitherMatrix - 242cdf0e10cSrcweir // -------------------------- 243cdf0e10cSrcweir 244cdf0e10cSrcweir void ImplCreateDitherMatrix( sal_uInt8 (*pDitherMatrix)[16][16] ) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir double fVal = 3.125; 247cdf0e10cSrcweir const double fVal16 = fVal / 16.; 248cdf0e10cSrcweir long i, j, k, l; 249cdf0e10cSrcweir sal_uInt16 pMtx[ 16 ][ 16 ]; 250cdf0e10cSrcweir sal_uInt16 nMax = 0; 251cdf0e10cSrcweir static sal_uInt8 pMagic[4][4] = { { 0, 14, 3, 13, }, 252cdf0e10cSrcweir {11, 5, 8, 6, }, 253cdf0e10cSrcweir {12, 2, 15, 1, }, 254cdf0e10cSrcweir {7, 9, 4, 10 } }; 255cdf0e10cSrcweir 256cdf0e10cSrcweir // MagicSquare aufbauen 257cdf0e10cSrcweir for ( i = 0; i < 4; i++ ) 258cdf0e10cSrcweir for ( j = 0; j < 4; j++ ) 259cdf0e10cSrcweir for ( k = 0; k < 4; k++ ) 260cdf0e10cSrcweir for ( l = 0; l < 4; l++ ) 261cdf0e10cSrcweir nMax = Max ( pMtx[ (k<<2) + i][(l<<2 ) + j] = 262cdf0e10cSrcweir (sal_uInt16) ( 0.5 + pMagic[i][j]*fVal + pMagic[k][l]*fVal16 ), nMax ); 263cdf0e10cSrcweir 264cdf0e10cSrcweir // auf Intervall [0;254] skalieren 265cdf0e10cSrcweir for ( i = 0, fVal = 254. / nMax; i < 16; i++ ) 266cdf0e10cSrcweir for( j = 0; j < 16; j++ ) 267cdf0e10cSrcweir (*pDitherMatrix)[i][j] = (sal_uInt8) ( fVal * pMtx[i][j] ); 268cdf0e10cSrcweir } 269cdf0e10cSrcweir 270cdf0e10cSrcweir // ---------- 271cdf0e10cSrcweir // - Bitmap - 272cdf0e10cSrcweir // ---------- 273cdf0e10cSrcweir 274cdf0e10cSrcweir sal_Bool Bitmap::Convert( BmpConversion eConversion ) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir const sal_uInt16 nBitCount = GetBitCount(); 277cdf0e10cSrcweir sal_Bool bRet = sal_False; 278cdf0e10cSrcweir 279cdf0e10cSrcweir switch( eConversion ) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir case( BMP_CONVERSION_1BIT_THRESHOLD ): 282cdf0e10cSrcweir bRet = ImplMakeMono( 128 ); 283cdf0e10cSrcweir break; 284cdf0e10cSrcweir 285cdf0e10cSrcweir case( BMP_CONVERSION_1BIT_MATRIX ): 286cdf0e10cSrcweir bRet = ImplMakeMonoDither(); 287cdf0e10cSrcweir break; 288cdf0e10cSrcweir 289cdf0e10cSrcweir case( BMP_CONVERSION_4BIT_GREYS ): 290cdf0e10cSrcweir bRet = ImplMakeGreyscales( 16 ); 291cdf0e10cSrcweir break; 292cdf0e10cSrcweir 293cdf0e10cSrcweir case( BMP_CONVERSION_4BIT_COLORS ): 294cdf0e10cSrcweir { 295cdf0e10cSrcweir if( nBitCount < 4 ) 296cdf0e10cSrcweir bRet = ImplConvertUp( 4, NULL ); 297cdf0e10cSrcweir else if( nBitCount > 4 ) 298cdf0e10cSrcweir bRet = ImplConvertDown( 4, NULL ); 299cdf0e10cSrcweir else 300cdf0e10cSrcweir bRet = sal_True; 301cdf0e10cSrcweir } 302cdf0e10cSrcweir break; 303cdf0e10cSrcweir 304cdf0e10cSrcweir case( BMP_CONVERSION_4BIT_TRANS ): 305cdf0e10cSrcweir { 306cdf0e10cSrcweir Color aTrans( BMP_COL_TRANS ); 307cdf0e10cSrcweir 308cdf0e10cSrcweir if( nBitCount < 4 ) 309cdf0e10cSrcweir bRet = ImplConvertUp( 4, &aTrans ); 310cdf0e10cSrcweir else 311cdf0e10cSrcweir bRet = ImplConvertDown( 4, &aTrans ); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir break; 314cdf0e10cSrcweir 315cdf0e10cSrcweir case( BMP_CONVERSION_8BIT_GREYS ): 316cdf0e10cSrcweir bRet = ImplMakeGreyscales( 256 ); 317cdf0e10cSrcweir break; 318cdf0e10cSrcweir 319cdf0e10cSrcweir case( BMP_CONVERSION_8BIT_COLORS ): 320cdf0e10cSrcweir { 321cdf0e10cSrcweir if( nBitCount < 8 ) 322cdf0e10cSrcweir bRet = ImplConvertUp( 8 ); 323cdf0e10cSrcweir else if( nBitCount > 8 ) 324cdf0e10cSrcweir bRet = ImplConvertDown( 8 ); 325cdf0e10cSrcweir else 326cdf0e10cSrcweir bRet = sal_True; 327cdf0e10cSrcweir } 328cdf0e10cSrcweir break; 329cdf0e10cSrcweir 330cdf0e10cSrcweir case( BMP_CONVERSION_8BIT_TRANS ): 331cdf0e10cSrcweir { 332cdf0e10cSrcweir Color aTrans( BMP_COL_TRANS ); 333cdf0e10cSrcweir 334cdf0e10cSrcweir if( nBitCount < 8 ) 335cdf0e10cSrcweir bRet = ImplConvertUp( 8, &aTrans ); 336cdf0e10cSrcweir else 337cdf0e10cSrcweir bRet = ImplConvertDown( 8, &aTrans ); 338cdf0e10cSrcweir } 339cdf0e10cSrcweir break; 340cdf0e10cSrcweir 341cdf0e10cSrcweir case( BMP_CONVERSION_24BIT ): 342cdf0e10cSrcweir { 343cdf0e10cSrcweir if( nBitCount < 24 ) 344cdf0e10cSrcweir bRet = ImplConvertUp( 24, sal_False ); 345cdf0e10cSrcweir else 346cdf0e10cSrcweir bRet = sal_True; 347cdf0e10cSrcweir } 348cdf0e10cSrcweir break; 349cdf0e10cSrcweir 350cdf0e10cSrcweir case( BMP_CONVERSION_GHOSTED ): 351cdf0e10cSrcweir bRet = ImplConvertGhosted(); 352cdf0e10cSrcweir break; 353cdf0e10cSrcweir 354cdf0e10cSrcweir default: 355cdf0e10cSrcweir DBG_ERROR( "Bitmap::Convert(): Unsupported conversion" ); 356cdf0e10cSrcweir break; 357cdf0e10cSrcweir } 358cdf0e10cSrcweir 359cdf0e10cSrcweir return bRet; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir 362cdf0e10cSrcweir // ------------------------------------------------------------------------ 363cdf0e10cSrcweir 364cdf0e10cSrcweir sal_Bool Bitmap::ImplMakeMono( sal_uInt8 cThreshold ) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 367cdf0e10cSrcweir sal_Bool bRet = sal_False; 368cdf0e10cSrcweir 369cdf0e10cSrcweir if( pReadAcc ) 370cdf0e10cSrcweir { 371cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 1 ); 372cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 373cdf0e10cSrcweir 374cdf0e10cSrcweir if( pWriteAcc ) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) ); 377cdf0e10cSrcweir const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); 378cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 379cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 380cdf0e10cSrcweir 381cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 384cdf0e10cSrcweir { 385cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 386cdf0e10cSrcweir { 38787bc88d3SHerbert Dürr const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX ); 38887bc88d3SHerbert Dürr if( pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >= 389cdf0e10cSrcweir cThreshold ) 390cdf0e10cSrcweir { 391cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite ); 392cdf0e10cSrcweir } 393cdf0e10cSrcweir else 394cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack ); 395cdf0e10cSrcweir } 396cdf0e10cSrcweir } 397cdf0e10cSrcweir } 398cdf0e10cSrcweir else 399cdf0e10cSrcweir { 400cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 401cdf0e10cSrcweir { 402cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 403cdf0e10cSrcweir { 404cdf0e10cSrcweir if( pReadAcc->GetPixel( nY, nX ).GetLuminance() >= 405cdf0e10cSrcweir cThreshold ) 406cdf0e10cSrcweir { 407cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite ); 408cdf0e10cSrcweir } 409cdf0e10cSrcweir else 410cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack ); 411cdf0e10cSrcweir } 412cdf0e10cSrcweir } 413cdf0e10cSrcweir } 414cdf0e10cSrcweir 415cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 416cdf0e10cSrcweir bRet = sal_True; 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 420cdf0e10cSrcweir 421cdf0e10cSrcweir if( bRet ) 422cdf0e10cSrcweir { 423cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 424cdf0e10cSrcweir const Size aSize( maPrefSize ); 425cdf0e10cSrcweir 426cdf0e10cSrcweir *this = aNewBmp; 427cdf0e10cSrcweir 428cdf0e10cSrcweir maPrefMapMode = aMap; 429cdf0e10cSrcweir maPrefSize = aSize; 430cdf0e10cSrcweir } 431cdf0e10cSrcweir } 432cdf0e10cSrcweir 433cdf0e10cSrcweir return bRet; 434cdf0e10cSrcweir } 435cdf0e10cSrcweir 436cdf0e10cSrcweir // ------------------------------------------------------------------------ 437cdf0e10cSrcweir 438cdf0e10cSrcweir sal_Bool Bitmap::ImplMakeMonoDither() 439cdf0e10cSrcweir { 440cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 441cdf0e10cSrcweir sal_Bool bRet = sal_False; 442cdf0e10cSrcweir 443cdf0e10cSrcweir if( pReadAcc ) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 1 ); 446cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 447cdf0e10cSrcweir 448cdf0e10cSrcweir if( pWriteAcc ) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) ); 451cdf0e10cSrcweir const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) ); 452cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 453cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 454cdf0e10cSrcweir sal_uInt8 pDitherMatrix[ 16 ][ 16 ]; 455cdf0e10cSrcweir 456cdf0e10cSrcweir ImplCreateDitherMatrix( &pDitherMatrix ); 457cdf0e10cSrcweir 458cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 459cdf0e10cSrcweir { 460cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ ) 463cdf0e10cSrcweir { 46487bc88d3SHerbert Dürr const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX ); 46587bc88d3SHerbert Dürr if( pReadAcc->GetPaletteColor( cIndex ).GetLuminance() > 466cdf0e10cSrcweir pDitherMatrix[ nModY ][ nX % 16 ] ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite ); 469cdf0e10cSrcweir } 470cdf0e10cSrcweir else 471cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack ); 472cdf0e10cSrcweir } 473cdf0e10cSrcweir } 474cdf0e10cSrcweir } 475cdf0e10cSrcweir else 476cdf0e10cSrcweir { 477cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 478cdf0e10cSrcweir { 479cdf0e10cSrcweir for( long nX = 0L, nModY = nY % 16; nX < nWidth; nX++ ) 480cdf0e10cSrcweir { 481cdf0e10cSrcweir if( pReadAcc->GetPixel( nY, nX ).GetLuminance() > 482cdf0e10cSrcweir pDitherMatrix[ nModY ][ nX % 16 ] ) 483cdf0e10cSrcweir { 484cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite ); 485cdf0e10cSrcweir } 486cdf0e10cSrcweir else 487cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack ); 488cdf0e10cSrcweir } 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir 492cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 493cdf0e10cSrcweir bRet = sal_True; 494cdf0e10cSrcweir } 495cdf0e10cSrcweir 496cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 497cdf0e10cSrcweir 498cdf0e10cSrcweir if( bRet ) 499cdf0e10cSrcweir { 500cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 501cdf0e10cSrcweir const Size aSize( maPrefSize ); 502cdf0e10cSrcweir 503cdf0e10cSrcweir *this = aNewBmp; 504cdf0e10cSrcweir 505cdf0e10cSrcweir maPrefMapMode = aMap; 506cdf0e10cSrcweir maPrefSize = aSize; 507cdf0e10cSrcweir } 508cdf0e10cSrcweir } 509cdf0e10cSrcweir 510cdf0e10cSrcweir return bRet; 511cdf0e10cSrcweir } 512cdf0e10cSrcweir 513cdf0e10cSrcweir // ------------------------------------------------------------------------ 514cdf0e10cSrcweir 515cdf0e10cSrcweir sal_Bool Bitmap::ImplMakeGreyscales( sal_uInt16 nGreys ) 516cdf0e10cSrcweir { 517cdf0e10cSrcweir DBG_ASSERT( nGreys == 16 || nGreys == 256, "Only 16 or 256 greyscales are supported!" ); 518cdf0e10cSrcweir 519cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 520cdf0e10cSrcweir sal_Bool bRet = sal_False; 521cdf0e10cSrcweir 522cdf0e10cSrcweir if( pReadAcc ) 523cdf0e10cSrcweir { 524cdf0e10cSrcweir const BitmapPalette& rPal = GetGreyPalette( nGreys ); 525cdf0e10cSrcweir sal_uLong nShift = ( ( nGreys == 16 ) ? 4UL : 0UL ); 526cdf0e10cSrcweir sal_Bool bPalDiffers = !pReadAcc->HasPalette() || ( rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount() ); 527cdf0e10cSrcweir 528cdf0e10cSrcweir if( !bPalDiffers ) 529cdf0e10cSrcweir bPalDiffers = ( (BitmapPalette&) rPal != pReadAcc->GetPalette() ); 530cdf0e10cSrcweir 531cdf0e10cSrcweir if( bPalDiffers ) 532cdf0e10cSrcweir { 533cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), ( nGreys == 16 ) ? 4 : 8, &rPal ); 534cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 535cdf0e10cSrcweir 536cdf0e10cSrcweir if( pWriteAcc ) 537cdf0e10cSrcweir { 538cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 539cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 540cdf0e10cSrcweir 541cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 542cdf0e10cSrcweir { 543cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 544cdf0e10cSrcweir { 545cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 546cdf0e10cSrcweir { 54787bc88d3SHerbert Dürr const sal_uInt8 cIndex = pReadAcc->GetPixelIndex( nY, nX ); 54887bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nY, nX, 54987bc88d3SHerbert Dürr (pReadAcc->GetPaletteColor( cIndex ).GetLuminance() >> nShift) ); 550cdf0e10cSrcweir } 551cdf0e10cSrcweir } 552cdf0e10cSrcweir } 553cdf0e10cSrcweir else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR && 554cdf0e10cSrcweir pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ) 555cdf0e10cSrcweir { 556cdf0e10cSrcweir nShift += 8; 557cdf0e10cSrcweir 558cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 559cdf0e10cSrcweir { 560cdf0e10cSrcweir Scanline pReadScan = pReadAcc->GetScanline( nY ); 561cdf0e10cSrcweir Scanline pWriteScan = pWriteAcc->GetScanline( nY ); 562cdf0e10cSrcweir 563cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 564cdf0e10cSrcweir { 565cdf0e10cSrcweir const sal_uLong nB = *pReadScan++; 566cdf0e10cSrcweir const sal_uLong nG = *pReadScan++; 567cdf0e10cSrcweir const sal_uLong nR = *pReadScan++; 568cdf0e10cSrcweir 569cdf0e10cSrcweir *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift ); 570cdf0e10cSrcweir } 571cdf0e10cSrcweir } 572cdf0e10cSrcweir } 573cdf0e10cSrcweir else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB && 574cdf0e10cSrcweir pWriteAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ) 575cdf0e10cSrcweir { 576cdf0e10cSrcweir nShift += 8; 577cdf0e10cSrcweir 578cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 579cdf0e10cSrcweir { 580cdf0e10cSrcweir Scanline pReadScan = pReadAcc->GetScanline( nY ); 581cdf0e10cSrcweir Scanline pWriteScan = pWriteAcc->GetScanline( nY ); 582cdf0e10cSrcweir 583cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 584cdf0e10cSrcweir { 585cdf0e10cSrcweir const sal_uLong nR = *pReadScan++; 586cdf0e10cSrcweir const sal_uLong nG = *pReadScan++; 587cdf0e10cSrcweir const sal_uLong nB = *pReadScan++; 588cdf0e10cSrcweir 589cdf0e10cSrcweir *pWriteScan++ = (sal_uInt8) ( ( nB * 28UL + nG * 151UL + nR * 77UL ) >> nShift ); 590cdf0e10cSrcweir } 591cdf0e10cSrcweir } 592cdf0e10cSrcweir } 593cdf0e10cSrcweir else 594cdf0e10cSrcweir { 595cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 596cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 59787bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nY, nX, (pReadAcc->GetPixel( nY, nX ) ).GetLuminance() >> nShift ); 598cdf0e10cSrcweir } 599cdf0e10cSrcweir 600cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 601cdf0e10cSrcweir bRet = sal_True; 602cdf0e10cSrcweir } 603cdf0e10cSrcweir 604cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 605cdf0e10cSrcweir 606cdf0e10cSrcweir if( bRet ) 607cdf0e10cSrcweir { 608cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 609cdf0e10cSrcweir const Size aSize( maPrefSize ); 610cdf0e10cSrcweir 611cdf0e10cSrcweir *this = aNewBmp; 612cdf0e10cSrcweir 613cdf0e10cSrcweir maPrefMapMode = aMap; 614cdf0e10cSrcweir maPrefSize = aSize; 615cdf0e10cSrcweir } 616cdf0e10cSrcweir } 617cdf0e10cSrcweir else 618cdf0e10cSrcweir { 619cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 620cdf0e10cSrcweir bRet = sal_True; 621cdf0e10cSrcweir } 622cdf0e10cSrcweir } 623cdf0e10cSrcweir 624cdf0e10cSrcweir return bRet; 625cdf0e10cSrcweir } 626cdf0e10cSrcweir 627cdf0e10cSrcweir // ------------------------------------------------------------------------ 628cdf0e10cSrcweir 629cdf0e10cSrcweir sal_Bool Bitmap::ImplConvertUp( sal_uInt16 nBitCount, Color* pExtColor ) 630cdf0e10cSrcweir { 631cdf0e10cSrcweir DBG_ASSERT( nBitCount > GetBitCount(), "New BitCount must be greater!" ); 632cdf0e10cSrcweir 633cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 634cdf0e10cSrcweir sal_Bool bRet = sal_False; 635cdf0e10cSrcweir 636cdf0e10cSrcweir if( pReadAcc ) 637cdf0e10cSrcweir { 638cdf0e10cSrcweir BitmapPalette aPal; 639cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount, pReadAcc->HasPalette() ? &pReadAcc->GetPalette() : &aPal ); 640cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 641cdf0e10cSrcweir 642cdf0e10cSrcweir if( pWriteAcc ) 643cdf0e10cSrcweir { 644cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 645cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 646cdf0e10cSrcweir 647cdf0e10cSrcweir if( pWriteAcc->HasPalette() ) 648cdf0e10cSrcweir { 649cdf0e10cSrcweir const sal_uInt16 nOldCount = 1 << GetBitCount(); 650cdf0e10cSrcweir const BitmapPalette& rOldPal = pReadAcc->GetPalette(); 651cdf0e10cSrcweir 652cdf0e10cSrcweir aPal.SetEntryCount( 1 << nBitCount ); 653cdf0e10cSrcweir 654cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nOldCount; i++ ) 655cdf0e10cSrcweir aPal[ i ] = rOldPal[ i ]; 656cdf0e10cSrcweir 657cdf0e10cSrcweir if( pExtColor ) 658cdf0e10cSrcweir aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor; 659cdf0e10cSrcweir 660cdf0e10cSrcweir pWriteAcc->SetPalette( aPal ); 661cdf0e10cSrcweir 662cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 663cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 664cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) ); 665cdf0e10cSrcweir } 666cdf0e10cSrcweir else 667cdf0e10cSrcweir { 668cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 669cdf0e10cSrcweir { 670cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 671cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 67287bc88d3SHerbert Dürr pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) ) ); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir else 675cdf0e10cSrcweir { 676cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 677cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 678cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY, nX ) ); 679cdf0e10cSrcweir } 680cdf0e10cSrcweir } 681cdf0e10cSrcweir 682cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 683cdf0e10cSrcweir bRet = sal_True; 684cdf0e10cSrcweir } 685cdf0e10cSrcweir 686cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 687cdf0e10cSrcweir 688cdf0e10cSrcweir if( bRet ) 689cdf0e10cSrcweir { 690cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 691cdf0e10cSrcweir const Size aSize( maPrefSize ); 692cdf0e10cSrcweir 693cdf0e10cSrcweir *this = aNewBmp; 694cdf0e10cSrcweir 695cdf0e10cSrcweir maPrefMapMode = aMap; 696cdf0e10cSrcweir maPrefSize = aSize; 697cdf0e10cSrcweir } 698cdf0e10cSrcweir } 699cdf0e10cSrcweir 700cdf0e10cSrcweir return bRet; 701cdf0e10cSrcweir } 702cdf0e10cSrcweir 703cdf0e10cSrcweir // ------------------------------------------------------------------------ 704cdf0e10cSrcweir 705cdf0e10cSrcweir sal_Bool Bitmap::ImplConvertDown( sal_uInt16 nBitCount, Color* pExtColor ) 706cdf0e10cSrcweir { 707cdf0e10cSrcweir DBG_ASSERT( nBitCount <= GetBitCount(), "New BitCount must be lower ( or equal when pExtColor is set )!" ); 708cdf0e10cSrcweir 709cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 710cdf0e10cSrcweir sal_Bool bRet = sal_False; 711cdf0e10cSrcweir 712cdf0e10cSrcweir if( pReadAcc ) 713cdf0e10cSrcweir { 714cdf0e10cSrcweir BitmapPalette aPal; 715cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount, &aPal ); 716cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 717cdf0e10cSrcweir 718cdf0e10cSrcweir if( pWriteAcc ) 719cdf0e10cSrcweir { 720cdf0e10cSrcweir const sal_uInt16 nCount = 1 << nBitCount; 721cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 722cdf0e10cSrcweir const long nWidth1 = nWidth - 1L; 723cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 724cdf0e10cSrcweir Octree aOctree( *pReadAcc, pExtColor ? ( nCount - 1 ) : nCount ); 725cdf0e10cSrcweir InverseColorMap aColorMap( aPal = aOctree.GetPalette() ); 726cdf0e10cSrcweir BitmapColor aColor; 727cdf0e10cSrcweir ImpErrorQuad aErrQuad; 728cdf0e10cSrcweir ImpErrorQuad* pErrQuad1 = new ImpErrorQuad[ nWidth ]; 729cdf0e10cSrcweir ImpErrorQuad* pErrQuad2 = new ImpErrorQuad[ nWidth ]; 730cdf0e10cSrcweir ImpErrorQuad* pQLine1 = pErrQuad1; 731cdf0e10cSrcweir ImpErrorQuad* pQLine2 = 0; 732cdf0e10cSrcweir long nX, nY; 733cdf0e10cSrcweir long nYTmp = 0L; 734cdf0e10cSrcweir sal_uInt8 cIndex; 735cdf0e10cSrcweir sal_Bool bQ1 = sal_True; 736cdf0e10cSrcweir 737cdf0e10cSrcweir if( pExtColor ) 738cdf0e10cSrcweir { 739cdf0e10cSrcweir aPal.SetEntryCount( aPal.GetEntryCount() + 1 ); 740cdf0e10cSrcweir aPal[ aPal.GetEntryCount() - 1 ] = *pExtColor; 741cdf0e10cSrcweir } 742cdf0e10cSrcweir 743cdf0e10cSrcweir // set Black/White always, if we have enough space 744cdf0e10cSrcweir if( aPal.GetEntryCount() < ( nCount - 1 ) ) 745cdf0e10cSrcweir { 746cdf0e10cSrcweir aPal.SetEntryCount( aPal.GetEntryCount() + 2 ); 747cdf0e10cSrcweir aPal[ aPal.GetEntryCount() - 2 ] = Color( COL_BLACK ); 748cdf0e10cSrcweir aPal[ aPal.GetEntryCount() - 1 ] = Color( COL_WHITE ); 749cdf0e10cSrcweir } 750cdf0e10cSrcweir 751cdf0e10cSrcweir pWriteAcc->SetPalette( aPal ); 752cdf0e10cSrcweir 753cdf0e10cSrcweir for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ ) 754cdf0e10cSrcweir { 755cdf0e10cSrcweir for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ ) 756cdf0e10cSrcweir { 757cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 75887bc88d3SHerbert Dürr pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nYTmp, nX ) ); 759cdf0e10cSrcweir else 760cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 761cdf0e10cSrcweir } 762cdf0e10cSrcweir } 763cdf0e10cSrcweir 764cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++, nYTmp++ ) 765cdf0e10cSrcweir { 76687bc88d3SHerbert Dürr // first pixel in the line 767cdf0e10cSrcweir cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ 0 ].ImplGetColor() ); 76887bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nY, 0, cIndex ); 769cdf0e10cSrcweir 770cdf0e10cSrcweir for( nX = 1L; nX < nWidth1; nX++ ) 771cdf0e10cSrcweir { 772cdf0e10cSrcweir cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( aColor = pQLine1[ nX ].ImplGetColor() ); 773cdf0e10cSrcweir aErrQuad = ( ImpErrorQuad( aColor ) -= pWriteAcc->GetPaletteColor( cIndex ) ); 774cdf0e10cSrcweir pQLine1[ ++nX ].ImplAddColorError7( aErrQuad ); 775cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError1( aErrQuad ); 776cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError5( aErrQuad ); 777cdf0e10cSrcweir pQLine2[ nX++ ].ImplAddColorError3( aErrQuad ); 77887bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nY, nX, cIndex ); 779cdf0e10cSrcweir } 780cdf0e10cSrcweir 781cdf0e10cSrcweir // letztes ZeilenPixel 782cdf0e10cSrcweir if( nX < nWidth ) 783cdf0e10cSrcweir { 784cdf0e10cSrcweir cIndex = (sal_uInt8) aColorMap.GetBestPaletteIndex( pQLine1[ nWidth1 ].ImplGetColor() ); 78587bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nY, nX, cIndex ); 786cdf0e10cSrcweir } 787cdf0e10cSrcweir 788cdf0e10cSrcweir // Zeilenpuffer neu fuellen/kopieren 789cdf0e10cSrcweir pQLine1 = pQLine2; 790cdf0e10cSrcweir pQLine2 = ( bQ1 = !bQ1 ) != sal_False ? pErrQuad2 : pErrQuad1; 791cdf0e10cSrcweir 792cdf0e10cSrcweir if( nYTmp < nHeight ) 793cdf0e10cSrcweir { 794cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 795cdf0e10cSrcweir { 796cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 79787bc88d3SHerbert Dürr pQLine2[ nX ] = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nYTmp, nX ) ); 798cdf0e10cSrcweir else 799cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 800cdf0e10cSrcweir } 801cdf0e10cSrcweir } 802cdf0e10cSrcweir } 803cdf0e10cSrcweir 804cdf0e10cSrcweir // Zeilenpuffer zerstoeren 805cdf0e10cSrcweir delete[] pErrQuad1; 806cdf0e10cSrcweir delete[] pErrQuad2; 807cdf0e10cSrcweir 808cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 809cdf0e10cSrcweir bRet = sal_True; 810cdf0e10cSrcweir } 811cdf0e10cSrcweir 812cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 813cdf0e10cSrcweir 814cdf0e10cSrcweir if( bRet ) 815cdf0e10cSrcweir { 816cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 817cdf0e10cSrcweir const Size aSize( maPrefSize ); 818cdf0e10cSrcweir 819cdf0e10cSrcweir *this = aNewBmp; 820cdf0e10cSrcweir 821cdf0e10cSrcweir maPrefMapMode = aMap; 822cdf0e10cSrcweir maPrefSize = aSize; 823cdf0e10cSrcweir } 824cdf0e10cSrcweir } 825cdf0e10cSrcweir 826cdf0e10cSrcweir return bRet; 827cdf0e10cSrcweir } 828cdf0e10cSrcweir 829cdf0e10cSrcweir // ------------------------------------------------------------------------ 830cdf0e10cSrcweir 831cdf0e10cSrcweir sal_Bool Bitmap::ImplConvertGhosted() 832cdf0e10cSrcweir { 833cdf0e10cSrcweir Bitmap aNewBmp; 834cdf0e10cSrcweir BitmapReadAccess* pR = AcquireReadAccess(); 835cdf0e10cSrcweir sal_Bool bRet = sal_False; 836cdf0e10cSrcweir 837cdf0e10cSrcweir if( pR ) 838cdf0e10cSrcweir { 839cdf0e10cSrcweir if( pR->HasPalette() ) 840cdf0e10cSrcweir { 841cdf0e10cSrcweir BitmapPalette aNewPal( pR->GetPaletteEntryCount() ); 842cdf0e10cSrcweir 843cdf0e10cSrcweir for( long i = 0, nCount = aNewPal.GetEntryCount(); i < nCount; i++ ) 844cdf0e10cSrcweir { 845cdf0e10cSrcweir const BitmapColor& rOld = pR->GetPaletteColor( (sal_uInt16) i ); 846cdf0e10cSrcweir aNewPal[ (sal_uInt16) i ] = BitmapColor( ( rOld.GetRed() >> 1 ) | 0x80, 847cdf0e10cSrcweir ( rOld.GetGreen() >> 1 ) | 0x80, 848cdf0e10cSrcweir ( rOld.GetBlue() >> 1 ) | 0x80 ); 849cdf0e10cSrcweir } 850cdf0e10cSrcweir 851cdf0e10cSrcweir aNewBmp = Bitmap( GetSizePixel(), GetBitCount(), &aNewPal ); 852cdf0e10cSrcweir BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess(); 853cdf0e10cSrcweir 854cdf0e10cSrcweir if( pW ) 855cdf0e10cSrcweir { 856cdf0e10cSrcweir pW->CopyBuffer( *pR ); 857cdf0e10cSrcweir aNewBmp.ReleaseAccess( pW ); 858cdf0e10cSrcweir bRet = sal_True; 859cdf0e10cSrcweir } 860cdf0e10cSrcweir } 861cdf0e10cSrcweir else 862cdf0e10cSrcweir { 863cdf0e10cSrcweir aNewBmp = Bitmap( GetSizePixel(), 24 ); 864cdf0e10cSrcweir 865cdf0e10cSrcweir BitmapWriteAccess* pW = aNewBmp.AcquireWriteAccess(); 866cdf0e10cSrcweir 867cdf0e10cSrcweir if( pW ) 868cdf0e10cSrcweir { 869cdf0e10cSrcweir const long nWidth = pR->Width(), nHeight = pR->Height(); 870cdf0e10cSrcweir 871cdf0e10cSrcweir for( long nY = 0; nY < nHeight; nY++ ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir for( long nX = 0; nX < nWidth; nX++ ) 874cdf0e10cSrcweir { 875cdf0e10cSrcweir const BitmapColor aOld( pR->GetPixel( nY, nX ) ); 876cdf0e10cSrcweir pW->SetPixel( nY, nX, BitmapColor( ( aOld.GetRed() >> 1 ) | 0x80, 877cdf0e10cSrcweir ( aOld.GetGreen() >> 1 ) | 0x80, 878cdf0e10cSrcweir ( aOld.GetBlue() >> 1 ) | 0x80 ) ); 879cdf0e10cSrcweir 880cdf0e10cSrcweir } 881cdf0e10cSrcweir } 882cdf0e10cSrcweir 883cdf0e10cSrcweir aNewBmp.ReleaseAccess( pW ); 884cdf0e10cSrcweir bRet = sal_True; 885cdf0e10cSrcweir } 886cdf0e10cSrcweir } 887cdf0e10cSrcweir 888cdf0e10cSrcweir ReleaseAccess( pR ); 889cdf0e10cSrcweir } 890cdf0e10cSrcweir 891cdf0e10cSrcweir if( bRet ) 892cdf0e10cSrcweir { 893cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 894cdf0e10cSrcweir const Size aSize( maPrefSize ); 895cdf0e10cSrcweir 896cdf0e10cSrcweir *this = aNewBmp; 897cdf0e10cSrcweir 898cdf0e10cSrcweir maPrefMapMode = aMap; 899cdf0e10cSrcweir maPrefSize = aSize; 900cdf0e10cSrcweir } 901cdf0e10cSrcweir 902cdf0e10cSrcweir return bRet; 903cdf0e10cSrcweir } 904cdf0e10cSrcweir 905cdf0e10cSrcweir // ------------------------------------------------------------------------ 906cdf0e10cSrcweir 907cdf0e10cSrcweir sal_Bool Bitmap::Scale( const double& rScaleX, const double& rScaleY, sal_uLong nScaleFlag ) 908cdf0e10cSrcweir { 909e9a409b3SArmin Le Grand bool bRetval(false); 910e9a409b3SArmin Le Grand 91137ab0f2dSArmin Le Grand #ifdef DBG_UTIL 91237ab0f2dSArmin Le Grand // #121233# allow to test the different scalers in debug build with source 91337ab0f2dSArmin Le Grand // level debugger (change nNumber to desired action) 91437ab0f2dSArmin Le Grand static sal_uInt16 nNumber(0); 915e9a409b3SArmin Le Grand const sal_uInt16 nStartCount(GetBitCount()); 91637ab0f2dSArmin Le Grand 91737ab0f2dSArmin Le Grand switch(nNumber) 91837ab0f2dSArmin Le Grand { 91937ab0f2dSArmin Le Grand case 0 : break; 92037ab0f2dSArmin Le Grand case 1: nScaleFlag = BMP_SCALE_FAST; break; 92137ab0f2dSArmin Le Grand case 2: nScaleFlag = BMP_SCALE_INTERPOLATE; break; 92237ab0f2dSArmin Le Grand case 3: nScaleFlag = BMP_SCALE_SUPER; break; 92337ab0f2dSArmin Le Grand case 4: nScaleFlag = BMP_SCALE_LANCZOS; break; 92437ab0f2dSArmin Le Grand case 5: nScaleFlag = BMP_SCALE_BICUBIC; break; 92537ab0f2dSArmin Le Grand case 6: nScaleFlag = BMP_SCALE_BILINEAR; break; 92637ab0f2dSArmin Le Grand case 7: nScaleFlag = BMP_SCALE_BOX; break; 92737ab0f2dSArmin Le Grand case 8: nScaleFlag = BMP_SCALE_BESTQUALITY; break; 92837ab0f2dSArmin Le Grand case 9: nScaleFlag = BMP_SCALE_FASTESTINTERPOLATE; break; 92937ab0f2dSArmin Le Grand } 93037ab0f2dSArmin Le Grand #endif // DBG_UTIL 93137ab0f2dSArmin Le Grand 93237ab0f2dSArmin Le Grand if(basegfx::fTools::equalZero(rScaleX) && basegfx::fTools::equalZero(rScaleY)) 93337ab0f2dSArmin Le Grand { 93437ab0f2dSArmin Le Grand // no scale 935e9a409b3SArmin Le Grand bRetval = true; 93637ab0f2dSArmin Le Grand } 93737ab0f2dSArmin Le Grand else 93837ab0f2dSArmin Le Grand { 93937ab0f2dSArmin Le Grand if(BMP_SCALE_BESTQUALITY == nScaleFlag) 94037ab0f2dSArmin Le Grand { 94137ab0f2dSArmin Le Grand // Use LANCZOS when best quality is requested 94237ab0f2dSArmin Le Grand nScaleFlag = BMP_SCALE_LANCZOS; 94337ab0f2dSArmin Le Grand } 94437ab0f2dSArmin Le Grand else if(BMP_SCALE_FASTESTINTERPOLATE == nScaleFlag) 94537ab0f2dSArmin Le Grand { 94637ab0f2dSArmin Le Grand // Use BMP_SCALE_SUPER when speed is requested, but not worst quality 94737ab0f2dSArmin Le Grand nScaleFlag = BMP_SCALE_SUPER; 94837ab0f2dSArmin Le Grand } 94937ab0f2dSArmin Le Grand 95037ab0f2dSArmin Le Grand switch(nScaleFlag) 95137ab0f2dSArmin Le Grand { 95237ab0f2dSArmin Le Grand default: 95337ab0f2dSArmin Le Grand case BMP_SCALE_NONE : 95437ab0f2dSArmin Le Grand { 955e9a409b3SArmin Le Grand bRetval = false; 95637ab0f2dSArmin Le Grand break; 95737ab0f2dSArmin Le Grand } 95837ab0f2dSArmin Le Grand case BMP_SCALE_FAST : 95937ab0f2dSArmin Le Grand { 960e9a409b3SArmin Le Grand bRetval = ImplScaleFast( rScaleX, rScaleY ); 96137ab0f2dSArmin Le Grand break; 96237ab0f2dSArmin Le Grand } 96337ab0f2dSArmin Le Grand case BMP_SCALE_INTERPOLATE : 96437ab0f2dSArmin Le Grand { 965e9a409b3SArmin Le Grand bRetval = ImplScaleInterpolate( rScaleX, rScaleY ); 96637ab0f2dSArmin Le Grand break; 96737ab0f2dSArmin Le Grand } 96837ab0f2dSArmin Le Grand case BMP_SCALE_SUPER : 96937ab0f2dSArmin Le Grand { 97037ab0f2dSArmin Le Grand if(GetSizePixel().Width() < 2 || GetSizePixel().Height() < 2) 97137ab0f2dSArmin Le Grand { 97237ab0f2dSArmin Le Grand // fallback to ImplScaleFast 973e9a409b3SArmin Le Grand bRetval = ImplScaleFast( rScaleX, rScaleY ); 97437ab0f2dSArmin Le Grand } 97537ab0f2dSArmin Le Grand else 97637ab0f2dSArmin Le Grand { 97737ab0f2dSArmin Le Grand // #121233# use method from symphony 978e9a409b3SArmin Le Grand bRetval = ImplScaleSuper( rScaleX, rScaleY ); 97937ab0f2dSArmin Le Grand } 98037ab0f2dSArmin Le Grand break; 98137ab0f2dSArmin Le Grand } 98237ab0f2dSArmin Le Grand case BMP_SCALE_LANCZOS : 98337ab0f2dSArmin Le Grand { 98437ab0f2dSArmin Le Grand const Lanczos3Kernel kernel; 98537ab0f2dSArmin Le Grand 986e9a409b3SArmin Le Grand bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel); 98737ab0f2dSArmin Le Grand break; 98837ab0f2dSArmin Le Grand } 98937ab0f2dSArmin Le Grand case BMP_SCALE_BICUBIC : 99037ab0f2dSArmin Le Grand { 99137ab0f2dSArmin Le Grand const BicubicKernel kernel; 99237ab0f2dSArmin Le Grand 993e9a409b3SArmin Le Grand bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel ); 99437ab0f2dSArmin Le Grand break; 99537ab0f2dSArmin Le Grand } 99637ab0f2dSArmin Le Grand case BMP_SCALE_BILINEAR : 99737ab0f2dSArmin Le Grand { 99837ab0f2dSArmin Le Grand const BilinearKernel kernel; 99937ab0f2dSArmin Le Grand 1000e9a409b3SArmin Le Grand bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel ); 100137ab0f2dSArmin Le Grand break; 100237ab0f2dSArmin Le Grand } 100337ab0f2dSArmin Le Grand case BMP_SCALE_BOX : 100437ab0f2dSArmin Le Grand { 100537ab0f2dSArmin Le Grand const BoxKernel kernel; 100637ab0f2dSArmin Le Grand 1007e9a409b3SArmin Le Grand bRetval = ImplScaleConvolution( rScaleX, rScaleY, kernel ); 100837ab0f2dSArmin Le Grand break; 100937ab0f2dSArmin Le Grand } 101037ab0f2dSArmin Le Grand } 101137ab0f2dSArmin Le Grand } 101237ab0f2dSArmin Le Grand 1013e9a409b3SArmin Le Grand #ifdef DBG_UTIL 1014e9a409b3SArmin Le Grand if(bRetval && nStartCount != GetBitCount()) 1015e9a409b3SArmin Le Grand { 1016e9a409b3SArmin Le Grand OSL_ENSURE(false, "Bitmap::Scale has changed the ColorDepth, this should *not* happen (!)"); 1017e9a409b3SArmin Le Grand } 1018e9a409b3SArmin Le Grand #endif 1019e9a409b3SArmin Le Grand 1020e9a409b3SArmin Le Grand return bRetval; 1021cdf0e10cSrcweir } 1022cdf0e10cSrcweir 1023cdf0e10cSrcweir // ------------------------------------------------------------------------ 1024cdf0e10cSrcweir 1025cdf0e10cSrcweir sal_Bool Bitmap::Scale( const Size& rNewSize, sal_uLong nScaleFlag ) 1026cdf0e10cSrcweir { 1027cdf0e10cSrcweir const Size aSize( GetSizePixel() ); 1028cdf0e10cSrcweir sal_Bool bRet; 1029cdf0e10cSrcweir 1030cdf0e10cSrcweir if( aSize.Width() && aSize.Height() ) 1031cdf0e10cSrcweir { 1032cdf0e10cSrcweir bRet = Scale( (double) rNewSize.Width() / aSize.Width(), 1033cdf0e10cSrcweir (double) rNewSize.Height() / aSize.Height(), 1034cdf0e10cSrcweir nScaleFlag ); 1035cdf0e10cSrcweir } 1036cdf0e10cSrcweir else 1037cdf0e10cSrcweir bRet = sal_True; 1038cdf0e10cSrcweir 1039cdf0e10cSrcweir return bRet; 1040cdf0e10cSrcweir } 1041cdf0e10cSrcweir 1042cdf0e10cSrcweir // ------------------------------------------------------------------------ 1043cdf0e10cSrcweir 1044c2821885SArmin Le Grand void Bitmap::AdaptBitCount(Bitmap& rNew) const 1045c2821885SArmin Le Grand { 1046c2821885SArmin Le Grand ImplAdaptBitCount(rNew); 1047c2821885SArmin Le Grand } 1048c2821885SArmin Le Grand 1049c2821885SArmin Le Grand // ------------------------------------------------------------------------ 1050c2821885SArmin Le Grand 1051c2821885SArmin Le Grand void Bitmap::ImplAdaptBitCount(Bitmap& rNew) const 105237ab0f2dSArmin Le Grand { 105337ab0f2dSArmin Le Grand // aNew is the result of some operation; adapt it's BitCount to the original (this) 105437ab0f2dSArmin Le Grand if(GetBitCount() != rNew.GetBitCount()) 105537ab0f2dSArmin Le Grand { 105637ab0f2dSArmin Le Grand switch(GetBitCount()) 105737ab0f2dSArmin Le Grand { 105837ab0f2dSArmin Le Grand case 1: 105937ab0f2dSArmin Le Grand { 106037ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_1BIT_THRESHOLD); 106137ab0f2dSArmin Le Grand break; 106237ab0f2dSArmin Le Grand } 106337ab0f2dSArmin Le Grand case 4: 106437ab0f2dSArmin Le Grand { 106537ab0f2dSArmin Le Grand if(HasGreyPalette()) 106637ab0f2dSArmin Le Grand { 106737ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_4BIT_GREYS); 106837ab0f2dSArmin Le Grand } 106937ab0f2dSArmin Le Grand else 107037ab0f2dSArmin Le Grand { 107137ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_4BIT_COLORS); 107237ab0f2dSArmin Le Grand } 107337ab0f2dSArmin Le Grand break; 107437ab0f2dSArmin Le Grand } 107537ab0f2dSArmin Le Grand case 8: 107637ab0f2dSArmin Le Grand { 107737ab0f2dSArmin Le Grand if(HasGreyPalette()) 107837ab0f2dSArmin Le Grand { 107937ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_8BIT_GREYS); 108037ab0f2dSArmin Le Grand } 108137ab0f2dSArmin Le Grand else 108237ab0f2dSArmin Le Grand { 108337ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_8BIT_COLORS); 108437ab0f2dSArmin Le Grand } 108537ab0f2dSArmin Le Grand break; 108637ab0f2dSArmin Le Grand } 108737ab0f2dSArmin Le Grand case 24: 108837ab0f2dSArmin Le Grand { 108937ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_24BIT); 109037ab0f2dSArmin Le Grand break; 109137ab0f2dSArmin Le Grand } 109237ab0f2dSArmin Le Grand default: 109337ab0f2dSArmin Le Grand { 109437ab0f2dSArmin Le Grand OSL_ENSURE(false, "BitDepth adaption failed (!)"); 109537ab0f2dSArmin Le Grand break; 109637ab0f2dSArmin Le Grand } 109737ab0f2dSArmin Le Grand } 109837ab0f2dSArmin Le Grand } 109937ab0f2dSArmin Le Grand } 110037ab0f2dSArmin Le Grand 110137ab0f2dSArmin Le Grand // ------------------------------------------------------------------------ 110237ab0f2dSArmin Le Grand 1103cdf0e10cSrcweir sal_Bool Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) 1104cdf0e10cSrcweir { 1105cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 1106cdf0e10cSrcweir const long nNewWidth = FRound( aSizePix.Width() * rScaleX ); 1107cdf0e10cSrcweir const long nNewHeight = FRound( aSizePix.Height() * rScaleY ); 1108cdf0e10cSrcweir sal_Bool bRet = sal_False; 1109cdf0e10cSrcweir 1110cdf0e10cSrcweir if( nNewWidth && nNewHeight ) 1111cdf0e10cSrcweir { 1112cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 11130f740837SAriel Constenla-Haile if ( !pReadAcc ) 11140f740837SAriel Constenla-Haile return sal_False; 11150f740837SAriel Constenla-Haile 1116cdf0e10cSrcweir Bitmap aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() ); 1117cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 1118cdf0e10cSrcweir 11190f740837SAriel Constenla-Haile if( pWriteAcc ) 1120cdf0e10cSrcweir { 1121cdf0e10cSrcweir const long nScanlineSize = pWriteAcc->GetScanlineSize(); 1122cdf0e10cSrcweir const long nNewWidth1 = nNewWidth - 1L; 1123cdf0e10cSrcweir const long nNewHeight1 = nNewHeight - 1L; 1124cdf0e10cSrcweir const long nWidth = pReadAcc->Width(); 1125cdf0e10cSrcweir const long nHeight = pReadAcc->Height(); 1126cdf0e10cSrcweir long* pLutX = new long[ nNewWidth ]; 1127cdf0e10cSrcweir long* pLutY = new long[ nNewHeight ]; 1128cdf0e10cSrcweir long nX, nY, nMapY, nActY = 0L; 1129cdf0e10cSrcweir 1130cdf0e10cSrcweir if( nNewWidth1 && nNewHeight1 ) 1131cdf0e10cSrcweir { 1132cdf0e10cSrcweir for( nX = 0L; nX < nNewWidth; nX++ ) 1133cdf0e10cSrcweir pLutX[ nX ] = nX * nWidth / nNewWidth; 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir for( nY = 0L; nY < nNewHeight; nY++ ) 1136cdf0e10cSrcweir pLutY[ nY ] = nY * nHeight / nNewHeight; 1137cdf0e10cSrcweir 1138cdf0e10cSrcweir while( nActY < nNewHeight ) 1139cdf0e10cSrcweir { 1140cdf0e10cSrcweir nMapY = pLutY[ nActY ]; 1141cdf0e10cSrcweir 1142cdf0e10cSrcweir for( nX = 0L; nX < nNewWidth; nX++ ) 1143cdf0e10cSrcweir pWriteAcc->SetPixel( nActY, nX, pReadAcc->GetPixel( nMapY , pLutX[ nX ] ) ); 1144cdf0e10cSrcweir 1145cdf0e10cSrcweir while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) ) 1146cdf0e10cSrcweir { 1147cdf0e10cSrcweir memcpy( pWriteAcc->GetScanline( nActY + 1L ), 1148cdf0e10cSrcweir pWriteAcc->GetScanline( nActY ), nScanlineSize ); 1149cdf0e10cSrcweir nActY++; 1150cdf0e10cSrcweir } 1151cdf0e10cSrcweir 1152cdf0e10cSrcweir nActY++; 1153cdf0e10cSrcweir } 1154cdf0e10cSrcweir 1155cdf0e10cSrcweir bRet = sal_True; 1156cdf0e10cSrcweir } 1157cdf0e10cSrcweir 1158cdf0e10cSrcweir delete[] pLutX; 1159cdf0e10cSrcweir delete[] pLutY; 1160cdf0e10cSrcweir } 1161cdf0e10cSrcweir 1162cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1163cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1164cdf0e10cSrcweir 1165cdf0e10cSrcweir if( bRet ) 1166cdf0e10cSrcweir ImplAssignWithSize( aNewBmp ); 1167cdf0e10cSrcweir } 1168cdf0e10cSrcweir 1169cdf0e10cSrcweir return bRet; 1170cdf0e10cSrcweir } 1171cdf0e10cSrcweir 1172cdf0e10cSrcweir // ------------------------------------------------------------------------ 1173cdf0e10cSrcweir 1174cdf0e10cSrcweir sal_Bool Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY ) 1175cdf0e10cSrcweir { 1176cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 1177cdf0e10cSrcweir const long nNewWidth = FRound( aSizePix.Width() * rScaleX ); 1178cdf0e10cSrcweir const long nNewHeight = FRound( aSizePix.Height() * rScaleY ); 1179cdf0e10cSrcweir sal_Bool bRet = sal_False; 1180cdf0e10cSrcweir 1181cdf0e10cSrcweir if( ( nNewWidth > 1L ) && ( nNewHeight > 1L ) ) 1182cdf0e10cSrcweir { 1183cdf0e10cSrcweir BitmapColor aCol0; 1184cdf0e10cSrcweir BitmapColor aCol1; 1185cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 1186cdf0e10cSrcweir long nWidth = pReadAcc->Width(); 1187cdf0e10cSrcweir long nHeight = pReadAcc->Height(); 1188cdf0e10cSrcweir Bitmap aNewBmp( Size( nNewWidth, nHeight ), 24 ); 1189cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 1190cdf0e10cSrcweir long* pLutInt; 1191cdf0e10cSrcweir long* pLutFrac; 1192cdf0e10cSrcweir long nX, nY; 1193cdf0e10cSrcweir long lXB0, lXB1, lXG0, lXG1, lXR0, lXR1; 1194cdf0e10cSrcweir double fTemp; 1195cdf0e10cSrcweir long nTemp; 1196cdf0e10cSrcweir 1197cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 1198cdf0e10cSrcweir { 1199cdf0e10cSrcweir const long nNewWidth1 = nNewWidth - 1L; 1200cdf0e10cSrcweir const long nWidth1 = pReadAcc->Width() - 1L; 1201cdf0e10cSrcweir const double fRevScaleX = (double) nWidth1 / nNewWidth1; 1202cdf0e10cSrcweir 1203cdf0e10cSrcweir pLutInt = new long[ nNewWidth ]; 1204cdf0e10cSrcweir pLutFrac = new long[ nNewWidth ]; 1205cdf0e10cSrcweir 1206cdf0e10cSrcweir for( nX = 0L, nTemp = nWidth - 2L; nX < nNewWidth; nX++ ) 1207cdf0e10cSrcweir { 1208cdf0e10cSrcweir fTemp = nX * fRevScaleX; 1209cdf0e10cSrcweir pLutInt[ nX ] = MinMax( (long) fTemp, 0, nTemp ); 1210cdf0e10cSrcweir fTemp -= pLutInt[ nX ]; 1211cdf0e10cSrcweir pLutFrac[ nX ] = (long) ( fTemp * 1024. ); 1212cdf0e10cSrcweir } 1213cdf0e10cSrcweir 1214c2821885SArmin Le Grand for( nY = 0L; nY < nHeight; nY++ ) 1215cdf0e10cSrcweir { 1216c2821885SArmin Le Grand if( 1 == nWidth ) 1217cdf0e10cSrcweir { 1218c2821885SArmin Le Grand if( pReadAcc->HasPalette() ) 1219c2821885SArmin Le Grand { 1220c2821885SArmin Le Grand aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, 0 ) ); 1221c2821885SArmin Le Grand } 1222c2821885SArmin Le Grand else 1223c2821885SArmin Le Grand { 1224c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( nY, 0 ); 1225c2821885SArmin Le Grand } 1226cdf0e10cSrcweir 1227c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1228c2821885SArmin Le Grand { 1229c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1230c2821885SArmin Le Grand } 1231cdf0e10cSrcweir } 1232c2821885SArmin Le Grand else 1233cdf0e10cSrcweir { 1234c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1235cdf0e10cSrcweir { 1236c2821885SArmin Le Grand nTemp = pLutInt[ nX ]; 1237cdf0e10cSrcweir 1238c2821885SArmin Le Grand if( pReadAcc->HasPalette() ) 1239c2821885SArmin Le Grand { 1240c2821885SArmin Le Grand aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp++ ) ); 1241c2821885SArmin Le Grand aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp ) ); 1242c2821885SArmin Le Grand } 1243c2821885SArmin Le Grand else 1244c2821885SArmin Le Grand { 1245cdf0e10cSrcweir aCol0 = pReadAcc->GetPixel( nY, nTemp++ ); 1246cdf0e10cSrcweir aCol1 = pReadAcc->GetPixel( nY, nTemp ); 1247c2821885SArmin Le Grand } 1248cdf0e10cSrcweir 1249c2821885SArmin Le Grand nTemp = pLutFrac[ nX ]; 1250cdf0e10cSrcweir 1251c2821885SArmin Le Grand lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() ); 1252c2821885SArmin Le Grand lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() ); 1253c2821885SArmin Le Grand lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() ); 1254cdf0e10cSrcweir 1255c2821885SArmin Le Grand aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); 1256c2821885SArmin Le Grand aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); 1257c2821885SArmin Le Grand aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) ); 1258cdf0e10cSrcweir 1259c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1260cdf0e10cSrcweir } 1261cdf0e10cSrcweir } 1262cdf0e10cSrcweir } 1263cdf0e10cSrcweir 1264cdf0e10cSrcweir delete[] pLutInt; 1265cdf0e10cSrcweir delete[] pLutFrac; 1266cdf0e10cSrcweir bRet = sal_True; 1267cdf0e10cSrcweir } 1268cdf0e10cSrcweir 1269cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1270cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1271cdf0e10cSrcweir 1272cdf0e10cSrcweir if( bRet ) 1273cdf0e10cSrcweir { 1274cdf0e10cSrcweir bRet = sal_False; 1275561c4886SArmin Le Grand const Bitmap aOriginal(*this); 1276c2821885SArmin Le Grand *this = aNewBmp; 1277cdf0e10cSrcweir aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 ); 1278c2821885SArmin Le Grand pReadAcc = AcquireReadAccess(); 1279cdf0e10cSrcweir pWriteAcc = aNewBmp.AcquireWriteAccess(); 1280cdf0e10cSrcweir 1281cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 1282cdf0e10cSrcweir { 1283cdf0e10cSrcweir const long nNewHeight1 = nNewHeight - 1L; 1284cdf0e10cSrcweir const long nHeight1 = pReadAcc->Height() - 1L; 1285cdf0e10cSrcweir const double fRevScaleY = (double) nHeight1 / nNewHeight1; 1286cdf0e10cSrcweir 1287cdf0e10cSrcweir pLutInt = new long[ nNewHeight ]; 1288cdf0e10cSrcweir pLutFrac = new long[ nNewHeight ]; 1289cdf0e10cSrcweir 1290cdf0e10cSrcweir for( nY = 0L, nTemp = nHeight - 2L; nY < nNewHeight; nY++ ) 1291cdf0e10cSrcweir { 1292cdf0e10cSrcweir fTemp = nY * fRevScaleY; 1293cdf0e10cSrcweir pLutInt[ nY ] = MinMax( (long) fTemp, 0, nTemp ); 1294cdf0e10cSrcweir fTemp -= pLutInt[ nY ]; 1295cdf0e10cSrcweir pLutFrac[ nY ] = (long) ( fTemp * 1024. ); 1296cdf0e10cSrcweir } 1297cdf0e10cSrcweir 1298c2821885SArmin Le Grand // after 1st step, bitmap *is* 24bit format (see above) 1299c2821885SArmin Le Grand OSL_ENSURE(!pReadAcc->HasPalette(), "OOps, somehow ImplScaleInterpolate in-between format has palette, should not happen (!)"); 1300c2821885SArmin Le Grand 1301c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1302cdf0e10cSrcweir { 1303c2821885SArmin Le Grand if( 1 == nHeight ) 1304cdf0e10cSrcweir { 1305c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( 0, nX ); 1306cdf0e10cSrcweir 1307c2821885SArmin Le Grand for( nY = 0L; nY < nNewHeight; nY++ ) 1308c2821885SArmin Le Grand { 1309c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1310c2821885SArmin Le Grand } 1311cdf0e10cSrcweir } 1312c2821885SArmin Le Grand else 1313cdf0e10cSrcweir { 1314c2821885SArmin Le Grand for( nY = 0L; nY < nNewHeight; nY++ ) 1315cdf0e10cSrcweir { 1316c2821885SArmin Le Grand nTemp = pLutInt[ nY ]; 1317cdf0e10cSrcweir 1318c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( nTemp++, nX ); 1319c2821885SArmin Le Grand aCol1 = pReadAcc->GetPixel( nTemp, nX ); 1320cdf0e10cSrcweir 1321c2821885SArmin Le Grand nTemp = pLutFrac[ nY ]; 1322cdf0e10cSrcweir 1323c2821885SArmin Le Grand lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() ); 1324c2821885SArmin Le Grand lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() ); 1325c2821885SArmin Le Grand lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() ); 1326cdf0e10cSrcweir 1327c2821885SArmin Le Grand aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); 1328c2821885SArmin Le Grand aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); 1329c2821885SArmin Le Grand aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) ); 1330cdf0e10cSrcweir 1331c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1332cdf0e10cSrcweir } 1333cdf0e10cSrcweir } 1334cdf0e10cSrcweir } 1335cdf0e10cSrcweir 1336cdf0e10cSrcweir delete[] pLutInt; 1337cdf0e10cSrcweir delete[] pLutFrac; 1338cdf0e10cSrcweir bRet = sal_True; 1339cdf0e10cSrcweir } 1340cdf0e10cSrcweir 1341cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1342cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1343cdf0e10cSrcweir 1344cdf0e10cSrcweir if( bRet ) 134537ab0f2dSArmin Le Grand { 1346561c4886SArmin Le Grand aOriginal.ImplAdaptBitCount(aNewBmp); 1347c2821885SArmin Le Grand *this = aNewBmp; 134837ab0f2dSArmin Le Grand } 1349cdf0e10cSrcweir } 1350cdf0e10cSrcweir } 1351cdf0e10cSrcweir 1352cdf0e10cSrcweir if( !bRet ) 1353c2821885SArmin Le Grand { 1354cdf0e10cSrcweir bRet = ImplScaleFast( rScaleX, rScaleY ); 1355c2821885SArmin Le Grand } 1356cdf0e10cSrcweir 1357cdf0e10cSrcweir return bRet; 1358cdf0e10cSrcweir } 1359cdf0e10cSrcweir 136037ab0f2dSArmin Le Grand // ------------------------------------------------------------------------ 136137ab0f2dSArmin Le Grand // #121233# Added BMP_SCALE_SUPER from symphony code 136237ab0f2dSArmin Le Grand 136337ab0f2dSArmin Le Grand sal_Bool Bitmap::ImplScaleSuper( 136437ab0f2dSArmin Le Grand const double& rScaleX, 136537ab0f2dSArmin Le Grand const double& rScaleY ) 136637ab0f2dSArmin Le Grand { 136737ab0f2dSArmin Le Grand const Size aSizePix( GetSizePixel() ); 136837ab0f2dSArmin Le Grand bool bHMirr = ( rScaleX < 0 ); 136937ab0f2dSArmin Le Grand bool bVMirr = ( rScaleY < 0 ); 137037ab0f2dSArmin Le Grand double scaleX = bHMirr ? -rScaleX : rScaleX; 137137ab0f2dSArmin Le Grand double scaleY = bVMirr ? -rScaleY : rScaleY; 137237ab0f2dSArmin Le Grand const long nDstW = FRound( aSizePix.Width() * scaleX ); 137337ab0f2dSArmin Le Grand const long nDstH = FRound( aSizePix.Height() * scaleY ); 137437ab0f2dSArmin Le Grand const double fScaleThresh = 0.6; 137537ab0f2dSArmin Le Grand bool bRet = false; 137637ab0f2dSArmin Le Grand 137737ab0f2dSArmin Le Grand if( ( nDstW > 1L ) && ( nDstH > 1L ) ) 137837ab0f2dSArmin Le Grand { 137937ab0f2dSArmin Le Grand BitmapColor aCol0, aCol1, aColRes; 138037ab0f2dSArmin Le Grand BitmapReadAccess* pAcc = AcquireReadAccess(); 138137ab0f2dSArmin Le Grand long nW = pAcc->Width() ; 138237ab0f2dSArmin Le Grand long nH = pAcc->Height() ; 138337ab0f2dSArmin Le Grand Bitmap aOutBmp( Size( nDstW, nDstH ), 24 ); 138437ab0f2dSArmin Le Grand BitmapWriteAccess* pWAcc = aOutBmp.AcquireWriteAccess(); 138537ab0f2dSArmin Le Grand long* pMapIX = new long[ nDstW ]; 138637ab0f2dSArmin Le Grand long* pMapIY = new long[ nDstH ]; 138737ab0f2dSArmin Le Grand long* pMapFX = new long[ nDstW ]; 138837ab0f2dSArmin Le Grand long* pMapFY = new long[ nDstH ]; 138937ab0f2dSArmin Le Grand long nX, nY, nXDst, nYDst;; 139037ab0f2dSArmin Le Grand double fTemp; 139137ab0f2dSArmin Le Grand long nTemp , nTempX, nTempY, nTempFX, nTempFY; 139237ab0f2dSArmin Le Grand sal_uInt8 cR0, cG0, cB0, cR1, cG1, cB1; 139337ab0f2dSArmin Le Grand long nStartX = 0 , nStartY = 0; 139437ab0f2dSArmin Le Grand long nEndX = nDstW - 1L; 139537ab0f2dSArmin Le Grand long nEndY = nDstH - 1L; 139637ab0f2dSArmin Le Grand long nMax = 1 << 7L; 139737ab0f2dSArmin Le Grand 139837ab0f2dSArmin Le Grand if( pAcc && pWAcc ) 139937ab0f2dSArmin Le Grand { 140037ab0f2dSArmin Le Grand const double fRevScaleX = ( nDstW > 1L ) ? ( (double) ( nW - 1 ) / ( nDstW - 1 ) ) : 0.0; 140137ab0f2dSArmin Le Grand const double fRevScaleY = ( nDstH > 1L ) ? ( (double) ( nH - 1 ) / ( nDstH - 1 ) ) : 0.0; 140237ab0f2dSArmin Le Grand 140337ab0f2dSArmin Le Grand // create horizontal mapping table 140437ab0f2dSArmin Le Grand for( nX = 0L, nTempX = nW - 1L, nTemp = nW - 2L; nX < nDstW; nX++ ) 140537ab0f2dSArmin Le Grand { 140637ab0f2dSArmin Le Grand fTemp = nX * fRevScaleX; 140737ab0f2dSArmin Le Grand 140837ab0f2dSArmin Le Grand if( bHMirr ) 140937ab0f2dSArmin Le Grand fTemp = nTempX - fTemp; 141037ab0f2dSArmin Le Grand 141137ab0f2dSArmin Le Grand pMapFX[ nX ] = (long) ( ( fTemp - ( pMapIX[ nX ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. ); 141237ab0f2dSArmin Le Grand } 141337ab0f2dSArmin Le Grand 141437ab0f2dSArmin Le Grand // create vertical mapping table 141537ab0f2dSArmin Le Grand for( nY = 0L, nTempY = nH - 1L, nTemp = nH - 2L; nY < nDstH; nY++ ) 141637ab0f2dSArmin Le Grand { 141737ab0f2dSArmin Le Grand fTemp = nY * fRevScaleY; 141837ab0f2dSArmin Le Grand 141937ab0f2dSArmin Le Grand if( bVMirr ) 142037ab0f2dSArmin Le Grand fTemp = nTempY - fTemp; 142137ab0f2dSArmin Le Grand 142237ab0f2dSArmin Le Grand pMapFY[ nY ] = (long) ( ( fTemp - ( pMapIY[ nY ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. ); 142337ab0f2dSArmin Le Grand } 142437ab0f2dSArmin Le Grand 142537ab0f2dSArmin Le Grand if( pAcc->HasPalette() ) 142637ab0f2dSArmin Le Grand { 142737ab0f2dSArmin Le Grand if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ) 142837ab0f2dSArmin Le Grand { 142937ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 143037ab0f2dSArmin Le Grand { 143137ab0f2dSArmin Le Grand Scanline pLine0, pLine1; 143237ab0f2dSArmin Le Grand 143337ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 143437ab0f2dSArmin Le Grand { 143537ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 143637ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 143737ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 143837ab0f2dSArmin Le Grand 143937ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 144037ab0f2dSArmin Le Grand { 144137ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 144237ab0f2dSArmin Le Grand 144337ab0f2dSArmin Le Grand const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTempX ] ); 144437ab0f2dSArmin Le Grand const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTempX ] ); 144537ab0f2dSArmin Le Grand const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTempX ] ); 144637ab0f2dSArmin Le Grand const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTempX ] ); 144737ab0f2dSArmin Le Grand 144837ab0f2dSArmin Le Grand cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTempFX ); 144937ab0f2dSArmin Le Grand cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTempFX ); 145037ab0f2dSArmin Le Grand cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTempFX ); 145137ab0f2dSArmin Le Grand 145237ab0f2dSArmin Le Grand cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTempFX ); 145337ab0f2dSArmin Le Grand cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTempFX ); 145437ab0f2dSArmin Le Grand cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTempFX ); 145537ab0f2dSArmin Le Grand 145637ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 145737ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 145837ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 145937ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 146037ab0f2dSArmin Le Grand } 146137ab0f2dSArmin Le Grand } 146237ab0f2dSArmin Le Grand } 146337ab0f2dSArmin Le Grand else 146437ab0f2dSArmin Le Grand { 146537ab0f2dSArmin Le Grand Scanline pTmpY; 146637ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 146737ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 146837ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 146937ab0f2dSArmin Le Grand 147037ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 147137ab0f2dSArmin Le Grand { 147237ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 147337ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 147437ab0f2dSArmin Le Grand 147537ab0f2dSArmin Le Grand if( nY ==nEndY ) 147637ab0f2dSArmin Le Grand { 147737ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 147837ab0f2dSArmin Le Grand nLineRange = 0; 147937ab0f2dSArmin Le Grand } 148037ab0f2dSArmin Le Grand else 148137ab0f2dSArmin Le Grand { 148237ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 148337ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 148437ab0f2dSArmin Le Grand } 148537ab0f2dSArmin Le Grand 148637ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 148737ab0f2dSArmin Le Grand { 148837ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 148937ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 149037ab0f2dSArmin Le Grand 149137ab0f2dSArmin Le Grand if( nX == nEndX ) 149237ab0f2dSArmin Le Grand { 149337ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 149437ab0f2dSArmin Le Grand nRowRange = 0; 149537ab0f2dSArmin Le Grand } 149637ab0f2dSArmin Le Grand else 149737ab0f2dSArmin Le Grand { 149837ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 149937ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 150037ab0f2dSArmin Le Grand } 150137ab0f2dSArmin Le Grand 150237ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 150337ab0f2dSArmin Le Grand nTotalWeightY = 0; 150437ab0f2dSArmin Le Grand 150537ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 150637ab0f2dSArmin Le Grand { 150737ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 150837ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 150937ab0f2dSArmin Le Grand nTotalWeightX = 0; 151037ab0f2dSArmin Le Grand 151137ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 151237ab0f2dSArmin Le Grand { 151337ab0f2dSArmin Le Grand const BitmapColor& rCol = pAcc->GetPaletteColor( pTmpY[ nRowStart + j ] ); 151437ab0f2dSArmin Le Grand 151537ab0f2dSArmin Le Grand if(nX == nEndX ) 151637ab0f2dSArmin Le Grand { 151737ab0f2dSArmin Le Grand nSumRowB += rCol.GetBlue() << 7L; 151837ab0f2dSArmin Le Grand nSumRowG += rCol.GetGreen() << 7L; 151937ab0f2dSArmin Le Grand nSumRowR += rCol.GetRed() << 7L; 152037ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 152137ab0f2dSArmin Le Grand } 152237ab0f2dSArmin Le Grand else if( j == 0 ) 152337ab0f2dSArmin Le Grand { 152437ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 152537ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *rCol.GetBlue()) ; 152637ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *rCol.GetGreen()) ; 152737ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *rCol.GetRed()) ; 152837ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 152937ab0f2dSArmin Le Grand } 153037ab0f2dSArmin Le Grand else if ( nRowRange == j ) 153137ab0f2dSArmin Le Grand { 153237ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 153337ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *rCol.GetBlue() ); 153437ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *rCol.GetGreen() ); 153537ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *rCol.GetRed() ); 153637ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 153737ab0f2dSArmin Le Grand } 153837ab0f2dSArmin Le Grand else 153937ab0f2dSArmin Le Grand { 154037ab0f2dSArmin Le Grand nSumRowB += rCol.GetBlue() << 7L; 154137ab0f2dSArmin Le Grand nSumRowG += rCol.GetGreen() << 7L; 154237ab0f2dSArmin Le Grand nSumRowR += rCol.GetRed() << 7L; 154337ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 154437ab0f2dSArmin Le Grand } 154537ab0f2dSArmin Le Grand } 154637ab0f2dSArmin Le Grand 154737ab0f2dSArmin Le Grand if( nY == nEndY ) 154837ab0f2dSArmin Le Grand nWeightY = nMax; 154937ab0f2dSArmin Le Grand else if( i == 0 ) 155037ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 155137ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 155237ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 155337ab0f2dSArmin Le Grand else if ( nLineRange == i ) 155437ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 155537ab0f2dSArmin Le Grand else 155637ab0f2dSArmin Le Grand nWeightY = nMax; 155737ab0f2dSArmin Le Grand 155837ab0f2dSArmin Le Grand nWeightY = nWeightY ; 155937ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 156037ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 156137ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 156237ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 156337ab0f2dSArmin Le Grand } 156437ab0f2dSArmin Le Grand 156537ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 156637ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 156737ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 156837ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 156937ab0f2dSArmin Le Grand 157037ab0f2dSArmin Le Grand } 157137ab0f2dSArmin Le Grand } 157237ab0f2dSArmin Le Grand } 157337ab0f2dSArmin Le Grand } 157437ab0f2dSArmin Le Grand else 157537ab0f2dSArmin Le Grand { 157637ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 157737ab0f2dSArmin Le Grand { 157837ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 157937ab0f2dSArmin Le Grand { 158037ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ], nTempFY = pMapFY[ nY ]; 158137ab0f2dSArmin Le Grand 158237ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 158337ab0f2dSArmin Le Grand { 158437ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 158537ab0f2dSArmin Le Grand 158637ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, nTempX ) ); 158737ab0f2dSArmin Le Grand aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, ++nTempX ) ); 158837ab0f2dSArmin Le Grand cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 158937ab0f2dSArmin Le Grand cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 159037ab0f2dSArmin Le Grand cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 159137ab0f2dSArmin Le Grand 159237ab0f2dSArmin Le Grand aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( ++nTempY, nTempX ) ); 159337ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY--, --nTempX ) ); 159437ab0f2dSArmin Le Grand cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 159537ab0f2dSArmin Le Grand cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 159637ab0f2dSArmin Le Grand cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 159737ab0f2dSArmin Le Grand 159837ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 159937ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 160037ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 160137ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 160237ab0f2dSArmin Le Grand } 160337ab0f2dSArmin Le Grand } 160437ab0f2dSArmin Le Grand 160537ab0f2dSArmin Le Grand } 160637ab0f2dSArmin Le Grand else 160737ab0f2dSArmin Le Grand { 160837ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 160937ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 161037ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 161137ab0f2dSArmin Le Grand 161237ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 161337ab0f2dSArmin Le Grand { 161437ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 161537ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 161637ab0f2dSArmin Le Grand 161737ab0f2dSArmin Le Grand if( nY ==nEndY ) 161837ab0f2dSArmin Le Grand { 161937ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 162037ab0f2dSArmin Le Grand nLineRange = 0; 162137ab0f2dSArmin Le Grand } 162237ab0f2dSArmin Le Grand else 162337ab0f2dSArmin Le Grand { 162437ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 162537ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 162637ab0f2dSArmin Le Grand } 162737ab0f2dSArmin Le Grand 162837ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 162937ab0f2dSArmin Le Grand { 163037ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 163137ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 163237ab0f2dSArmin Le Grand 163337ab0f2dSArmin Le Grand if( nX == nEndX ) 163437ab0f2dSArmin Le Grand { 163537ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 163637ab0f2dSArmin Le Grand nRowRange = 0; 163737ab0f2dSArmin Le Grand } 163837ab0f2dSArmin Le Grand else 163937ab0f2dSArmin Le Grand { 164037ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 164137ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 164237ab0f2dSArmin Le Grand } 164337ab0f2dSArmin Le Grand 164437ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 164537ab0f2dSArmin Le Grand nTotalWeightY = 0; 164637ab0f2dSArmin Le Grand 164737ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 164837ab0f2dSArmin Le Grand { 164937ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 165037ab0f2dSArmin Le Grand nTotalWeightX = 0; 165137ab0f2dSArmin Le Grand 165237ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 165337ab0f2dSArmin Le Grand { 165437ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor ( pAcc->GetPixelIndex( nLineStart + i, nRowStart + j ) ); 165537ab0f2dSArmin Le Grand 165637ab0f2dSArmin Le Grand if(nX == nEndX ) 165737ab0f2dSArmin Le Grand { 165837ab0f2dSArmin Le Grand 165937ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 166037ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 166137ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 166237ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 166337ab0f2dSArmin Le Grand } 166437ab0f2dSArmin Le Grand else if( j == 0 ) 166537ab0f2dSArmin Le Grand { 166637ab0f2dSArmin Le Grand 166737ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 166837ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue()) ; 166937ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen()) ; 167037ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed()) ; 167137ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 167237ab0f2dSArmin Le Grand } 167337ab0f2dSArmin Le Grand else if ( nRowRange == j ) 167437ab0f2dSArmin Le Grand { 167537ab0f2dSArmin Le Grand 167637ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 167737ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue() ); 167837ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen() ); 167937ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed() ); 168037ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 168137ab0f2dSArmin Le Grand } 168237ab0f2dSArmin Le Grand else 168337ab0f2dSArmin Le Grand { 168437ab0f2dSArmin Le Grand 168537ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 168637ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 168737ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 168837ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 168937ab0f2dSArmin Le Grand } 169037ab0f2dSArmin Le Grand } 169137ab0f2dSArmin Le Grand 169237ab0f2dSArmin Le Grand if( nY == nEndY ) 169337ab0f2dSArmin Le Grand nWeightY = nMax; 169437ab0f2dSArmin Le Grand else if( i == 0 ) 169537ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 169637ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 169737ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 169837ab0f2dSArmin Le Grand else if ( nLineRange == i ) 169937ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 170037ab0f2dSArmin Le Grand else 170137ab0f2dSArmin Le Grand nWeightY = nMax; 170237ab0f2dSArmin Le Grand 170337ab0f2dSArmin Le Grand nWeightY = nWeightY ; 170437ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 170537ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 170637ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 170737ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 170837ab0f2dSArmin Le Grand } 170937ab0f2dSArmin Le Grand 171037ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 171137ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 171237ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 171337ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 171437ab0f2dSArmin Le Grand } 171537ab0f2dSArmin Le Grand } 171637ab0f2dSArmin Le Grand } 171737ab0f2dSArmin Le Grand } 171837ab0f2dSArmin Le Grand } 171937ab0f2dSArmin Le Grand else 172037ab0f2dSArmin Le Grand { 172137ab0f2dSArmin Le Grand if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ) 172237ab0f2dSArmin Le Grand { 172337ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 172437ab0f2dSArmin Le Grand { 172537ab0f2dSArmin Le Grand Scanline pLine0, pLine1, pTmp0, pTmp1; 172637ab0f2dSArmin Le Grand long nOff; 172737ab0f2dSArmin Le Grand 172837ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 172937ab0f2dSArmin Le Grand { 173037ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 173137ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 173237ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 173337ab0f2dSArmin Le Grand 173437ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 173537ab0f2dSArmin Le Grand { 173637ab0f2dSArmin Le Grand nOff = 3L * ( nTempX = pMapIX[ nX ] ); 173737ab0f2dSArmin Le Grand nTempFX = pMapFX[ nX ]; 173837ab0f2dSArmin Le Grand 173937ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L; 174037ab0f2dSArmin Le Grand cB0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 174137ab0f2dSArmin Le Grand cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 174237ab0f2dSArmin Le Grand cR0 = MAP( *pTmp0, *pTmp1, nTempFX ); 174337ab0f2dSArmin Le Grand 174437ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L; 174537ab0f2dSArmin Le Grand cB1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 174637ab0f2dSArmin Le Grand cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 174737ab0f2dSArmin Le Grand cR1 = MAP( *pTmp0, *pTmp1, nTempFX ); 174837ab0f2dSArmin Le Grand 174937ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 175037ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 175137ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 175237ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 175337ab0f2dSArmin Le Grand } 175437ab0f2dSArmin Le Grand } 175537ab0f2dSArmin Le Grand } 175637ab0f2dSArmin Le Grand else 175737ab0f2dSArmin Le Grand { 175837ab0f2dSArmin Le Grand Scanline pTmpY, pTmpX; 175937ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 176037ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 176137ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 176237ab0f2dSArmin Le Grand 176337ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 176437ab0f2dSArmin Le Grand { 176537ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 176637ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 176737ab0f2dSArmin Le Grand 176837ab0f2dSArmin Le Grand if( nY ==nEndY ) 176937ab0f2dSArmin Le Grand { 177037ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 177137ab0f2dSArmin Le Grand nLineRange = 0; 177237ab0f2dSArmin Le Grand } 177337ab0f2dSArmin Le Grand else 177437ab0f2dSArmin Le Grand { 177537ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 177637ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 177737ab0f2dSArmin Le Grand } 177837ab0f2dSArmin Le Grand 177937ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 178037ab0f2dSArmin Le Grand { 178137ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 178237ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 178337ab0f2dSArmin Le Grand 178437ab0f2dSArmin Le Grand if( nX == nEndX ) 178537ab0f2dSArmin Le Grand { 178637ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 178737ab0f2dSArmin Le Grand nRowRange = 0; 178837ab0f2dSArmin Le Grand } 178937ab0f2dSArmin Le Grand else 179037ab0f2dSArmin Le Grand { 179137ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 179237ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 179337ab0f2dSArmin Le Grand } 179437ab0f2dSArmin Le Grand 179537ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 179637ab0f2dSArmin Le Grand nTotalWeightY = 0; 179737ab0f2dSArmin Le Grand 179837ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 179937ab0f2dSArmin Le Grand { 180037ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 180137ab0f2dSArmin Le Grand pTmpX = pTmpY + 3L * nRowStart; 180237ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 180337ab0f2dSArmin Le Grand nTotalWeightX = 0; 180437ab0f2dSArmin Le Grand 180537ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 180637ab0f2dSArmin Le Grand { 180737ab0f2dSArmin Le Grand if(nX == nEndX ) 180837ab0f2dSArmin Le Grand { 180937ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 181037ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 181137ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 181237ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 181337ab0f2dSArmin Le Grand } 181437ab0f2dSArmin Le Grand else if( j == 0 ) 181537ab0f2dSArmin Le Grand { 181637ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 181737ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++; 181837ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++; 181937ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++; 182037ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 182137ab0f2dSArmin Le Grand } 182237ab0f2dSArmin Le Grand else if ( nRowRange == j ) 182337ab0f2dSArmin Le Grand { 182437ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 182537ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++; 182637ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++; 182737ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++; 182837ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 182937ab0f2dSArmin Le Grand } 183037ab0f2dSArmin Le Grand else 183137ab0f2dSArmin Le Grand { 183237ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 183337ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 183437ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 183537ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 183637ab0f2dSArmin Le Grand } 183737ab0f2dSArmin Le Grand } 183837ab0f2dSArmin Le Grand 183937ab0f2dSArmin Le Grand if( nY == nEndY ) 184037ab0f2dSArmin Le Grand nWeightY = nMax; 184137ab0f2dSArmin Le Grand else if( i == 0 ) 184237ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 184337ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 184437ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 184537ab0f2dSArmin Le Grand else if ( nLineRange == i ) 184637ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 184737ab0f2dSArmin Le Grand else 184837ab0f2dSArmin Le Grand nWeightY = nMax; 184937ab0f2dSArmin Le Grand 185037ab0f2dSArmin Le Grand nWeightY = nWeightY ; 185137ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 185237ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 185337ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 185437ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 185537ab0f2dSArmin Le Grand } 185637ab0f2dSArmin Le Grand 185737ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 185837ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 185937ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 186037ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 186137ab0f2dSArmin Le Grand 186237ab0f2dSArmin Le Grand } 186337ab0f2dSArmin Le Grand } 186437ab0f2dSArmin Le Grand } 186537ab0f2dSArmin Le Grand } 186637ab0f2dSArmin Le Grand else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ) 186737ab0f2dSArmin Le Grand { 186837ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 186937ab0f2dSArmin Le Grand { 187037ab0f2dSArmin Le Grand Scanline pLine0, pLine1, pTmp0, pTmp1; 187137ab0f2dSArmin Le Grand long nOff; 187237ab0f2dSArmin Le Grand 187337ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 187437ab0f2dSArmin Le Grand { 187537ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 187637ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 187737ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 187837ab0f2dSArmin Le Grand 187937ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 188037ab0f2dSArmin Le Grand { 188137ab0f2dSArmin Le Grand nOff = 3L * ( nTempX = pMapIX[ nX ] ); 188237ab0f2dSArmin Le Grand nTempFX = pMapFX[ nX ]; 188337ab0f2dSArmin Le Grand 188437ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L; 188537ab0f2dSArmin Le Grand cR0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 188637ab0f2dSArmin Le Grand cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 188737ab0f2dSArmin Le Grand cB0 = MAP( *pTmp0, *pTmp1, nTempFX ); 188837ab0f2dSArmin Le Grand 188937ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L; 189037ab0f2dSArmin Le Grand cR1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 189137ab0f2dSArmin Le Grand cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 189237ab0f2dSArmin Le Grand cB1 = MAP( *pTmp0, *pTmp1, nTempFX ); 189337ab0f2dSArmin Le Grand 189437ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 189537ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 189637ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 189737ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 189837ab0f2dSArmin Le Grand } 189937ab0f2dSArmin Le Grand } 190037ab0f2dSArmin Le Grand } 190137ab0f2dSArmin Le Grand else 190237ab0f2dSArmin Le Grand { 190337ab0f2dSArmin Le Grand Scanline pTmpY, pTmpX; 190437ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 190537ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 190637ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 190737ab0f2dSArmin Le Grand 190837ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 190937ab0f2dSArmin Le Grand { 191037ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 191137ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 191237ab0f2dSArmin Le Grand 191337ab0f2dSArmin Le Grand if( nY ==nEndY ) 191437ab0f2dSArmin Le Grand { 191537ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 191637ab0f2dSArmin Le Grand nLineRange = 0; 191737ab0f2dSArmin Le Grand } 191837ab0f2dSArmin Le Grand else 191937ab0f2dSArmin Le Grand { 192037ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 192137ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 192237ab0f2dSArmin Le Grand } 192337ab0f2dSArmin Le Grand 192437ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 192537ab0f2dSArmin Le Grand { 192637ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 192737ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 192837ab0f2dSArmin Le Grand 192937ab0f2dSArmin Le Grand if( nX == nEndX ) 193037ab0f2dSArmin Le Grand { 193137ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 193237ab0f2dSArmin Le Grand nRowRange = 0; 193337ab0f2dSArmin Le Grand } 193437ab0f2dSArmin Le Grand else 193537ab0f2dSArmin Le Grand { 193637ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 193737ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 193837ab0f2dSArmin Le Grand } 193937ab0f2dSArmin Le Grand 194037ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 194137ab0f2dSArmin Le Grand nTotalWeightY = 0; 194237ab0f2dSArmin Le Grand 194337ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 194437ab0f2dSArmin Le Grand { 194537ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 194637ab0f2dSArmin Le Grand pTmpX = pTmpY + 3L * nRowStart; 194737ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 194837ab0f2dSArmin Le Grand nTotalWeightX = 0; 194937ab0f2dSArmin Le Grand 195037ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 195137ab0f2dSArmin Le Grand { 195237ab0f2dSArmin Le Grand if(nX == nEndX ) 195337ab0f2dSArmin Le Grand { 195437ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 195537ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 195637ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 195737ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 195837ab0f2dSArmin Le Grand } 195937ab0f2dSArmin Le Grand else if( j == 0 ) 196037ab0f2dSArmin Le Grand { 196137ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 196237ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++; 196337ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++; 196437ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++; 196537ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 196637ab0f2dSArmin Le Grand } 196737ab0f2dSArmin Le Grand else if ( nRowRange == j ) 196837ab0f2dSArmin Le Grand { 196937ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 197037ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++; 197137ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++; 197237ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++; 197337ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 197437ab0f2dSArmin Le Grand } 197537ab0f2dSArmin Le Grand else 197637ab0f2dSArmin Le Grand { 197737ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 197837ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 197937ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 198037ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 198137ab0f2dSArmin Le Grand } 198237ab0f2dSArmin Le Grand } 198337ab0f2dSArmin Le Grand 198437ab0f2dSArmin Le Grand if( nY == nEndY ) 198537ab0f2dSArmin Le Grand nWeightY = nMax; 198637ab0f2dSArmin Le Grand else if( i == 0 ) 198737ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 198837ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 198937ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 199037ab0f2dSArmin Le Grand else if ( nLineRange == i ) 199137ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 199237ab0f2dSArmin Le Grand else 199337ab0f2dSArmin Le Grand nWeightY = nMax; 199437ab0f2dSArmin Le Grand 199537ab0f2dSArmin Le Grand nWeightY = nWeightY ; 199637ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 199737ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 199837ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 199937ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 200037ab0f2dSArmin Le Grand } 200137ab0f2dSArmin Le Grand 200237ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 200337ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 200437ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 200537ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 200637ab0f2dSArmin Le Grand 200737ab0f2dSArmin Le Grand } 200837ab0f2dSArmin Le Grand } 200937ab0f2dSArmin Le Grand } 201037ab0f2dSArmin Le Grand } 201137ab0f2dSArmin Le Grand else 201237ab0f2dSArmin Le Grand { 201337ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 201437ab0f2dSArmin Le Grand { 201537ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 201637ab0f2dSArmin Le Grand { 201737ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 201837ab0f2dSArmin Le Grand 201937ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 202037ab0f2dSArmin Le Grand { 202137ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 202237ab0f2dSArmin Le Grand 202337ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nTempY, nTempX ); 202437ab0f2dSArmin Le Grand aCol1 = pAcc->GetPixel( nTempY, ++nTempX ); 202537ab0f2dSArmin Le Grand cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 202637ab0f2dSArmin Le Grand cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 202737ab0f2dSArmin Le Grand cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 202837ab0f2dSArmin Le Grand 202937ab0f2dSArmin Le Grand aCol1 = pAcc->GetPixel( ++nTempY, nTempX ); 203037ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nTempY--, --nTempX ); 203137ab0f2dSArmin Le Grand cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 203237ab0f2dSArmin Le Grand cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 203337ab0f2dSArmin Le Grand cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 203437ab0f2dSArmin Le Grand 203537ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 203637ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 203737ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 203837ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 203937ab0f2dSArmin Le Grand } 204037ab0f2dSArmin Le Grand } 204137ab0f2dSArmin Le Grand } 204237ab0f2dSArmin Le Grand else 204337ab0f2dSArmin Le Grand { 204437ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 204537ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 204637ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 204737ab0f2dSArmin Le Grand 204837ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 204937ab0f2dSArmin Le Grand { 205037ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 205137ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 205237ab0f2dSArmin Le Grand 205337ab0f2dSArmin Le Grand if( nY ==nEndY ) 205437ab0f2dSArmin Le Grand { 205537ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 205637ab0f2dSArmin Le Grand nLineRange = 0; 205737ab0f2dSArmin Le Grand } 205837ab0f2dSArmin Le Grand else 205937ab0f2dSArmin Le Grand { 206037ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 206137ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 206237ab0f2dSArmin Le Grand } 206337ab0f2dSArmin Le Grand 206437ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 206537ab0f2dSArmin Le Grand { 206637ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 206737ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 206837ab0f2dSArmin Le Grand 206937ab0f2dSArmin Le Grand if( nX == nEndX ) 207037ab0f2dSArmin Le Grand { 207137ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 207237ab0f2dSArmin Le Grand nRowRange = 0; 207337ab0f2dSArmin Le Grand } 207437ab0f2dSArmin Le Grand else 207537ab0f2dSArmin Le Grand { 207637ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 207737ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 207837ab0f2dSArmin Le Grand } 207937ab0f2dSArmin Le Grand 208037ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 208137ab0f2dSArmin Le Grand nTotalWeightY = 0; 208237ab0f2dSArmin Le Grand 208337ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 208437ab0f2dSArmin Le Grand { 208537ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 208637ab0f2dSArmin Le Grand nTotalWeightX = 0; 208737ab0f2dSArmin Le Grand 208837ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 208937ab0f2dSArmin Le Grand { 209037ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nLineStart + i, nRowStart + j ); 209137ab0f2dSArmin Le Grand 209237ab0f2dSArmin Le Grand if(nX == nEndX ) 209337ab0f2dSArmin Le Grand { 209437ab0f2dSArmin Le Grand 209537ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 209637ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 209737ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 209837ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 209937ab0f2dSArmin Le Grand } 210037ab0f2dSArmin Le Grand else if( j == 0 ) 210137ab0f2dSArmin Le Grand { 210237ab0f2dSArmin Le Grand 210337ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 210437ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue()) ; 210537ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen()) ; 210637ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed()) ; 210737ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 210837ab0f2dSArmin Le Grand } 210937ab0f2dSArmin Le Grand else if ( nRowRange == j ) 211037ab0f2dSArmin Le Grand { 211137ab0f2dSArmin Le Grand 211237ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 211337ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue() ); 211437ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen() ); 211537ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed() ); 211637ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 211737ab0f2dSArmin Le Grand } 211837ab0f2dSArmin Le Grand else 211937ab0f2dSArmin Le Grand { 212037ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 212137ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 212237ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 212337ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 212437ab0f2dSArmin Le Grand } 212537ab0f2dSArmin Le Grand } 212637ab0f2dSArmin Le Grand 212737ab0f2dSArmin Le Grand if( nY == nEndY ) 212837ab0f2dSArmin Le Grand nWeightY = nMax; 212937ab0f2dSArmin Le Grand else if( i == 0 ) 213037ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 213137ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 213237ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 213337ab0f2dSArmin Le Grand else if ( nLineRange == i ) 213437ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 213537ab0f2dSArmin Le Grand else 213637ab0f2dSArmin Le Grand nWeightY = nMax; 213737ab0f2dSArmin Le Grand 213837ab0f2dSArmin Le Grand nWeightY = nWeightY ; 213937ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 214037ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 214137ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 214237ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 214337ab0f2dSArmin Le Grand } 214437ab0f2dSArmin Le Grand 214537ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 214637ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 214737ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 214837ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 214937ab0f2dSArmin Le Grand 215037ab0f2dSArmin Le Grand } 215137ab0f2dSArmin Le Grand } 215237ab0f2dSArmin Le Grand } 215337ab0f2dSArmin Le Grand } 215437ab0f2dSArmin Le Grand } 215537ab0f2dSArmin Le Grand 215637ab0f2dSArmin Le Grand bRet = true; 215737ab0f2dSArmin Le Grand } 215837ab0f2dSArmin Le Grand 215937ab0f2dSArmin Le Grand delete[] pMapIX; 216037ab0f2dSArmin Le Grand delete[] pMapIY; 216137ab0f2dSArmin Le Grand delete[] pMapFX; 216237ab0f2dSArmin Le Grand delete[] pMapFY; 216337ab0f2dSArmin Le Grand 216437ab0f2dSArmin Le Grand ReleaseAccess( pAcc ); 216537ab0f2dSArmin Le Grand aOutBmp.ReleaseAccess( pWAcc ); 216637ab0f2dSArmin Le Grand 216737ab0f2dSArmin Le Grand if( bRet ) 216837ab0f2dSArmin Le Grand { 216937ab0f2dSArmin Le Grand ImplAdaptBitCount(aOutBmp); 217037ab0f2dSArmin Le Grand ImplAssignWithSize(aOutBmp); 217137ab0f2dSArmin Le Grand } 217237ab0f2dSArmin Le Grand 217337ab0f2dSArmin Le Grand if( !bRet ) 217437ab0f2dSArmin Le Grand bRet = ImplScaleFast( scaleX, scaleY ); 217537ab0f2dSArmin Le Grand } 217637ab0f2dSArmin Le Grand 217737ab0f2dSArmin Le Grand return bRet; 217837ab0f2dSArmin Le Grand } 217937ab0f2dSArmin Le Grand 218037ab0f2dSArmin Le Grand //----------------------------------------------------------------------------------- 218137ab0f2dSArmin Le Grand 218237ab0f2dSArmin Le Grand namespace 218337ab0f2dSArmin Le Grand { 218437ab0f2dSArmin Le Grand void ImplCalculateContributions( 218537ab0f2dSArmin Le Grand const sal_uInt32 aSourceSize, 218637ab0f2dSArmin Le Grand const sal_uInt32 aDestinationSize, 218737ab0f2dSArmin Le Grand sal_uInt32& aNumberOfContributions, 218837ab0f2dSArmin Le Grand double*& pWeights, 218937ab0f2dSArmin Le Grand sal_uInt32*& pPixels, 219037ab0f2dSArmin Le Grand sal_uInt32*& pCount, 219137ab0f2dSArmin Le Grand const Kernel& aKernel) 219237ab0f2dSArmin Le Grand { 219337ab0f2dSArmin Le Grand const double fSamplingRadius(aKernel.GetWidth()); 219437ab0f2dSArmin Le Grand const double fScale(aDestinationSize / static_cast< double >(aSourceSize)); 219537ab0f2dSArmin Le Grand const double fScaledRadius((fScale < 1.0) ? fSamplingRadius / fScale : fSamplingRadius); 219637ab0f2dSArmin Le Grand const double fFilterFactor((fScale < 1.0) ? fScale : 1.0); 219737ab0f2dSArmin Le Grand 219837ab0f2dSArmin Le Grand aNumberOfContributions = (static_cast< sal_uInt32 >(fabs(ceil(fScaledRadius))) * 2) + 1; 219937ab0f2dSArmin Le Grand const sal_uInt32 nAllocSize(aDestinationSize * aNumberOfContributions); 220037ab0f2dSArmin Le Grand pWeights = new double[nAllocSize]; 220137ab0f2dSArmin Le Grand pPixels = new sal_uInt32[nAllocSize]; 220237ab0f2dSArmin Le Grand pCount = new sal_uInt32[aDestinationSize]; 220337ab0f2dSArmin Le Grand 220437ab0f2dSArmin Le Grand for(sal_uInt32 i(0); i < aDestinationSize; i++) 220537ab0f2dSArmin Le Grand { 220637ab0f2dSArmin Le Grand const sal_uInt32 aIndex(i * aNumberOfContributions); 220737ab0f2dSArmin Le Grand const double aCenter(i / fScale); 220837ab0f2dSArmin Le Grand const sal_Int32 aLeft(static_cast< sal_Int32 >(floor(aCenter - fScaledRadius))); 220937ab0f2dSArmin Le Grand const sal_Int32 aRight(static_cast< sal_Int32 >(ceil(aCenter + fScaledRadius))); 221037ab0f2dSArmin Le Grand sal_uInt32 aCurrentCount(0); 221137ab0f2dSArmin Le Grand 221237ab0f2dSArmin Le Grand for(sal_Int32 j(aLeft); j <= aRight; j++) 221337ab0f2dSArmin Le Grand { 221437ab0f2dSArmin Le Grand const double aWeight(aKernel.Calculate(fFilterFactor * (aCenter - static_cast< double>(j)))); 221537ab0f2dSArmin Le Grand 221637ab0f2dSArmin Le Grand // Reduce calculations with ignoring weights of 0.0 221737ab0f2dSArmin Le Grand if(fabs(aWeight) < 0.0001) 221837ab0f2dSArmin Le Grand { 221937ab0f2dSArmin Le Grand continue; 222037ab0f2dSArmin Le Grand } 222137ab0f2dSArmin Le Grand 222237ab0f2dSArmin Le Grand // Handling on edges 222337ab0f2dSArmin Le Grand const sal_uInt32 aPixelIndex(MinMax(j, 0, aSourceSize - 1)); 222437ab0f2dSArmin Le Grand const sal_uInt32 nIndex(aIndex + aCurrentCount); 222537ab0f2dSArmin Le Grand 222637ab0f2dSArmin Le Grand pWeights[nIndex] = aWeight; 222737ab0f2dSArmin Le Grand pPixels[nIndex] = aPixelIndex; 222837ab0f2dSArmin Le Grand 222937ab0f2dSArmin Le Grand aCurrentCount++; 223037ab0f2dSArmin Le Grand } 223137ab0f2dSArmin Le Grand 223237ab0f2dSArmin Le Grand pCount[i] = aCurrentCount; 223337ab0f2dSArmin Le Grand } 223437ab0f2dSArmin Le Grand } 223537ab0f2dSArmin Le Grand 223637ab0f2dSArmin Le Grand sal_Bool ImplScaleConvolutionHor( 223737ab0f2dSArmin Le Grand Bitmap& rSource, 223837ab0f2dSArmin Le Grand Bitmap& rTarget, 223937ab0f2dSArmin Le Grand const double& rScaleX, 224037ab0f2dSArmin Le Grand const Kernel& aKernel) 224137ab0f2dSArmin Le Grand { 224237ab0f2dSArmin Le Grand // Do horizontal filtering 224337ab0f2dSArmin Le Grand OSL_ENSURE(rScaleX > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); 224437ab0f2dSArmin Le Grand const sal_uInt32 nWidth(rSource.GetSizePixel().Width()); 224537ab0f2dSArmin Le Grand const sal_uInt32 nNewWidth(FRound(nWidth * rScaleX)); 224637ab0f2dSArmin Le Grand 224737ab0f2dSArmin Le Grand if(nWidth == nNewWidth) 224837ab0f2dSArmin Le Grand { 224937ab0f2dSArmin Le Grand return true; 225037ab0f2dSArmin Le Grand } 225137ab0f2dSArmin Le Grand 225237ab0f2dSArmin Le Grand BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess(); 225337ab0f2dSArmin Le Grand 225437ab0f2dSArmin Le Grand if(pReadAcc) 225537ab0f2dSArmin Le Grand { 225637ab0f2dSArmin Le Grand double* pWeights = 0; 225737ab0f2dSArmin Le Grand sal_uInt32* pPixels = 0; 225837ab0f2dSArmin Le Grand sal_uInt32* pCount = 0; 225937ab0f2dSArmin Le Grand sal_uInt32 aNumberOfContributions(0); 226037ab0f2dSArmin Le Grand 226137ab0f2dSArmin Le Grand const sal_uInt32 nHeight(rSource.GetSizePixel().Height()); 226237ab0f2dSArmin Le Grand ImplCalculateContributions(nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel); 226337ab0f2dSArmin Le Grand rTarget = Bitmap(Size(nNewWidth, nHeight), 24); 226437ab0f2dSArmin Le Grand BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess(); 226537ab0f2dSArmin Le Grand bool bResult(0 != pWriteAcc); 226637ab0f2dSArmin Le Grand 226737ab0f2dSArmin Le Grand if(bResult) 226837ab0f2dSArmin Le Grand { 226937ab0f2dSArmin Le Grand for(sal_uInt32 y(0); y < nHeight; y++) 227037ab0f2dSArmin Le Grand { 227137ab0f2dSArmin Le Grand for(sal_uInt32 x(0); x < nNewWidth; x++) 227237ab0f2dSArmin Le Grand { 227337ab0f2dSArmin Le Grand const sal_uInt32 aBaseIndex(x * aNumberOfContributions); 227437ab0f2dSArmin Le Grand double aSum(0.0); 227537ab0f2dSArmin Le Grand double aValueRed(0.0); 227637ab0f2dSArmin Le Grand double aValueGreen(0.0); 227737ab0f2dSArmin Le Grand double aValueBlue(0.0); 227837ab0f2dSArmin Le Grand 227937ab0f2dSArmin Le Grand for(sal_uInt32 j(0); j < pCount[x]; j++) 228037ab0f2dSArmin Le Grand { 228137ab0f2dSArmin Le Grand const sal_uInt32 aIndex(aBaseIndex + j); 228237ab0f2dSArmin Le Grand const double aWeight(pWeights[aIndex]); 228337ab0f2dSArmin Le Grand BitmapColor aColor; 228437ab0f2dSArmin Le Grand 228537ab0f2dSArmin Le Grand aSum += aWeight; 228637ab0f2dSArmin Le Grand 228737ab0f2dSArmin Le Grand if(pReadAcc->HasPalette()) 228837ab0f2dSArmin Le Grand { 228937ab0f2dSArmin Le Grand aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(y, pPixels[aIndex])); 229037ab0f2dSArmin Le Grand } 229137ab0f2dSArmin Le Grand else 229237ab0f2dSArmin Le Grand { 229337ab0f2dSArmin Le Grand aColor = pReadAcc->GetPixel(y, pPixels[aIndex]); 229437ab0f2dSArmin Le Grand } 229537ab0f2dSArmin Le Grand 229637ab0f2dSArmin Le Grand aValueRed += aWeight * aColor.GetRed(); 229737ab0f2dSArmin Le Grand aValueGreen += aWeight * aColor.GetGreen(); 229837ab0f2dSArmin Le Grand aValueBlue += aWeight * aColor.GetBlue(); 229937ab0f2dSArmin Le Grand } 230037ab0f2dSArmin Le Grand 230137ab0f2dSArmin Le Grand const BitmapColor aResultColor( 230237ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)), 230337ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)), 230437ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255))); 230537ab0f2dSArmin Le Grand 230637ab0f2dSArmin Le Grand pWriteAcc->SetPixel(y, x, aResultColor); 230737ab0f2dSArmin Le Grand } 230837ab0f2dSArmin Le Grand } 230937ab0f2dSArmin Le Grand 231037ab0f2dSArmin Le Grand rTarget.ReleaseAccess(pWriteAcc); 231137ab0f2dSArmin Le Grand } 231237ab0f2dSArmin Le Grand 231337ab0f2dSArmin Le Grand rSource.ReleaseAccess(pReadAcc); 231437ab0f2dSArmin Le Grand delete[] pWeights; 231537ab0f2dSArmin Le Grand delete[] pCount; 231637ab0f2dSArmin Le Grand delete[] pPixels; 231737ab0f2dSArmin Le Grand 231837ab0f2dSArmin Le Grand if(bResult) 231937ab0f2dSArmin Le Grand { 232037ab0f2dSArmin Le Grand return true; 232137ab0f2dSArmin Le Grand } 232237ab0f2dSArmin Le Grand } 232337ab0f2dSArmin Le Grand 232437ab0f2dSArmin Le Grand return false; 232537ab0f2dSArmin Le Grand } 232637ab0f2dSArmin Le Grand 232737ab0f2dSArmin Le Grand bool ImplScaleConvolutionVer( 232837ab0f2dSArmin Le Grand Bitmap& rSource, 232937ab0f2dSArmin Le Grand Bitmap& rTarget, 233037ab0f2dSArmin Le Grand const double& rScaleY, 233137ab0f2dSArmin Le Grand const Kernel& aKernel) 233237ab0f2dSArmin Le Grand { 233337ab0f2dSArmin Le Grand // Do vertical filtering 233437ab0f2dSArmin Le Grand OSL_ENSURE(rScaleY > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); 233537ab0f2dSArmin Le Grand const sal_uInt32 nHeight(rSource.GetSizePixel().Height()); 233637ab0f2dSArmin Le Grand const sal_uInt32 nNewHeight(FRound(nHeight * rScaleY)); 233737ab0f2dSArmin Le Grand 233837ab0f2dSArmin Le Grand if(nHeight == nNewHeight) 233937ab0f2dSArmin Le Grand { 234037ab0f2dSArmin Le Grand return true; 234137ab0f2dSArmin Le Grand } 234237ab0f2dSArmin Le Grand 234337ab0f2dSArmin Le Grand BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess(); 234437ab0f2dSArmin Le Grand 234537ab0f2dSArmin Le Grand if(pReadAcc) 234637ab0f2dSArmin Le Grand { 234737ab0f2dSArmin Le Grand double* pWeights = 0; 234837ab0f2dSArmin Le Grand sal_uInt32* pPixels = 0; 234937ab0f2dSArmin Le Grand sal_uInt32* pCount = 0; 235037ab0f2dSArmin Le Grand sal_uInt32 aNumberOfContributions(0); 235137ab0f2dSArmin Le Grand 235237ab0f2dSArmin Le Grand const sal_uInt32 nWidth(rSource.GetSizePixel().Width()); 235337ab0f2dSArmin Le Grand ImplCalculateContributions(nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel); 235437ab0f2dSArmin Le Grand rTarget = Bitmap(Size(nWidth, nNewHeight), 24); 235537ab0f2dSArmin Le Grand BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess(); 235637ab0f2dSArmin Le Grand bool bResult(0 != pWriteAcc); 235737ab0f2dSArmin Le Grand 235837ab0f2dSArmin Le Grand if(pWriteAcc) 235937ab0f2dSArmin Le Grand { 236037ab0f2dSArmin Le Grand for(sal_uInt32 x(0); x < nWidth; x++) 236137ab0f2dSArmin Le Grand { 236237ab0f2dSArmin Le Grand for(sal_uInt32 y(0); y < nNewHeight; y++) 236337ab0f2dSArmin Le Grand { 236437ab0f2dSArmin Le Grand const sal_uInt32 aBaseIndex(y * aNumberOfContributions); 236537ab0f2dSArmin Le Grand double aSum(0.0); 236637ab0f2dSArmin Le Grand double aValueRed(0.0); 236737ab0f2dSArmin Le Grand double aValueGreen(0.0); 236837ab0f2dSArmin Le Grand double aValueBlue(0.0); 236937ab0f2dSArmin Le Grand 237037ab0f2dSArmin Le Grand for(sal_uInt32 j(0); j < pCount[y]; j++) 237137ab0f2dSArmin Le Grand { 237237ab0f2dSArmin Le Grand const sal_uInt32 aIndex(aBaseIndex + j); 237337ab0f2dSArmin Le Grand const double aWeight(pWeights[aIndex]); 237437ab0f2dSArmin Le Grand BitmapColor aColor; 237537ab0f2dSArmin Le Grand 237637ab0f2dSArmin Le Grand aSum += aWeight; 237737ab0f2dSArmin Le Grand 237837ab0f2dSArmin Le Grand if(pReadAcc->HasPalette()) 237937ab0f2dSArmin Le Grand { 238037ab0f2dSArmin Le Grand aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(pPixels[aIndex], x)); 238137ab0f2dSArmin Le Grand } 238237ab0f2dSArmin Le Grand else 238337ab0f2dSArmin Le Grand { 238437ab0f2dSArmin Le Grand aColor = pReadAcc->GetPixel(pPixels[aIndex], x); 238537ab0f2dSArmin Le Grand } 238637ab0f2dSArmin Le Grand 238737ab0f2dSArmin Le Grand aValueRed += aWeight * aColor.GetRed(); 238837ab0f2dSArmin Le Grand aValueGreen += aWeight * aColor.GetGreen(); 238937ab0f2dSArmin Le Grand aValueBlue += aWeight * aColor.GetBlue(); 239037ab0f2dSArmin Le Grand } 239137ab0f2dSArmin Le Grand 239237ab0f2dSArmin Le Grand const BitmapColor aResultColor( 239337ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)), 239437ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)), 239537ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255))); 239637ab0f2dSArmin Le Grand 239737ab0f2dSArmin Le Grand if(pWriteAcc->HasPalette()) 239837ab0f2dSArmin Le Grand { 239937ab0f2dSArmin Le Grand pWriteAcc->SetPixelIndex(y, x, static_cast< sal_uInt8 >(pWriteAcc->GetBestPaletteIndex(aResultColor))); 240037ab0f2dSArmin Le Grand } 240137ab0f2dSArmin Le Grand else 240237ab0f2dSArmin Le Grand { 240337ab0f2dSArmin Le Grand pWriteAcc->SetPixel(y, x, aResultColor); 240437ab0f2dSArmin Le Grand } 240537ab0f2dSArmin Le Grand } 240637ab0f2dSArmin Le Grand } 240737ab0f2dSArmin Le Grand } 240837ab0f2dSArmin Le Grand 240937ab0f2dSArmin Le Grand rTarget.ReleaseAccess(pWriteAcc); 241037ab0f2dSArmin Le Grand rSource.ReleaseAccess(pReadAcc); 241137ab0f2dSArmin Le Grand 241237ab0f2dSArmin Le Grand delete[] pWeights; 241337ab0f2dSArmin Le Grand delete[] pCount; 241437ab0f2dSArmin Le Grand delete[] pPixels; 241537ab0f2dSArmin Le Grand 241637ab0f2dSArmin Le Grand if(bResult) 241737ab0f2dSArmin Le Grand { 241837ab0f2dSArmin Le Grand return true; 241937ab0f2dSArmin Le Grand } 242037ab0f2dSArmin Le Grand } 242137ab0f2dSArmin Le Grand 242237ab0f2dSArmin Le Grand return false; 242337ab0f2dSArmin Le Grand } 242437ab0f2dSArmin Le Grand } 242537ab0f2dSArmin Le Grand 242637ab0f2dSArmin Le Grand // #121233# Added BMP_SCALE_LANCZOS, BMP_SCALE_BICUBIC, BMP_SCALE_BILINEAR and 242737ab0f2dSArmin Le Grand // BMP_SCALE_BOX derived from the original commit from Toma� Vajngerl (see 242837ab0f2dSArmin Le Grand // bugzilla task for deitails) Thanks! 242937ab0f2dSArmin Le Grand sal_Bool Bitmap::ImplScaleConvolution( 243037ab0f2dSArmin Le Grand const double& rScaleX, 243137ab0f2dSArmin Le Grand const double& rScaleY, 243237ab0f2dSArmin Le Grand const Kernel& aKernel) 243337ab0f2dSArmin Le Grand { 243437ab0f2dSArmin Le Grand const bool bMirrorHor(rScaleX < 0.0); 243537ab0f2dSArmin Le Grand const bool bMirrorVer(rScaleY < 0.0); 243637ab0f2dSArmin Le Grand const double fScaleX(bMirrorHor ? -rScaleX : rScaleX); 243737ab0f2dSArmin Le Grand const double fScaleY(bMirrorVer ? -rScaleY : rScaleY); 243837ab0f2dSArmin Le Grand const sal_uInt32 nWidth(GetSizePixel().Width()); 243937ab0f2dSArmin Le Grand const sal_uInt32 nHeight(GetSizePixel().Height()); 244037ab0f2dSArmin Le Grand const sal_uInt32 nNewWidth(FRound(nWidth * fScaleX)); 244137ab0f2dSArmin Le Grand const sal_uInt32 nNewHeight(FRound(nHeight * fScaleY)); 244237ab0f2dSArmin Le Grand const bool bScaleHor(nWidth != nNewWidth); 244337ab0f2dSArmin Le Grand const bool bScaleVer(nHeight != nNewHeight); 244437ab0f2dSArmin Le Grand const bool bMirror(bMirrorHor || bMirrorVer); 244537ab0f2dSArmin Le Grand 244637ab0f2dSArmin Le Grand if(!bMirror && !bScaleHor && !bScaleVer) 244737ab0f2dSArmin Le Grand { 244837ab0f2dSArmin Le Grand return true; 244937ab0f2dSArmin Le Grand } 245037ab0f2dSArmin Le Grand 245137ab0f2dSArmin Le Grand bool bResult(true); 245237ab0f2dSArmin Le Grand sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE); 245337ab0f2dSArmin Le Grand bool bMirrorAfter(false); 245437ab0f2dSArmin Le Grand 245537ab0f2dSArmin Le Grand if(bMirror) 245637ab0f2dSArmin Le Grand { 245737ab0f2dSArmin Le Grand if(bMirrorHor) 245837ab0f2dSArmin Le Grand { 245937ab0f2dSArmin Le Grand nMirrorFlags |= BMP_MIRROR_HORZ; 246037ab0f2dSArmin Le Grand } 246137ab0f2dSArmin Le Grand 246237ab0f2dSArmin Le Grand if(bMirrorVer) 246337ab0f2dSArmin Le Grand { 246437ab0f2dSArmin Le Grand nMirrorFlags |= BMP_MIRROR_VERT; 246537ab0f2dSArmin Le Grand } 246637ab0f2dSArmin Le Grand 246737ab0f2dSArmin Le Grand const sal_uInt32 nStartSize(nWidth * nHeight); 246837ab0f2dSArmin Le Grand const sal_uInt32 nEndSize(nNewWidth * nNewHeight); 246937ab0f2dSArmin Le Grand 247037ab0f2dSArmin Le Grand bMirrorAfter = nStartSize > nEndSize; 247137ab0f2dSArmin Le Grand 247237ab0f2dSArmin Le Grand if(!bMirrorAfter) 247337ab0f2dSArmin Le Grand { 247437ab0f2dSArmin Le Grand bResult = Mirror(nMirrorFlags); 247537ab0f2dSArmin Le Grand } 247637ab0f2dSArmin Le Grand } 247737ab0f2dSArmin Le Grand 247837ab0f2dSArmin Le Grand Bitmap aResult; 247937ab0f2dSArmin Le Grand 248037ab0f2dSArmin Le Grand if(bResult) 248137ab0f2dSArmin Le Grand { 248237ab0f2dSArmin Le Grand const sal_uInt32 nInBetweenSizeHorFirst(nHeight * nNewWidth); 248337ab0f2dSArmin Le Grand const sal_uInt32 nInBetweenSizeVerFirst(nNewHeight * nWidth); 2484*1a517a07SArmin Le Grand Bitmap aSource(*this); 248537ab0f2dSArmin Le Grand 248637ab0f2dSArmin Le Grand if(nInBetweenSizeHorFirst < nInBetweenSizeVerFirst) 248737ab0f2dSArmin Le Grand { 248837ab0f2dSArmin Le Grand if(bScaleHor) 248937ab0f2dSArmin Le Grand { 2490*1a517a07SArmin Le Grand bResult = ImplScaleConvolutionHor(aSource, aResult, fScaleX, aKernel); 249137ab0f2dSArmin Le Grand } 249237ab0f2dSArmin Le Grand 249337ab0f2dSArmin Le Grand if(bResult && bScaleVer) 249437ab0f2dSArmin Le Grand { 2495*1a517a07SArmin Le Grand if(bScaleHor) 2496*1a517a07SArmin Le Grand { 2497*1a517a07SArmin Le Grand // copy partial result, independent of color depth 2498*1a517a07SArmin Le Grand aSource = aResult; 2499*1a517a07SArmin Le Grand } 2500*1a517a07SArmin Le Grand 2501*1a517a07SArmin Le Grand bResult = ImplScaleConvolutionVer(aSource, aResult, fScaleY, aKernel); 250237ab0f2dSArmin Le Grand } 250337ab0f2dSArmin Le Grand } 250437ab0f2dSArmin Le Grand else 250537ab0f2dSArmin Le Grand { 250637ab0f2dSArmin Le Grand if(bScaleVer) 250737ab0f2dSArmin Le Grand { 2508*1a517a07SArmin Le Grand bResult = ImplScaleConvolutionVer(aSource, aResult, fScaleY, aKernel); 250937ab0f2dSArmin Le Grand } 251037ab0f2dSArmin Le Grand 251137ab0f2dSArmin Le Grand if(bResult && bScaleHor) 251237ab0f2dSArmin Le Grand { 2513*1a517a07SArmin Le Grand if(bScaleVer) 2514*1a517a07SArmin Le Grand { 2515*1a517a07SArmin Le Grand // copy partial result, independent of color depth 2516*1a517a07SArmin Le Grand aSource = aResult; 2517*1a517a07SArmin Le Grand } 2518*1a517a07SArmin Le Grand 2519*1a517a07SArmin Le Grand bResult = ImplScaleConvolutionHor(aSource, aResult, fScaleX, aKernel); 252037ab0f2dSArmin Le Grand } 252137ab0f2dSArmin Le Grand } 252237ab0f2dSArmin Le Grand } 252337ab0f2dSArmin Le Grand 252437ab0f2dSArmin Le Grand if(bResult && bMirrorAfter) 252537ab0f2dSArmin Le Grand { 252637ab0f2dSArmin Le Grand bResult = aResult.Mirror(nMirrorFlags); 252737ab0f2dSArmin Le Grand } 252837ab0f2dSArmin Le Grand 252937ab0f2dSArmin Le Grand if(bResult) 253037ab0f2dSArmin Le Grand { 253137ab0f2dSArmin Le Grand ImplAdaptBitCount(aResult); 253237ab0f2dSArmin Le Grand *this = aResult; 253337ab0f2dSArmin Le Grand } 253437ab0f2dSArmin Le Grand 253537ab0f2dSArmin Le Grand return bResult; 253637ab0f2dSArmin Le Grand } 253737ab0f2dSArmin Le Grand 2538cdf0e10cSrcweir // ------------------------------------------------------------------------ 2539cdf0e10cSrcweir 2540cdf0e10cSrcweir sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) 2541cdf0e10cSrcweir { 2542cdf0e10cSrcweir sal_Bool bRet = sal_False; 2543cdf0e10cSrcweir 2544cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 2545cdf0e10cSrcweir 2546cdf0e10cSrcweir if( aSizePix.Width() == 1 || aSizePix.Height() == 1 ) 2547cdf0e10cSrcweir bRet = sal_True; 2548cdf0e10cSrcweir else if( nDitherFlags & BMP_DITHER_MATRIX ) 2549cdf0e10cSrcweir bRet = ImplDitherMatrix(); 2550cdf0e10cSrcweir else if( nDitherFlags & BMP_DITHER_FLOYD ) 2551cdf0e10cSrcweir bRet = ImplDitherFloyd(); 2552cdf0e10cSrcweir else if( ( nDitherFlags & BMP_DITHER_FLOYD_16 ) && ( GetBitCount() == 24 ) ) 2553cdf0e10cSrcweir bRet = ImplDitherFloyd16(); 2554cdf0e10cSrcweir 2555cdf0e10cSrcweir return bRet; 2556cdf0e10cSrcweir } 2557cdf0e10cSrcweir 2558cdf0e10cSrcweir // ------------------------------------------------------------------------ 2559cdf0e10cSrcweir 2560cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherMatrix() 2561cdf0e10cSrcweir { 2562cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2563cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 8 ); 2564cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2565cdf0e10cSrcweir sal_Bool bRet = sal_False; 2566cdf0e10cSrcweir 2567cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2568cdf0e10cSrcweir { 2569cdf0e10cSrcweir const sal_uLong nWidth = pReadAcc->Width(); 2570cdf0e10cSrcweir const sal_uLong nHeight = pReadAcc->Height(); 2571cdf0e10cSrcweir BitmapColor aIndex( (sal_uInt8) 0 ); 2572cdf0e10cSrcweir 2573cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 2574cdf0e10cSrcweir { 2575cdf0e10cSrcweir for( sal_uLong nY = 0UL; nY < nHeight; nY++ ) 2576cdf0e10cSrcweir { 2577cdf0e10cSrcweir for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ ) 2578cdf0e10cSrcweir { 257987bc88d3SHerbert Dürr const BitmapColor aCol( pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) ) ); 2580cdf0e10cSrcweir const sal_uLong nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ]; 2581cdf0e10cSrcweir const sal_uLong nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL; 2582cdf0e10cSrcweir const sal_uLong nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL; 2583cdf0e10cSrcweir const sal_uLong nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL; 2584cdf0e10cSrcweir 2585cdf0e10cSrcweir aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) ); 2586cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aIndex ); 2587cdf0e10cSrcweir } 2588cdf0e10cSrcweir } 2589cdf0e10cSrcweir } 2590cdf0e10cSrcweir else 2591cdf0e10cSrcweir { 2592cdf0e10cSrcweir for( sal_uLong nY = 0UL; nY < nHeight; nY++ ) 2593cdf0e10cSrcweir { 2594cdf0e10cSrcweir for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ ) 2595cdf0e10cSrcweir { 2596cdf0e10cSrcweir const BitmapColor aCol( pReadAcc->GetPixel( nY, nX ) ); 2597cdf0e10cSrcweir const sal_uLong nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ]; 2598cdf0e10cSrcweir const sal_uLong nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL; 2599cdf0e10cSrcweir const sal_uLong nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL; 2600cdf0e10cSrcweir const sal_uLong nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL; 2601cdf0e10cSrcweir 2602cdf0e10cSrcweir aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) ); 2603cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aIndex ); 2604cdf0e10cSrcweir } 2605cdf0e10cSrcweir } 2606cdf0e10cSrcweir } 2607cdf0e10cSrcweir 2608cdf0e10cSrcweir bRet = sal_True; 2609cdf0e10cSrcweir } 2610cdf0e10cSrcweir 2611cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2612cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2613cdf0e10cSrcweir 2614cdf0e10cSrcweir if( bRet ) 2615cdf0e10cSrcweir { 2616cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2617cdf0e10cSrcweir const Size aSize( maPrefSize ); 2618cdf0e10cSrcweir 2619cdf0e10cSrcweir *this = aNewBmp; 2620cdf0e10cSrcweir 2621cdf0e10cSrcweir maPrefMapMode = aMap; 2622cdf0e10cSrcweir maPrefSize = aSize; 2623cdf0e10cSrcweir } 2624cdf0e10cSrcweir 2625cdf0e10cSrcweir return bRet; 2626cdf0e10cSrcweir } 2627cdf0e10cSrcweir 2628cdf0e10cSrcweir // ------------------------------------------------------------------------ 2629cdf0e10cSrcweir 2630cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherFloyd() 2631cdf0e10cSrcweir { 2632cdf0e10cSrcweir const Size aSize( GetSizePixel() ); 2633cdf0e10cSrcweir sal_Bool bRet = sal_False; 2634cdf0e10cSrcweir 2635cdf0e10cSrcweir if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) ) 2636cdf0e10cSrcweir { 2637cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2638cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 8 ); 2639cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2640cdf0e10cSrcweir 2641cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2642cdf0e10cSrcweir { 2643cdf0e10cSrcweir BitmapColor aColor; 2644cdf0e10cSrcweir long nWidth = pReadAcc->Width(); 2645cdf0e10cSrcweir long nWidth1 = nWidth - 1L; 2646cdf0e10cSrcweir long nHeight = pReadAcc->Height(); 2647cdf0e10cSrcweir long nX; 2648cdf0e10cSrcweir long nW = nWidth * 3L; 2649cdf0e10cSrcweir long nW2 = nW - 3L; 2650cdf0e10cSrcweir long nRErr, nGErr, nBErr; 2651cdf0e10cSrcweir long nRC, nGC, nBC; 2652cdf0e10cSrcweir long nTemp; 2653cdf0e10cSrcweir long nZ; 2654cdf0e10cSrcweir long* p1 = new long[ nW ]; 2655cdf0e10cSrcweir long* p2 = new long[ nW ]; 2656cdf0e10cSrcweir long* p1T = p1; 2657cdf0e10cSrcweir long* p2T = p2; 2658cdf0e10cSrcweir long* pTmp; 2659cdf0e10cSrcweir sal_Bool bPal = pReadAcc->HasPalette(); 2660cdf0e10cSrcweir 2661cdf0e10cSrcweir pTmp = p2T; 2662cdf0e10cSrcweir 2663cdf0e10cSrcweir if( bPal ) 2664cdf0e10cSrcweir { 2665cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2666cdf0e10cSrcweir { 266787bc88d3SHerbert Dürr aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( 0, nZ ) ); 2668cdf0e10cSrcweir 2669cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2670cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2671cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2672cdf0e10cSrcweir } 2673cdf0e10cSrcweir } 2674cdf0e10cSrcweir else 2675cdf0e10cSrcweir { 2676cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2677cdf0e10cSrcweir { 2678cdf0e10cSrcweir aColor = pReadAcc->GetPixel( 0, nZ ); 2679cdf0e10cSrcweir 2680cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2681cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2682cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2683cdf0e10cSrcweir } 2684cdf0e10cSrcweir } 2685cdf0e10cSrcweir 2686cdf0e10cSrcweir for( long nY = 1, nYAcc = 0L; nY <= nHeight; nY++, nYAcc++ ) 2687cdf0e10cSrcweir { 2688cdf0e10cSrcweir pTmp = p1T; 2689cdf0e10cSrcweir p1T = p2T; 2690cdf0e10cSrcweir p2T = pTmp; 2691cdf0e10cSrcweir 2692cdf0e10cSrcweir if( nY < nHeight ) 2693cdf0e10cSrcweir { 2694cdf0e10cSrcweir if( bPal ) 2695cdf0e10cSrcweir { 2696cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2697cdf0e10cSrcweir { 269887bc88d3SHerbert Dürr aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nZ ) ); 2699cdf0e10cSrcweir 2700cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2701cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2702cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2703cdf0e10cSrcweir } 2704cdf0e10cSrcweir } 2705cdf0e10cSrcweir else 2706cdf0e10cSrcweir { 2707cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2708cdf0e10cSrcweir { 2709cdf0e10cSrcweir aColor = pReadAcc->GetPixel( nY, nZ ); 2710cdf0e10cSrcweir 2711cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2712cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2713cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2714cdf0e10cSrcweir } 2715cdf0e10cSrcweir } 2716cdf0e10cSrcweir } 2717cdf0e10cSrcweir 2718cdf0e10cSrcweir // erstes Pixel gesondert betrachten 2719cdf0e10cSrcweir nX = 0; 2720cdf0e10cSrcweir CALC_ERRORS; 2721cdf0e10cSrcweir CALC_TABLES7; 2722cdf0e10cSrcweir nX -= 5; 2723cdf0e10cSrcweir CALC_TABLES5; 272487bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, 0, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2725cdf0e10cSrcweir 2726cdf0e10cSrcweir // mittlere Pixel ueber Schleife 2727cdf0e10cSrcweir long nXAcc; 2728cdf0e10cSrcweir for ( nX = 3L, nXAcc = 1L; nX < nW2; nXAcc++ ) 2729cdf0e10cSrcweir { 2730cdf0e10cSrcweir CALC_ERRORS; 2731cdf0e10cSrcweir CALC_TABLES7; 2732cdf0e10cSrcweir nX -= 8; 2733cdf0e10cSrcweir CALC_TABLES3; 2734cdf0e10cSrcweir CALC_TABLES5; 273587bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, nXAcc, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2736cdf0e10cSrcweir } 2737cdf0e10cSrcweir 2738cdf0e10cSrcweir // letztes Pixel gesondert betrachten 2739cdf0e10cSrcweir CALC_ERRORS; 2740cdf0e10cSrcweir nX -= 5; 2741cdf0e10cSrcweir CALC_TABLES3; 2742cdf0e10cSrcweir CALC_TABLES5; 274387bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, nWidth1, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2744cdf0e10cSrcweir } 2745cdf0e10cSrcweir 2746cdf0e10cSrcweir delete[] p1; 2747cdf0e10cSrcweir delete[] p2; 2748cdf0e10cSrcweir bRet = sal_True; 2749cdf0e10cSrcweir } 2750cdf0e10cSrcweir 2751cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2752cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2753cdf0e10cSrcweir 2754cdf0e10cSrcweir if( bRet ) 2755cdf0e10cSrcweir { 2756cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2757cdf0e10cSrcweir const Size aPrefSize( maPrefSize ); 2758cdf0e10cSrcweir 2759cdf0e10cSrcweir *this = aNewBmp; 2760cdf0e10cSrcweir 2761cdf0e10cSrcweir maPrefMapMode = aMap; 2762cdf0e10cSrcweir maPrefSize = aPrefSize; 2763cdf0e10cSrcweir } 2764cdf0e10cSrcweir } 2765cdf0e10cSrcweir 2766cdf0e10cSrcweir return bRet; 2767cdf0e10cSrcweir } 2768cdf0e10cSrcweir 2769cdf0e10cSrcweir // ------------------------------------------------------------------------ 2770cdf0e10cSrcweir 2771cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherFloyd16() 2772cdf0e10cSrcweir { 2773cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2774cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 24 ); 2775cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2776cdf0e10cSrcweir sal_Bool bRet = sal_False; 2777cdf0e10cSrcweir 2778cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2779cdf0e10cSrcweir { 2780cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 2781cdf0e10cSrcweir const long nWidth1 = nWidth - 1L; 2782cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 2783cdf0e10cSrcweir BitmapColor aColor; 2784cdf0e10cSrcweir BitmapColor aBestCol; 2785cdf0e10cSrcweir ImpErrorQuad aErrQuad; 2786cdf0e10cSrcweir ImpErrorQuad* pErrQuad1 = new ImpErrorQuad[ nWidth ]; 2787cdf0e10cSrcweir ImpErrorQuad* pErrQuad2 = new ImpErrorQuad[ nWidth ]; 2788cdf0e10cSrcweir ImpErrorQuad* pQLine1 = pErrQuad1; 2789cdf0e10cSrcweir ImpErrorQuad* pQLine2 = 0; 2790cdf0e10cSrcweir long nX, nY; 2791cdf0e10cSrcweir long nYTmp = 0L; 2792cdf0e10cSrcweir sal_Bool bQ1 = sal_True; 2793cdf0e10cSrcweir 2794cdf0e10cSrcweir for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ ) 2795cdf0e10cSrcweir for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ ) 2796cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 2797cdf0e10cSrcweir 2798cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++, nYTmp++ ) 2799cdf0e10cSrcweir { 2800cdf0e10cSrcweir // erstes ZeilenPixel 2801cdf0e10cSrcweir aBestCol = pQLine1[ 0 ].ImplGetColor(); 2802cdf0e10cSrcweir aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 ); 2803cdf0e10cSrcweir aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 ); 2804cdf0e10cSrcweir aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 ); 2805cdf0e10cSrcweir pWriteAcc->SetPixel( nY, 0, aBestCol ); 2806cdf0e10cSrcweir 2807cdf0e10cSrcweir for( nX = 1L; nX < nWidth1; nX++ ) 2808cdf0e10cSrcweir { 2809cdf0e10cSrcweir aColor = pQLine1[ nX ].ImplGetColor(); 2810cdf0e10cSrcweir aBestCol.SetRed( ( aColor.GetRed() & 248 ) | 7 ); 2811cdf0e10cSrcweir aBestCol.SetGreen( ( aColor.GetGreen() & 248 ) | 7 ); 2812cdf0e10cSrcweir aBestCol.SetBlue( ( aColor.GetBlue() & 248 ) | 7 ); 2813cdf0e10cSrcweir aErrQuad = ( ImpErrorQuad( aColor ) -= aBestCol ); 2814cdf0e10cSrcweir pQLine1[ ++nX ].ImplAddColorError7( aErrQuad ); 2815cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError1( aErrQuad ); 2816cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError5( aErrQuad ); 2817cdf0e10cSrcweir pQLine2[ nX++ ].ImplAddColorError3( aErrQuad ); 2818cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBestCol ); 2819cdf0e10cSrcweir } 2820cdf0e10cSrcweir 2821cdf0e10cSrcweir // letztes ZeilenPixel 2822cdf0e10cSrcweir aBestCol = pQLine1[ nWidth1 ].ImplGetColor(); 2823cdf0e10cSrcweir aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 ); 2824cdf0e10cSrcweir aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 ); 2825cdf0e10cSrcweir aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 ); 2826cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBestCol ); 2827cdf0e10cSrcweir 2828cdf0e10cSrcweir // Zeilenpuffer neu fuellen/kopieren 2829cdf0e10cSrcweir pQLine1 = pQLine2; 2830cdf0e10cSrcweir pQLine2 = ( bQ1 = !bQ1 ) != sal_False ? pErrQuad2 : pErrQuad1; 2831cdf0e10cSrcweir 2832cdf0e10cSrcweir if( nYTmp < nHeight ) 2833cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 2834cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 2835cdf0e10cSrcweir } 2836cdf0e10cSrcweir 2837cdf0e10cSrcweir // Zeilenpuffer zerstoeren 2838cdf0e10cSrcweir delete[] pErrQuad1; 2839cdf0e10cSrcweir delete[] pErrQuad2; 2840cdf0e10cSrcweir bRet = sal_True; 2841cdf0e10cSrcweir } 2842cdf0e10cSrcweir 2843cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2844cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2845cdf0e10cSrcweir 2846cdf0e10cSrcweir if( bRet ) 2847cdf0e10cSrcweir { 2848cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2849cdf0e10cSrcweir const Size aSize( maPrefSize ); 2850cdf0e10cSrcweir 2851cdf0e10cSrcweir *this = aNewBmp; 2852cdf0e10cSrcweir 2853cdf0e10cSrcweir maPrefMapMode = aMap; 2854cdf0e10cSrcweir maPrefSize = aSize; 2855cdf0e10cSrcweir } 2856cdf0e10cSrcweir 2857cdf0e10cSrcweir return bRet; 2858cdf0e10cSrcweir } 2859cdf0e10cSrcweir 2860cdf0e10cSrcweir // ------------------------------------------------------------------------ 2861cdf0e10cSrcweir 2862cdf0e10cSrcweir sal_Bool Bitmap::ReduceColors( sal_uInt16 nColorCount, BmpReduce eReduce ) 2863cdf0e10cSrcweir { 2864cdf0e10cSrcweir sal_Bool bRet; 2865cdf0e10cSrcweir 2866cdf0e10cSrcweir if( GetColorCount() <= (sal_uLong) nColorCount ) 2867cdf0e10cSrcweir bRet = sal_True; 2868cdf0e10cSrcweir else if( nColorCount ) 2869cdf0e10cSrcweir { 2870cdf0e10cSrcweir if( BMP_REDUCE_SIMPLE == eReduce ) 2871cdf0e10cSrcweir bRet = ImplReduceSimple( nColorCount ); 2872cdf0e10cSrcweir else if( BMP_REDUCE_POPULAR == eReduce ) 2873cdf0e10cSrcweir bRet = ImplReducePopular( nColorCount ); 2874cdf0e10cSrcweir else 2875cdf0e10cSrcweir bRet = ImplReduceMedian( nColorCount ); 2876cdf0e10cSrcweir } 2877cdf0e10cSrcweir else 2878cdf0e10cSrcweir bRet = sal_False; 2879cdf0e10cSrcweir 2880cdf0e10cSrcweir return bRet; 2881cdf0e10cSrcweir } 2882cdf0e10cSrcweir 2883cdf0e10cSrcweir // ------------------------------------------------------------------------ 2884cdf0e10cSrcweir 2885cdf0e10cSrcweir sal_Bool Bitmap::ImplReduceSimple( sal_uInt16 nColorCount ) 2886cdf0e10cSrcweir { 2887cdf0e10cSrcweir Bitmap aNewBmp; 2888cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 2889cdf0e10cSrcweir const sal_uInt16 nColCount = Min( nColorCount, (sal_uInt16) 256 ); 2890cdf0e10cSrcweir sal_uInt16 nBitCount; 2891cdf0e10cSrcweir sal_Bool bRet = sal_False; 2892cdf0e10cSrcweir 2893cdf0e10cSrcweir if( nColCount <= 2 ) 2894cdf0e10cSrcweir nBitCount = 1; 2895cdf0e10cSrcweir else if( nColCount <= 16 ) 2896cdf0e10cSrcweir nBitCount = 4; 2897cdf0e10cSrcweir else 2898cdf0e10cSrcweir nBitCount = 8; 2899cdf0e10cSrcweir 2900cdf0e10cSrcweir if( pRAcc ) 2901cdf0e10cSrcweir { 2902cdf0e10cSrcweir Octree aOct( *pRAcc, nColCount ); 2903cdf0e10cSrcweir const BitmapPalette& rPal = aOct.GetPalette(); 2904cdf0e10cSrcweir BitmapWriteAccess* pWAcc; 2905cdf0e10cSrcweir 2906cdf0e10cSrcweir aNewBmp = Bitmap( GetSizePixel(), nBitCount, &rPal ); 2907cdf0e10cSrcweir pWAcc = aNewBmp.AcquireWriteAccess(); 2908cdf0e10cSrcweir 2909cdf0e10cSrcweir if( pWAcc ) 2910cdf0e10cSrcweir { 2911cdf0e10cSrcweir const long nWidth = pRAcc->Width(); 2912cdf0e10cSrcweir const long nHeight = pRAcc->Height(); 2913cdf0e10cSrcweir 2914cdf0e10cSrcweir if( pRAcc->HasPalette() ) 2915cdf0e10cSrcweir { 2916cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 2917cdf0e10cSrcweir for( long nX =0L; nX < nWidth; nX++ ) 291887bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ))) ); 2919cdf0e10cSrcweir } 2920cdf0e10cSrcweir else 2921cdf0e10cSrcweir { 2922cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 2923cdf0e10cSrcweir for( long nX =0L; nX < nWidth; nX++ ) 292487bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPixel( nY, nX ) )) ); 2925cdf0e10cSrcweir } 2926cdf0e10cSrcweir 2927cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 2928cdf0e10cSrcweir bRet = sal_True; 2929cdf0e10cSrcweir } 2930cdf0e10cSrcweir 2931cdf0e10cSrcweir ReleaseAccess( pRAcc ); 2932cdf0e10cSrcweir } 2933cdf0e10cSrcweir 2934cdf0e10cSrcweir if( bRet ) 2935cdf0e10cSrcweir { 2936cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2937cdf0e10cSrcweir const Size aSize( maPrefSize ); 2938cdf0e10cSrcweir 2939cdf0e10cSrcweir *this = aNewBmp; 2940cdf0e10cSrcweir maPrefMapMode = aMap; 2941cdf0e10cSrcweir maPrefSize = aSize; 2942cdf0e10cSrcweir } 2943cdf0e10cSrcweir 2944cdf0e10cSrcweir return bRet; 2945cdf0e10cSrcweir } 2946cdf0e10cSrcweir 2947cdf0e10cSrcweir // ------------------------------------------------------------------------ 2948cdf0e10cSrcweir 2949cdf0e10cSrcweir struct PopularColorCount 2950cdf0e10cSrcweir { 2951cdf0e10cSrcweir sal_uInt32 mnIndex; 2952cdf0e10cSrcweir sal_uInt32 mnCount; 2953cdf0e10cSrcweir }; 2954cdf0e10cSrcweir 2955cdf0e10cSrcweir // ------------------------------------------------------------------------ 2956cdf0e10cSrcweir 2957cdf0e10cSrcweir extern "C" int __LOADONCALLAPI ImplPopularCmpFnc( const void* p1, const void* p2 ) 2958cdf0e10cSrcweir { 2959cdf0e10cSrcweir int nRet; 2960cdf0e10cSrcweir 2961cdf0e10cSrcweir if( ( (PopularColorCount*) p1 )->mnCount < ( (PopularColorCount*) p2 )->mnCount ) 2962cdf0e10cSrcweir nRet = 1; 2963cdf0e10cSrcweir else if( ( (PopularColorCount*) p1 )->mnCount == ( (PopularColorCount*) p2 )->mnCount ) 2964cdf0e10cSrcweir nRet = 0; 2965cdf0e10cSrcweir else 2966cdf0e10cSrcweir nRet = -1; 2967cdf0e10cSrcweir 2968cdf0e10cSrcweir return nRet; 2969cdf0e10cSrcweir } 2970cdf0e10cSrcweir 2971cdf0e10cSrcweir // ------------------------------------------------------------------------ 2972cdf0e10cSrcweir 2973cdf0e10cSrcweir sal_Bool Bitmap::ImplReducePopular( sal_uInt16 nColCount ) 2974cdf0e10cSrcweir { 2975cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 2976cdf0e10cSrcweir sal_uInt16 nBitCount; 2977cdf0e10cSrcweir sal_Bool bRet = sal_False; 2978cdf0e10cSrcweir 2979cdf0e10cSrcweir if( nColCount > 256 ) 2980cdf0e10cSrcweir nColCount = 256; 2981cdf0e10cSrcweir 2982cdf0e10cSrcweir if( nColCount < 17 ) 2983cdf0e10cSrcweir nBitCount = 4; 2984cdf0e10cSrcweir else 2985cdf0e10cSrcweir nBitCount = 8; 2986cdf0e10cSrcweir 2987cdf0e10cSrcweir if( pRAcc ) 2988cdf0e10cSrcweir { 2989cdf0e10cSrcweir const sal_uInt32 nValidBits = 4; 2990cdf0e10cSrcweir const sal_uInt32 nRightShiftBits = 8 - nValidBits; 2991cdf0e10cSrcweir const sal_uInt32 nLeftShiftBits1 = nValidBits; 2992cdf0e10cSrcweir const sal_uInt32 nLeftShiftBits2 = nValidBits << 1; 2993cdf0e10cSrcweir const sal_uInt32 nColorsPerComponent = 1 << nValidBits; 2994cdf0e10cSrcweir const sal_uInt32 nColorOffset = 256 / nColorsPerComponent; 2995cdf0e10cSrcweir const sal_uInt32 nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent; 2996cdf0e10cSrcweir const long nWidth = pRAcc->Width(); 2997cdf0e10cSrcweir const long nHeight = pRAcc->Height(); 2998cdf0e10cSrcweir PopularColorCount* pCountTable = new PopularColorCount[ nTotalColors ]; 2999cdf0e10cSrcweir long nX, nY, nR, nG, nB, nIndex; 3000cdf0e10cSrcweir 3001cdf0e10cSrcweir rtl_zeroMemory( pCountTable, nTotalColors * sizeof( PopularColorCount ) ); 3002cdf0e10cSrcweir 3003cdf0e10cSrcweir for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset ) 3004cdf0e10cSrcweir { 3005cdf0e10cSrcweir for( nG = 0; nG < 256; nG += nColorOffset ) 3006cdf0e10cSrcweir { 3007cdf0e10cSrcweir for( nB = 0; nB < 256; nB += nColorOffset ) 3008cdf0e10cSrcweir { 3009cdf0e10cSrcweir pCountTable[ nIndex ].mnIndex = nIndex; 3010cdf0e10cSrcweir nIndex++; 3011cdf0e10cSrcweir } 3012cdf0e10cSrcweir } 3013cdf0e10cSrcweir } 3014cdf0e10cSrcweir 3015cdf0e10cSrcweir if( pRAcc->HasPalette() ) 3016cdf0e10cSrcweir { 3017cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3018cdf0e10cSrcweir { 3019cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3020cdf0e10cSrcweir { 302187bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3022cdf0e10cSrcweir pCountTable[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3023cdf0e10cSrcweir ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3024cdf0e10cSrcweir ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++; 3025cdf0e10cSrcweir } 3026cdf0e10cSrcweir } 3027cdf0e10cSrcweir } 3028cdf0e10cSrcweir else 3029cdf0e10cSrcweir { 3030cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3031cdf0e10cSrcweir { 3032cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3033cdf0e10cSrcweir { 3034cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3035cdf0e10cSrcweir pCountTable[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3036cdf0e10cSrcweir ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3037cdf0e10cSrcweir ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++; 3038cdf0e10cSrcweir } 3039cdf0e10cSrcweir } 3040cdf0e10cSrcweir } 3041cdf0e10cSrcweir 3042cdf0e10cSrcweir BitmapPalette aNewPal( nColCount ); 3043cdf0e10cSrcweir 3044cdf0e10cSrcweir qsort( pCountTable, nTotalColors, sizeof( PopularColorCount ), ImplPopularCmpFnc ); 3045cdf0e10cSrcweir 3046cdf0e10cSrcweir for( sal_uInt16 n = 0; n < nColCount; n++ ) 3047cdf0e10cSrcweir { 3048cdf0e10cSrcweir const PopularColorCount& rPop = pCountTable[ n ]; 3049cdf0e10cSrcweir aNewPal[ n ] = BitmapColor( (sal_uInt8) ( ( rPop.mnIndex >> nLeftShiftBits2 ) << nRightShiftBits ), 3050cdf0e10cSrcweir (sal_uInt8) ( ( ( rPop.mnIndex >> nLeftShiftBits1 ) & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ), 3051cdf0e10cSrcweir (sal_uInt8) ( ( rPop.mnIndex & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ) ); 3052cdf0e10cSrcweir } 3053cdf0e10cSrcweir 3054cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount, &aNewPal ); 3055cdf0e10cSrcweir BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess(); 3056cdf0e10cSrcweir 3057cdf0e10cSrcweir if( pWAcc ) 3058cdf0e10cSrcweir { 3059cdf0e10cSrcweir BitmapColor aDstCol( (sal_uInt8) 0 ); 3060cdf0e10cSrcweir sal_uInt8* pIndexMap = new sal_uInt8[ nTotalColors ]; 3061cdf0e10cSrcweir 3062cdf0e10cSrcweir for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset ) 3063cdf0e10cSrcweir for( nG = 0; nG < 256; nG += nColorOffset ) 3064cdf0e10cSrcweir for( nB = 0; nB < 256; nB += nColorOffset ) 3065cdf0e10cSrcweir pIndexMap[ nIndex++ ] = (sal_uInt8) aNewPal.GetBestIndex( BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB ) ); 3066cdf0e10cSrcweir 3067cdf0e10cSrcweir if( pRAcc->HasPalette() ) 3068cdf0e10cSrcweir { 3069cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3070cdf0e10cSrcweir { 3071cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3072cdf0e10cSrcweir { 307387bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3074cdf0e10cSrcweir aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3075cdf0e10cSrcweir ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3076cdf0e10cSrcweir ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ] ); 3077cdf0e10cSrcweir pWAcc->SetPixel( nY, nX, aDstCol ); 3078cdf0e10cSrcweir } 3079cdf0e10cSrcweir } 3080cdf0e10cSrcweir } 3081cdf0e10cSrcweir else 3082cdf0e10cSrcweir { 3083cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3084cdf0e10cSrcweir { 3085cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3086cdf0e10cSrcweir { 3087cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3088cdf0e10cSrcweir aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3089cdf0e10cSrcweir ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3090cdf0e10cSrcweir ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ] ); 3091cdf0e10cSrcweir pWAcc->SetPixel( nY, nX, aDstCol ); 3092cdf0e10cSrcweir } 3093cdf0e10cSrcweir } 3094cdf0e10cSrcweir } 3095cdf0e10cSrcweir 3096cdf0e10cSrcweir delete[] pIndexMap; 3097cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 3098cdf0e10cSrcweir bRet = sal_True; 3099cdf0e10cSrcweir } 3100cdf0e10cSrcweir 3101cdf0e10cSrcweir delete[] pCountTable; 3102cdf0e10cSrcweir ReleaseAccess( pRAcc ); 3103cdf0e10cSrcweir 3104cdf0e10cSrcweir if( bRet ) 3105cdf0e10cSrcweir { 3106cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 3107cdf0e10cSrcweir const Size aSize( maPrefSize ); 3108cdf0e10cSrcweir 3109cdf0e10cSrcweir *this = aNewBmp; 3110cdf0e10cSrcweir maPrefMapMode = aMap; 3111cdf0e10cSrcweir maPrefSize = aSize; 3112cdf0e10cSrcweir } 3113cdf0e10cSrcweir } 3114cdf0e10cSrcweir 3115cdf0e10cSrcweir return bRet; 3116cdf0e10cSrcweir } 3117cdf0e10cSrcweir 3118cdf0e10cSrcweir // ------------------------------------------------------------------------ 3119cdf0e10cSrcweir 3120cdf0e10cSrcweir sal_Bool Bitmap::ImplReduceMedian( sal_uInt16 nColCount ) 3121cdf0e10cSrcweir { 3122cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 3123cdf0e10cSrcweir sal_uInt16 nBitCount; 3124cdf0e10cSrcweir sal_Bool bRet = sal_False; 3125cdf0e10cSrcweir 3126cdf0e10cSrcweir if( nColCount < 17 ) 3127cdf0e10cSrcweir nBitCount = 4; 3128cdf0e10cSrcweir else if( nColCount < 257 ) 3129cdf0e10cSrcweir nBitCount = 8; 3130cdf0e10cSrcweir else 3131cdf0e10cSrcweir { 3132cdf0e10cSrcweir DBG_ERROR( "Bitmap::ImplReduceMedian(): invalid color count!" ); 3133cdf0e10cSrcweir nBitCount = 8; 3134cdf0e10cSrcweir nColCount = 256; 3135cdf0e10cSrcweir } 3136cdf0e10cSrcweir 3137cdf0e10cSrcweir if( pRAcc ) 3138cdf0e10cSrcweir { 3139cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount ); 3140cdf0e10cSrcweir BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess(); 3141cdf0e10cSrcweir 3142cdf0e10cSrcweir if( pWAcc ) 3143cdf0e10cSrcweir { 3144cdf0e10cSrcweir const sal_uLong nSize = 32768UL * sizeof( sal_uLong ); 3145cdf0e10cSrcweir sal_uLong* pColBuf = (sal_uLong*) rtl_allocateMemory( nSize ); 3146cdf0e10cSrcweir const long nWidth = pWAcc->Width(); 3147cdf0e10cSrcweir const long nHeight = pWAcc->Height(); 3148cdf0e10cSrcweir long nIndex = 0L; 3149cdf0e10cSrcweir 3150cdf0e10cSrcweir memset( (HPBYTE) pColBuf, 0, nSize ); 3151cdf0e10cSrcweir 3152cdf0e10cSrcweir // create Buffer 3153cdf0e10cSrcweir if( pRAcc->HasPalette() ) 3154cdf0e10cSrcweir { 3155cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3156cdf0e10cSrcweir { 3157cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 3158cdf0e10cSrcweir { 315987bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3160cdf0e10cSrcweir pColBuf[ RGB15( rCol.GetRed() >> 3, rCol.GetGreen() >> 3, rCol.GetBlue() >> 3 ) ]++; 3161cdf0e10cSrcweir } 3162cdf0e10cSrcweir } 3163cdf0e10cSrcweir } 3164cdf0e10cSrcweir else 3165cdf0e10cSrcweir { 3166cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3167cdf0e10cSrcweir { 3168cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 3169cdf0e10cSrcweir { 3170cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3171cdf0e10cSrcweir pColBuf[ RGB15( aCol.GetRed() >> 3, aCol.GetGreen() >> 3, aCol.GetBlue() >> 3 ) ]++; 3172cdf0e10cSrcweir } 3173cdf0e10cSrcweir } 3174cdf0e10cSrcweir } 3175cdf0e10cSrcweir 3176cdf0e10cSrcweir // create palette via median cut 3177cdf0e10cSrcweir BitmapPalette aPal( pWAcc->GetPaletteEntryCount() ); 3178cdf0e10cSrcweir ImplMedianCut( pColBuf, aPal, 0, 31, 0, 31, 0, 31, 3179cdf0e10cSrcweir nColCount, nWidth * nHeight, nIndex ); 3180cdf0e10cSrcweir 3181cdf0e10cSrcweir // do mapping of colors to palette 3182cdf0e10cSrcweir InverseColorMap aMap( aPal ); 3183cdf0e10cSrcweir pWAcc->SetPalette( aPal ); 3184cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3185cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 318687bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>( aMap.GetBestPaletteIndex( pRAcc->GetColor( nY, nX ) )) ); 3187cdf0e10cSrcweir 3188cdf0e10cSrcweir rtl_freeMemory( pColBuf ); 3189cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 3190cdf0e10cSrcweir bRet = sal_True; 3191cdf0e10cSrcweir } 3192cdf0e10cSrcweir 3193cdf0e10cSrcweir ReleaseAccess( pRAcc ); 3194cdf0e10cSrcweir 3195cdf0e10cSrcweir if( bRet ) 3196cdf0e10cSrcweir { 3197cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 3198cdf0e10cSrcweir const Size aSize( maPrefSize ); 3199cdf0e10cSrcweir 3200cdf0e10cSrcweir *this = aNewBmp; 3201cdf0e10cSrcweir maPrefMapMode = aMap; 3202cdf0e10cSrcweir maPrefSize = aSize; 3203cdf0e10cSrcweir } 3204cdf0e10cSrcweir } 3205cdf0e10cSrcweir 3206cdf0e10cSrcweir return bRet; 3207cdf0e10cSrcweir } 3208cdf0e10cSrcweir 3209cdf0e10cSrcweir // ------------------------------------------------------------------------ 3210cdf0e10cSrcweir 3211cdf0e10cSrcweir void Bitmap::ImplMedianCut( sal_uLong* pColBuf, BitmapPalette& rPal, 3212cdf0e10cSrcweir long nR1, long nR2, long nG1, long nG2, long nB1, long nB2, 3213cdf0e10cSrcweir long nColors, long nPixels, long& rIndex ) 3214cdf0e10cSrcweir { 3215cdf0e10cSrcweir if( !nPixels ) 3216cdf0e10cSrcweir return; 3217cdf0e10cSrcweir 3218cdf0e10cSrcweir BitmapColor aCol; 3219cdf0e10cSrcweir const long nRLen = nR2 - nR1; 3220cdf0e10cSrcweir const long nGLen = nG2 - nG1; 3221cdf0e10cSrcweir const long nBLen = nB2 - nB1; 3222cdf0e10cSrcweir long nR, nG, nB; 3223cdf0e10cSrcweir sal_uLong* pBuf = pColBuf; 3224cdf0e10cSrcweir 3225cdf0e10cSrcweir if( !nRLen && !nGLen && !nBLen ) 3226cdf0e10cSrcweir { 3227cdf0e10cSrcweir if( pBuf[ RGB15( nR1, nG1, nB1 ) ] ) 3228cdf0e10cSrcweir { 3229cdf0e10cSrcweir aCol.SetRed( (sal_uInt8) ( nR1 << 3 ) ); 3230cdf0e10cSrcweir aCol.SetGreen( (sal_uInt8) ( nG1 << 3 ) ); 3231cdf0e10cSrcweir aCol.SetBlue( (sal_uInt8) ( nB1 << 3 ) ); 3232cdf0e10cSrcweir rPal[ (sal_uInt16) rIndex++ ] = aCol; 3233cdf0e10cSrcweir } 3234cdf0e10cSrcweir } 3235cdf0e10cSrcweir else 3236cdf0e10cSrcweir { 3237cdf0e10cSrcweir if( 1 == nColors || 1 == nPixels ) 3238cdf0e10cSrcweir { 3239cdf0e10cSrcweir long nPixSum = 0, nRSum = 0, nGSum = 0, nBSum = 0; 3240cdf0e10cSrcweir 3241cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3242cdf0e10cSrcweir { 3243cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3244cdf0e10cSrcweir { 3245cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3246cdf0e10cSrcweir { 3247cdf0e10cSrcweir nPixSum = pBuf[ RGB15( nR, nG, nB ) ]; 3248cdf0e10cSrcweir 3249cdf0e10cSrcweir if( nPixSum ) 3250cdf0e10cSrcweir { 3251cdf0e10cSrcweir nRSum += nR * nPixSum; 3252cdf0e10cSrcweir nGSum += nG * nPixSum; 3253cdf0e10cSrcweir nBSum += nB * nPixSum; 3254cdf0e10cSrcweir } 3255cdf0e10cSrcweir } 3256cdf0e10cSrcweir } 3257cdf0e10cSrcweir } 3258cdf0e10cSrcweir 3259cdf0e10cSrcweir aCol.SetRed( (sal_uInt8) ( ( nRSum / nPixels ) << 3 ) ); 3260cdf0e10cSrcweir aCol.SetGreen( (sal_uInt8) ( ( nGSum / nPixels ) << 3 ) ); 3261cdf0e10cSrcweir aCol.SetBlue( (sal_uInt8) ( ( nBSum / nPixels ) << 3 ) ); 3262cdf0e10cSrcweir rPal[ (sal_uInt16) rIndex++ ] = aCol; 3263cdf0e10cSrcweir } 3264cdf0e10cSrcweir else 3265cdf0e10cSrcweir { 3266cdf0e10cSrcweir const long nTest = ( nPixels >> 1 ); 3267cdf0e10cSrcweir long nPixOld = 0; 3268cdf0e10cSrcweir long nPixNew = 0; 3269cdf0e10cSrcweir 3270cdf0e10cSrcweir if( nBLen > nGLen && nBLen > nRLen ) 3271cdf0e10cSrcweir { 3272cdf0e10cSrcweir nB = nB1 - 1; 3273cdf0e10cSrcweir 3274cdf0e10cSrcweir while( nPixNew < nTest ) 3275cdf0e10cSrcweir { 3276cdf0e10cSrcweir nB++, nPixOld = nPixNew; 3277cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3278cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3279cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3280cdf0e10cSrcweir } 3281cdf0e10cSrcweir 3282cdf0e10cSrcweir if( nB < nB2 ) 3283cdf0e10cSrcweir { 3284cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB, nColors >> 1, nPixNew, rIndex ); 3285cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB + 1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3286cdf0e10cSrcweir } 3287cdf0e10cSrcweir else 3288cdf0e10cSrcweir { 3289cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB - 1, nColors >> 1, nPixOld, rIndex ); 3290cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3291cdf0e10cSrcweir } 3292cdf0e10cSrcweir } 3293cdf0e10cSrcweir else if( nGLen > nRLen ) 3294cdf0e10cSrcweir { 3295cdf0e10cSrcweir nG = nG1 - 1; 3296cdf0e10cSrcweir 3297cdf0e10cSrcweir while( nPixNew < nTest ) 3298cdf0e10cSrcweir { 3299cdf0e10cSrcweir nG++, nPixOld = nPixNew; 3300cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3301cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3302cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3303cdf0e10cSrcweir } 3304cdf0e10cSrcweir 3305cdf0e10cSrcweir if( nG < nG2 ) 3306cdf0e10cSrcweir { 3307cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG, nB1, nB2, nColors >> 1, nPixNew, rIndex ); 3308cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG + 1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3309cdf0e10cSrcweir } 3310cdf0e10cSrcweir else 3311cdf0e10cSrcweir { 3312cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG - 1, nB1, nB2, nColors >> 1, nPixOld, rIndex ); 3313cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3314cdf0e10cSrcweir } 3315cdf0e10cSrcweir } 3316cdf0e10cSrcweir else 3317cdf0e10cSrcweir { 3318cdf0e10cSrcweir nR = nR1 - 1; 3319cdf0e10cSrcweir 3320cdf0e10cSrcweir while( nPixNew < nTest ) 3321cdf0e10cSrcweir { 3322cdf0e10cSrcweir nR++, nPixOld = nPixNew; 3323cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3324cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3325cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3326cdf0e10cSrcweir } 3327cdf0e10cSrcweir 3328cdf0e10cSrcweir if( nR < nR2 ) 3329cdf0e10cSrcweir { 3330cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR, nG1, nG2, nB1, nB2, nColors >> 1, nPixNew, rIndex ); 3331cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1 + 1, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3332cdf0e10cSrcweir } 3333cdf0e10cSrcweir else 3334cdf0e10cSrcweir { 3335cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR - 1, nG1, nG2, nB1, nB2, nColors >> 1, nPixOld, rIndex ); 3336cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3337cdf0e10cSrcweir } 3338cdf0e10cSrcweir } 3339cdf0e10cSrcweir } 3340cdf0e10cSrcweir } 3341cdf0e10cSrcweir } 3342cdf0e10cSrcweir 3343cdf0e10cSrcweir // ------------------------------------------------------------------------ 3344cdf0e10cSrcweir 3345cdf0e10cSrcweir sal_Bool Bitmap::Vectorize( PolyPolygon& rPolyPoly, sal_uLong nFlags, const Link* pProgress ) 3346cdf0e10cSrcweir { 3347cdf0e10cSrcweir return ImplVectorizer().ImplVectorize( *this, rPolyPoly, nFlags, pProgress ); 3348cdf0e10cSrcweir } 3349cdf0e10cSrcweir 3350cdf0e10cSrcweir // ------------------------------------------------------------------------ 3351cdf0e10cSrcweir 3352cdf0e10cSrcweir sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFlags, const Link* pProgress ) 3353cdf0e10cSrcweir { 3354cdf0e10cSrcweir return ImplVectorizer().ImplVectorize( *this, rMtf, cReduce, nFlags, pProgress ); 3355cdf0e10cSrcweir } 3356cdf0e10cSrcweir 3357cdf0e10cSrcweir // ------------------------------------------------------------------------ 3358cdf0e10cSrcweir 3359cdf0e10cSrcweir sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent, 3360cdf0e10cSrcweir short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, 3361cdf0e10cSrcweir double fGamma, sal_Bool bInvert ) 3362cdf0e10cSrcweir { 3363cdf0e10cSrcweir sal_Bool bRet = sal_False; 3364cdf0e10cSrcweir 3365cdf0e10cSrcweir // nothing to do => return quickly 3366cdf0e10cSrcweir if( !nLuminancePercent && !nContrastPercent && 3367cdf0e10cSrcweir !nChannelRPercent && !nChannelGPercent && !nChannelBPercent && 3368cdf0e10cSrcweir ( fGamma == 1.0 ) && !bInvert ) 3369cdf0e10cSrcweir { 3370cdf0e10cSrcweir bRet = sal_True; 3371cdf0e10cSrcweir } 3372cdf0e10cSrcweir else 3373cdf0e10cSrcweir { 3374cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess(); 3375cdf0e10cSrcweir 3376cdf0e10cSrcweir if( pAcc ) 3377cdf0e10cSrcweir { 3378cdf0e10cSrcweir BitmapColor aCol; 3379cdf0e10cSrcweir const long nW = pAcc->Width(); 3380cdf0e10cSrcweir const long nH = pAcc->Height(); 3381cdf0e10cSrcweir sal_uInt8* cMapR = new sal_uInt8[ 256 ]; 3382cdf0e10cSrcweir sal_uInt8* cMapG = new sal_uInt8[ 256 ]; 3383cdf0e10cSrcweir sal_uInt8* cMapB = new sal_uInt8[ 256 ]; 3384cdf0e10cSrcweir long nX, nY; 3385cdf0e10cSrcweir double fM, fROff, fGOff, fBOff, fOff; 3386cdf0e10cSrcweir 3387cdf0e10cSrcweir // calculate slope 3388cdf0e10cSrcweir if( nContrastPercent >= 0 ) 3389cdf0e10cSrcweir fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) ); 3390cdf0e10cSrcweir else 3391cdf0e10cSrcweir fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0; 3392cdf0e10cSrcweir 3393cdf0e10cSrcweir // total offset = luminance offset + contrast offset 3394cdf0e10cSrcweir fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0; 3395cdf0e10cSrcweir 3396cdf0e10cSrcweir // channel offset = channel offset + total offset 3397cdf0e10cSrcweir fROff = nChannelRPercent * 2.55 + fOff; 3398cdf0e10cSrcweir fGOff = nChannelGPercent * 2.55 + fOff; 3399cdf0e10cSrcweir fBOff = nChannelBPercent * 2.55 + fOff; 3400cdf0e10cSrcweir 3401cdf0e10cSrcweir // calculate gamma value 3402cdf0e10cSrcweir fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); 3403cdf0e10cSrcweir const sal_Bool bGamma = ( fGamma != 1.0 ); 3404cdf0e10cSrcweir 3405cdf0e10cSrcweir // create mapping table 3406cdf0e10cSrcweir for( nX = 0L; nX < 256L; nX++ ) 3407cdf0e10cSrcweir { 3408cdf0e10cSrcweir cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L ); 3409cdf0e10cSrcweir cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L ); 3410cdf0e10cSrcweir cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L ); 3411cdf0e10cSrcweir 3412cdf0e10cSrcweir if( bGamma ) 3413cdf0e10cSrcweir { 3414cdf0e10cSrcweir cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma ); 3415cdf0e10cSrcweir cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma ); 3416cdf0e10cSrcweir cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma ); 3417cdf0e10cSrcweir } 3418cdf0e10cSrcweir 3419cdf0e10cSrcweir if( bInvert ) 3420cdf0e10cSrcweir { 3421cdf0e10cSrcweir cMapR[ nX ] = ~cMapR[ nX ]; 3422cdf0e10cSrcweir cMapG[ nX ] = ~cMapG[ nX ]; 3423cdf0e10cSrcweir cMapB[ nX ] = ~cMapB[ nX ]; 3424cdf0e10cSrcweir } 3425cdf0e10cSrcweir } 3426cdf0e10cSrcweir 3427cdf0e10cSrcweir // do modifying 3428cdf0e10cSrcweir if( pAcc->HasPalette() ) 3429cdf0e10cSrcweir { 3430cdf0e10cSrcweir BitmapColor aNewCol; 3431cdf0e10cSrcweir 3432cdf0e10cSrcweir for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ ) 3433cdf0e10cSrcweir { 3434cdf0e10cSrcweir const BitmapColor& rCol = pAcc->GetPaletteColor( i ); 3435cdf0e10cSrcweir aNewCol.SetRed( cMapR[ rCol.GetRed() ] ); 3436cdf0e10cSrcweir aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] ); 3437cdf0e10cSrcweir aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] ); 3438cdf0e10cSrcweir pAcc->SetPaletteColor( i, aNewCol ); 3439cdf0e10cSrcweir } 3440cdf0e10cSrcweir } 3441cdf0e10cSrcweir else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ) 3442cdf0e10cSrcweir { 3443cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3444cdf0e10cSrcweir { 3445cdf0e10cSrcweir Scanline pScan = pAcc->GetScanline( nY ); 3446cdf0e10cSrcweir 3447cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3448cdf0e10cSrcweir { 3449cdf0e10cSrcweir *pScan = cMapB[ *pScan ]; pScan++; 3450cdf0e10cSrcweir *pScan = cMapG[ *pScan ]; pScan++; 3451cdf0e10cSrcweir *pScan = cMapR[ *pScan ]; pScan++; 3452cdf0e10cSrcweir } 3453cdf0e10cSrcweir } 3454cdf0e10cSrcweir } 3455cdf0e10cSrcweir else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ) 3456cdf0e10cSrcweir { 3457cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3458cdf0e10cSrcweir { 3459cdf0e10cSrcweir Scanline pScan = pAcc->GetScanline( nY ); 3460cdf0e10cSrcweir 3461cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3462cdf0e10cSrcweir { 3463cdf0e10cSrcweir *pScan = cMapR[ *pScan ]; pScan++; 3464cdf0e10cSrcweir *pScan = cMapG[ *pScan ]; pScan++; 3465cdf0e10cSrcweir *pScan = cMapB[ *pScan ]; pScan++; 3466cdf0e10cSrcweir } 3467cdf0e10cSrcweir } 3468cdf0e10cSrcweir } 3469cdf0e10cSrcweir else 3470cdf0e10cSrcweir { 3471cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3472cdf0e10cSrcweir { 3473cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3474cdf0e10cSrcweir { 3475cdf0e10cSrcweir aCol = pAcc->GetPixel( nY, nX ); 3476cdf0e10cSrcweir aCol.SetRed( cMapR[ aCol.GetRed() ] ); 3477cdf0e10cSrcweir aCol.SetGreen( cMapG[ aCol.GetGreen() ] ); 3478cdf0e10cSrcweir aCol.SetBlue( cMapB[ aCol.GetBlue() ] ); 3479cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aCol ); 3480cdf0e10cSrcweir } 3481cdf0e10cSrcweir } 3482cdf0e10cSrcweir } 3483cdf0e10cSrcweir 3484cdf0e10cSrcweir delete[] cMapR; 3485cdf0e10cSrcweir delete[] cMapG; 3486cdf0e10cSrcweir delete[] cMapB; 3487cdf0e10cSrcweir ReleaseAccess( pAcc ); 3488cdf0e10cSrcweir bRet = sal_True; 3489cdf0e10cSrcweir } 3490cdf0e10cSrcweir } 3491cdf0e10cSrcweir 3492cdf0e10cSrcweir return bRet; 3493cdf0e10cSrcweir } 3494