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