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