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 { 90937ab0f2dSArmin Le Grand #ifdef DBG_UTIL 91037ab0f2dSArmin Le Grand // #121233# allow to test the different scalers in debug build with source 91137ab0f2dSArmin Le Grand // level debugger (change nNumber to desired action) 91237ab0f2dSArmin Le Grand static sal_uInt16 nNumber(0); 91337ab0f2dSArmin Le Grand 91437ab0f2dSArmin Le Grand switch(nNumber) 91537ab0f2dSArmin Le Grand { 91637ab0f2dSArmin Le Grand case 0 : break; 91737ab0f2dSArmin Le Grand case 1: nScaleFlag = BMP_SCALE_FAST; break; 91837ab0f2dSArmin Le Grand case 2: nScaleFlag = BMP_SCALE_INTERPOLATE; break; 91937ab0f2dSArmin Le Grand case 3: nScaleFlag = BMP_SCALE_SUPER; break; 92037ab0f2dSArmin Le Grand case 4: nScaleFlag = BMP_SCALE_LANCZOS; break; 92137ab0f2dSArmin Le Grand case 5: nScaleFlag = BMP_SCALE_BICUBIC; break; 92237ab0f2dSArmin Le Grand case 6: nScaleFlag = BMP_SCALE_BILINEAR; break; 92337ab0f2dSArmin Le Grand case 7: nScaleFlag = BMP_SCALE_BOX; break; 92437ab0f2dSArmin Le Grand case 8: nScaleFlag = BMP_SCALE_BESTQUALITY; break; 92537ab0f2dSArmin Le Grand case 9: nScaleFlag = BMP_SCALE_FASTESTINTERPOLATE; break; 92637ab0f2dSArmin Le Grand } 92737ab0f2dSArmin Le Grand #endif // DBG_UTIL 92837ab0f2dSArmin Le Grand 92937ab0f2dSArmin Le Grand if(basegfx::fTools::equalZero(rScaleX) && basegfx::fTools::equalZero(rScaleY)) 93037ab0f2dSArmin Le Grand { 93137ab0f2dSArmin Le Grand // no scale 93237ab0f2dSArmin Le Grand return true; 93337ab0f2dSArmin Le Grand } 93437ab0f2dSArmin Le Grand else 93537ab0f2dSArmin Le Grand { 93637ab0f2dSArmin Le Grand if(BMP_SCALE_BESTQUALITY == nScaleFlag) 93737ab0f2dSArmin Le Grand { 93837ab0f2dSArmin Le Grand // Use LANCZOS when best quality is requested 93937ab0f2dSArmin Le Grand nScaleFlag = BMP_SCALE_LANCZOS; 94037ab0f2dSArmin Le Grand } 94137ab0f2dSArmin Le Grand else if(BMP_SCALE_FASTESTINTERPOLATE == nScaleFlag) 94237ab0f2dSArmin Le Grand { 94337ab0f2dSArmin Le Grand // Use BMP_SCALE_SUPER when speed is requested, but not worst quality 94437ab0f2dSArmin Le Grand nScaleFlag = BMP_SCALE_SUPER; 94537ab0f2dSArmin Le Grand } 94637ab0f2dSArmin Le Grand 94737ab0f2dSArmin Le Grand switch(nScaleFlag) 94837ab0f2dSArmin Le Grand { 94937ab0f2dSArmin Le Grand default: 95037ab0f2dSArmin Le Grand case BMP_SCALE_NONE : 95137ab0f2dSArmin Le Grand { 95237ab0f2dSArmin Le Grand return false; 95337ab0f2dSArmin Le Grand break; 95437ab0f2dSArmin Le Grand } 95537ab0f2dSArmin Le Grand case BMP_SCALE_FAST : 95637ab0f2dSArmin Le Grand { 95737ab0f2dSArmin Le Grand return ImplScaleFast( rScaleX, rScaleY ); 95837ab0f2dSArmin Le Grand break; 95937ab0f2dSArmin Le Grand } 96037ab0f2dSArmin Le Grand case BMP_SCALE_INTERPOLATE : 96137ab0f2dSArmin Le Grand { 96237ab0f2dSArmin Le Grand return ImplScaleInterpolate( rScaleX, rScaleY ); 96337ab0f2dSArmin Le Grand break; 96437ab0f2dSArmin Le Grand } 96537ab0f2dSArmin Le Grand case BMP_SCALE_SUPER : 96637ab0f2dSArmin Le Grand { 96737ab0f2dSArmin Le Grand if(GetSizePixel().Width() < 2 || GetSizePixel().Height() < 2) 96837ab0f2dSArmin Le Grand { 96937ab0f2dSArmin Le Grand // fallback to ImplScaleFast 97037ab0f2dSArmin Le Grand return ImplScaleFast( rScaleX, rScaleY ); 97137ab0f2dSArmin Le Grand } 97237ab0f2dSArmin Le Grand else 97337ab0f2dSArmin Le Grand { 97437ab0f2dSArmin Le Grand // #121233# use method from symphony 97537ab0f2dSArmin Le Grand return ImplScaleSuper( rScaleX, rScaleY ); 97637ab0f2dSArmin Le Grand } 97737ab0f2dSArmin Le Grand break; 97837ab0f2dSArmin Le Grand } 97937ab0f2dSArmin Le Grand case BMP_SCALE_LANCZOS : 98037ab0f2dSArmin Le Grand { 98137ab0f2dSArmin Le Grand const Lanczos3Kernel kernel; 98237ab0f2dSArmin Le Grand 98337ab0f2dSArmin Le Grand return ImplScaleConvolution( rScaleX, rScaleY, kernel); 98437ab0f2dSArmin Le Grand break; 98537ab0f2dSArmin Le Grand } 98637ab0f2dSArmin Le Grand case BMP_SCALE_BICUBIC : 98737ab0f2dSArmin Le Grand { 98837ab0f2dSArmin Le Grand const BicubicKernel kernel; 98937ab0f2dSArmin Le Grand 99037ab0f2dSArmin Le Grand return ImplScaleConvolution( rScaleX, rScaleY, kernel ); 99137ab0f2dSArmin Le Grand break; 99237ab0f2dSArmin Le Grand } 99337ab0f2dSArmin Le Grand case BMP_SCALE_BILINEAR : 99437ab0f2dSArmin Le Grand { 99537ab0f2dSArmin Le Grand const BilinearKernel kernel; 99637ab0f2dSArmin Le Grand 99737ab0f2dSArmin Le Grand return ImplScaleConvolution( rScaleX, rScaleY, kernel ); 99837ab0f2dSArmin Le Grand break; 99937ab0f2dSArmin Le Grand } 100037ab0f2dSArmin Le Grand case BMP_SCALE_BOX : 100137ab0f2dSArmin Le Grand { 100237ab0f2dSArmin Le Grand const BoxKernel kernel; 100337ab0f2dSArmin Le Grand 100437ab0f2dSArmin Le Grand return ImplScaleConvolution( rScaleX, rScaleY, kernel ); 100537ab0f2dSArmin Le Grand break; 100637ab0f2dSArmin Le Grand } 100737ab0f2dSArmin Le Grand } 100837ab0f2dSArmin Le Grand } 100937ab0f2dSArmin Le Grand 101037ab0f2dSArmin Le Grand // should not happen 101137ab0f2dSArmin Le Grand return false; 1012cdf0e10cSrcweir } 1013cdf0e10cSrcweir 1014cdf0e10cSrcweir // ------------------------------------------------------------------------ 1015cdf0e10cSrcweir 1016cdf0e10cSrcweir sal_Bool Bitmap::Scale( const Size& rNewSize, sal_uLong nScaleFlag ) 1017cdf0e10cSrcweir { 1018cdf0e10cSrcweir const Size aSize( GetSizePixel() ); 1019cdf0e10cSrcweir sal_Bool bRet; 1020cdf0e10cSrcweir 1021cdf0e10cSrcweir if( aSize.Width() && aSize.Height() ) 1022cdf0e10cSrcweir { 1023cdf0e10cSrcweir bRet = Scale( (double) rNewSize.Width() / aSize.Width(), 1024cdf0e10cSrcweir (double) rNewSize.Height() / aSize.Height(), 1025cdf0e10cSrcweir nScaleFlag ); 1026cdf0e10cSrcweir } 1027cdf0e10cSrcweir else 1028cdf0e10cSrcweir bRet = sal_True; 1029cdf0e10cSrcweir 1030cdf0e10cSrcweir return bRet; 1031cdf0e10cSrcweir } 1032cdf0e10cSrcweir 1033cdf0e10cSrcweir // ------------------------------------------------------------------------ 1034cdf0e10cSrcweir 1035c2821885SArmin Le Grand void Bitmap::AdaptBitCount(Bitmap& rNew) const 1036c2821885SArmin Le Grand { 1037c2821885SArmin Le Grand ImplAdaptBitCount(rNew); 1038c2821885SArmin Le Grand } 1039c2821885SArmin Le Grand 1040c2821885SArmin Le Grand // ------------------------------------------------------------------------ 1041c2821885SArmin Le Grand 1042c2821885SArmin Le Grand void Bitmap::ImplAdaptBitCount(Bitmap& rNew) const 104337ab0f2dSArmin Le Grand { 104437ab0f2dSArmin Le Grand // aNew is the result of some operation; adapt it's BitCount to the original (this) 104537ab0f2dSArmin Le Grand if(GetBitCount() != rNew.GetBitCount()) 104637ab0f2dSArmin Le Grand { 104737ab0f2dSArmin Le Grand switch(GetBitCount()) 104837ab0f2dSArmin Le Grand { 104937ab0f2dSArmin Le Grand case 1: 105037ab0f2dSArmin Le Grand { 105137ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_1BIT_THRESHOLD); 105237ab0f2dSArmin Le Grand break; 105337ab0f2dSArmin Le Grand } 105437ab0f2dSArmin Le Grand case 4: 105537ab0f2dSArmin Le Grand { 105637ab0f2dSArmin Le Grand if(HasGreyPalette()) 105737ab0f2dSArmin Le Grand { 105837ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_4BIT_GREYS); 105937ab0f2dSArmin Le Grand } 106037ab0f2dSArmin Le Grand else 106137ab0f2dSArmin Le Grand { 106237ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_4BIT_COLORS); 106337ab0f2dSArmin Le Grand } 106437ab0f2dSArmin Le Grand break; 106537ab0f2dSArmin Le Grand } 106637ab0f2dSArmin Le Grand case 8: 106737ab0f2dSArmin Le Grand { 106837ab0f2dSArmin Le Grand if(HasGreyPalette()) 106937ab0f2dSArmin Le Grand { 107037ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_8BIT_GREYS); 107137ab0f2dSArmin Le Grand } 107237ab0f2dSArmin Le Grand else 107337ab0f2dSArmin Le Grand { 107437ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_8BIT_COLORS); 107537ab0f2dSArmin Le Grand } 107637ab0f2dSArmin Le Grand break; 107737ab0f2dSArmin Le Grand } 107837ab0f2dSArmin Le Grand case 24: 107937ab0f2dSArmin Le Grand { 108037ab0f2dSArmin Le Grand rNew.Convert(BMP_CONVERSION_24BIT); 108137ab0f2dSArmin Le Grand break; 108237ab0f2dSArmin Le Grand } 108337ab0f2dSArmin Le Grand default: 108437ab0f2dSArmin Le Grand { 108537ab0f2dSArmin Le Grand OSL_ENSURE(false, "BitDepth adaption failed (!)"); 108637ab0f2dSArmin Le Grand break; 108737ab0f2dSArmin Le Grand } 108837ab0f2dSArmin Le Grand } 108937ab0f2dSArmin Le Grand } 109037ab0f2dSArmin Le Grand } 109137ab0f2dSArmin Le Grand 109237ab0f2dSArmin Le Grand // ------------------------------------------------------------------------ 109337ab0f2dSArmin Le Grand 1094cdf0e10cSrcweir sal_Bool Bitmap::ImplScaleFast( const double& rScaleX, const double& rScaleY ) 1095cdf0e10cSrcweir { 1096cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 1097cdf0e10cSrcweir const long nNewWidth = FRound( aSizePix.Width() * rScaleX ); 1098cdf0e10cSrcweir const long nNewHeight = FRound( aSizePix.Height() * rScaleY ); 1099cdf0e10cSrcweir sal_Bool bRet = sal_False; 1100cdf0e10cSrcweir 1101cdf0e10cSrcweir if( nNewWidth && nNewHeight ) 1102cdf0e10cSrcweir { 1103cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 11040f740837SAriel Constenla-Haile if ( !pReadAcc ) 11050f740837SAriel Constenla-Haile return sal_False; 11060f740837SAriel Constenla-Haile 1107cdf0e10cSrcweir Bitmap aNewBmp( Size( nNewWidth, nNewHeight ), GetBitCount(), &pReadAcc->GetPalette() ); 1108cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 1109cdf0e10cSrcweir 11100f740837SAriel Constenla-Haile if( pWriteAcc ) 1111cdf0e10cSrcweir { 1112cdf0e10cSrcweir const long nScanlineSize = pWriteAcc->GetScanlineSize(); 1113cdf0e10cSrcweir const long nNewWidth1 = nNewWidth - 1L; 1114cdf0e10cSrcweir const long nNewHeight1 = nNewHeight - 1L; 1115cdf0e10cSrcweir const long nWidth = pReadAcc->Width(); 1116cdf0e10cSrcweir const long nHeight = pReadAcc->Height(); 1117cdf0e10cSrcweir long* pLutX = new long[ nNewWidth ]; 1118cdf0e10cSrcweir long* pLutY = new long[ nNewHeight ]; 1119cdf0e10cSrcweir long nX, nY, nMapY, nActY = 0L; 1120cdf0e10cSrcweir 1121cdf0e10cSrcweir if( nNewWidth1 && nNewHeight1 ) 1122cdf0e10cSrcweir { 1123cdf0e10cSrcweir for( nX = 0L; nX < nNewWidth; nX++ ) 1124cdf0e10cSrcweir pLutX[ nX ] = nX * nWidth / nNewWidth; 1125cdf0e10cSrcweir 1126cdf0e10cSrcweir for( nY = 0L; nY < nNewHeight; nY++ ) 1127cdf0e10cSrcweir pLutY[ nY ] = nY * nHeight / nNewHeight; 1128cdf0e10cSrcweir 1129cdf0e10cSrcweir while( nActY < nNewHeight ) 1130cdf0e10cSrcweir { 1131cdf0e10cSrcweir nMapY = pLutY[ nActY ]; 1132cdf0e10cSrcweir 1133cdf0e10cSrcweir for( nX = 0L; nX < nNewWidth; nX++ ) 1134cdf0e10cSrcweir pWriteAcc->SetPixel( nActY, nX, pReadAcc->GetPixel( nMapY , pLutX[ nX ] ) ); 1135cdf0e10cSrcweir 1136cdf0e10cSrcweir while( ( nActY < nNewHeight1 ) && ( pLutY[ nActY + 1 ] == nMapY ) ) 1137cdf0e10cSrcweir { 1138cdf0e10cSrcweir memcpy( pWriteAcc->GetScanline( nActY + 1L ), 1139cdf0e10cSrcweir pWriteAcc->GetScanline( nActY ), nScanlineSize ); 1140cdf0e10cSrcweir nActY++; 1141cdf0e10cSrcweir } 1142cdf0e10cSrcweir 1143cdf0e10cSrcweir nActY++; 1144cdf0e10cSrcweir } 1145cdf0e10cSrcweir 1146cdf0e10cSrcweir bRet = sal_True; 1147cdf0e10cSrcweir } 1148cdf0e10cSrcweir 1149cdf0e10cSrcweir delete[] pLutX; 1150cdf0e10cSrcweir delete[] pLutY; 1151cdf0e10cSrcweir } 1152cdf0e10cSrcweir 1153cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1154cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1155cdf0e10cSrcweir 1156cdf0e10cSrcweir if( bRet ) 1157cdf0e10cSrcweir ImplAssignWithSize( aNewBmp ); 1158cdf0e10cSrcweir } 1159cdf0e10cSrcweir 1160cdf0e10cSrcweir return bRet; 1161cdf0e10cSrcweir } 1162cdf0e10cSrcweir 1163cdf0e10cSrcweir // ------------------------------------------------------------------------ 1164cdf0e10cSrcweir 1165cdf0e10cSrcweir sal_Bool Bitmap::ImplScaleInterpolate( const double& rScaleX, const double& rScaleY ) 1166cdf0e10cSrcweir { 1167cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 1168cdf0e10cSrcweir const long nNewWidth = FRound( aSizePix.Width() * rScaleX ); 1169cdf0e10cSrcweir const long nNewHeight = FRound( aSizePix.Height() * rScaleY ); 1170cdf0e10cSrcweir sal_Bool bRet = sal_False; 1171cdf0e10cSrcweir 1172cdf0e10cSrcweir if( ( nNewWidth > 1L ) && ( nNewHeight > 1L ) ) 1173cdf0e10cSrcweir { 1174cdf0e10cSrcweir BitmapColor aCol0; 1175cdf0e10cSrcweir BitmapColor aCol1; 1176cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 1177cdf0e10cSrcweir long nWidth = pReadAcc->Width(); 1178cdf0e10cSrcweir long nHeight = pReadAcc->Height(); 1179cdf0e10cSrcweir Bitmap aNewBmp( Size( nNewWidth, nHeight ), 24 ); 1180cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 1181cdf0e10cSrcweir long* pLutInt; 1182cdf0e10cSrcweir long* pLutFrac; 1183cdf0e10cSrcweir long nX, nY; 1184cdf0e10cSrcweir long lXB0, lXB1, lXG0, lXG1, lXR0, lXR1; 1185cdf0e10cSrcweir double fTemp; 1186cdf0e10cSrcweir long nTemp; 1187cdf0e10cSrcweir 1188cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 1189cdf0e10cSrcweir { 1190cdf0e10cSrcweir const long nNewWidth1 = nNewWidth - 1L; 1191cdf0e10cSrcweir const long nWidth1 = pReadAcc->Width() - 1L; 1192cdf0e10cSrcweir const double fRevScaleX = (double) nWidth1 / nNewWidth1; 1193cdf0e10cSrcweir 1194cdf0e10cSrcweir pLutInt = new long[ nNewWidth ]; 1195cdf0e10cSrcweir pLutFrac = new long[ nNewWidth ]; 1196cdf0e10cSrcweir 1197cdf0e10cSrcweir for( nX = 0L, nTemp = nWidth - 2L; nX < nNewWidth; nX++ ) 1198cdf0e10cSrcweir { 1199cdf0e10cSrcweir fTemp = nX * fRevScaleX; 1200cdf0e10cSrcweir pLutInt[ nX ] = MinMax( (long) fTemp, 0, nTemp ); 1201cdf0e10cSrcweir fTemp -= pLutInt[ nX ]; 1202cdf0e10cSrcweir pLutFrac[ nX ] = (long) ( fTemp * 1024. ); 1203cdf0e10cSrcweir } 1204cdf0e10cSrcweir 1205c2821885SArmin Le Grand for( nY = 0L; nY < nHeight; nY++ ) 1206cdf0e10cSrcweir { 1207c2821885SArmin Le Grand if( 1 == nWidth ) 1208cdf0e10cSrcweir { 1209c2821885SArmin Le Grand if( pReadAcc->HasPalette() ) 1210c2821885SArmin Le Grand { 1211c2821885SArmin Le Grand aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, 0 ) ); 1212c2821885SArmin Le Grand } 1213c2821885SArmin Le Grand else 1214c2821885SArmin Le Grand { 1215c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( nY, 0 ); 1216c2821885SArmin Le Grand } 1217cdf0e10cSrcweir 1218c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1219c2821885SArmin Le Grand { 1220c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1221c2821885SArmin Le Grand } 1222cdf0e10cSrcweir } 1223c2821885SArmin Le Grand else 1224cdf0e10cSrcweir { 1225c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1226cdf0e10cSrcweir { 1227c2821885SArmin Le Grand nTemp = pLutInt[ nX ]; 1228cdf0e10cSrcweir 1229c2821885SArmin Le Grand if( pReadAcc->HasPalette() ) 1230c2821885SArmin Le Grand { 1231c2821885SArmin Le Grand aCol0 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp++ ) ); 1232c2821885SArmin Le Grand aCol1 = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nTemp ) ); 1233c2821885SArmin Le Grand } 1234c2821885SArmin Le Grand else 1235c2821885SArmin Le Grand { 1236cdf0e10cSrcweir aCol0 = pReadAcc->GetPixel( nY, nTemp++ ); 1237cdf0e10cSrcweir aCol1 = pReadAcc->GetPixel( nY, nTemp ); 1238c2821885SArmin Le Grand } 1239cdf0e10cSrcweir 1240c2821885SArmin Le Grand nTemp = pLutFrac[ nX ]; 1241cdf0e10cSrcweir 1242c2821885SArmin Le Grand lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() ); 1243c2821885SArmin Le Grand lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() ); 1244c2821885SArmin Le Grand lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() ); 1245cdf0e10cSrcweir 1246c2821885SArmin Le Grand aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); 1247c2821885SArmin Le Grand aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); 1248c2821885SArmin Le Grand aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) ); 1249cdf0e10cSrcweir 1250c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1251cdf0e10cSrcweir } 1252cdf0e10cSrcweir } 1253cdf0e10cSrcweir } 1254cdf0e10cSrcweir 1255cdf0e10cSrcweir delete[] pLutInt; 1256cdf0e10cSrcweir delete[] pLutFrac; 1257cdf0e10cSrcweir bRet = sal_True; 1258cdf0e10cSrcweir } 1259cdf0e10cSrcweir 1260cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1261cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1262cdf0e10cSrcweir 1263cdf0e10cSrcweir if( bRet ) 1264cdf0e10cSrcweir { 1265cdf0e10cSrcweir bRet = sal_False; 1266*561c4886SArmin Le Grand const Bitmap aOriginal(*this); 1267c2821885SArmin Le Grand *this = aNewBmp; 1268cdf0e10cSrcweir aNewBmp = Bitmap( Size( nNewWidth, nNewHeight ), 24 ); 1269c2821885SArmin Le Grand pReadAcc = AcquireReadAccess(); 1270cdf0e10cSrcweir pWriteAcc = aNewBmp.AcquireWriteAccess(); 1271cdf0e10cSrcweir 1272cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 1273cdf0e10cSrcweir { 1274cdf0e10cSrcweir const long nNewHeight1 = nNewHeight - 1L; 1275cdf0e10cSrcweir const long nHeight1 = pReadAcc->Height() - 1L; 1276cdf0e10cSrcweir const double fRevScaleY = (double) nHeight1 / nNewHeight1; 1277cdf0e10cSrcweir 1278cdf0e10cSrcweir pLutInt = new long[ nNewHeight ]; 1279cdf0e10cSrcweir pLutFrac = new long[ nNewHeight ]; 1280cdf0e10cSrcweir 1281cdf0e10cSrcweir for( nY = 0L, nTemp = nHeight - 2L; nY < nNewHeight; nY++ ) 1282cdf0e10cSrcweir { 1283cdf0e10cSrcweir fTemp = nY * fRevScaleY; 1284cdf0e10cSrcweir pLutInt[ nY ] = MinMax( (long) fTemp, 0, nTemp ); 1285cdf0e10cSrcweir fTemp -= pLutInt[ nY ]; 1286cdf0e10cSrcweir pLutFrac[ nY ] = (long) ( fTemp * 1024. ); 1287cdf0e10cSrcweir } 1288cdf0e10cSrcweir 1289c2821885SArmin Le Grand // after 1st step, bitmap *is* 24bit format (see above) 1290c2821885SArmin Le Grand OSL_ENSURE(!pReadAcc->HasPalette(), "OOps, somehow ImplScaleInterpolate in-between format has palette, should not happen (!)"); 1291c2821885SArmin Le Grand 1292c2821885SArmin Le Grand for( nX = 0L; nX < nNewWidth; nX++ ) 1293cdf0e10cSrcweir { 1294c2821885SArmin Le Grand if( 1 == nHeight ) 1295cdf0e10cSrcweir { 1296c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( 0, nX ); 1297cdf0e10cSrcweir 1298c2821885SArmin Le Grand for( nY = 0L; nY < nNewHeight; nY++ ) 1299c2821885SArmin Le Grand { 1300c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1301c2821885SArmin Le Grand } 1302cdf0e10cSrcweir } 1303c2821885SArmin Le Grand else 1304cdf0e10cSrcweir { 1305c2821885SArmin Le Grand for( nY = 0L; nY < nNewHeight; nY++ ) 1306cdf0e10cSrcweir { 1307c2821885SArmin Le Grand nTemp = pLutInt[ nY ]; 1308cdf0e10cSrcweir 1309c2821885SArmin Le Grand aCol0 = pReadAcc->GetPixel( nTemp++, nX ); 1310c2821885SArmin Le Grand aCol1 = pReadAcc->GetPixel( nTemp, nX ); 1311cdf0e10cSrcweir 1312c2821885SArmin Le Grand nTemp = pLutFrac[ nY ]; 1313cdf0e10cSrcweir 1314c2821885SArmin Le Grand lXR1 = aCol1.GetRed() - ( lXR0 = aCol0.GetRed() ); 1315c2821885SArmin Le Grand lXG1 = aCol1.GetGreen() - ( lXG0 = aCol0.GetGreen() ); 1316c2821885SArmin Le Grand lXB1 = aCol1.GetBlue() - ( lXB0 = aCol0.GetBlue() ); 1317cdf0e10cSrcweir 1318c2821885SArmin Le Grand aCol0.SetRed( (sal_uInt8) ( ( lXR1 * nTemp + ( lXR0 << 10 ) ) >> 10 ) ); 1319c2821885SArmin Le Grand aCol0.SetGreen( (sal_uInt8) ( ( lXG1 * nTemp + ( lXG0 << 10 ) ) >> 10 ) ); 1320c2821885SArmin Le Grand aCol0.SetBlue( (sal_uInt8) ( ( lXB1 * nTemp + ( lXB0 << 10 ) ) >> 10 ) ); 1321cdf0e10cSrcweir 1322c2821885SArmin Le Grand pWriteAcc->SetPixel( nY, nX, aCol0 ); 1323cdf0e10cSrcweir } 1324cdf0e10cSrcweir } 1325cdf0e10cSrcweir } 1326cdf0e10cSrcweir 1327cdf0e10cSrcweir delete[] pLutInt; 1328cdf0e10cSrcweir delete[] pLutFrac; 1329cdf0e10cSrcweir bRet = sal_True; 1330cdf0e10cSrcweir } 1331cdf0e10cSrcweir 1332cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 1333cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 1334cdf0e10cSrcweir 1335cdf0e10cSrcweir if( bRet ) 133637ab0f2dSArmin Le Grand { 1337*561c4886SArmin Le Grand aOriginal.ImplAdaptBitCount(aNewBmp); 1338c2821885SArmin Le Grand *this = aNewBmp; 133937ab0f2dSArmin Le Grand } 1340cdf0e10cSrcweir } 1341cdf0e10cSrcweir } 1342cdf0e10cSrcweir 1343cdf0e10cSrcweir if( !bRet ) 1344c2821885SArmin Le Grand { 1345cdf0e10cSrcweir bRet = ImplScaleFast( rScaleX, rScaleY ); 1346c2821885SArmin Le Grand } 1347cdf0e10cSrcweir 1348cdf0e10cSrcweir return bRet; 1349cdf0e10cSrcweir } 1350cdf0e10cSrcweir 135137ab0f2dSArmin Le Grand // ------------------------------------------------------------------------ 135237ab0f2dSArmin Le Grand // #121233# Added BMP_SCALE_SUPER from symphony code 135337ab0f2dSArmin Le Grand 135437ab0f2dSArmin Le Grand sal_Bool Bitmap::ImplScaleSuper( 135537ab0f2dSArmin Le Grand const double& rScaleX, 135637ab0f2dSArmin Le Grand const double& rScaleY ) 135737ab0f2dSArmin Le Grand { 135837ab0f2dSArmin Le Grand const Size aSizePix( GetSizePixel() ); 135937ab0f2dSArmin Le Grand bool bHMirr = ( rScaleX < 0 ); 136037ab0f2dSArmin Le Grand bool bVMirr = ( rScaleY < 0 ); 136137ab0f2dSArmin Le Grand double scaleX = bHMirr ? -rScaleX : rScaleX; 136237ab0f2dSArmin Le Grand double scaleY = bVMirr ? -rScaleY : rScaleY; 136337ab0f2dSArmin Le Grand const long nDstW = FRound( aSizePix.Width() * scaleX ); 136437ab0f2dSArmin Le Grand const long nDstH = FRound( aSizePix.Height() * scaleY ); 136537ab0f2dSArmin Le Grand const double fScaleThresh = 0.6; 136637ab0f2dSArmin Le Grand bool bRet = false; 136737ab0f2dSArmin Le Grand 136837ab0f2dSArmin Le Grand if( ( nDstW > 1L ) && ( nDstH > 1L ) ) 136937ab0f2dSArmin Le Grand { 137037ab0f2dSArmin Le Grand BitmapColor aCol0, aCol1, aColRes; 137137ab0f2dSArmin Le Grand BitmapReadAccess* pAcc = AcquireReadAccess(); 137237ab0f2dSArmin Le Grand long nW = pAcc->Width() ; 137337ab0f2dSArmin Le Grand long nH = pAcc->Height() ; 137437ab0f2dSArmin Le Grand Bitmap aOutBmp( Size( nDstW, nDstH ), 24 ); 137537ab0f2dSArmin Le Grand BitmapWriteAccess* pWAcc = aOutBmp.AcquireWriteAccess(); 137637ab0f2dSArmin Le Grand long* pMapIX = new long[ nDstW ]; 137737ab0f2dSArmin Le Grand long* pMapIY = new long[ nDstH ]; 137837ab0f2dSArmin Le Grand long* pMapFX = new long[ nDstW ]; 137937ab0f2dSArmin Le Grand long* pMapFY = new long[ nDstH ]; 138037ab0f2dSArmin Le Grand long nX, nY, nXDst, nYDst;; 138137ab0f2dSArmin Le Grand double fTemp; 138237ab0f2dSArmin Le Grand long nTemp , nTempX, nTempY, nTempFX, nTempFY; 138337ab0f2dSArmin Le Grand sal_uInt8 cR0, cG0, cB0, cR1, cG1, cB1; 138437ab0f2dSArmin Le Grand long nStartX = 0 , nStartY = 0; 138537ab0f2dSArmin Le Grand long nEndX = nDstW - 1L; 138637ab0f2dSArmin Le Grand long nEndY = nDstH - 1L; 138737ab0f2dSArmin Le Grand long nMax = 1 << 7L; 138837ab0f2dSArmin Le Grand 138937ab0f2dSArmin Le Grand if( pAcc && pWAcc ) 139037ab0f2dSArmin Le Grand { 139137ab0f2dSArmin Le Grand const double fRevScaleX = ( nDstW > 1L ) ? ( (double) ( nW - 1 ) / ( nDstW - 1 ) ) : 0.0; 139237ab0f2dSArmin Le Grand const double fRevScaleY = ( nDstH > 1L ) ? ( (double) ( nH - 1 ) / ( nDstH - 1 ) ) : 0.0; 139337ab0f2dSArmin Le Grand 139437ab0f2dSArmin Le Grand // create horizontal mapping table 139537ab0f2dSArmin Le Grand for( nX = 0L, nTempX = nW - 1L, nTemp = nW - 2L; nX < nDstW; nX++ ) 139637ab0f2dSArmin Le Grand { 139737ab0f2dSArmin Le Grand fTemp = nX * fRevScaleX; 139837ab0f2dSArmin Le Grand 139937ab0f2dSArmin Le Grand if( bHMirr ) 140037ab0f2dSArmin Le Grand fTemp = nTempX - fTemp; 140137ab0f2dSArmin Le Grand 140237ab0f2dSArmin Le Grand pMapFX[ nX ] = (long) ( ( fTemp - ( pMapIX[ nX ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. ); 140337ab0f2dSArmin Le Grand } 140437ab0f2dSArmin Le Grand 140537ab0f2dSArmin Le Grand // create vertical mapping table 140637ab0f2dSArmin Le Grand for( nY = 0L, nTempY = nH - 1L, nTemp = nH - 2L; nY < nDstH; nY++ ) 140737ab0f2dSArmin Le Grand { 140837ab0f2dSArmin Le Grand fTemp = nY * fRevScaleY; 140937ab0f2dSArmin Le Grand 141037ab0f2dSArmin Le Grand if( bVMirr ) 141137ab0f2dSArmin Le Grand fTemp = nTempY - fTemp; 141237ab0f2dSArmin Le Grand 141337ab0f2dSArmin Le Grand pMapFY[ nY ] = (long) ( ( fTemp - ( pMapIY[ nY ] = MinMax( (long) fTemp, 0, nTemp ) ) ) * 128. ); 141437ab0f2dSArmin Le Grand } 141537ab0f2dSArmin Le Grand 141637ab0f2dSArmin Le Grand if( pAcc->HasPalette() ) 141737ab0f2dSArmin Le Grand { 141837ab0f2dSArmin Le Grand if( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL ) 141937ab0f2dSArmin Le Grand { 142037ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 142137ab0f2dSArmin Le Grand { 142237ab0f2dSArmin Le Grand Scanline pLine0, pLine1; 142337ab0f2dSArmin Le Grand 142437ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 142537ab0f2dSArmin Le Grand { 142637ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 142737ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 142837ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 142937ab0f2dSArmin Le Grand 143037ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 143137ab0f2dSArmin Le Grand { 143237ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 143337ab0f2dSArmin Le Grand 143437ab0f2dSArmin Le Grand const BitmapColor& rCol0 = pAcc->GetPaletteColor( pLine0[ nTempX ] ); 143537ab0f2dSArmin Le Grand const BitmapColor& rCol2 = pAcc->GetPaletteColor( pLine1[ nTempX ] ); 143637ab0f2dSArmin Le Grand const BitmapColor& rCol1 = pAcc->GetPaletteColor( pLine0[ ++nTempX ] ); 143737ab0f2dSArmin Le Grand const BitmapColor& rCol3 = pAcc->GetPaletteColor( pLine1[ nTempX ] ); 143837ab0f2dSArmin Le Grand 143937ab0f2dSArmin Le Grand cR0 = MAP( rCol0.GetRed(), rCol1.GetRed(), nTempFX ); 144037ab0f2dSArmin Le Grand cG0 = MAP( rCol0.GetGreen(), rCol1.GetGreen(), nTempFX ); 144137ab0f2dSArmin Le Grand cB0 = MAP( rCol0.GetBlue(), rCol1.GetBlue(), nTempFX ); 144237ab0f2dSArmin Le Grand 144337ab0f2dSArmin Le Grand cR1 = MAP( rCol2.GetRed(), rCol3.GetRed(), nTempFX ); 144437ab0f2dSArmin Le Grand cG1 = MAP( rCol2.GetGreen(), rCol3.GetGreen(), nTempFX ); 144537ab0f2dSArmin Le Grand cB1 = MAP( rCol2.GetBlue(), rCol3.GetBlue(), nTempFX ); 144637ab0f2dSArmin Le Grand 144737ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 144837ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 144937ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 145037ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 145137ab0f2dSArmin Le Grand } 145237ab0f2dSArmin Le Grand } 145337ab0f2dSArmin Le Grand } 145437ab0f2dSArmin Le Grand else 145537ab0f2dSArmin Le Grand { 145637ab0f2dSArmin Le Grand Scanline pTmpY; 145737ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 145837ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 145937ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 146037ab0f2dSArmin Le Grand 146137ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 146237ab0f2dSArmin Le Grand { 146337ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 146437ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 146537ab0f2dSArmin Le Grand 146637ab0f2dSArmin Le Grand if( nY ==nEndY ) 146737ab0f2dSArmin Le Grand { 146837ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 146937ab0f2dSArmin Le Grand nLineRange = 0; 147037ab0f2dSArmin Le Grand } 147137ab0f2dSArmin Le Grand else 147237ab0f2dSArmin Le Grand { 147337ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 147437ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 147537ab0f2dSArmin Le Grand } 147637ab0f2dSArmin Le Grand 147737ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 147837ab0f2dSArmin Le Grand { 147937ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 148037ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 148137ab0f2dSArmin Le Grand 148237ab0f2dSArmin Le Grand if( nX == nEndX ) 148337ab0f2dSArmin Le Grand { 148437ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 148537ab0f2dSArmin Le Grand nRowRange = 0; 148637ab0f2dSArmin Le Grand } 148737ab0f2dSArmin Le Grand else 148837ab0f2dSArmin Le Grand { 148937ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 149037ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 149137ab0f2dSArmin Le Grand } 149237ab0f2dSArmin Le Grand 149337ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 149437ab0f2dSArmin Le Grand nTotalWeightY = 0; 149537ab0f2dSArmin Le Grand 149637ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 149737ab0f2dSArmin Le Grand { 149837ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 149937ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 150037ab0f2dSArmin Le Grand nTotalWeightX = 0; 150137ab0f2dSArmin Le Grand 150237ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 150337ab0f2dSArmin Le Grand { 150437ab0f2dSArmin Le Grand const BitmapColor& rCol = pAcc->GetPaletteColor( pTmpY[ nRowStart + j ] ); 150537ab0f2dSArmin Le Grand 150637ab0f2dSArmin Le Grand if(nX == nEndX ) 150737ab0f2dSArmin Le Grand { 150837ab0f2dSArmin Le Grand nSumRowB += rCol.GetBlue() << 7L; 150937ab0f2dSArmin Le Grand nSumRowG += rCol.GetGreen() << 7L; 151037ab0f2dSArmin Le Grand nSumRowR += rCol.GetRed() << 7L; 151137ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 151237ab0f2dSArmin Le Grand } 151337ab0f2dSArmin Le Grand else if( j == 0 ) 151437ab0f2dSArmin Le Grand { 151537ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 151637ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *rCol.GetBlue()) ; 151737ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *rCol.GetGreen()) ; 151837ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *rCol.GetRed()) ; 151937ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 152037ab0f2dSArmin Le Grand } 152137ab0f2dSArmin Le Grand else if ( nRowRange == j ) 152237ab0f2dSArmin Le Grand { 152337ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 152437ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *rCol.GetBlue() ); 152537ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *rCol.GetGreen() ); 152637ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *rCol.GetRed() ); 152737ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 152837ab0f2dSArmin Le Grand } 152937ab0f2dSArmin Le Grand else 153037ab0f2dSArmin Le Grand { 153137ab0f2dSArmin Le Grand nSumRowB += rCol.GetBlue() << 7L; 153237ab0f2dSArmin Le Grand nSumRowG += rCol.GetGreen() << 7L; 153337ab0f2dSArmin Le Grand nSumRowR += rCol.GetRed() << 7L; 153437ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 153537ab0f2dSArmin Le Grand } 153637ab0f2dSArmin Le Grand } 153737ab0f2dSArmin Le Grand 153837ab0f2dSArmin Le Grand if( nY == nEndY ) 153937ab0f2dSArmin Le Grand nWeightY = nMax; 154037ab0f2dSArmin Le Grand else if( i == 0 ) 154137ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 154237ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 154337ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 154437ab0f2dSArmin Le Grand else if ( nLineRange == i ) 154537ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 154637ab0f2dSArmin Le Grand else 154737ab0f2dSArmin Le Grand nWeightY = nMax; 154837ab0f2dSArmin Le Grand 154937ab0f2dSArmin Le Grand nWeightY = nWeightY ; 155037ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 155137ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 155237ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 155337ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 155437ab0f2dSArmin Le Grand } 155537ab0f2dSArmin Le Grand 155637ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 155737ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 155837ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 155937ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 156037ab0f2dSArmin Le Grand 156137ab0f2dSArmin Le Grand } 156237ab0f2dSArmin Le Grand } 156337ab0f2dSArmin Le Grand } 156437ab0f2dSArmin Le Grand } 156537ab0f2dSArmin Le Grand else 156637ab0f2dSArmin Le Grand { 156737ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 156837ab0f2dSArmin Le Grand { 156937ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 157037ab0f2dSArmin Le Grand { 157137ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ], nTempFY = pMapFY[ nY ]; 157237ab0f2dSArmin Le Grand 157337ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 157437ab0f2dSArmin Le Grand { 157537ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 157637ab0f2dSArmin Le Grand 157737ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, nTempX ) ); 157837ab0f2dSArmin Le Grand aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY, ++nTempX ) ); 157937ab0f2dSArmin Le Grand cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 158037ab0f2dSArmin Le Grand cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 158137ab0f2dSArmin Le Grand cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 158237ab0f2dSArmin Le Grand 158337ab0f2dSArmin Le Grand aCol1 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( ++nTempY, nTempX ) ); 158437ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor( pAcc->GetPixelIndex( nTempY--, --nTempX ) ); 158537ab0f2dSArmin Le Grand cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 158637ab0f2dSArmin Le Grand cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 158737ab0f2dSArmin Le Grand cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 158837ab0f2dSArmin Le Grand 158937ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 159037ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 159137ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 159237ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 159337ab0f2dSArmin Le Grand } 159437ab0f2dSArmin Le Grand } 159537ab0f2dSArmin Le Grand 159637ab0f2dSArmin Le Grand } 159737ab0f2dSArmin Le Grand else 159837ab0f2dSArmin Le Grand { 159937ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 160037ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 160137ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 160237ab0f2dSArmin Le Grand 160337ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 160437ab0f2dSArmin Le Grand { 160537ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 160637ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 160737ab0f2dSArmin Le Grand 160837ab0f2dSArmin Le Grand if( nY ==nEndY ) 160937ab0f2dSArmin Le Grand { 161037ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 161137ab0f2dSArmin Le Grand nLineRange = 0; 161237ab0f2dSArmin Le Grand } 161337ab0f2dSArmin Le Grand else 161437ab0f2dSArmin Le Grand { 161537ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 161637ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 161737ab0f2dSArmin Le Grand } 161837ab0f2dSArmin Le Grand 161937ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 162037ab0f2dSArmin Le Grand { 162137ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 162237ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 162337ab0f2dSArmin Le Grand 162437ab0f2dSArmin Le Grand if( nX == nEndX ) 162537ab0f2dSArmin Le Grand { 162637ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 162737ab0f2dSArmin Le Grand nRowRange = 0; 162837ab0f2dSArmin Le Grand } 162937ab0f2dSArmin Le Grand else 163037ab0f2dSArmin Le Grand { 163137ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 163237ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 163337ab0f2dSArmin Le Grand } 163437ab0f2dSArmin Le Grand 163537ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 163637ab0f2dSArmin Le Grand nTotalWeightY = 0; 163737ab0f2dSArmin Le Grand 163837ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 163937ab0f2dSArmin Le Grand { 164037ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 164137ab0f2dSArmin Le Grand nTotalWeightX = 0; 164237ab0f2dSArmin Le Grand 164337ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 164437ab0f2dSArmin Le Grand { 164537ab0f2dSArmin Le Grand aCol0 = pAcc->GetPaletteColor ( pAcc->GetPixelIndex( nLineStart + i, nRowStart + j ) ); 164637ab0f2dSArmin Le Grand 164737ab0f2dSArmin Le Grand if(nX == nEndX ) 164837ab0f2dSArmin Le Grand { 164937ab0f2dSArmin Le Grand 165037ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 165137ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 165237ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 165337ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 165437ab0f2dSArmin Le Grand } 165537ab0f2dSArmin Le Grand else if( j == 0 ) 165637ab0f2dSArmin Le Grand { 165737ab0f2dSArmin Le Grand 165837ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 165937ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue()) ; 166037ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen()) ; 166137ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed()) ; 166237ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 166337ab0f2dSArmin Le Grand } 166437ab0f2dSArmin Le Grand else if ( nRowRange == j ) 166537ab0f2dSArmin Le Grand { 166637ab0f2dSArmin Le Grand 166737ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 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 167437ab0f2dSArmin Le Grand { 167537ab0f2dSArmin Le Grand 167637ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 167737ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 167837ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 167937ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 168037ab0f2dSArmin Le Grand } 168137ab0f2dSArmin Le Grand } 168237ab0f2dSArmin Le Grand 168337ab0f2dSArmin Le Grand if( nY == nEndY ) 168437ab0f2dSArmin Le Grand nWeightY = nMax; 168537ab0f2dSArmin Le Grand else if( i == 0 ) 168637ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 168737ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 168837ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 168937ab0f2dSArmin Le Grand else if ( nLineRange == i ) 169037ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 169137ab0f2dSArmin Le Grand else 169237ab0f2dSArmin Le Grand nWeightY = nMax; 169337ab0f2dSArmin Le Grand 169437ab0f2dSArmin Le Grand nWeightY = nWeightY ; 169537ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 169637ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 169737ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 169837ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 169937ab0f2dSArmin Le Grand } 170037ab0f2dSArmin Le Grand 170137ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 170237ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 170337ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 170437ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 170537ab0f2dSArmin Le Grand } 170637ab0f2dSArmin Le Grand } 170737ab0f2dSArmin Le Grand } 170837ab0f2dSArmin Le Grand } 170937ab0f2dSArmin Le Grand } 171037ab0f2dSArmin Le Grand else 171137ab0f2dSArmin Le Grand { 171237ab0f2dSArmin Le Grand if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ) 171337ab0f2dSArmin Le Grand { 171437ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 171537ab0f2dSArmin Le Grand { 171637ab0f2dSArmin Le Grand Scanline pLine0, pLine1, pTmp0, pTmp1; 171737ab0f2dSArmin Le Grand long nOff; 171837ab0f2dSArmin Le Grand 171937ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 172037ab0f2dSArmin Le Grand { 172137ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 172237ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 172337ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 172437ab0f2dSArmin Le Grand 172537ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 172637ab0f2dSArmin Le Grand { 172737ab0f2dSArmin Le Grand nOff = 3L * ( nTempX = pMapIX[ nX ] ); 172837ab0f2dSArmin Le Grand nTempFX = pMapFX[ nX ]; 172937ab0f2dSArmin Le Grand 173037ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L; 173137ab0f2dSArmin Le Grand cB0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 173237ab0f2dSArmin Le Grand cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 173337ab0f2dSArmin Le Grand cR0 = MAP( *pTmp0, *pTmp1, nTempFX ); 173437ab0f2dSArmin Le Grand 173537ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L; 173637ab0f2dSArmin Le Grand cB1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 173737ab0f2dSArmin Le Grand cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 173837ab0f2dSArmin Le Grand cR1 = MAP( *pTmp0, *pTmp1, nTempFX ); 173937ab0f2dSArmin Le Grand 174037ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 174137ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 174237ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 174337ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 174437ab0f2dSArmin Le Grand } 174537ab0f2dSArmin Le Grand } 174637ab0f2dSArmin Le Grand } 174737ab0f2dSArmin Le Grand else 174837ab0f2dSArmin Le Grand { 174937ab0f2dSArmin Le Grand Scanline pTmpY, pTmpX; 175037ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 175137ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 175237ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 175337ab0f2dSArmin Le Grand 175437ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 175537ab0f2dSArmin Le Grand { 175637ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 175737ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 175837ab0f2dSArmin Le Grand 175937ab0f2dSArmin Le Grand if( nY ==nEndY ) 176037ab0f2dSArmin Le Grand { 176137ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 176237ab0f2dSArmin Le Grand nLineRange = 0; 176337ab0f2dSArmin Le Grand } 176437ab0f2dSArmin Le Grand else 176537ab0f2dSArmin Le Grand { 176637ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 176737ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 176837ab0f2dSArmin Le Grand } 176937ab0f2dSArmin Le Grand 177037ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 177137ab0f2dSArmin Le Grand { 177237ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 177337ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 177437ab0f2dSArmin Le Grand 177537ab0f2dSArmin Le Grand if( nX == nEndX ) 177637ab0f2dSArmin Le Grand { 177737ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 177837ab0f2dSArmin Le Grand nRowRange = 0; 177937ab0f2dSArmin Le Grand } 178037ab0f2dSArmin Le Grand else 178137ab0f2dSArmin Le Grand { 178237ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 178337ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 178437ab0f2dSArmin Le Grand } 178537ab0f2dSArmin Le Grand 178637ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 178737ab0f2dSArmin Le Grand nTotalWeightY = 0; 178837ab0f2dSArmin Le Grand 178937ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 179037ab0f2dSArmin Le Grand { 179137ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 179237ab0f2dSArmin Le Grand pTmpX = pTmpY + 3L * nRowStart; 179337ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 179437ab0f2dSArmin Le Grand nTotalWeightX = 0; 179537ab0f2dSArmin Le Grand 179637ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 179737ab0f2dSArmin Le Grand { 179837ab0f2dSArmin Le Grand if(nX == nEndX ) 179937ab0f2dSArmin Le Grand { 180037ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 180137ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 180237ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 180337ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 180437ab0f2dSArmin Le Grand } 180537ab0f2dSArmin Le Grand else if( j == 0 ) 180637ab0f2dSArmin Le Grand { 180737ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 180837ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++; 180937ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++; 181037ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++; 181137ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 181237ab0f2dSArmin Le Grand } 181337ab0f2dSArmin Le Grand else if ( nRowRange == j ) 181437ab0f2dSArmin Le Grand { 181537ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 181637ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++; 181737ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++; 181837ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++; 181937ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 182037ab0f2dSArmin Le Grand } 182137ab0f2dSArmin Le Grand else 182237ab0f2dSArmin Le Grand { 182337ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 182437ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 182537ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 182637ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 182737ab0f2dSArmin Le Grand } 182837ab0f2dSArmin Le Grand } 182937ab0f2dSArmin Le Grand 183037ab0f2dSArmin Le Grand if( nY == nEndY ) 183137ab0f2dSArmin Le Grand nWeightY = nMax; 183237ab0f2dSArmin Le Grand else if( i == 0 ) 183337ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 183437ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 183537ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 183637ab0f2dSArmin Le Grand else if ( nLineRange == i ) 183737ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 183837ab0f2dSArmin Le Grand else 183937ab0f2dSArmin Le Grand nWeightY = nMax; 184037ab0f2dSArmin Le Grand 184137ab0f2dSArmin Le Grand nWeightY = nWeightY ; 184237ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 184337ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 184437ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 184537ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 184637ab0f2dSArmin Le Grand } 184737ab0f2dSArmin Le Grand 184837ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 184937ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 185037ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 185137ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 185237ab0f2dSArmin Le Grand 185337ab0f2dSArmin Le Grand } 185437ab0f2dSArmin Le Grand } 185537ab0f2dSArmin Le Grand } 185637ab0f2dSArmin Le Grand } 185737ab0f2dSArmin Le Grand else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ) 185837ab0f2dSArmin Le Grand { 185937ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 186037ab0f2dSArmin Le Grand { 186137ab0f2dSArmin Le Grand Scanline pLine0, pLine1, pTmp0, pTmp1; 186237ab0f2dSArmin Le Grand long nOff; 186337ab0f2dSArmin Le Grand 186437ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 186537ab0f2dSArmin Le Grand { 186637ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 186737ab0f2dSArmin Le Grand pLine0 = pAcc->GetScanline( nTempY ); 186837ab0f2dSArmin Le Grand pLine1 = pAcc->GetScanline( ++nTempY ); 186937ab0f2dSArmin Le Grand 187037ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 187137ab0f2dSArmin Le Grand { 187237ab0f2dSArmin Le Grand nOff = 3L * ( nTempX = pMapIX[ nX ] ); 187337ab0f2dSArmin Le Grand nTempFX = pMapFX[ nX ]; 187437ab0f2dSArmin Le Grand 187537ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine0 + nOff ) + 3L; 187637ab0f2dSArmin Le Grand cR0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 187737ab0f2dSArmin Le Grand cG0 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 187837ab0f2dSArmin Le Grand cB0 = MAP( *pTmp0, *pTmp1, nTempFX ); 187937ab0f2dSArmin Le Grand 188037ab0f2dSArmin Le Grand pTmp1 = ( pTmp0 = pLine1 + nOff ) + 3L; 188137ab0f2dSArmin Le Grand cR1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 188237ab0f2dSArmin Le Grand cG1 = MAP( *pTmp0, *pTmp1, nTempFX ); pTmp0++; pTmp1++; 188337ab0f2dSArmin Le Grand cB1 = MAP( *pTmp0, *pTmp1, nTempFX ); 188437ab0f2dSArmin Le Grand 188537ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 188637ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 188737ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 188837ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 188937ab0f2dSArmin Le Grand } 189037ab0f2dSArmin Le Grand } 189137ab0f2dSArmin Le Grand } 189237ab0f2dSArmin Le Grand else 189337ab0f2dSArmin Le Grand { 189437ab0f2dSArmin Le Grand Scanline pTmpY, pTmpX; 189537ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 189637ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 189737ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 189837ab0f2dSArmin Le Grand 189937ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 190037ab0f2dSArmin Le Grand { 190137ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 190237ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 190337ab0f2dSArmin Le Grand 190437ab0f2dSArmin Le Grand if( nY ==nEndY ) 190537ab0f2dSArmin Le Grand { 190637ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 190737ab0f2dSArmin Le Grand nLineRange = 0; 190837ab0f2dSArmin Le Grand } 190937ab0f2dSArmin Le Grand else 191037ab0f2dSArmin Le Grand { 191137ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 191237ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 191337ab0f2dSArmin Le Grand } 191437ab0f2dSArmin Le Grand 191537ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 191637ab0f2dSArmin Le Grand { 191737ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 191837ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 191937ab0f2dSArmin Le Grand 192037ab0f2dSArmin Le Grand if( nX == nEndX ) 192137ab0f2dSArmin Le Grand { 192237ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 192337ab0f2dSArmin Le Grand nRowRange = 0; 192437ab0f2dSArmin Le Grand } 192537ab0f2dSArmin Le Grand else 192637ab0f2dSArmin Le Grand { 192737ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 192837ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 192937ab0f2dSArmin Le Grand } 193037ab0f2dSArmin Le Grand 193137ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 193237ab0f2dSArmin Le Grand nTotalWeightY = 0; 193337ab0f2dSArmin Le Grand 193437ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 193537ab0f2dSArmin Le Grand { 193637ab0f2dSArmin Le Grand pTmpY = pAcc->GetScanline( nLineStart + i ); 193737ab0f2dSArmin Le Grand pTmpX = pTmpY + 3L * nRowStart; 193837ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 193937ab0f2dSArmin Le Grand nTotalWeightX = 0; 194037ab0f2dSArmin Le Grand 194137ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 194237ab0f2dSArmin Le Grand { 194337ab0f2dSArmin Le Grand if(nX == nEndX ) 194437ab0f2dSArmin Le Grand { 194537ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 194637ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 194737ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 194837ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 194937ab0f2dSArmin Le Grand } 195037ab0f2dSArmin Le Grand else if( j == 0 ) 195137ab0f2dSArmin Le Grand { 195237ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 195337ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX )) ;pTmpX++; 195437ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX )) ;pTmpX++; 195537ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX )) ;pTmpX++; 195637ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 195737ab0f2dSArmin Le Grand } 195837ab0f2dSArmin Le Grand else if ( nRowRange == j ) 195937ab0f2dSArmin Le Grand { 196037ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 196137ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *( *pTmpX ) );pTmpX++; 196237ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *( *pTmpX ) );pTmpX++; 196337ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *( *pTmpX ) );pTmpX++; 196437ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 196537ab0f2dSArmin Le Grand } 196637ab0f2dSArmin Le Grand else 196737ab0f2dSArmin Le Grand { 196837ab0f2dSArmin Le Grand nSumRowR += ( *pTmpX ) << 7L;pTmpX++; 196937ab0f2dSArmin Le Grand nSumRowG += ( *pTmpX ) << 7L;pTmpX++; 197037ab0f2dSArmin Le Grand nSumRowB += ( *pTmpX ) << 7L;pTmpX++; 197137ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 197237ab0f2dSArmin Le Grand } 197337ab0f2dSArmin Le Grand } 197437ab0f2dSArmin Le Grand 197537ab0f2dSArmin Le Grand if( nY == nEndY ) 197637ab0f2dSArmin Le Grand nWeightY = nMax; 197737ab0f2dSArmin Le Grand else if( i == 0 ) 197837ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 197937ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 198037ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 198137ab0f2dSArmin Le Grand else if ( nLineRange == i ) 198237ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 198337ab0f2dSArmin Le Grand else 198437ab0f2dSArmin Le Grand nWeightY = nMax; 198537ab0f2dSArmin Le Grand 198637ab0f2dSArmin Le Grand nWeightY = nWeightY ; 198737ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 198837ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 198937ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 199037ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 199137ab0f2dSArmin Le Grand } 199237ab0f2dSArmin Le Grand 199337ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 199437ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 199537ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 199637ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 199737ab0f2dSArmin Le Grand 199837ab0f2dSArmin Le Grand } 199937ab0f2dSArmin Le Grand } 200037ab0f2dSArmin Le Grand } 200137ab0f2dSArmin Le Grand } 200237ab0f2dSArmin Le Grand else 200337ab0f2dSArmin Le Grand { 200437ab0f2dSArmin Le Grand if( scaleX >= fScaleThresh && scaleY >= fScaleThresh ) 200537ab0f2dSArmin Le Grand { 200637ab0f2dSArmin Le Grand for( nY = nStartY, nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 200737ab0f2dSArmin Le Grand { 200837ab0f2dSArmin Le Grand nTempY = pMapIY[ nY ]; nTempFY = pMapFY[ nY ]; 200937ab0f2dSArmin Le Grand 201037ab0f2dSArmin Le Grand for( nX = nStartX, nXDst = 0L; nX <= nEndX; nX++ ) 201137ab0f2dSArmin Le Grand { 201237ab0f2dSArmin Le Grand nTempX = pMapIX[ nX ]; nTempFX = pMapFX[ nX ]; 201337ab0f2dSArmin Le Grand 201437ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nTempY, nTempX ); 201537ab0f2dSArmin Le Grand aCol1 = pAcc->GetPixel( nTempY, ++nTempX ); 201637ab0f2dSArmin Le Grand cR0 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 201737ab0f2dSArmin Le Grand cG0 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 201837ab0f2dSArmin Le Grand cB0 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 201937ab0f2dSArmin Le Grand 202037ab0f2dSArmin Le Grand aCol1 = pAcc->GetPixel( ++nTempY, nTempX ); 202137ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nTempY--, --nTempX ); 202237ab0f2dSArmin Le Grand cR1 = MAP( aCol0.GetRed(), aCol1.GetRed(), nTempFX ); 202337ab0f2dSArmin Le Grand cG1 = MAP( aCol0.GetGreen(), aCol1.GetGreen(), nTempFX ); 202437ab0f2dSArmin Le Grand cB1 = MAP( aCol0.GetBlue(), aCol1.GetBlue(), nTempFX ); 202537ab0f2dSArmin Le Grand 202637ab0f2dSArmin Le Grand aColRes.SetRed( MAP( cR0, cR1, nTempFY ) ); 202737ab0f2dSArmin Le Grand aColRes.SetGreen( MAP( cG0, cG1, nTempFY ) ); 202837ab0f2dSArmin Le Grand aColRes.SetBlue( MAP( cB0, cB1, nTempFY ) ); 202937ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 203037ab0f2dSArmin Le Grand } 203137ab0f2dSArmin Le Grand } 203237ab0f2dSArmin Le Grand } 203337ab0f2dSArmin Le Grand else 203437ab0f2dSArmin Le Grand { 203537ab0f2dSArmin Le Grand long nSumR, nSumG, nSumB,nLineStart , nLineRange, nRowStart , nRowRange ; 203637ab0f2dSArmin Le Grand long nLeft, nRight, nTop, nBottom, nWeightX, nWeightY ; 203737ab0f2dSArmin Le Grand long nSumRowR ,nSumRowG,nSumRowB, nTotalWeightX, nTotalWeightY; 203837ab0f2dSArmin Le Grand 203937ab0f2dSArmin Le Grand for( nY = nStartY , nYDst = 0L; nY <= nEndY; nY++, nYDst++ ) 204037ab0f2dSArmin Le Grand { 204137ab0f2dSArmin Le Grand nTop = bVMirr ? ( nY + 1 ) : nY; 204237ab0f2dSArmin Le Grand nBottom = bVMirr ? nY : ( nY + 1 ) ; 204337ab0f2dSArmin Le Grand 204437ab0f2dSArmin Le Grand if( nY ==nEndY ) 204537ab0f2dSArmin Le Grand { 204637ab0f2dSArmin Le Grand nLineStart = pMapIY[ nY ]; 204737ab0f2dSArmin Le Grand nLineRange = 0; 204837ab0f2dSArmin Le Grand } 204937ab0f2dSArmin Le Grand else 205037ab0f2dSArmin Le Grand { 205137ab0f2dSArmin Le Grand nLineStart = pMapIY[ nTop ] ; 205237ab0f2dSArmin Le Grand nLineRange = ( pMapIY[ nBottom ] == pMapIY[ nTop ] ) ? 1 :( pMapIY[ nBottom ] - pMapIY[ nTop ] ); 205337ab0f2dSArmin Le Grand } 205437ab0f2dSArmin Le Grand 205537ab0f2dSArmin Le Grand for( nX = nStartX , nXDst = 0L; nX <= nEndX; nX++ ) 205637ab0f2dSArmin Le Grand { 205737ab0f2dSArmin Le Grand nLeft = bHMirr ? ( nX + 1 ) : nX; 205837ab0f2dSArmin Le Grand nRight = bHMirr ? nX : ( nX + 1 ) ; 205937ab0f2dSArmin Le Grand 206037ab0f2dSArmin Le Grand if( nX == nEndX ) 206137ab0f2dSArmin Le Grand { 206237ab0f2dSArmin Le Grand nRowStart = pMapIX[ nX ]; 206337ab0f2dSArmin Le Grand nRowRange = 0; 206437ab0f2dSArmin Le Grand } 206537ab0f2dSArmin Le Grand else 206637ab0f2dSArmin Le Grand { 206737ab0f2dSArmin Le Grand nRowStart = pMapIX[ nLeft ]; 206837ab0f2dSArmin Le Grand nRowRange = ( pMapIX[ nRight ] == pMapIX[ nLeft ] )? 1 : ( pMapIX[ nRight ] - pMapIX[ nLeft ] ); 206937ab0f2dSArmin Le Grand } 207037ab0f2dSArmin Le Grand 207137ab0f2dSArmin Le Grand nSumR = nSumG = nSumB = 0; 207237ab0f2dSArmin Le Grand nTotalWeightY = 0; 207337ab0f2dSArmin Le Grand 207437ab0f2dSArmin Le Grand for(int i = 0; i<= nLineRange; i++) 207537ab0f2dSArmin Le Grand { 207637ab0f2dSArmin Le Grand nSumRowR = nSumRowG = nSumRowB = 0; 207737ab0f2dSArmin Le Grand nTotalWeightX = 0; 207837ab0f2dSArmin Le Grand 207937ab0f2dSArmin Le Grand for(int j = 0; j <= nRowRange; j++) 208037ab0f2dSArmin Le Grand { 208137ab0f2dSArmin Le Grand aCol0 = pAcc->GetPixel( nLineStart + i, nRowStart + j ); 208237ab0f2dSArmin Le Grand 208337ab0f2dSArmin Le Grand if(nX == nEndX ) 208437ab0f2dSArmin Le Grand { 208537ab0f2dSArmin Le Grand 208637ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 208737ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 208837ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 208937ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 209037ab0f2dSArmin Le Grand } 209137ab0f2dSArmin Le Grand else if( j == 0 ) 209237ab0f2dSArmin Le Grand { 209337ab0f2dSArmin Le Grand 209437ab0f2dSArmin Le Grand nWeightX = (nMax- pMapFX[ nLeft ]) ; 209537ab0f2dSArmin Le Grand nSumRowB += ( nWeightX *aCol0.GetBlue()) ; 209637ab0f2dSArmin Le Grand nSumRowG += ( nWeightX *aCol0.GetGreen()) ; 209737ab0f2dSArmin Le Grand nSumRowR += ( nWeightX *aCol0.GetRed()) ; 209837ab0f2dSArmin Le Grand nTotalWeightX += nWeightX; 209937ab0f2dSArmin Le Grand } 210037ab0f2dSArmin Le Grand else if ( nRowRange == j ) 210137ab0f2dSArmin Le Grand { 210237ab0f2dSArmin Le Grand 210337ab0f2dSArmin Le Grand nWeightX = pMapFX[ nRight ] ; 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 211037ab0f2dSArmin Le Grand { 211137ab0f2dSArmin Le Grand nSumRowB += aCol0.GetBlue() << 7L; 211237ab0f2dSArmin Le Grand nSumRowG += aCol0.GetGreen() << 7L; 211337ab0f2dSArmin Le Grand nSumRowR += aCol0.GetRed() << 7L; 211437ab0f2dSArmin Le Grand nTotalWeightX += 1 << 7L; 211537ab0f2dSArmin Le Grand } 211637ab0f2dSArmin Le Grand } 211737ab0f2dSArmin Le Grand 211837ab0f2dSArmin Le Grand if( nY == nEndY ) 211937ab0f2dSArmin Le Grand nWeightY = nMax; 212037ab0f2dSArmin Le Grand else if( i == 0 ) 212137ab0f2dSArmin Le Grand nWeightY = nMax - pMapFY[ nTop ]; 212237ab0f2dSArmin Le Grand else if( nLineRange == 1 ) 212337ab0f2dSArmin Le Grand nWeightY = pMapFY[ nTop ]; 212437ab0f2dSArmin Le Grand else if ( nLineRange == i ) 212537ab0f2dSArmin Le Grand nWeightY = pMapFY[ nBottom ]; 212637ab0f2dSArmin Le Grand else 212737ab0f2dSArmin Le Grand nWeightY = nMax; 212837ab0f2dSArmin Le Grand 212937ab0f2dSArmin Le Grand nWeightY = nWeightY ; 213037ab0f2dSArmin Le Grand nSumB += nWeightY * ( nSumRowB / nTotalWeightX ); 213137ab0f2dSArmin Le Grand nSumG += nWeightY * ( nSumRowG / nTotalWeightX ); 213237ab0f2dSArmin Le Grand nSumR += nWeightY * ( nSumRowR / nTotalWeightX ); 213337ab0f2dSArmin Le Grand nTotalWeightY += nWeightY; 213437ab0f2dSArmin Le Grand } 213537ab0f2dSArmin Le Grand 213637ab0f2dSArmin Le Grand aColRes.SetRed( ( sal_uInt8 ) (( nSumR / nTotalWeightY ) )); 213737ab0f2dSArmin Le Grand aColRes.SetGreen( ( sal_uInt8 ) (( nSumG / nTotalWeightY) )); 213837ab0f2dSArmin Le Grand aColRes.SetBlue( ( sal_uInt8 ) (( nSumB / nTotalWeightY ) )); 213937ab0f2dSArmin Le Grand pWAcc->SetPixel( nYDst, nXDst++, aColRes ); 214037ab0f2dSArmin Le Grand 214137ab0f2dSArmin Le Grand } 214237ab0f2dSArmin Le Grand } 214337ab0f2dSArmin Le Grand } 214437ab0f2dSArmin Le Grand } 214537ab0f2dSArmin Le Grand } 214637ab0f2dSArmin Le Grand 214737ab0f2dSArmin Le Grand bRet = true; 214837ab0f2dSArmin Le Grand } 214937ab0f2dSArmin Le Grand 215037ab0f2dSArmin Le Grand delete[] pMapIX; 215137ab0f2dSArmin Le Grand delete[] pMapIY; 215237ab0f2dSArmin Le Grand delete[] pMapFX; 215337ab0f2dSArmin Le Grand delete[] pMapFY; 215437ab0f2dSArmin Le Grand 215537ab0f2dSArmin Le Grand ReleaseAccess( pAcc ); 215637ab0f2dSArmin Le Grand aOutBmp.ReleaseAccess( pWAcc ); 215737ab0f2dSArmin Le Grand 215837ab0f2dSArmin Le Grand if( bRet ) 215937ab0f2dSArmin Le Grand { 216037ab0f2dSArmin Le Grand ImplAdaptBitCount(aOutBmp); 216137ab0f2dSArmin Le Grand ImplAssignWithSize(aOutBmp); 216237ab0f2dSArmin Le Grand } 216337ab0f2dSArmin Le Grand 216437ab0f2dSArmin Le Grand if( !bRet ) 216537ab0f2dSArmin Le Grand bRet = ImplScaleFast( scaleX, scaleY ); 216637ab0f2dSArmin Le Grand } 216737ab0f2dSArmin Le Grand 216837ab0f2dSArmin Le Grand return bRet; 216937ab0f2dSArmin Le Grand } 217037ab0f2dSArmin Le Grand 217137ab0f2dSArmin Le Grand //----------------------------------------------------------------------------------- 217237ab0f2dSArmin Le Grand 217337ab0f2dSArmin Le Grand namespace 217437ab0f2dSArmin Le Grand { 217537ab0f2dSArmin Le Grand void ImplCalculateContributions( 217637ab0f2dSArmin Le Grand const sal_uInt32 aSourceSize, 217737ab0f2dSArmin Le Grand const sal_uInt32 aDestinationSize, 217837ab0f2dSArmin Le Grand sal_uInt32& aNumberOfContributions, 217937ab0f2dSArmin Le Grand double*& pWeights, 218037ab0f2dSArmin Le Grand sal_uInt32*& pPixels, 218137ab0f2dSArmin Le Grand sal_uInt32*& pCount, 218237ab0f2dSArmin Le Grand const Kernel& aKernel) 218337ab0f2dSArmin Le Grand { 218437ab0f2dSArmin Le Grand const double fSamplingRadius(aKernel.GetWidth()); 218537ab0f2dSArmin Le Grand const double fScale(aDestinationSize / static_cast< double >(aSourceSize)); 218637ab0f2dSArmin Le Grand const double fScaledRadius((fScale < 1.0) ? fSamplingRadius / fScale : fSamplingRadius); 218737ab0f2dSArmin Le Grand const double fFilterFactor((fScale < 1.0) ? fScale : 1.0); 218837ab0f2dSArmin Le Grand 218937ab0f2dSArmin Le Grand aNumberOfContributions = (static_cast< sal_uInt32 >(fabs(ceil(fScaledRadius))) * 2) + 1; 219037ab0f2dSArmin Le Grand const sal_uInt32 nAllocSize(aDestinationSize * aNumberOfContributions); 219137ab0f2dSArmin Le Grand pWeights = new double[nAllocSize]; 219237ab0f2dSArmin Le Grand pPixels = new sal_uInt32[nAllocSize]; 219337ab0f2dSArmin Le Grand pCount = new sal_uInt32[aDestinationSize]; 219437ab0f2dSArmin Le Grand 219537ab0f2dSArmin Le Grand for(sal_uInt32 i(0); i < aDestinationSize; i++) 219637ab0f2dSArmin Le Grand { 219737ab0f2dSArmin Le Grand const sal_uInt32 aIndex(i * aNumberOfContributions); 219837ab0f2dSArmin Le Grand const double aCenter(i / fScale); 219937ab0f2dSArmin Le Grand const sal_Int32 aLeft(static_cast< sal_Int32 >(floor(aCenter - fScaledRadius))); 220037ab0f2dSArmin Le Grand const sal_Int32 aRight(static_cast< sal_Int32 >(ceil(aCenter + fScaledRadius))); 220137ab0f2dSArmin Le Grand sal_uInt32 aCurrentCount(0); 220237ab0f2dSArmin Le Grand 220337ab0f2dSArmin Le Grand for(sal_Int32 j(aLeft); j <= aRight; j++) 220437ab0f2dSArmin Le Grand { 220537ab0f2dSArmin Le Grand const double aWeight(aKernel.Calculate(fFilterFactor * (aCenter - static_cast< double>(j)))); 220637ab0f2dSArmin Le Grand 220737ab0f2dSArmin Le Grand // Reduce calculations with ignoring weights of 0.0 220837ab0f2dSArmin Le Grand if(fabs(aWeight) < 0.0001) 220937ab0f2dSArmin Le Grand { 221037ab0f2dSArmin Le Grand continue; 221137ab0f2dSArmin Le Grand } 221237ab0f2dSArmin Le Grand 221337ab0f2dSArmin Le Grand // Handling on edges 221437ab0f2dSArmin Le Grand const sal_uInt32 aPixelIndex(MinMax(j, 0, aSourceSize - 1)); 221537ab0f2dSArmin Le Grand const sal_uInt32 nIndex(aIndex + aCurrentCount); 221637ab0f2dSArmin Le Grand 221737ab0f2dSArmin Le Grand pWeights[nIndex] = aWeight; 221837ab0f2dSArmin Le Grand pPixels[nIndex] = aPixelIndex; 221937ab0f2dSArmin Le Grand 222037ab0f2dSArmin Le Grand aCurrentCount++; 222137ab0f2dSArmin Le Grand } 222237ab0f2dSArmin Le Grand 222337ab0f2dSArmin Le Grand pCount[i] = aCurrentCount; 222437ab0f2dSArmin Le Grand } 222537ab0f2dSArmin Le Grand } 222637ab0f2dSArmin Le Grand 222737ab0f2dSArmin Le Grand sal_Bool ImplScaleConvolutionHor( 222837ab0f2dSArmin Le Grand Bitmap& rSource, 222937ab0f2dSArmin Le Grand Bitmap& rTarget, 223037ab0f2dSArmin Le Grand const double& rScaleX, 223137ab0f2dSArmin Le Grand const Kernel& aKernel) 223237ab0f2dSArmin Le Grand { 223337ab0f2dSArmin Le Grand // Do horizontal filtering 223437ab0f2dSArmin Le Grand OSL_ENSURE(rScaleX > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); 223537ab0f2dSArmin Le Grand const sal_uInt32 nWidth(rSource.GetSizePixel().Width()); 223637ab0f2dSArmin Le Grand const sal_uInt32 nNewWidth(FRound(nWidth * rScaleX)); 223737ab0f2dSArmin Le Grand 223837ab0f2dSArmin Le Grand if(nWidth == nNewWidth) 223937ab0f2dSArmin Le Grand { 224037ab0f2dSArmin Le Grand return true; 224137ab0f2dSArmin Le Grand } 224237ab0f2dSArmin Le Grand 224337ab0f2dSArmin Le Grand BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess(); 224437ab0f2dSArmin Le Grand 224537ab0f2dSArmin Le Grand if(pReadAcc) 224637ab0f2dSArmin Le Grand { 224737ab0f2dSArmin Le Grand double* pWeights = 0; 224837ab0f2dSArmin Le Grand sal_uInt32* pPixels = 0; 224937ab0f2dSArmin Le Grand sal_uInt32* pCount = 0; 225037ab0f2dSArmin Le Grand sal_uInt32 aNumberOfContributions(0); 225137ab0f2dSArmin Le Grand 225237ab0f2dSArmin Le Grand const sal_uInt32 nHeight(rSource.GetSizePixel().Height()); 225337ab0f2dSArmin Le Grand ImplCalculateContributions(nWidth, nNewWidth, aNumberOfContributions, pWeights, pPixels, pCount, aKernel); 225437ab0f2dSArmin Le Grand rTarget = Bitmap(Size(nNewWidth, nHeight), 24); 225537ab0f2dSArmin Le Grand BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess(); 225637ab0f2dSArmin Le Grand bool bResult(0 != pWriteAcc); 225737ab0f2dSArmin Le Grand 225837ab0f2dSArmin Le Grand if(bResult) 225937ab0f2dSArmin Le Grand { 226037ab0f2dSArmin Le Grand for(sal_uInt32 y(0); y < nHeight; y++) 226137ab0f2dSArmin Le Grand { 226237ab0f2dSArmin Le Grand for(sal_uInt32 x(0); x < nNewWidth; x++) 226337ab0f2dSArmin Le Grand { 226437ab0f2dSArmin Le Grand const sal_uInt32 aBaseIndex(x * aNumberOfContributions); 226537ab0f2dSArmin Le Grand double aSum(0.0); 226637ab0f2dSArmin Le Grand double aValueRed(0.0); 226737ab0f2dSArmin Le Grand double aValueGreen(0.0); 226837ab0f2dSArmin Le Grand double aValueBlue(0.0); 226937ab0f2dSArmin Le Grand 227037ab0f2dSArmin Le Grand for(sal_uInt32 j(0); j < pCount[x]; j++) 227137ab0f2dSArmin Le Grand { 227237ab0f2dSArmin Le Grand const sal_uInt32 aIndex(aBaseIndex + j); 227337ab0f2dSArmin Le Grand const double aWeight(pWeights[aIndex]); 227437ab0f2dSArmin Le Grand BitmapColor aColor; 227537ab0f2dSArmin Le Grand 227637ab0f2dSArmin Le Grand aSum += aWeight; 227737ab0f2dSArmin Le Grand 227837ab0f2dSArmin Le Grand if(pReadAcc->HasPalette()) 227937ab0f2dSArmin Le Grand { 228037ab0f2dSArmin Le Grand aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(y, pPixels[aIndex])); 228137ab0f2dSArmin Le Grand } 228237ab0f2dSArmin Le Grand else 228337ab0f2dSArmin Le Grand { 228437ab0f2dSArmin Le Grand aColor = pReadAcc->GetPixel(y, pPixels[aIndex]); 228537ab0f2dSArmin Le Grand } 228637ab0f2dSArmin Le Grand 228737ab0f2dSArmin Le Grand aValueRed += aWeight * aColor.GetRed(); 228837ab0f2dSArmin Le Grand aValueGreen += aWeight * aColor.GetGreen(); 228937ab0f2dSArmin Le Grand aValueBlue += aWeight * aColor.GetBlue(); 229037ab0f2dSArmin Le Grand } 229137ab0f2dSArmin Le Grand 229237ab0f2dSArmin Le Grand const BitmapColor aResultColor( 229337ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)), 229437ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)), 229537ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255))); 229637ab0f2dSArmin Le Grand 229737ab0f2dSArmin Le Grand pWriteAcc->SetPixel(y, x, aResultColor); 229837ab0f2dSArmin Le Grand } 229937ab0f2dSArmin Le Grand } 230037ab0f2dSArmin Le Grand 230137ab0f2dSArmin Le Grand rTarget.ReleaseAccess(pWriteAcc); 230237ab0f2dSArmin Le Grand } 230337ab0f2dSArmin Le Grand 230437ab0f2dSArmin Le Grand rSource.ReleaseAccess(pReadAcc); 230537ab0f2dSArmin Le Grand delete[] pWeights; 230637ab0f2dSArmin Le Grand delete[] pCount; 230737ab0f2dSArmin Le Grand delete[] pPixels; 230837ab0f2dSArmin Le Grand 230937ab0f2dSArmin Le Grand if(bResult) 231037ab0f2dSArmin Le Grand { 231137ab0f2dSArmin Le Grand return true; 231237ab0f2dSArmin Le Grand } 231337ab0f2dSArmin Le Grand } 231437ab0f2dSArmin Le Grand 231537ab0f2dSArmin Le Grand return false; 231637ab0f2dSArmin Le Grand } 231737ab0f2dSArmin Le Grand 231837ab0f2dSArmin Le Grand bool ImplScaleConvolutionVer( 231937ab0f2dSArmin Le Grand Bitmap& rSource, 232037ab0f2dSArmin Le Grand Bitmap& rTarget, 232137ab0f2dSArmin Le Grand const double& rScaleY, 232237ab0f2dSArmin Le Grand const Kernel& aKernel) 232337ab0f2dSArmin Le Grand { 232437ab0f2dSArmin Le Grand // Do vertical filtering 232537ab0f2dSArmin Le Grand OSL_ENSURE(rScaleY > 0.0, "Error in scaling: Mirror given in non-mirror-capable method (!)"); 232637ab0f2dSArmin Le Grand const sal_uInt32 nHeight(rSource.GetSizePixel().Height()); 232737ab0f2dSArmin Le Grand const sal_uInt32 nNewHeight(FRound(nHeight * rScaleY)); 232837ab0f2dSArmin Le Grand 232937ab0f2dSArmin Le Grand if(nHeight == nNewHeight) 233037ab0f2dSArmin Le Grand { 233137ab0f2dSArmin Le Grand return true; 233237ab0f2dSArmin Le Grand } 233337ab0f2dSArmin Le Grand 233437ab0f2dSArmin Le Grand BitmapReadAccess* pReadAcc = rSource.AcquireReadAccess(); 233537ab0f2dSArmin Le Grand 233637ab0f2dSArmin Le Grand if(pReadAcc) 233737ab0f2dSArmin Le Grand { 233837ab0f2dSArmin Le Grand double* pWeights = 0; 233937ab0f2dSArmin Le Grand sal_uInt32* pPixels = 0; 234037ab0f2dSArmin Le Grand sal_uInt32* pCount = 0; 234137ab0f2dSArmin Le Grand sal_uInt32 aNumberOfContributions(0); 234237ab0f2dSArmin Le Grand 234337ab0f2dSArmin Le Grand const sal_uInt32 nWidth(rSource.GetSizePixel().Width()); 234437ab0f2dSArmin Le Grand ImplCalculateContributions(nHeight, nNewHeight, aNumberOfContributions, pWeights, pPixels, pCount, aKernel); 234537ab0f2dSArmin Le Grand rTarget = Bitmap(Size(nWidth, nNewHeight), 24); 234637ab0f2dSArmin Le Grand BitmapWriteAccess* pWriteAcc = rTarget.AcquireWriteAccess(); 234737ab0f2dSArmin Le Grand bool bResult(0 != pWriteAcc); 234837ab0f2dSArmin Le Grand 234937ab0f2dSArmin Le Grand if(pWriteAcc) 235037ab0f2dSArmin Le Grand { 235137ab0f2dSArmin Le Grand for(sal_uInt32 x(0); x < nWidth; x++) 235237ab0f2dSArmin Le Grand { 235337ab0f2dSArmin Le Grand for(sal_uInt32 y(0); y < nNewHeight; y++) 235437ab0f2dSArmin Le Grand { 235537ab0f2dSArmin Le Grand const sal_uInt32 aBaseIndex(y * aNumberOfContributions); 235637ab0f2dSArmin Le Grand double aSum(0.0); 235737ab0f2dSArmin Le Grand double aValueRed(0.0); 235837ab0f2dSArmin Le Grand double aValueGreen(0.0); 235937ab0f2dSArmin Le Grand double aValueBlue(0.0); 236037ab0f2dSArmin Le Grand 236137ab0f2dSArmin Le Grand for(sal_uInt32 j(0); j < pCount[y]; j++) 236237ab0f2dSArmin Le Grand { 236337ab0f2dSArmin Le Grand const sal_uInt32 aIndex(aBaseIndex + j); 236437ab0f2dSArmin Le Grand const double aWeight(pWeights[aIndex]); 236537ab0f2dSArmin Le Grand BitmapColor aColor; 236637ab0f2dSArmin Le Grand 236737ab0f2dSArmin Le Grand aSum += aWeight; 236837ab0f2dSArmin Le Grand 236937ab0f2dSArmin Le Grand if(pReadAcc->HasPalette()) 237037ab0f2dSArmin Le Grand { 237137ab0f2dSArmin Le Grand aColor = pReadAcc->GetPaletteColor(pReadAcc->GetPixelIndex(pPixels[aIndex], x)); 237237ab0f2dSArmin Le Grand } 237337ab0f2dSArmin Le Grand else 237437ab0f2dSArmin Le Grand { 237537ab0f2dSArmin Le Grand aColor = pReadAcc->GetPixel(pPixels[aIndex], x); 237637ab0f2dSArmin Le Grand } 237737ab0f2dSArmin Le Grand 237837ab0f2dSArmin Le Grand aValueRed += aWeight * aColor.GetRed(); 237937ab0f2dSArmin Le Grand aValueGreen += aWeight * aColor.GetGreen(); 238037ab0f2dSArmin Le Grand aValueBlue += aWeight * aColor.GetBlue(); 238137ab0f2dSArmin Le Grand } 238237ab0f2dSArmin Le Grand 238337ab0f2dSArmin Le Grand const BitmapColor aResultColor( 238437ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueRed / aSum), 0, 255)), 238537ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueGreen / aSum), 0, 255)), 238637ab0f2dSArmin Le Grand static_cast< sal_uInt8 >(MinMax(static_cast< sal_Int32 >(aValueBlue / aSum), 0, 255))); 238737ab0f2dSArmin Le Grand 238837ab0f2dSArmin Le Grand if(pWriteAcc->HasPalette()) 238937ab0f2dSArmin Le Grand { 239037ab0f2dSArmin Le Grand pWriteAcc->SetPixelIndex(y, x, static_cast< sal_uInt8 >(pWriteAcc->GetBestPaletteIndex(aResultColor))); 239137ab0f2dSArmin Le Grand } 239237ab0f2dSArmin Le Grand else 239337ab0f2dSArmin Le Grand { 239437ab0f2dSArmin Le Grand pWriteAcc->SetPixel(y, x, aResultColor); 239537ab0f2dSArmin Le Grand } 239637ab0f2dSArmin Le Grand } 239737ab0f2dSArmin Le Grand } 239837ab0f2dSArmin Le Grand } 239937ab0f2dSArmin Le Grand 240037ab0f2dSArmin Le Grand rTarget.ReleaseAccess(pWriteAcc); 240137ab0f2dSArmin Le Grand rSource.ReleaseAccess(pReadAcc); 240237ab0f2dSArmin Le Grand 240337ab0f2dSArmin Le Grand delete[] pWeights; 240437ab0f2dSArmin Le Grand delete[] pCount; 240537ab0f2dSArmin Le Grand delete[] pPixels; 240637ab0f2dSArmin Le Grand 240737ab0f2dSArmin Le Grand if(bResult) 240837ab0f2dSArmin Le Grand { 240937ab0f2dSArmin Le Grand return true; 241037ab0f2dSArmin Le Grand } 241137ab0f2dSArmin Le Grand } 241237ab0f2dSArmin Le Grand 241337ab0f2dSArmin Le Grand return false; 241437ab0f2dSArmin Le Grand } 241537ab0f2dSArmin Le Grand } 241637ab0f2dSArmin Le Grand 241737ab0f2dSArmin Le Grand // #121233# Added BMP_SCALE_LANCZOS, BMP_SCALE_BICUBIC, BMP_SCALE_BILINEAR and 241837ab0f2dSArmin Le Grand // BMP_SCALE_BOX derived from the original commit from Toma� Vajngerl (see 241937ab0f2dSArmin Le Grand // bugzilla task for deitails) Thanks! 242037ab0f2dSArmin Le Grand sal_Bool Bitmap::ImplScaleConvolution( 242137ab0f2dSArmin Le Grand const double& rScaleX, 242237ab0f2dSArmin Le Grand const double& rScaleY, 242337ab0f2dSArmin Le Grand const Kernel& aKernel) 242437ab0f2dSArmin Le Grand { 242537ab0f2dSArmin Le Grand const bool bMirrorHor(rScaleX < 0.0); 242637ab0f2dSArmin Le Grand const bool bMirrorVer(rScaleY < 0.0); 242737ab0f2dSArmin Le Grand const double fScaleX(bMirrorHor ? -rScaleX : rScaleX); 242837ab0f2dSArmin Le Grand const double fScaleY(bMirrorVer ? -rScaleY : rScaleY); 242937ab0f2dSArmin Le Grand const sal_uInt32 nWidth(GetSizePixel().Width()); 243037ab0f2dSArmin Le Grand const sal_uInt32 nHeight(GetSizePixel().Height()); 243137ab0f2dSArmin Le Grand const sal_uInt32 nNewWidth(FRound(nWidth * fScaleX)); 243237ab0f2dSArmin Le Grand const sal_uInt32 nNewHeight(FRound(nHeight * fScaleY)); 243337ab0f2dSArmin Le Grand const bool bScaleHor(nWidth != nNewWidth); 243437ab0f2dSArmin Le Grand const bool bScaleVer(nHeight != nNewHeight); 243537ab0f2dSArmin Le Grand const bool bMirror(bMirrorHor || bMirrorVer); 243637ab0f2dSArmin Le Grand 243737ab0f2dSArmin Le Grand if(!bMirror && !bScaleHor && !bScaleVer) 243837ab0f2dSArmin Le Grand { 243937ab0f2dSArmin Le Grand return true; 244037ab0f2dSArmin Le Grand } 244137ab0f2dSArmin Le Grand 244237ab0f2dSArmin Le Grand bool bResult(true); 244337ab0f2dSArmin Le Grand sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE); 244437ab0f2dSArmin Le Grand bool bMirrorAfter(false); 244537ab0f2dSArmin Le Grand 244637ab0f2dSArmin Le Grand if(bMirror) 244737ab0f2dSArmin Le Grand { 244837ab0f2dSArmin Le Grand if(bMirrorHor) 244937ab0f2dSArmin Le Grand { 245037ab0f2dSArmin Le Grand nMirrorFlags |= BMP_MIRROR_HORZ; 245137ab0f2dSArmin Le Grand } 245237ab0f2dSArmin Le Grand 245337ab0f2dSArmin Le Grand if(bMirrorVer) 245437ab0f2dSArmin Le Grand { 245537ab0f2dSArmin Le Grand nMirrorFlags |= BMP_MIRROR_VERT; 245637ab0f2dSArmin Le Grand } 245737ab0f2dSArmin Le Grand 245837ab0f2dSArmin Le Grand const sal_uInt32 nStartSize(nWidth * nHeight); 245937ab0f2dSArmin Le Grand const sal_uInt32 nEndSize(nNewWidth * nNewHeight); 246037ab0f2dSArmin Le Grand 246137ab0f2dSArmin Le Grand bMirrorAfter = nStartSize > nEndSize; 246237ab0f2dSArmin Le Grand 246337ab0f2dSArmin Le Grand if(!bMirrorAfter) 246437ab0f2dSArmin Le Grand { 246537ab0f2dSArmin Le Grand bResult = Mirror(nMirrorFlags); 246637ab0f2dSArmin Le Grand } 246737ab0f2dSArmin Le Grand } 246837ab0f2dSArmin Le Grand 246937ab0f2dSArmin Le Grand Bitmap aResult; 247037ab0f2dSArmin Le Grand 247137ab0f2dSArmin Le Grand if(bResult) 247237ab0f2dSArmin Le Grand { 247337ab0f2dSArmin Le Grand const sal_uInt32 nInBetweenSizeHorFirst(nHeight * nNewWidth); 247437ab0f2dSArmin Le Grand const sal_uInt32 nInBetweenSizeVerFirst(nNewHeight * nWidth); 247537ab0f2dSArmin Le Grand 247637ab0f2dSArmin Le Grand if(nInBetweenSizeHorFirst < nInBetweenSizeVerFirst) 247737ab0f2dSArmin Le Grand { 247837ab0f2dSArmin Le Grand if(bScaleHor) 247937ab0f2dSArmin Le Grand { 248037ab0f2dSArmin Le Grand bResult = ImplScaleConvolutionHor(*this, aResult, fScaleX, aKernel); 248137ab0f2dSArmin Le Grand } 248237ab0f2dSArmin Le Grand 248337ab0f2dSArmin Le Grand if(bResult && bScaleVer) 248437ab0f2dSArmin Le Grand { 248537ab0f2dSArmin Le Grand bResult = ImplScaleConvolutionVer(*this, aResult, fScaleY, aKernel); 248637ab0f2dSArmin Le Grand } 248737ab0f2dSArmin Le Grand } 248837ab0f2dSArmin Le Grand else 248937ab0f2dSArmin Le Grand { 249037ab0f2dSArmin Le Grand if(bScaleVer) 249137ab0f2dSArmin Le Grand { 249237ab0f2dSArmin Le Grand bResult = ImplScaleConvolutionVer(*this, aResult, fScaleY, aKernel); 249337ab0f2dSArmin Le Grand } 249437ab0f2dSArmin Le Grand 249537ab0f2dSArmin Le Grand if(bResult && bScaleHor) 249637ab0f2dSArmin Le Grand { 249737ab0f2dSArmin Le Grand bResult = ImplScaleConvolutionHor(*this, aResult, fScaleX, aKernel); 249837ab0f2dSArmin Le Grand } 249937ab0f2dSArmin Le Grand } 250037ab0f2dSArmin Le Grand } 250137ab0f2dSArmin Le Grand 250237ab0f2dSArmin Le Grand if(bResult && bMirrorAfter) 250337ab0f2dSArmin Le Grand { 250437ab0f2dSArmin Le Grand bResult = aResult.Mirror(nMirrorFlags); 250537ab0f2dSArmin Le Grand } 250637ab0f2dSArmin Le Grand 250737ab0f2dSArmin Le Grand if(bResult) 250837ab0f2dSArmin Le Grand { 250937ab0f2dSArmin Le Grand ImplAdaptBitCount(aResult); 251037ab0f2dSArmin Le Grand *this = aResult; 251137ab0f2dSArmin Le Grand } 251237ab0f2dSArmin Le Grand 251337ab0f2dSArmin Le Grand return bResult; 251437ab0f2dSArmin Le Grand } 251537ab0f2dSArmin Le Grand 2516cdf0e10cSrcweir // ------------------------------------------------------------------------ 2517cdf0e10cSrcweir 2518cdf0e10cSrcweir sal_Bool Bitmap::Dither( sal_uLong nDitherFlags ) 2519cdf0e10cSrcweir { 2520cdf0e10cSrcweir sal_Bool bRet = sal_False; 2521cdf0e10cSrcweir 2522cdf0e10cSrcweir const Size aSizePix( GetSizePixel() ); 2523cdf0e10cSrcweir 2524cdf0e10cSrcweir if( aSizePix.Width() == 1 || aSizePix.Height() == 1 ) 2525cdf0e10cSrcweir bRet = sal_True; 2526cdf0e10cSrcweir else if( nDitherFlags & BMP_DITHER_MATRIX ) 2527cdf0e10cSrcweir bRet = ImplDitherMatrix(); 2528cdf0e10cSrcweir else if( nDitherFlags & BMP_DITHER_FLOYD ) 2529cdf0e10cSrcweir bRet = ImplDitherFloyd(); 2530cdf0e10cSrcweir else if( ( nDitherFlags & BMP_DITHER_FLOYD_16 ) && ( GetBitCount() == 24 ) ) 2531cdf0e10cSrcweir bRet = ImplDitherFloyd16(); 2532cdf0e10cSrcweir 2533cdf0e10cSrcweir return bRet; 2534cdf0e10cSrcweir } 2535cdf0e10cSrcweir 2536cdf0e10cSrcweir // ------------------------------------------------------------------------ 2537cdf0e10cSrcweir 2538cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherMatrix() 2539cdf0e10cSrcweir { 2540cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2541cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 8 ); 2542cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2543cdf0e10cSrcweir sal_Bool bRet = sal_False; 2544cdf0e10cSrcweir 2545cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2546cdf0e10cSrcweir { 2547cdf0e10cSrcweir const sal_uLong nWidth = pReadAcc->Width(); 2548cdf0e10cSrcweir const sal_uLong nHeight = pReadAcc->Height(); 2549cdf0e10cSrcweir BitmapColor aIndex( (sal_uInt8) 0 ); 2550cdf0e10cSrcweir 2551cdf0e10cSrcweir if( pReadAcc->HasPalette() ) 2552cdf0e10cSrcweir { 2553cdf0e10cSrcweir for( sal_uLong nY = 0UL; nY < nHeight; nY++ ) 2554cdf0e10cSrcweir { 2555cdf0e10cSrcweir for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ ) 2556cdf0e10cSrcweir { 255787bc88d3SHerbert Dürr const BitmapColor aCol( pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) ) ); 2558cdf0e10cSrcweir const sal_uLong nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ]; 2559cdf0e10cSrcweir const sal_uLong nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL; 2560cdf0e10cSrcweir const sal_uLong nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL; 2561cdf0e10cSrcweir const sal_uLong nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL; 2562cdf0e10cSrcweir 2563cdf0e10cSrcweir aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) ); 2564cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aIndex ); 2565cdf0e10cSrcweir } 2566cdf0e10cSrcweir } 2567cdf0e10cSrcweir } 2568cdf0e10cSrcweir else 2569cdf0e10cSrcweir { 2570cdf0e10cSrcweir for( sal_uLong nY = 0UL; nY < nHeight; nY++ ) 2571cdf0e10cSrcweir { 2572cdf0e10cSrcweir for( sal_uLong nX = 0UL, nModY = ( nY & 0x0FUL ) << 4UL; nX < nWidth; nX++ ) 2573cdf0e10cSrcweir { 2574cdf0e10cSrcweir const BitmapColor aCol( pReadAcc->GetPixel( nY, nX ) ); 2575cdf0e10cSrcweir const sal_uLong nD = nVCLDitherLut[ nModY + ( nX & 0x0FUL ) ]; 2576cdf0e10cSrcweir const sal_uLong nR = ( nVCLLut[ aCol.GetRed() ] + nD ) >> 16UL; 2577cdf0e10cSrcweir const sal_uLong nG = ( nVCLLut[ aCol.GetGreen() ] + nD ) >> 16UL; 2578cdf0e10cSrcweir const sal_uLong nB = ( nVCLLut[ aCol.GetBlue() ] + nD ) >> 16UL; 2579cdf0e10cSrcweir 2580cdf0e10cSrcweir aIndex.SetIndex( (sal_uInt8) ( nVCLRLut[ nR ] + nVCLGLut[ nG ] + nVCLBLut[ nB ] ) ); 2581cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aIndex ); 2582cdf0e10cSrcweir } 2583cdf0e10cSrcweir } 2584cdf0e10cSrcweir } 2585cdf0e10cSrcweir 2586cdf0e10cSrcweir bRet = sal_True; 2587cdf0e10cSrcweir } 2588cdf0e10cSrcweir 2589cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2590cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2591cdf0e10cSrcweir 2592cdf0e10cSrcweir if( bRet ) 2593cdf0e10cSrcweir { 2594cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2595cdf0e10cSrcweir const Size aSize( maPrefSize ); 2596cdf0e10cSrcweir 2597cdf0e10cSrcweir *this = aNewBmp; 2598cdf0e10cSrcweir 2599cdf0e10cSrcweir maPrefMapMode = aMap; 2600cdf0e10cSrcweir maPrefSize = aSize; 2601cdf0e10cSrcweir } 2602cdf0e10cSrcweir 2603cdf0e10cSrcweir return bRet; 2604cdf0e10cSrcweir } 2605cdf0e10cSrcweir 2606cdf0e10cSrcweir // ------------------------------------------------------------------------ 2607cdf0e10cSrcweir 2608cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherFloyd() 2609cdf0e10cSrcweir { 2610cdf0e10cSrcweir const Size aSize( GetSizePixel() ); 2611cdf0e10cSrcweir sal_Bool bRet = sal_False; 2612cdf0e10cSrcweir 2613cdf0e10cSrcweir if( ( aSize.Width() > 3 ) && ( aSize.Height() > 2 ) ) 2614cdf0e10cSrcweir { 2615cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2616cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 8 ); 2617cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2618cdf0e10cSrcweir 2619cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2620cdf0e10cSrcweir { 2621cdf0e10cSrcweir BitmapColor aColor; 2622cdf0e10cSrcweir long nWidth = pReadAcc->Width(); 2623cdf0e10cSrcweir long nWidth1 = nWidth - 1L; 2624cdf0e10cSrcweir long nHeight = pReadAcc->Height(); 2625cdf0e10cSrcweir long nX; 2626cdf0e10cSrcweir long nW = nWidth * 3L; 2627cdf0e10cSrcweir long nW2 = nW - 3L; 2628cdf0e10cSrcweir long nRErr, nGErr, nBErr; 2629cdf0e10cSrcweir long nRC, nGC, nBC; 2630cdf0e10cSrcweir long nTemp; 2631cdf0e10cSrcweir long nZ; 2632cdf0e10cSrcweir long* p1 = new long[ nW ]; 2633cdf0e10cSrcweir long* p2 = new long[ nW ]; 2634cdf0e10cSrcweir long* p1T = p1; 2635cdf0e10cSrcweir long* p2T = p2; 2636cdf0e10cSrcweir long* pTmp; 2637cdf0e10cSrcweir sal_Bool bPal = pReadAcc->HasPalette(); 2638cdf0e10cSrcweir 2639cdf0e10cSrcweir pTmp = p2T; 2640cdf0e10cSrcweir 2641cdf0e10cSrcweir if( bPal ) 2642cdf0e10cSrcweir { 2643cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2644cdf0e10cSrcweir { 264587bc88d3SHerbert Dürr aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( 0, nZ ) ); 2646cdf0e10cSrcweir 2647cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2648cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2649cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2650cdf0e10cSrcweir } 2651cdf0e10cSrcweir } 2652cdf0e10cSrcweir else 2653cdf0e10cSrcweir { 2654cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2655cdf0e10cSrcweir { 2656cdf0e10cSrcweir aColor = pReadAcc->GetPixel( 0, nZ ); 2657cdf0e10cSrcweir 2658cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2659cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2660cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2661cdf0e10cSrcweir } 2662cdf0e10cSrcweir } 2663cdf0e10cSrcweir 2664cdf0e10cSrcweir for( long nY = 1, nYAcc = 0L; nY <= nHeight; nY++, nYAcc++ ) 2665cdf0e10cSrcweir { 2666cdf0e10cSrcweir pTmp = p1T; 2667cdf0e10cSrcweir p1T = p2T; 2668cdf0e10cSrcweir p2T = pTmp; 2669cdf0e10cSrcweir 2670cdf0e10cSrcweir if( nY < nHeight ) 2671cdf0e10cSrcweir { 2672cdf0e10cSrcweir if( bPal ) 2673cdf0e10cSrcweir { 2674cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2675cdf0e10cSrcweir { 267687bc88d3SHerbert Dürr aColor = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nZ ) ); 2677cdf0e10cSrcweir 2678cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2679cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2680cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2681cdf0e10cSrcweir } 2682cdf0e10cSrcweir } 2683cdf0e10cSrcweir else 2684cdf0e10cSrcweir { 2685cdf0e10cSrcweir for( nZ = 0; nZ < nWidth; nZ++ ) 2686cdf0e10cSrcweir { 2687cdf0e10cSrcweir aColor = pReadAcc->GetPixel( nY, nZ ); 2688cdf0e10cSrcweir 2689cdf0e10cSrcweir *pTmp++ = (long) aColor.GetBlue() << 12; 2690cdf0e10cSrcweir *pTmp++ = (long) aColor.GetGreen() << 12; 2691cdf0e10cSrcweir *pTmp++ = (long) aColor.GetRed() << 12; 2692cdf0e10cSrcweir } 2693cdf0e10cSrcweir } 2694cdf0e10cSrcweir } 2695cdf0e10cSrcweir 2696cdf0e10cSrcweir // erstes Pixel gesondert betrachten 2697cdf0e10cSrcweir nX = 0; 2698cdf0e10cSrcweir CALC_ERRORS; 2699cdf0e10cSrcweir CALC_TABLES7; 2700cdf0e10cSrcweir nX -= 5; 2701cdf0e10cSrcweir CALC_TABLES5; 270287bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, 0, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2703cdf0e10cSrcweir 2704cdf0e10cSrcweir // mittlere Pixel ueber Schleife 2705cdf0e10cSrcweir long nXAcc; 2706cdf0e10cSrcweir for ( nX = 3L, nXAcc = 1L; nX < nW2; nXAcc++ ) 2707cdf0e10cSrcweir { 2708cdf0e10cSrcweir CALC_ERRORS; 2709cdf0e10cSrcweir CALC_TABLES7; 2710cdf0e10cSrcweir nX -= 8; 2711cdf0e10cSrcweir CALC_TABLES3; 2712cdf0e10cSrcweir CALC_TABLES5; 271387bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, nXAcc, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2714cdf0e10cSrcweir } 2715cdf0e10cSrcweir 2716cdf0e10cSrcweir // letztes Pixel gesondert betrachten 2717cdf0e10cSrcweir CALC_ERRORS; 2718cdf0e10cSrcweir nX -= 5; 2719cdf0e10cSrcweir CALC_TABLES3; 2720cdf0e10cSrcweir CALC_TABLES5; 272187bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nYAcc, nWidth1, static_cast<sal_uInt8>(nVCLBLut[ nBC ] + nVCLGLut[nGC ] + nVCLRLut[nRC ]) ); 2722cdf0e10cSrcweir } 2723cdf0e10cSrcweir 2724cdf0e10cSrcweir delete[] p1; 2725cdf0e10cSrcweir delete[] p2; 2726cdf0e10cSrcweir bRet = sal_True; 2727cdf0e10cSrcweir } 2728cdf0e10cSrcweir 2729cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2730cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2731cdf0e10cSrcweir 2732cdf0e10cSrcweir if( bRet ) 2733cdf0e10cSrcweir { 2734cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2735cdf0e10cSrcweir const Size aPrefSize( maPrefSize ); 2736cdf0e10cSrcweir 2737cdf0e10cSrcweir *this = aNewBmp; 2738cdf0e10cSrcweir 2739cdf0e10cSrcweir maPrefMapMode = aMap; 2740cdf0e10cSrcweir maPrefSize = aPrefSize; 2741cdf0e10cSrcweir } 2742cdf0e10cSrcweir } 2743cdf0e10cSrcweir 2744cdf0e10cSrcweir return bRet; 2745cdf0e10cSrcweir } 2746cdf0e10cSrcweir 2747cdf0e10cSrcweir // ------------------------------------------------------------------------ 2748cdf0e10cSrcweir 2749cdf0e10cSrcweir sal_Bool Bitmap::ImplDitherFloyd16() 2750cdf0e10cSrcweir { 2751cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess(); 2752cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 24 ); 2753cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess(); 2754cdf0e10cSrcweir sal_Bool bRet = sal_False; 2755cdf0e10cSrcweir 2756cdf0e10cSrcweir if( pReadAcc && pWriteAcc ) 2757cdf0e10cSrcweir { 2758cdf0e10cSrcweir const long nWidth = pWriteAcc->Width(); 2759cdf0e10cSrcweir const long nWidth1 = nWidth - 1L; 2760cdf0e10cSrcweir const long nHeight = pWriteAcc->Height(); 2761cdf0e10cSrcweir BitmapColor aColor; 2762cdf0e10cSrcweir BitmapColor aBestCol; 2763cdf0e10cSrcweir ImpErrorQuad aErrQuad; 2764cdf0e10cSrcweir ImpErrorQuad* pErrQuad1 = new ImpErrorQuad[ nWidth ]; 2765cdf0e10cSrcweir ImpErrorQuad* pErrQuad2 = new ImpErrorQuad[ nWidth ]; 2766cdf0e10cSrcweir ImpErrorQuad* pQLine1 = pErrQuad1; 2767cdf0e10cSrcweir ImpErrorQuad* pQLine2 = 0; 2768cdf0e10cSrcweir long nX, nY; 2769cdf0e10cSrcweir long nYTmp = 0L; 2770cdf0e10cSrcweir sal_Bool bQ1 = sal_True; 2771cdf0e10cSrcweir 2772cdf0e10cSrcweir for( nY = 0L; nY < Min( nHeight, 2L ); nY++, nYTmp++ ) 2773cdf0e10cSrcweir for( nX = 0L, pQLine2 = !nY ? pErrQuad1 : pErrQuad2; nX < nWidth; nX++ ) 2774cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 2775cdf0e10cSrcweir 2776cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++, nYTmp++ ) 2777cdf0e10cSrcweir { 2778cdf0e10cSrcweir // erstes ZeilenPixel 2779cdf0e10cSrcweir aBestCol = pQLine1[ 0 ].ImplGetColor(); 2780cdf0e10cSrcweir aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 ); 2781cdf0e10cSrcweir aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 ); 2782cdf0e10cSrcweir aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 ); 2783cdf0e10cSrcweir pWriteAcc->SetPixel( nY, 0, aBestCol ); 2784cdf0e10cSrcweir 2785cdf0e10cSrcweir for( nX = 1L; nX < nWidth1; nX++ ) 2786cdf0e10cSrcweir { 2787cdf0e10cSrcweir aColor = pQLine1[ nX ].ImplGetColor(); 2788cdf0e10cSrcweir aBestCol.SetRed( ( aColor.GetRed() & 248 ) | 7 ); 2789cdf0e10cSrcweir aBestCol.SetGreen( ( aColor.GetGreen() & 248 ) | 7 ); 2790cdf0e10cSrcweir aBestCol.SetBlue( ( aColor.GetBlue() & 248 ) | 7 ); 2791cdf0e10cSrcweir aErrQuad = ( ImpErrorQuad( aColor ) -= aBestCol ); 2792cdf0e10cSrcweir pQLine1[ ++nX ].ImplAddColorError7( aErrQuad ); 2793cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError1( aErrQuad ); 2794cdf0e10cSrcweir pQLine2[ nX-- ].ImplAddColorError5( aErrQuad ); 2795cdf0e10cSrcweir pQLine2[ nX++ ].ImplAddColorError3( aErrQuad ); 2796cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBestCol ); 2797cdf0e10cSrcweir } 2798cdf0e10cSrcweir 2799cdf0e10cSrcweir // letztes ZeilenPixel 2800cdf0e10cSrcweir aBestCol = pQLine1[ nWidth1 ].ImplGetColor(); 2801cdf0e10cSrcweir aBestCol.SetRed( ( aBestCol.GetRed() & 248 ) | 7 ); 2802cdf0e10cSrcweir aBestCol.SetGreen( ( aBestCol.GetGreen() & 248 ) | 7 ); 2803cdf0e10cSrcweir aBestCol.SetBlue( ( aBestCol.GetBlue() & 248 ) | 7 ); 2804cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBestCol ); 2805cdf0e10cSrcweir 2806cdf0e10cSrcweir // Zeilenpuffer neu fuellen/kopieren 2807cdf0e10cSrcweir pQLine1 = pQLine2; 2808cdf0e10cSrcweir pQLine2 = ( bQ1 = !bQ1 ) != sal_False ? pErrQuad2 : pErrQuad1; 2809cdf0e10cSrcweir 2810cdf0e10cSrcweir if( nYTmp < nHeight ) 2811cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 2812cdf0e10cSrcweir pQLine2[ nX ] = pReadAcc->GetPixel( nYTmp, nX ); 2813cdf0e10cSrcweir } 2814cdf0e10cSrcweir 2815cdf0e10cSrcweir // Zeilenpuffer zerstoeren 2816cdf0e10cSrcweir delete[] pErrQuad1; 2817cdf0e10cSrcweir delete[] pErrQuad2; 2818cdf0e10cSrcweir bRet = sal_True; 2819cdf0e10cSrcweir } 2820cdf0e10cSrcweir 2821cdf0e10cSrcweir ReleaseAccess( pReadAcc ); 2822cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc ); 2823cdf0e10cSrcweir 2824cdf0e10cSrcweir if( bRet ) 2825cdf0e10cSrcweir { 2826cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2827cdf0e10cSrcweir const Size aSize( maPrefSize ); 2828cdf0e10cSrcweir 2829cdf0e10cSrcweir *this = aNewBmp; 2830cdf0e10cSrcweir 2831cdf0e10cSrcweir maPrefMapMode = aMap; 2832cdf0e10cSrcweir maPrefSize = aSize; 2833cdf0e10cSrcweir } 2834cdf0e10cSrcweir 2835cdf0e10cSrcweir return bRet; 2836cdf0e10cSrcweir } 2837cdf0e10cSrcweir 2838cdf0e10cSrcweir // ------------------------------------------------------------------------ 2839cdf0e10cSrcweir 2840cdf0e10cSrcweir sal_Bool Bitmap::ReduceColors( sal_uInt16 nColorCount, BmpReduce eReduce ) 2841cdf0e10cSrcweir { 2842cdf0e10cSrcweir sal_Bool bRet; 2843cdf0e10cSrcweir 2844cdf0e10cSrcweir if( GetColorCount() <= (sal_uLong) nColorCount ) 2845cdf0e10cSrcweir bRet = sal_True; 2846cdf0e10cSrcweir else if( nColorCount ) 2847cdf0e10cSrcweir { 2848cdf0e10cSrcweir if( BMP_REDUCE_SIMPLE == eReduce ) 2849cdf0e10cSrcweir bRet = ImplReduceSimple( nColorCount ); 2850cdf0e10cSrcweir else if( BMP_REDUCE_POPULAR == eReduce ) 2851cdf0e10cSrcweir bRet = ImplReducePopular( nColorCount ); 2852cdf0e10cSrcweir else 2853cdf0e10cSrcweir bRet = ImplReduceMedian( nColorCount ); 2854cdf0e10cSrcweir } 2855cdf0e10cSrcweir else 2856cdf0e10cSrcweir bRet = sal_False; 2857cdf0e10cSrcweir 2858cdf0e10cSrcweir return bRet; 2859cdf0e10cSrcweir } 2860cdf0e10cSrcweir 2861cdf0e10cSrcweir // ------------------------------------------------------------------------ 2862cdf0e10cSrcweir 2863cdf0e10cSrcweir sal_Bool Bitmap::ImplReduceSimple( sal_uInt16 nColorCount ) 2864cdf0e10cSrcweir { 2865cdf0e10cSrcweir Bitmap aNewBmp; 2866cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 2867cdf0e10cSrcweir const sal_uInt16 nColCount = Min( nColorCount, (sal_uInt16) 256 ); 2868cdf0e10cSrcweir sal_uInt16 nBitCount; 2869cdf0e10cSrcweir sal_Bool bRet = sal_False; 2870cdf0e10cSrcweir 2871cdf0e10cSrcweir if( nColCount <= 2 ) 2872cdf0e10cSrcweir nBitCount = 1; 2873cdf0e10cSrcweir else if( nColCount <= 16 ) 2874cdf0e10cSrcweir nBitCount = 4; 2875cdf0e10cSrcweir else 2876cdf0e10cSrcweir nBitCount = 8; 2877cdf0e10cSrcweir 2878cdf0e10cSrcweir if( pRAcc ) 2879cdf0e10cSrcweir { 2880cdf0e10cSrcweir Octree aOct( *pRAcc, nColCount ); 2881cdf0e10cSrcweir const BitmapPalette& rPal = aOct.GetPalette(); 2882cdf0e10cSrcweir BitmapWriteAccess* pWAcc; 2883cdf0e10cSrcweir 2884cdf0e10cSrcweir aNewBmp = Bitmap( GetSizePixel(), nBitCount, &rPal ); 2885cdf0e10cSrcweir pWAcc = aNewBmp.AcquireWriteAccess(); 2886cdf0e10cSrcweir 2887cdf0e10cSrcweir if( pWAcc ) 2888cdf0e10cSrcweir { 2889cdf0e10cSrcweir const long nWidth = pRAcc->Width(); 2890cdf0e10cSrcweir const long nHeight = pRAcc->Height(); 2891cdf0e10cSrcweir 2892cdf0e10cSrcweir if( pRAcc->HasPalette() ) 2893cdf0e10cSrcweir { 2894cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 2895cdf0e10cSrcweir for( long nX =0L; nX < nWidth; nX++ ) 289687bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ))) ); 2897cdf0e10cSrcweir } 2898cdf0e10cSrcweir else 2899cdf0e10cSrcweir { 2900cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 2901cdf0e10cSrcweir for( long nX =0L; nX < nWidth; nX++ ) 290287bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>(aOct.GetBestPaletteIndex( pRAcc->GetPixel( nY, nX ) )) ); 2903cdf0e10cSrcweir } 2904cdf0e10cSrcweir 2905cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 2906cdf0e10cSrcweir bRet = sal_True; 2907cdf0e10cSrcweir } 2908cdf0e10cSrcweir 2909cdf0e10cSrcweir ReleaseAccess( pRAcc ); 2910cdf0e10cSrcweir } 2911cdf0e10cSrcweir 2912cdf0e10cSrcweir if( bRet ) 2913cdf0e10cSrcweir { 2914cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 2915cdf0e10cSrcweir const Size aSize( maPrefSize ); 2916cdf0e10cSrcweir 2917cdf0e10cSrcweir *this = aNewBmp; 2918cdf0e10cSrcweir maPrefMapMode = aMap; 2919cdf0e10cSrcweir maPrefSize = aSize; 2920cdf0e10cSrcweir } 2921cdf0e10cSrcweir 2922cdf0e10cSrcweir return bRet; 2923cdf0e10cSrcweir } 2924cdf0e10cSrcweir 2925cdf0e10cSrcweir // ------------------------------------------------------------------------ 2926cdf0e10cSrcweir 2927cdf0e10cSrcweir struct PopularColorCount 2928cdf0e10cSrcweir { 2929cdf0e10cSrcweir sal_uInt32 mnIndex; 2930cdf0e10cSrcweir sal_uInt32 mnCount; 2931cdf0e10cSrcweir }; 2932cdf0e10cSrcweir 2933cdf0e10cSrcweir // ------------------------------------------------------------------------ 2934cdf0e10cSrcweir 2935cdf0e10cSrcweir extern "C" int __LOADONCALLAPI ImplPopularCmpFnc( const void* p1, const void* p2 ) 2936cdf0e10cSrcweir { 2937cdf0e10cSrcweir int nRet; 2938cdf0e10cSrcweir 2939cdf0e10cSrcweir if( ( (PopularColorCount*) p1 )->mnCount < ( (PopularColorCount*) p2 )->mnCount ) 2940cdf0e10cSrcweir nRet = 1; 2941cdf0e10cSrcweir else if( ( (PopularColorCount*) p1 )->mnCount == ( (PopularColorCount*) p2 )->mnCount ) 2942cdf0e10cSrcweir nRet = 0; 2943cdf0e10cSrcweir else 2944cdf0e10cSrcweir nRet = -1; 2945cdf0e10cSrcweir 2946cdf0e10cSrcweir return nRet; 2947cdf0e10cSrcweir } 2948cdf0e10cSrcweir 2949cdf0e10cSrcweir // ------------------------------------------------------------------------ 2950cdf0e10cSrcweir 2951cdf0e10cSrcweir sal_Bool Bitmap::ImplReducePopular( sal_uInt16 nColCount ) 2952cdf0e10cSrcweir { 2953cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 2954cdf0e10cSrcweir sal_uInt16 nBitCount; 2955cdf0e10cSrcweir sal_Bool bRet = sal_False; 2956cdf0e10cSrcweir 2957cdf0e10cSrcweir if( nColCount > 256 ) 2958cdf0e10cSrcweir nColCount = 256; 2959cdf0e10cSrcweir 2960cdf0e10cSrcweir if( nColCount < 17 ) 2961cdf0e10cSrcweir nBitCount = 4; 2962cdf0e10cSrcweir else 2963cdf0e10cSrcweir nBitCount = 8; 2964cdf0e10cSrcweir 2965cdf0e10cSrcweir if( pRAcc ) 2966cdf0e10cSrcweir { 2967cdf0e10cSrcweir const sal_uInt32 nValidBits = 4; 2968cdf0e10cSrcweir const sal_uInt32 nRightShiftBits = 8 - nValidBits; 2969cdf0e10cSrcweir const sal_uInt32 nLeftShiftBits1 = nValidBits; 2970cdf0e10cSrcweir const sal_uInt32 nLeftShiftBits2 = nValidBits << 1; 2971cdf0e10cSrcweir const sal_uInt32 nColorsPerComponent = 1 << nValidBits; 2972cdf0e10cSrcweir const sal_uInt32 nColorOffset = 256 / nColorsPerComponent; 2973cdf0e10cSrcweir const sal_uInt32 nTotalColors = nColorsPerComponent * nColorsPerComponent * nColorsPerComponent; 2974cdf0e10cSrcweir const long nWidth = pRAcc->Width(); 2975cdf0e10cSrcweir const long nHeight = pRAcc->Height(); 2976cdf0e10cSrcweir PopularColorCount* pCountTable = new PopularColorCount[ nTotalColors ]; 2977cdf0e10cSrcweir long nX, nY, nR, nG, nB, nIndex; 2978cdf0e10cSrcweir 2979cdf0e10cSrcweir rtl_zeroMemory( pCountTable, nTotalColors * sizeof( PopularColorCount ) ); 2980cdf0e10cSrcweir 2981cdf0e10cSrcweir for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset ) 2982cdf0e10cSrcweir { 2983cdf0e10cSrcweir for( nG = 0; nG < 256; nG += nColorOffset ) 2984cdf0e10cSrcweir { 2985cdf0e10cSrcweir for( nB = 0; nB < 256; nB += nColorOffset ) 2986cdf0e10cSrcweir { 2987cdf0e10cSrcweir pCountTable[ nIndex ].mnIndex = nIndex; 2988cdf0e10cSrcweir nIndex++; 2989cdf0e10cSrcweir } 2990cdf0e10cSrcweir } 2991cdf0e10cSrcweir } 2992cdf0e10cSrcweir 2993cdf0e10cSrcweir if( pRAcc->HasPalette() ) 2994cdf0e10cSrcweir { 2995cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 2996cdf0e10cSrcweir { 2997cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 2998cdf0e10cSrcweir { 299987bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3000cdf0e10cSrcweir pCountTable[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3001cdf0e10cSrcweir ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3002cdf0e10cSrcweir ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++; 3003cdf0e10cSrcweir } 3004cdf0e10cSrcweir } 3005cdf0e10cSrcweir } 3006cdf0e10cSrcweir else 3007cdf0e10cSrcweir { 3008cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3009cdf0e10cSrcweir { 3010cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3011cdf0e10cSrcweir { 3012cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3013cdf0e10cSrcweir pCountTable[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3014cdf0e10cSrcweir ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3015cdf0e10cSrcweir ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ].mnCount++; 3016cdf0e10cSrcweir } 3017cdf0e10cSrcweir } 3018cdf0e10cSrcweir } 3019cdf0e10cSrcweir 3020cdf0e10cSrcweir BitmapPalette aNewPal( nColCount ); 3021cdf0e10cSrcweir 3022cdf0e10cSrcweir qsort( pCountTable, nTotalColors, sizeof( PopularColorCount ), ImplPopularCmpFnc ); 3023cdf0e10cSrcweir 3024cdf0e10cSrcweir for( sal_uInt16 n = 0; n < nColCount; n++ ) 3025cdf0e10cSrcweir { 3026cdf0e10cSrcweir const PopularColorCount& rPop = pCountTable[ n ]; 3027cdf0e10cSrcweir aNewPal[ n ] = BitmapColor( (sal_uInt8) ( ( rPop.mnIndex >> nLeftShiftBits2 ) << nRightShiftBits ), 3028cdf0e10cSrcweir (sal_uInt8) ( ( ( rPop.mnIndex >> nLeftShiftBits1 ) & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ), 3029cdf0e10cSrcweir (sal_uInt8) ( ( rPop.mnIndex & ( nColorsPerComponent - 1 ) ) << nRightShiftBits ) ); 3030cdf0e10cSrcweir } 3031cdf0e10cSrcweir 3032cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount, &aNewPal ); 3033cdf0e10cSrcweir BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess(); 3034cdf0e10cSrcweir 3035cdf0e10cSrcweir if( pWAcc ) 3036cdf0e10cSrcweir { 3037cdf0e10cSrcweir BitmapColor aDstCol( (sal_uInt8) 0 ); 3038cdf0e10cSrcweir sal_uInt8* pIndexMap = new sal_uInt8[ nTotalColors ]; 3039cdf0e10cSrcweir 3040cdf0e10cSrcweir for( nR = 0, nIndex = 0; nR < 256; nR += nColorOffset ) 3041cdf0e10cSrcweir for( nG = 0; nG < 256; nG += nColorOffset ) 3042cdf0e10cSrcweir for( nB = 0; nB < 256; nB += nColorOffset ) 3043cdf0e10cSrcweir pIndexMap[ nIndex++ ] = (sal_uInt8) aNewPal.GetBestIndex( BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB ) ); 3044cdf0e10cSrcweir 3045cdf0e10cSrcweir if( pRAcc->HasPalette() ) 3046cdf0e10cSrcweir { 3047cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3048cdf0e10cSrcweir { 3049cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3050cdf0e10cSrcweir { 305187bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3052cdf0e10cSrcweir aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) rCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3053cdf0e10cSrcweir ( ( ( (sal_uInt32) rCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3054cdf0e10cSrcweir ( ( (sal_uInt32) rCol.GetBlue() ) >> nRightShiftBits ) ] ); 3055cdf0e10cSrcweir pWAcc->SetPixel( nY, nX, aDstCol ); 3056cdf0e10cSrcweir } 3057cdf0e10cSrcweir } 3058cdf0e10cSrcweir } 3059cdf0e10cSrcweir else 3060cdf0e10cSrcweir { 3061cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ ) 3062cdf0e10cSrcweir { 3063cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ ) 3064cdf0e10cSrcweir { 3065cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3066cdf0e10cSrcweir aDstCol.SetIndex( pIndexMap[ ( ( ( (sal_uInt32) aCol.GetRed() ) >> nRightShiftBits ) << nLeftShiftBits2 ) | 3067cdf0e10cSrcweir ( ( ( (sal_uInt32) aCol.GetGreen() ) >> nRightShiftBits ) << nLeftShiftBits1 ) | 3068cdf0e10cSrcweir ( ( (sal_uInt32) aCol.GetBlue() ) >> nRightShiftBits ) ] ); 3069cdf0e10cSrcweir pWAcc->SetPixel( nY, nX, aDstCol ); 3070cdf0e10cSrcweir } 3071cdf0e10cSrcweir } 3072cdf0e10cSrcweir } 3073cdf0e10cSrcweir 3074cdf0e10cSrcweir delete[] pIndexMap; 3075cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 3076cdf0e10cSrcweir bRet = sal_True; 3077cdf0e10cSrcweir } 3078cdf0e10cSrcweir 3079cdf0e10cSrcweir delete[] pCountTable; 3080cdf0e10cSrcweir ReleaseAccess( pRAcc ); 3081cdf0e10cSrcweir 3082cdf0e10cSrcweir if( bRet ) 3083cdf0e10cSrcweir { 3084cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 3085cdf0e10cSrcweir const Size aSize( maPrefSize ); 3086cdf0e10cSrcweir 3087cdf0e10cSrcweir *this = aNewBmp; 3088cdf0e10cSrcweir maPrefMapMode = aMap; 3089cdf0e10cSrcweir maPrefSize = aSize; 3090cdf0e10cSrcweir } 3091cdf0e10cSrcweir } 3092cdf0e10cSrcweir 3093cdf0e10cSrcweir return bRet; 3094cdf0e10cSrcweir } 3095cdf0e10cSrcweir 3096cdf0e10cSrcweir // ------------------------------------------------------------------------ 3097cdf0e10cSrcweir 3098cdf0e10cSrcweir sal_Bool Bitmap::ImplReduceMedian( sal_uInt16 nColCount ) 3099cdf0e10cSrcweir { 3100cdf0e10cSrcweir BitmapReadAccess* pRAcc = AcquireReadAccess(); 3101cdf0e10cSrcweir sal_uInt16 nBitCount; 3102cdf0e10cSrcweir sal_Bool bRet = sal_False; 3103cdf0e10cSrcweir 3104cdf0e10cSrcweir if( nColCount < 17 ) 3105cdf0e10cSrcweir nBitCount = 4; 3106cdf0e10cSrcweir else if( nColCount < 257 ) 3107cdf0e10cSrcweir nBitCount = 8; 3108cdf0e10cSrcweir else 3109cdf0e10cSrcweir { 3110cdf0e10cSrcweir DBG_ERROR( "Bitmap::ImplReduceMedian(): invalid color count!" ); 3111cdf0e10cSrcweir nBitCount = 8; 3112cdf0e10cSrcweir nColCount = 256; 3113cdf0e10cSrcweir } 3114cdf0e10cSrcweir 3115cdf0e10cSrcweir if( pRAcc ) 3116cdf0e10cSrcweir { 3117cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), nBitCount ); 3118cdf0e10cSrcweir BitmapWriteAccess* pWAcc = aNewBmp.AcquireWriteAccess(); 3119cdf0e10cSrcweir 3120cdf0e10cSrcweir if( pWAcc ) 3121cdf0e10cSrcweir { 3122cdf0e10cSrcweir const sal_uLong nSize = 32768UL * sizeof( sal_uLong ); 3123cdf0e10cSrcweir sal_uLong* pColBuf = (sal_uLong*) rtl_allocateMemory( nSize ); 3124cdf0e10cSrcweir const long nWidth = pWAcc->Width(); 3125cdf0e10cSrcweir const long nHeight = pWAcc->Height(); 3126cdf0e10cSrcweir long nIndex = 0L; 3127cdf0e10cSrcweir 3128cdf0e10cSrcweir memset( (HPBYTE) pColBuf, 0, nSize ); 3129cdf0e10cSrcweir 3130cdf0e10cSrcweir // create Buffer 3131cdf0e10cSrcweir if( pRAcc->HasPalette() ) 3132cdf0e10cSrcweir { 3133cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3134cdf0e10cSrcweir { 3135cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 3136cdf0e10cSrcweir { 313787bc88d3SHerbert Dürr const BitmapColor& rCol = pRAcc->GetPaletteColor( pRAcc->GetPixelIndex( nY, nX ) ); 3138cdf0e10cSrcweir pColBuf[ RGB15( rCol.GetRed() >> 3, rCol.GetGreen() >> 3, rCol.GetBlue() >> 3 ) ]++; 3139cdf0e10cSrcweir } 3140cdf0e10cSrcweir } 3141cdf0e10cSrcweir } 3142cdf0e10cSrcweir else 3143cdf0e10cSrcweir { 3144cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3145cdf0e10cSrcweir { 3146cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 3147cdf0e10cSrcweir { 3148cdf0e10cSrcweir const BitmapColor aCol( pRAcc->GetPixel( nY, nX ) ); 3149cdf0e10cSrcweir pColBuf[ RGB15( aCol.GetRed() >> 3, aCol.GetGreen() >> 3, aCol.GetBlue() >> 3 ) ]++; 3150cdf0e10cSrcweir } 3151cdf0e10cSrcweir } 3152cdf0e10cSrcweir } 3153cdf0e10cSrcweir 3154cdf0e10cSrcweir // create palette via median cut 3155cdf0e10cSrcweir BitmapPalette aPal( pWAcc->GetPaletteEntryCount() ); 3156cdf0e10cSrcweir ImplMedianCut( pColBuf, aPal, 0, 31, 0, 31, 0, 31, 3157cdf0e10cSrcweir nColCount, nWidth * nHeight, nIndex ); 3158cdf0e10cSrcweir 3159cdf0e10cSrcweir // do mapping of colors to palette 3160cdf0e10cSrcweir InverseColorMap aMap( aPal ); 3161cdf0e10cSrcweir pWAcc->SetPalette( aPal ); 3162cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) 3163cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ ) 316487bc88d3SHerbert Dürr pWAcc->SetPixelIndex( nY, nX, static_cast<sal_uInt8>( aMap.GetBestPaletteIndex( pRAcc->GetColor( nY, nX ) )) ); 3165cdf0e10cSrcweir 3166cdf0e10cSrcweir rtl_freeMemory( pColBuf ); 3167cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWAcc ); 3168cdf0e10cSrcweir bRet = sal_True; 3169cdf0e10cSrcweir } 3170cdf0e10cSrcweir 3171cdf0e10cSrcweir ReleaseAccess( pRAcc ); 3172cdf0e10cSrcweir 3173cdf0e10cSrcweir if( bRet ) 3174cdf0e10cSrcweir { 3175cdf0e10cSrcweir const MapMode aMap( maPrefMapMode ); 3176cdf0e10cSrcweir const Size aSize( maPrefSize ); 3177cdf0e10cSrcweir 3178cdf0e10cSrcweir *this = aNewBmp; 3179cdf0e10cSrcweir maPrefMapMode = aMap; 3180cdf0e10cSrcweir maPrefSize = aSize; 3181cdf0e10cSrcweir } 3182cdf0e10cSrcweir } 3183cdf0e10cSrcweir 3184cdf0e10cSrcweir return bRet; 3185cdf0e10cSrcweir } 3186cdf0e10cSrcweir 3187cdf0e10cSrcweir // ------------------------------------------------------------------------ 3188cdf0e10cSrcweir 3189cdf0e10cSrcweir void Bitmap::ImplMedianCut( sal_uLong* pColBuf, BitmapPalette& rPal, 3190cdf0e10cSrcweir long nR1, long nR2, long nG1, long nG2, long nB1, long nB2, 3191cdf0e10cSrcweir long nColors, long nPixels, long& rIndex ) 3192cdf0e10cSrcweir { 3193cdf0e10cSrcweir if( !nPixels ) 3194cdf0e10cSrcweir return; 3195cdf0e10cSrcweir 3196cdf0e10cSrcweir BitmapColor aCol; 3197cdf0e10cSrcweir const long nRLen = nR2 - nR1; 3198cdf0e10cSrcweir const long nGLen = nG2 - nG1; 3199cdf0e10cSrcweir const long nBLen = nB2 - nB1; 3200cdf0e10cSrcweir long nR, nG, nB; 3201cdf0e10cSrcweir sal_uLong* pBuf = pColBuf; 3202cdf0e10cSrcweir 3203cdf0e10cSrcweir if( !nRLen && !nGLen && !nBLen ) 3204cdf0e10cSrcweir { 3205cdf0e10cSrcweir if( pBuf[ RGB15( nR1, nG1, nB1 ) ] ) 3206cdf0e10cSrcweir { 3207cdf0e10cSrcweir aCol.SetRed( (sal_uInt8) ( nR1 << 3 ) ); 3208cdf0e10cSrcweir aCol.SetGreen( (sal_uInt8) ( nG1 << 3 ) ); 3209cdf0e10cSrcweir aCol.SetBlue( (sal_uInt8) ( nB1 << 3 ) ); 3210cdf0e10cSrcweir rPal[ (sal_uInt16) rIndex++ ] = aCol; 3211cdf0e10cSrcweir } 3212cdf0e10cSrcweir } 3213cdf0e10cSrcweir else 3214cdf0e10cSrcweir { 3215cdf0e10cSrcweir if( 1 == nColors || 1 == nPixels ) 3216cdf0e10cSrcweir { 3217cdf0e10cSrcweir long nPixSum = 0, nRSum = 0, nGSum = 0, nBSum = 0; 3218cdf0e10cSrcweir 3219cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3220cdf0e10cSrcweir { 3221cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3222cdf0e10cSrcweir { 3223cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3224cdf0e10cSrcweir { 3225cdf0e10cSrcweir nPixSum = pBuf[ RGB15( nR, nG, nB ) ]; 3226cdf0e10cSrcweir 3227cdf0e10cSrcweir if( nPixSum ) 3228cdf0e10cSrcweir { 3229cdf0e10cSrcweir nRSum += nR * nPixSum; 3230cdf0e10cSrcweir nGSum += nG * nPixSum; 3231cdf0e10cSrcweir nBSum += nB * nPixSum; 3232cdf0e10cSrcweir } 3233cdf0e10cSrcweir } 3234cdf0e10cSrcweir } 3235cdf0e10cSrcweir } 3236cdf0e10cSrcweir 3237cdf0e10cSrcweir aCol.SetRed( (sal_uInt8) ( ( nRSum / nPixels ) << 3 ) ); 3238cdf0e10cSrcweir aCol.SetGreen( (sal_uInt8) ( ( nGSum / nPixels ) << 3 ) ); 3239cdf0e10cSrcweir aCol.SetBlue( (sal_uInt8) ( ( nBSum / nPixels ) << 3 ) ); 3240cdf0e10cSrcweir rPal[ (sal_uInt16) rIndex++ ] = aCol; 3241cdf0e10cSrcweir } 3242cdf0e10cSrcweir else 3243cdf0e10cSrcweir { 3244cdf0e10cSrcweir const long nTest = ( nPixels >> 1 ); 3245cdf0e10cSrcweir long nPixOld = 0; 3246cdf0e10cSrcweir long nPixNew = 0; 3247cdf0e10cSrcweir 3248cdf0e10cSrcweir if( nBLen > nGLen && nBLen > nRLen ) 3249cdf0e10cSrcweir { 3250cdf0e10cSrcweir nB = nB1 - 1; 3251cdf0e10cSrcweir 3252cdf0e10cSrcweir while( nPixNew < nTest ) 3253cdf0e10cSrcweir { 3254cdf0e10cSrcweir nB++, nPixOld = nPixNew; 3255cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3256cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3257cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3258cdf0e10cSrcweir } 3259cdf0e10cSrcweir 3260cdf0e10cSrcweir if( nB < nB2 ) 3261cdf0e10cSrcweir { 3262cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB, nColors >> 1, nPixNew, rIndex ); 3263cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB + 1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3264cdf0e10cSrcweir } 3265cdf0e10cSrcweir else 3266cdf0e10cSrcweir { 3267cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB1, nB - 1, nColors >> 1, nPixOld, rIndex ); 3268cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG2, nB, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3269cdf0e10cSrcweir } 3270cdf0e10cSrcweir } 3271cdf0e10cSrcweir else if( nGLen > nRLen ) 3272cdf0e10cSrcweir { 3273cdf0e10cSrcweir nG = nG1 - 1; 3274cdf0e10cSrcweir 3275cdf0e10cSrcweir while( nPixNew < nTest ) 3276cdf0e10cSrcweir { 3277cdf0e10cSrcweir nG++, nPixOld = nPixNew; 3278cdf0e10cSrcweir for( nR = nR1; nR <= nR2; nR++ ) 3279cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3280cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3281cdf0e10cSrcweir } 3282cdf0e10cSrcweir 3283cdf0e10cSrcweir if( nG < nG2 ) 3284cdf0e10cSrcweir { 3285cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG, nB1, nB2, nColors >> 1, nPixNew, rIndex ); 3286cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG + 1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3287cdf0e10cSrcweir } 3288cdf0e10cSrcweir else 3289cdf0e10cSrcweir { 3290cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG1, nG - 1, nB1, nB2, nColors >> 1, nPixOld, rIndex ); 3291cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR2, nG, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3292cdf0e10cSrcweir } 3293cdf0e10cSrcweir } 3294cdf0e10cSrcweir else 3295cdf0e10cSrcweir { 3296cdf0e10cSrcweir nR = nR1 - 1; 3297cdf0e10cSrcweir 3298cdf0e10cSrcweir while( nPixNew < nTest ) 3299cdf0e10cSrcweir { 3300cdf0e10cSrcweir nR++, nPixOld = nPixNew; 3301cdf0e10cSrcweir for( nG = nG1; nG <= nG2; nG++ ) 3302cdf0e10cSrcweir for( nB = nB1; nB <= nB2; nB++ ) 3303cdf0e10cSrcweir nPixNew += pBuf[ RGB15( nR, nG, nB ) ]; 3304cdf0e10cSrcweir } 3305cdf0e10cSrcweir 3306cdf0e10cSrcweir if( nR < nR2 ) 3307cdf0e10cSrcweir { 3308cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR, nG1, nG2, nB1, nB2, nColors >> 1, nPixNew, rIndex ); 3309cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1 + 1, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixNew, rIndex ); 3310cdf0e10cSrcweir } 3311cdf0e10cSrcweir else 3312cdf0e10cSrcweir { 3313cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR1, nR - 1, nG1, nG2, nB1, nB2, nColors >> 1, nPixOld, rIndex ); 3314cdf0e10cSrcweir ImplMedianCut( pBuf, rPal, nR, nR2, nG1, nG2, nB1, nB2, nColors >> 1, nPixels - nPixOld, rIndex ); 3315cdf0e10cSrcweir } 3316cdf0e10cSrcweir } 3317cdf0e10cSrcweir } 3318cdf0e10cSrcweir } 3319cdf0e10cSrcweir } 3320cdf0e10cSrcweir 3321cdf0e10cSrcweir // ------------------------------------------------------------------------ 3322cdf0e10cSrcweir 3323cdf0e10cSrcweir sal_Bool Bitmap::Vectorize( PolyPolygon& rPolyPoly, sal_uLong nFlags, const Link* pProgress ) 3324cdf0e10cSrcweir { 3325cdf0e10cSrcweir return ImplVectorizer().ImplVectorize( *this, rPolyPoly, nFlags, pProgress ); 3326cdf0e10cSrcweir } 3327cdf0e10cSrcweir 3328cdf0e10cSrcweir // ------------------------------------------------------------------------ 3329cdf0e10cSrcweir 3330cdf0e10cSrcweir sal_Bool Bitmap::Vectorize( GDIMetaFile& rMtf, sal_uInt8 cReduce, sal_uLong nFlags, const Link* pProgress ) 3331cdf0e10cSrcweir { 3332cdf0e10cSrcweir return ImplVectorizer().ImplVectorize( *this, rMtf, cReduce, nFlags, pProgress ); 3333cdf0e10cSrcweir } 3334cdf0e10cSrcweir 3335cdf0e10cSrcweir // ------------------------------------------------------------------------ 3336cdf0e10cSrcweir 3337cdf0e10cSrcweir sal_Bool Bitmap::Adjust( short nLuminancePercent, short nContrastPercent, 3338cdf0e10cSrcweir short nChannelRPercent, short nChannelGPercent, short nChannelBPercent, 3339cdf0e10cSrcweir double fGamma, sal_Bool bInvert ) 3340cdf0e10cSrcweir { 3341cdf0e10cSrcweir sal_Bool bRet = sal_False; 3342cdf0e10cSrcweir 3343cdf0e10cSrcweir // nothing to do => return quickly 3344cdf0e10cSrcweir if( !nLuminancePercent && !nContrastPercent && 3345cdf0e10cSrcweir !nChannelRPercent && !nChannelGPercent && !nChannelBPercent && 3346cdf0e10cSrcweir ( fGamma == 1.0 ) && !bInvert ) 3347cdf0e10cSrcweir { 3348cdf0e10cSrcweir bRet = sal_True; 3349cdf0e10cSrcweir } 3350cdf0e10cSrcweir else 3351cdf0e10cSrcweir { 3352cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess(); 3353cdf0e10cSrcweir 3354cdf0e10cSrcweir if( pAcc ) 3355cdf0e10cSrcweir { 3356cdf0e10cSrcweir BitmapColor aCol; 3357cdf0e10cSrcweir const long nW = pAcc->Width(); 3358cdf0e10cSrcweir const long nH = pAcc->Height(); 3359cdf0e10cSrcweir sal_uInt8* cMapR = new sal_uInt8[ 256 ]; 3360cdf0e10cSrcweir sal_uInt8* cMapG = new sal_uInt8[ 256 ]; 3361cdf0e10cSrcweir sal_uInt8* cMapB = new sal_uInt8[ 256 ]; 3362cdf0e10cSrcweir long nX, nY; 3363cdf0e10cSrcweir double fM, fROff, fGOff, fBOff, fOff; 3364cdf0e10cSrcweir 3365cdf0e10cSrcweir // calculate slope 3366cdf0e10cSrcweir if( nContrastPercent >= 0 ) 3367cdf0e10cSrcweir fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) ); 3368cdf0e10cSrcweir else 3369cdf0e10cSrcweir fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0; 3370cdf0e10cSrcweir 3371cdf0e10cSrcweir // total offset = luminance offset + contrast offset 3372cdf0e10cSrcweir fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0; 3373cdf0e10cSrcweir 3374cdf0e10cSrcweir // channel offset = channel offset + total offset 3375cdf0e10cSrcweir fROff = nChannelRPercent * 2.55 + fOff; 3376cdf0e10cSrcweir fGOff = nChannelGPercent * 2.55 + fOff; 3377cdf0e10cSrcweir fBOff = nChannelBPercent * 2.55 + fOff; 3378cdf0e10cSrcweir 3379cdf0e10cSrcweir // calculate gamma value 3380cdf0e10cSrcweir fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); 3381cdf0e10cSrcweir const sal_Bool bGamma = ( fGamma != 1.0 ); 3382cdf0e10cSrcweir 3383cdf0e10cSrcweir // create mapping table 3384cdf0e10cSrcweir for( nX = 0L; nX < 256L; nX++ ) 3385cdf0e10cSrcweir { 3386cdf0e10cSrcweir cMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L ); 3387cdf0e10cSrcweir cMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L ); 3388cdf0e10cSrcweir cMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L ); 3389cdf0e10cSrcweir 3390cdf0e10cSrcweir if( bGamma ) 3391cdf0e10cSrcweir { 3392cdf0e10cSrcweir cMapR[ nX ] = GAMMA( cMapR[ nX ], fGamma ); 3393cdf0e10cSrcweir cMapG[ nX ] = GAMMA( cMapG[ nX ], fGamma ); 3394cdf0e10cSrcweir cMapB[ nX ] = GAMMA( cMapB[ nX ], fGamma ); 3395cdf0e10cSrcweir } 3396cdf0e10cSrcweir 3397cdf0e10cSrcweir if( bInvert ) 3398cdf0e10cSrcweir { 3399cdf0e10cSrcweir cMapR[ nX ] = ~cMapR[ nX ]; 3400cdf0e10cSrcweir cMapG[ nX ] = ~cMapG[ nX ]; 3401cdf0e10cSrcweir cMapB[ nX ] = ~cMapB[ nX ]; 3402cdf0e10cSrcweir } 3403cdf0e10cSrcweir } 3404cdf0e10cSrcweir 3405cdf0e10cSrcweir // do modifying 3406cdf0e10cSrcweir if( pAcc->HasPalette() ) 3407cdf0e10cSrcweir { 3408cdf0e10cSrcweir BitmapColor aNewCol; 3409cdf0e10cSrcweir 3410cdf0e10cSrcweir for( sal_uInt16 i = 0, nCount = pAcc->GetPaletteEntryCount(); i < nCount; i++ ) 3411cdf0e10cSrcweir { 3412cdf0e10cSrcweir const BitmapColor& rCol = pAcc->GetPaletteColor( i ); 3413cdf0e10cSrcweir aNewCol.SetRed( cMapR[ rCol.GetRed() ] ); 3414cdf0e10cSrcweir aNewCol.SetGreen( cMapG[ rCol.GetGreen() ] ); 3415cdf0e10cSrcweir aNewCol.SetBlue( cMapB[ rCol.GetBlue() ] ); 3416cdf0e10cSrcweir pAcc->SetPaletteColor( i, aNewCol ); 3417cdf0e10cSrcweir } 3418cdf0e10cSrcweir } 3419cdf0e10cSrcweir else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR ) 3420cdf0e10cSrcweir { 3421cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3422cdf0e10cSrcweir { 3423cdf0e10cSrcweir Scanline pScan = pAcc->GetScanline( nY ); 3424cdf0e10cSrcweir 3425cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3426cdf0e10cSrcweir { 3427cdf0e10cSrcweir *pScan = cMapB[ *pScan ]; pScan++; 3428cdf0e10cSrcweir *pScan = cMapG[ *pScan ]; pScan++; 3429cdf0e10cSrcweir *pScan = cMapR[ *pScan ]; pScan++; 3430cdf0e10cSrcweir } 3431cdf0e10cSrcweir } 3432cdf0e10cSrcweir } 3433cdf0e10cSrcweir else if( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB ) 3434cdf0e10cSrcweir { 3435cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3436cdf0e10cSrcweir { 3437cdf0e10cSrcweir Scanline pScan = pAcc->GetScanline( nY ); 3438cdf0e10cSrcweir 3439cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3440cdf0e10cSrcweir { 3441cdf0e10cSrcweir *pScan = cMapR[ *pScan ]; pScan++; 3442cdf0e10cSrcweir *pScan = cMapG[ *pScan ]; pScan++; 3443cdf0e10cSrcweir *pScan = cMapB[ *pScan ]; pScan++; 3444cdf0e10cSrcweir } 3445cdf0e10cSrcweir } 3446cdf0e10cSrcweir } 3447cdf0e10cSrcweir else 3448cdf0e10cSrcweir { 3449cdf0e10cSrcweir for( nY = 0L; nY < nH; nY++ ) 3450cdf0e10cSrcweir { 3451cdf0e10cSrcweir for( nX = 0L; nX < nW; nX++ ) 3452cdf0e10cSrcweir { 3453cdf0e10cSrcweir aCol = pAcc->GetPixel( nY, nX ); 3454cdf0e10cSrcweir aCol.SetRed( cMapR[ aCol.GetRed() ] ); 3455cdf0e10cSrcweir aCol.SetGreen( cMapG[ aCol.GetGreen() ] ); 3456cdf0e10cSrcweir aCol.SetBlue( cMapB[ aCol.GetBlue() ] ); 3457cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aCol ); 3458cdf0e10cSrcweir } 3459cdf0e10cSrcweir } 3460cdf0e10cSrcweir } 3461cdf0e10cSrcweir 3462cdf0e10cSrcweir delete[] cMapR; 3463cdf0e10cSrcweir delete[] cMapG; 3464cdf0e10cSrcweir delete[] cMapB; 3465cdf0e10cSrcweir ReleaseAccess( pAcc ); 3466cdf0e10cSrcweir bRet = sal_True; 3467cdf0e10cSrcweir } 3468cdf0e10cSrcweir } 3469cdf0e10cSrcweir 3470cdf0e10cSrcweir return bRet; 3471cdf0e10cSrcweir } 3472