xref: /trunk/main/vcl/source/gdi/bitmap4.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3) !
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <stdlib.h>
32*cdf0e10cSrcweir #include <vos/macros.hxx>
33*cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
34*cdf0e10cSrcweir #include <vcl/bitmap.hxx>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir // -----------
37*cdf0e10cSrcweir // - Defines -
38*cdf0e10cSrcweir // -----------
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir #define S2(a,b)             { register long t; if( ( t = b - a ) < 0 ) { a += t; b -= t; } }
41*cdf0e10cSrcweir #define MN3(a,b,c)          S2(a,b); S2(a,c);
42*cdf0e10cSrcweir #define MX3(a,b,c)          S2(b,c); S2(a,c);
43*cdf0e10cSrcweir #define MNMX3(a,b,c)        MX3(a,b,c); S2(a,b);
44*cdf0e10cSrcweir #define MNMX4(a,b,c,d)      S2(a,b); S2(c,d); S2(a,c); S2(b,d);
45*cdf0e10cSrcweir #define MNMX5(a,b,c,d,e)    S2(a,b); S2(c,d); MN3(a,c,e); MX3(b,d,e);
46*cdf0e10cSrcweir #define MNMX6(a,b,c,d,e,f)  S2(a,d); S2(b,e); S2(c,f); MN3(a,b,c); MX3(d,e,f);
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir // ----------
49*cdf0e10cSrcweir // - Bitmap -
50*cdf0e10cSrcweir // ----------
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir sal_Bool Bitmap::Filter( BmpFilter eFilter, const BmpFilterParam* pFilterParam, const Link* pProgress )
53*cdf0e10cSrcweir {
54*cdf0e10cSrcweir     sal_Bool bRet = sal_False;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir     switch( eFilter )
57*cdf0e10cSrcweir     {
58*cdf0e10cSrcweir         case( BMP_FILTER_SMOOTH ):
59*cdf0e10cSrcweir         {
60*cdf0e10cSrcweir             const long pSmoothMatrix[] = { 1, 2, 1, 2, 5, 2, 1, 2, 1 };
61*cdf0e10cSrcweir             bRet = ImplConvolute3( &pSmoothMatrix[ 0 ], 17, pFilterParam, pProgress );
62*cdf0e10cSrcweir         }
63*cdf0e10cSrcweir         break;
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir         case( BMP_FILTER_SHARPEN ):
66*cdf0e10cSrcweir         {
67*cdf0e10cSrcweir             const long pSharpenMatrix[] = { -1, -1,  -1, -1, 16, -1, -1, -1,  -1 };
68*cdf0e10cSrcweir             bRet = ImplConvolute3( &pSharpenMatrix[ 0 ], 8, pFilterParam, pProgress );
69*cdf0e10cSrcweir         }
70*cdf0e10cSrcweir         break;
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir         case( BMP_FILTER_REMOVENOISE ):
73*cdf0e10cSrcweir             bRet = ImplMedianFilter( pFilterParam, pProgress );
74*cdf0e10cSrcweir         break;
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir         case( BMP_FILTER_SOBEL_GREY ):
77*cdf0e10cSrcweir             bRet = ImplSobelGrey( pFilterParam, pProgress );
78*cdf0e10cSrcweir         break;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir         case( BMP_FILTER_SOLARIZE ):
81*cdf0e10cSrcweir             bRet = ImplSolarize( pFilterParam, pProgress );
82*cdf0e10cSrcweir         break;
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir         case( BMP_FILTER_SEPIA ):
85*cdf0e10cSrcweir             bRet = ImplSepia( pFilterParam, pProgress );
86*cdf0e10cSrcweir         break;
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir         case( BMP_FILTER_MOSAIC ):
89*cdf0e10cSrcweir             bRet = ImplMosaic( pFilterParam, pProgress );
90*cdf0e10cSrcweir         break;
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir         case( BMP_FILTER_EMBOSS_GREY ):
93*cdf0e10cSrcweir             bRet = ImplEmbossGrey( pFilterParam, pProgress );
94*cdf0e10cSrcweir         break;
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir         case( BMP_FILTER_POPART ):
97*cdf0e10cSrcweir             bRet = ImplPopArt( pFilterParam, pProgress );
98*cdf0e10cSrcweir         break;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir         default:
101*cdf0e10cSrcweir             DBG_ERROR( "Bitmap::Convert(): Unsupported filter" );
102*cdf0e10cSrcweir         break;
103*cdf0e10cSrcweir     }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir     return bRet;
106*cdf0e10cSrcweir }
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir // -----------------------------------------------------------------------------
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir sal_Bool Bitmap::ImplConvolute3( const long* pMatrix, long nDivisor,
111*cdf0e10cSrcweir                              const BmpFilterParam* /*pFilterParam*/, const Link* /*pProgress*/ )
112*cdf0e10cSrcweir {
113*cdf0e10cSrcweir     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
114*cdf0e10cSrcweir     sal_Bool                bRet = sal_False;
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir     if( pReadAcc )
117*cdf0e10cSrcweir     {
118*cdf0e10cSrcweir         Bitmap              aNewBmp( GetSizePixel(), 24 );
119*cdf0e10cSrcweir         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir         if( pWriteAcc )
122*cdf0e10cSrcweir         {
123*cdf0e10cSrcweir             const long      nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
124*cdf0e10cSrcweir             const long      nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
125*cdf0e10cSrcweir             long*           pColm = new long[ nWidth2 ];
126*cdf0e10cSrcweir             long*           pRows = new long[ nHeight2 ];
127*cdf0e10cSrcweir             BitmapColor*    pColRow1 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
128*cdf0e10cSrcweir             BitmapColor*    pColRow2 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
129*cdf0e10cSrcweir             BitmapColor*    pColRow3 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
130*cdf0e10cSrcweir             BitmapColor*    pRowTmp1 = pColRow1;
131*cdf0e10cSrcweir             BitmapColor*    pRowTmp2 = pColRow2;
132*cdf0e10cSrcweir             BitmapColor*    pRowTmp3 = pColRow3;
133*cdf0e10cSrcweir             BitmapColor*    pColor;
134*cdf0e10cSrcweir             long            nY, nX, i, nSumR, nSumG, nSumB, nMatrixVal, nTmp;
135*cdf0e10cSrcweir             long            (*pKoeff)[ 256 ] = new long[ 9 ][ 256 ];
136*cdf0e10cSrcweir             long*           pTmp;
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir             // create LUT of products of matrix value and possible color component values
139*cdf0e10cSrcweir             for( nY = 0; nY < 9; nY++ )
140*cdf0e10cSrcweir                 for( nX = nTmp = 0, nMatrixVal = pMatrix[ nY ]; nX < 256; nX++, nTmp += nMatrixVal )
141*cdf0e10cSrcweir                     pKoeff[ nY ][ nX ] = nTmp;
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir             // create column LUT
144*cdf0e10cSrcweir             for( i = 0; i < nWidth2; i++ )
145*cdf0e10cSrcweir                 pColm[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir             pColm[ nWidth + 1 ] = pColm[ nWidth ];
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir             // create row LUT
150*cdf0e10cSrcweir             for( i = 0; i < nHeight2; i++ )
151*cdf0e10cSrcweir                 pRows[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir             pRows[ nHeight + 1 ] = pRows[ nHeight ];
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir             // read first three rows of bitmap color
156*cdf0e10cSrcweir             for( i = 0; i < nWidth2; i++ )
157*cdf0e10cSrcweir             {
158*cdf0e10cSrcweir                 pColRow1[ i ] = pReadAcc->GetColor( pRows[ 0 ], pColm[ i ] );
159*cdf0e10cSrcweir                 pColRow2[ i ] = pReadAcc->GetColor( pRows[ 1 ], pColm[ i ] );
160*cdf0e10cSrcweir                 pColRow3[ i ] = pReadAcc->GetColor( pRows[ 2 ], pColm[ i ] );
161*cdf0e10cSrcweir             }
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir             // do convolution
164*cdf0e10cSrcweir             for( nY = 0; nY < nHeight; )
165*cdf0e10cSrcweir             {
166*cdf0e10cSrcweir                 for( nX = 0; nX < nWidth; nX++ )
167*cdf0e10cSrcweir                 {
168*cdf0e10cSrcweir                     // first row
169*cdf0e10cSrcweir                     nSumR = ( pTmp = pKoeff[ 0 ] )[ ( pColor = pRowTmp1 + nX )->GetRed() ];
170*cdf0e10cSrcweir                     nSumG = pTmp[ pColor->GetGreen() ];
171*cdf0e10cSrcweir                     nSumB = pTmp[ pColor->GetBlue() ];
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 1 ] )[ ( ++pColor )->GetRed() ];
174*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
175*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 2 ] )[ ( ++pColor )->GetRed() ];
178*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
179*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir                     // second row
182*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 3 ] )[ ( pColor = pRowTmp2 + nX )->GetRed() ];
183*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
184*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
185*cdf0e10cSrcweir 
186*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 4 ] )[ ( ++pColor )->GetRed() ];
187*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
188*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 5 ] )[ ( ++pColor )->GetRed() ];
191*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
192*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir                     // third row
195*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 6 ] )[ ( pColor = pRowTmp3 + nX )->GetRed() ];
196*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
197*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 7 ] )[ ( ++pColor )->GetRed() ];
200*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
201*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir                     nSumR += ( pTmp = pKoeff[ 8 ] )[ ( ++pColor )->GetRed() ];
204*cdf0e10cSrcweir                     nSumG += pTmp[ pColor->GetGreen() ];
205*cdf0e10cSrcweir                     nSumB += pTmp[ pColor->GetBlue() ];
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir                     // calculate destination color
208*cdf0e10cSrcweir                     pWriteAcc->SetPixel( nY, nX, BitmapColor( (sal_uInt8) MinMax( nSumR / nDivisor, 0, 255 ),
209*cdf0e10cSrcweir                                                               (sal_uInt8) MinMax( nSumG / nDivisor, 0, 255 ),
210*cdf0e10cSrcweir                                                               (sal_uInt8) MinMax( nSumB / nDivisor, 0, 255 ) ) );
211*cdf0e10cSrcweir                 }
212*cdf0e10cSrcweir 
213*cdf0e10cSrcweir                 if( ++nY < nHeight )
214*cdf0e10cSrcweir                 {
215*cdf0e10cSrcweir                     if( pRowTmp1 == pColRow1 )
216*cdf0e10cSrcweir                         pRowTmp1 = pColRow2, pRowTmp2 = pColRow3, pRowTmp3 = pColRow1;
217*cdf0e10cSrcweir                     else if( pRowTmp1 == pColRow2 )
218*cdf0e10cSrcweir                         pRowTmp1 = pColRow3, pRowTmp2 = pColRow1, pRowTmp3 = pColRow2;
219*cdf0e10cSrcweir                     else
220*cdf0e10cSrcweir                         pRowTmp1 = pColRow1, pRowTmp2 = pColRow2, pRowTmp3 = pColRow3;
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir                     for( i = 0; i < nWidth2; i++ )
223*cdf0e10cSrcweir                         pRowTmp3[ i ] = pReadAcc->GetColor( pRows[ nY + 2 ], pColm[ i ] );
224*cdf0e10cSrcweir                 }
225*cdf0e10cSrcweir             }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir             delete[] pKoeff;
228*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow1;
229*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow2;
230*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow3;
231*cdf0e10cSrcweir             delete[] pColm;
232*cdf0e10cSrcweir             delete[] pRows;
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir             aNewBmp.ReleaseAccess( pWriteAcc );
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir             bRet = sal_True;
237*cdf0e10cSrcweir         }
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir         ReleaseAccess( pReadAcc );
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir         if( bRet )
242*cdf0e10cSrcweir         {
243*cdf0e10cSrcweir             const MapMode   aMap( maPrefMapMode );
244*cdf0e10cSrcweir             const Size      aSize( maPrefSize );
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir             *this = aNewBmp;
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir             maPrefMapMode = aMap;
249*cdf0e10cSrcweir             maPrefSize = aSize;
250*cdf0e10cSrcweir         }
251*cdf0e10cSrcweir     }
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir     return bRet;
254*cdf0e10cSrcweir }
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir // -----------------------------------------------------------------------------
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir sal_Bool Bitmap::ImplMedianFilter( const BmpFilterParam* /*pFilterParam*/, const Link* /*pProgress*/ )
259*cdf0e10cSrcweir {
260*cdf0e10cSrcweir     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
261*cdf0e10cSrcweir     sal_Bool                bRet = sal_False;
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir     if( pReadAcc )
264*cdf0e10cSrcweir     {
265*cdf0e10cSrcweir         Bitmap              aNewBmp( GetSizePixel(), 24 );
266*cdf0e10cSrcweir         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir         if( pWriteAcc )
269*cdf0e10cSrcweir         {
270*cdf0e10cSrcweir             const long      nWidth = pWriteAcc->Width(), nWidth2 = nWidth + 2;
271*cdf0e10cSrcweir             const long      nHeight = pWriteAcc->Height(), nHeight2 = nHeight + 2;
272*cdf0e10cSrcweir             long*           pColm = new long[ nWidth2 ];
273*cdf0e10cSrcweir             long*           pRows = new long[ nHeight2 ];
274*cdf0e10cSrcweir             BitmapColor*    pColRow1 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
275*cdf0e10cSrcweir             BitmapColor*    pColRow2 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
276*cdf0e10cSrcweir             BitmapColor*    pColRow3 = (BitmapColor*) new sal_uInt8[ sizeof( BitmapColor ) * nWidth2 ];
277*cdf0e10cSrcweir             BitmapColor*    pRowTmp1 = pColRow1;
278*cdf0e10cSrcweir             BitmapColor*    pRowTmp2 = pColRow2;
279*cdf0e10cSrcweir             BitmapColor*    pRowTmp3 = pColRow3;
280*cdf0e10cSrcweir             BitmapColor*    pColor;
281*cdf0e10cSrcweir             long            nY, nX, i;
282*cdf0e10cSrcweir             long            nR1, nR2, nR3, nR4, nR5, nR6, nR7, nR8, nR9;
283*cdf0e10cSrcweir             long            nG1, nG2, nG3, nG4, nG5, nG6, nG7, nG8, nG9;
284*cdf0e10cSrcweir             long            nB1, nB2, nB3, nB4, nB5, nB6, nB7, nB8, nB9;
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir             // create column LUT
287*cdf0e10cSrcweir             for( i = 0; i < nWidth2; i++ )
288*cdf0e10cSrcweir                 pColm[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
289*cdf0e10cSrcweir 
290*cdf0e10cSrcweir             pColm[ nWidth + 1 ] = pColm[ nWidth ];
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir             // create row LUT
293*cdf0e10cSrcweir             for( i = 0; i < nHeight2; i++ )
294*cdf0e10cSrcweir                 pRows[ i ] = ( i > 0 ) ? ( i - 1 ) : 0;
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir             pRows[ nHeight + 1 ] = pRows[ nHeight ];
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir             // read first three rows of bitmap color
299*cdf0e10cSrcweir             if (nHeight2 > 2)
300*cdf0e10cSrcweir             {
301*cdf0e10cSrcweir                 for( i = 0; i < nWidth2; i++ )
302*cdf0e10cSrcweir                 {
303*cdf0e10cSrcweir                     pColRow1[ i ] = pReadAcc->GetColor( pRows[ 0 ], pColm[ i ] );
304*cdf0e10cSrcweir                     pColRow2[ i ] = pReadAcc->GetColor( pRows[ 1 ], pColm[ i ] );
305*cdf0e10cSrcweir                     pColRow3[ i ] = pReadAcc->GetColor( pRows[ 2 ], pColm[ i ] );
306*cdf0e10cSrcweir                 }
307*cdf0e10cSrcweir             }
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir             // do median filtering
310*cdf0e10cSrcweir             for( nY = 0; nY < nHeight; )
311*cdf0e10cSrcweir             {
312*cdf0e10cSrcweir                 for( nX = 0; nX < nWidth; nX++ )
313*cdf0e10cSrcweir                 {
314*cdf0e10cSrcweir                     nR1 = ( pColor = pRowTmp1 + nX )->GetRed(), nG1 = pColor->GetGreen(), nB1 = pColor->GetBlue();
315*cdf0e10cSrcweir                     nR2 = ( ++pColor )->GetRed(), nG2 = pColor->GetGreen(), nB2 = pColor->GetBlue();
316*cdf0e10cSrcweir                     nR3 = ( ++pColor )->GetRed(), nG3 = pColor->GetGreen(), nB3 = pColor->GetBlue();
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir                     nR4 = ( pColor = pRowTmp2 + nX )->GetRed(), nG4 = pColor->GetGreen(), nB4 = pColor->GetBlue();
319*cdf0e10cSrcweir                     nR5 = ( ++pColor )->GetRed(), nG5 = pColor->GetGreen(), nB5 = pColor->GetBlue();
320*cdf0e10cSrcweir                     nR6 = ( ++pColor )->GetRed(), nG6 = pColor->GetGreen(), nB6 = pColor->GetBlue();
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir                     nR7 = ( pColor = pRowTmp3 + nX )->GetRed(), nG7 = pColor->GetGreen(), nB7 = pColor->GetBlue();
323*cdf0e10cSrcweir                     nR8 = ( ++pColor )->GetRed(), nG8 = pColor->GetGreen(), nB8 = pColor->GetBlue();
324*cdf0e10cSrcweir                     nR9 = ( ++pColor )->GetRed(), nG9 = pColor->GetGreen(), nB9 = pColor->GetBlue();
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir                     MNMX6( nR1, nR2, nR3, nR4, nR5, nR6 );
327*cdf0e10cSrcweir                     MNMX5( nR7, nR2, nR3, nR4, nR5 );
328*cdf0e10cSrcweir                     MNMX4( nR8, nR2, nR3, nR4 );
329*cdf0e10cSrcweir                     MNMX3( nR9, nR2, nR3 );
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir                     MNMX6( nG1, nG2, nG3, nG4, nG5, nG6 );
332*cdf0e10cSrcweir                     MNMX5( nG7, nG2, nG3, nG4, nG5 );
333*cdf0e10cSrcweir                     MNMX4( nG8, nG2, nG3, nG4 );
334*cdf0e10cSrcweir                     MNMX3( nG9, nG2, nG3 );
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir                     MNMX6( nB1, nB2, nB3, nB4, nB5, nB6 );
337*cdf0e10cSrcweir                     MNMX5( nB7, nB2, nB3, nB4, nB5 );
338*cdf0e10cSrcweir                     MNMX4( nB8, nB2, nB3, nB4 );
339*cdf0e10cSrcweir                     MNMX3( nB9, nB2, nB3 );
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir                     // set destination color
342*cdf0e10cSrcweir                     pWriteAcc->SetPixel( nY, nX, BitmapColor( (sal_uInt8) nR2, (sal_uInt8) nG2, (sal_uInt8) nB2 ) );
343*cdf0e10cSrcweir                 }
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir                 if( ++nY < nHeight )
346*cdf0e10cSrcweir                 {
347*cdf0e10cSrcweir                     if( pRowTmp1 == pColRow1 )
348*cdf0e10cSrcweir                         pRowTmp1 = pColRow2, pRowTmp2 = pColRow3, pRowTmp3 = pColRow1;
349*cdf0e10cSrcweir                     else if( pRowTmp1 == pColRow2 )
350*cdf0e10cSrcweir                         pRowTmp1 = pColRow3, pRowTmp2 = pColRow1, pRowTmp3 = pColRow2;
351*cdf0e10cSrcweir                     else
352*cdf0e10cSrcweir                         pRowTmp1 = pColRow1, pRowTmp2 = pColRow2, pRowTmp3 = pColRow3;
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir                     for( i = 0; i < nWidth2; i++ )
355*cdf0e10cSrcweir                         pRowTmp3[ i ] = pReadAcc->GetColor( pRows[ nY + 2 ], pColm[ i ] );
356*cdf0e10cSrcweir                 }
357*cdf0e10cSrcweir             }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow1;
360*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow2;
361*cdf0e10cSrcweir             delete[] (sal_uInt8*) pColRow3;
362*cdf0e10cSrcweir             delete[] pColm;
363*cdf0e10cSrcweir             delete[] pRows;
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir             aNewBmp.ReleaseAccess( pWriteAcc );
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir             bRet = sal_True;
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir         ReleaseAccess( pReadAcc );
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir         if( bRet )
373*cdf0e10cSrcweir         {
374*cdf0e10cSrcweir             const MapMode   aMap( maPrefMapMode );
375*cdf0e10cSrcweir             const Size      aSize( maPrefSize );
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir             *this = aNewBmp;
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir             maPrefMapMode = aMap;
380*cdf0e10cSrcweir             maPrefSize = aSize;
381*cdf0e10cSrcweir         }
382*cdf0e10cSrcweir     }
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir     return bRet;
385*cdf0e10cSrcweir }
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir // -----------------------------------------------------------------------------
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir sal_Bool Bitmap::ImplSobelGrey( const BmpFilterParam* /*pFilterParam*/, const Link* /*pProgress*/ )
390*cdf0e10cSrcweir {
391*cdf0e10cSrcweir     sal_Bool bRet = ImplMakeGreyscales( 256 );
392*cdf0e10cSrcweir 
393*cdf0e10cSrcweir     if( bRet )
394*cdf0e10cSrcweir     {
395*cdf0e10cSrcweir         bRet = sal_False;
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir         BitmapReadAccess* pReadAcc = AcquireReadAccess();
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir         if( pReadAcc )
400*cdf0e10cSrcweir         {
401*cdf0e10cSrcweir             Bitmap              aNewBmp( GetSizePixel(), 8, &pReadAcc->GetPalette() );
402*cdf0e10cSrcweir             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir             if( pWriteAcc )
405*cdf0e10cSrcweir             {
406*cdf0e10cSrcweir                 BitmapColor aGrey( (sal_uInt8) 0 );
407*cdf0e10cSrcweir                 const long  nWidth = pWriteAcc->Width();
408*cdf0e10cSrcweir                 const long  nHeight = pWriteAcc->Height();
409*cdf0e10cSrcweir                 const long  nMask111 = -1, nMask121 =  0, nMask131 =  1;
410*cdf0e10cSrcweir                 const long  nMask211 = -2, nMask221 =  0, nMask231 =  2;
411*cdf0e10cSrcweir                 const long  nMask311 = -1, nMask321 =  0, nMask331 =  1;
412*cdf0e10cSrcweir                 const long  nMask112 =  1, nMask122 =  2, nMask132 =  1;
413*cdf0e10cSrcweir                 const long  nMask212 =  0, nMask222 =  0, nMask232 =  0;
414*cdf0e10cSrcweir                 const long  nMask312 = -1, nMask322 = -2, nMask332 = -1;
415*cdf0e10cSrcweir                 long        nGrey11, nGrey12, nGrey13;
416*cdf0e10cSrcweir                 long        nGrey21, nGrey22, nGrey23;
417*cdf0e10cSrcweir                 long        nGrey31, nGrey32, nGrey33;
418*cdf0e10cSrcweir                 long*       pHMap = new long[ nWidth + 2 ];
419*cdf0e10cSrcweir                 long*       pVMap = new long[ nHeight + 2 ];
420*cdf0e10cSrcweir                 long        nX, nY, nSum1, nSum2;
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir                 // fill mapping tables
423*cdf0e10cSrcweir                 pHMap[ 0 ] = 0;
424*cdf0e10cSrcweir                 for( nX = 1; nX <= nWidth; nX++ )
425*cdf0e10cSrcweir                     pHMap[ nX ] = nX - 1;
426*cdf0e10cSrcweir                 pHMap[ nWidth + 1 ] = nWidth - 1;
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir                 pVMap[ 0 ] = 0;
429*cdf0e10cSrcweir                 for( nY = 1; nY <= nHeight; nY++ )
430*cdf0e10cSrcweir                     pVMap[ nY ] = nY - 1;
431*cdf0e10cSrcweir                 pVMap[ nHeight + 1 ] = nHeight - 1;
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir                 for( nY = 0; nY < nHeight ; nY++ )
434*cdf0e10cSrcweir                 {
435*cdf0e10cSrcweir                     nGrey11 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 0 ] ).GetIndex();
436*cdf0e10cSrcweir                     nGrey12 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 1 ] ).GetIndex();
437*cdf0e10cSrcweir                     nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 2 ] ).GetIndex();
438*cdf0e10cSrcweir                     nGrey21 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 0 ] ).GetIndex();
439*cdf0e10cSrcweir                     nGrey22 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 1 ] ).GetIndex();
440*cdf0e10cSrcweir                     nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 2 ] ).GetIndex();
441*cdf0e10cSrcweir                     nGrey31 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 0 ] ).GetIndex();
442*cdf0e10cSrcweir                     nGrey32 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 1 ] ).GetIndex();
443*cdf0e10cSrcweir                     nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 2 ] ).GetIndex();
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir                     for( nX = 0; nX < nWidth; nX++ )
446*cdf0e10cSrcweir                     {
447*cdf0e10cSrcweir                         nSum1 = nSum2 = 0;
448*cdf0e10cSrcweir 
449*cdf0e10cSrcweir                         nSum1 += nMask111 * nGrey11;
450*cdf0e10cSrcweir                         nSum2 += nMask112 * nGrey11;
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir                         nSum1 += nMask121 * nGrey12;
453*cdf0e10cSrcweir                         nSum2 += nMask122 * nGrey12;
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir                         nSum1 += nMask131 * nGrey13;
456*cdf0e10cSrcweir                         nSum2 += nMask132 * nGrey13;
457*cdf0e10cSrcweir 
458*cdf0e10cSrcweir                         nSum1 += nMask211 * nGrey21;
459*cdf0e10cSrcweir                         nSum2 += nMask212 * nGrey21;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir                         nSum1 += nMask221 * nGrey22;
462*cdf0e10cSrcweir                         nSum2 += nMask222 * nGrey22;
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir                         nSum1 += nMask231 * nGrey23;
465*cdf0e10cSrcweir                         nSum2 += nMask232 * nGrey23;
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir                         nSum1 += nMask311 * nGrey31;
468*cdf0e10cSrcweir                         nSum2 += nMask312 * nGrey31;
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir                         nSum1 += nMask321 * nGrey32;
471*cdf0e10cSrcweir                         nSum2 += nMask322 * nGrey32;
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir                         nSum1 += nMask331 * nGrey33;
474*cdf0e10cSrcweir                         nSum2 += nMask332 * nGrey33;
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir                         nSum1 = (long) sqrt( (double)( nSum1 * nSum1 + nSum2 * nSum2 ) );
477*cdf0e10cSrcweir                         aGrey.SetIndex( ~(sal_uInt8) VOS_BOUND( nSum1, 0, 255 ) );
478*cdf0e10cSrcweir                         pWriteAcc->SetPixel( nY, nX, aGrey );
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir                         if( nX < ( nWidth - 1 ) )
481*cdf0e10cSrcweir                         {
482*cdf0e10cSrcweir                             const long nNextX = pHMap[ nX + 3 ];
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir                             nGrey11 = nGrey12; nGrey12 = nGrey13; nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], nNextX ).GetIndex();
485*cdf0e10cSrcweir                             nGrey21 = nGrey22; nGrey22 = nGrey23; nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], nNextX ).GetIndex();
486*cdf0e10cSrcweir                             nGrey31 = nGrey32; nGrey32 = nGrey33; nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], nNextX ).GetIndex();
487*cdf0e10cSrcweir                         }
488*cdf0e10cSrcweir                     }
489*cdf0e10cSrcweir                 }
490*cdf0e10cSrcweir 
491*cdf0e10cSrcweir                 delete[] pHMap;
492*cdf0e10cSrcweir                 delete[] pVMap;
493*cdf0e10cSrcweir                 aNewBmp.ReleaseAccess( pWriteAcc );
494*cdf0e10cSrcweir                 bRet = sal_True;
495*cdf0e10cSrcweir             }
496*cdf0e10cSrcweir 
497*cdf0e10cSrcweir             ReleaseAccess( pReadAcc );
498*cdf0e10cSrcweir 
499*cdf0e10cSrcweir             if( bRet )
500*cdf0e10cSrcweir             {
501*cdf0e10cSrcweir                 const MapMode   aMap( maPrefMapMode );
502*cdf0e10cSrcweir                 const Size      aSize( maPrefSize );
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir                 *this = aNewBmp;
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir                 maPrefMapMode = aMap;
507*cdf0e10cSrcweir                 maPrefSize = aSize;
508*cdf0e10cSrcweir             }
509*cdf0e10cSrcweir         }
510*cdf0e10cSrcweir     }
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir     return bRet;
513*cdf0e10cSrcweir }
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir // -----------------------------------------------------------------------------
516*cdf0e10cSrcweir 
517*cdf0e10cSrcweir sal_Bool Bitmap::ImplEmbossGrey( const BmpFilterParam* pFilterParam, const Link* /*pProgress*/ )
518*cdf0e10cSrcweir {
519*cdf0e10cSrcweir     sal_Bool bRet = ImplMakeGreyscales( 256 );
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir     if( bRet )
522*cdf0e10cSrcweir     {
523*cdf0e10cSrcweir         bRet = sal_False;
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir         BitmapReadAccess* pReadAcc = AcquireReadAccess();
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir         if( pReadAcc )
528*cdf0e10cSrcweir         {
529*cdf0e10cSrcweir             Bitmap              aNewBmp( GetSizePixel(), 8, &pReadAcc->GetPalette() );
530*cdf0e10cSrcweir             BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir             if( pWriteAcc )
533*cdf0e10cSrcweir             {
534*cdf0e10cSrcweir                 BitmapColor aGrey( (sal_uInt8) 0 );
535*cdf0e10cSrcweir                 const long  nWidth = pWriteAcc->Width();
536*cdf0e10cSrcweir                 const long  nHeight = pWriteAcc->Height();
537*cdf0e10cSrcweir                 long        nGrey11, nGrey12, nGrey13;
538*cdf0e10cSrcweir                 long        nGrey21, nGrey22, nGrey23;
539*cdf0e10cSrcweir                 long        nGrey31, nGrey32, nGrey33;
540*cdf0e10cSrcweir                 double      fAzim = ( ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_EMBOSS_GREY ) ?
541*cdf0e10cSrcweir                                       ( pFilterParam->maEmbossAngles.mnAzimuthAngle100 * 0.01 ) : 0.0 ) * F_PI180;
542*cdf0e10cSrcweir                 double      fElev = ( ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_EMBOSS_GREY ) ?
543*cdf0e10cSrcweir                                       ( pFilterParam->maEmbossAngles.mnElevationAngle100 * 0.01 ) : 90.0 ) * F_PI180;
544*cdf0e10cSrcweir                 long*       pHMap = new long[ nWidth + 2 ];
545*cdf0e10cSrcweir                 long*       pVMap = new long[ nHeight + 2 ];
546*cdf0e10cSrcweir                 long        nX, nY, nNx, nNy, nDotL;
547*cdf0e10cSrcweir                 const long  nLx = FRound( cos( fAzim ) * cos( fElev ) * 255.0 );
548*cdf0e10cSrcweir                 const long  nLy = FRound( sin( fAzim ) * cos( fElev ) * 255.0 );
549*cdf0e10cSrcweir                 const long  nLz = FRound( sin( fElev ) * 255.0 );
550*cdf0e10cSrcweir                 const long  nZ2 = ( ( 6 * 255 ) / 4 ) * ( ( 6 * 255 ) / 4 );
551*cdf0e10cSrcweir                 const long  nNzLz = ( ( 6 * 255 ) / 4 ) * nLz;
552*cdf0e10cSrcweir                 const sal_uInt8 cLz = (sal_uInt8) VOS_BOUND( nLz, 0, 255 );
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir                 // fill mapping tables
555*cdf0e10cSrcweir                 pHMap[ 0 ] = 0;
556*cdf0e10cSrcweir                 for( nX = 1; nX <= nWidth; nX++ )
557*cdf0e10cSrcweir                     pHMap[ nX ] = nX - 1;
558*cdf0e10cSrcweir                 pHMap[ nWidth + 1 ] = nWidth - 1;
559*cdf0e10cSrcweir 
560*cdf0e10cSrcweir                 pVMap[ 0 ] = 0;
561*cdf0e10cSrcweir                 for( nY = 1; nY <= nHeight; nY++ )
562*cdf0e10cSrcweir                     pVMap[ nY ] = nY - 1;
563*cdf0e10cSrcweir                 pVMap[ nHeight + 1 ] = nHeight - 1;
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir                 for( nY = 0; nY < nHeight ; nY++ )
566*cdf0e10cSrcweir                 {
567*cdf0e10cSrcweir                     nGrey11 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 0 ] ).GetIndex();
568*cdf0e10cSrcweir                     nGrey12 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 1 ] ).GetIndex();
569*cdf0e10cSrcweir                     nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], pHMap[ 2 ] ).GetIndex();
570*cdf0e10cSrcweir                     nGrey21 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 0 ] ).GetIndex();
571*cdf0e10cSrcweir                     nGrey22 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 1 ] ).GetIndex();
572*cdf0e10cSrcweir                     nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], pHMap[ 2 ] ).GetIndex();
573*cdf0e10cSrcweir                     nGrey31 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 0 ] ).GetIndex();
574*cdf0e10cSrcweir                     nGrey32 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 1 ] ).GetIndex();
575*cdf0e10cSrcweir                     nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], pHMap[ 2 ] ).GetIndex();
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir                     for( nX = 0; nX < nWidth; nX++ )
578*cdf0e10cSrcweir                     {
579*cdf0e10cSrcweir                         nNx = nGrey11 + nGrey21 + nGrey31 - nGrey13 - nGrey23 - nGrey33;
580*cdf0e10cSrcweir                         nNy = nGrey31 + nGrey32 + nGrey33 - nGrey11 - nGrey12 - nGrey13;
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir                         if( !nNx && !nNy )
583*cdf0e10cSrcweir                             aGrey.SetIndex( cLz );
584*cdf0e10cSrcweir                         else if( ( nDotL = nNx * nLx + nNy * nLy +nNzLz ) < 0 )
585*cdf0e10cSrcweir                             aGrey.SetIndex( 0 );
586*cdf0e10cSrcweir                         else
587*cdf0e10cSrcweir                         {
588*cdf0e10cSrcweir                             const double fGrey = nDotL / sqrt( (double)(nNx * nNx + nNy * nNy + nZ2) );
589*cdf0e10cSrcweir                             aGrey.SetIndex( (sal_uInt8) VOS_BOUND( fGrey, 0, 255 ) );
590*cdf0e10cSrcweir                         }
591*cdf0e10cSrcweir 
592*cdf0e10cSrcweir                         pWriteAcc->SetPixel( nY, nX, aGrey );
593*cdf0e10cSrcweir 
594*cdf0e10cSrcweir                         if( nX < ( nWidth - 1 ) )
595*cdf0e10cSrcweir                         {
596*cdf0e10cSrcweir                             const long nNextX = pHMap[ nX + 3 ];
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir                             nGrey11 = nGrey12; nGrey12 = nGrey13; nGrey13 = pReadAcc->GetPixel( pVMap[ nY ], nNextX ).GetIndex();
599*cdf0e10cSrcweir                             nGrey21 = nGrey22; nGrey22 = nGrey23; nGrey23 = pReadAcc->GetPixel( pVMap[ nY + 1 ], nNextX ).GetIndex();
600*cdf0e10cSrcweir                             nGrey31 = nGrey32; nGrey32 = nGrey33; nGrey33 = pReadAcc->GetPixel( pVMap[ nY + 2 ], nNextX ).GetIndex();
601*cdf0e10cSrcweir                         }
602*cdf0e10cSrcweir                     }
603*cdf0e10cSrcweir                 }
604*cdf0e10cSrcweir 
605*cdf0e10cSrcweir                 delete[] pHMap;
606*cdf0e10cSrcweir                 delete[] pVMap;
607*cdf0e10cSrcweir                 aNewBmp.ReleaseAccess( pWriteAcc );
608*cdf0e10cSrcweir                 bRet = sal_True;
609*cdf0e10cSrcweir             }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir             ReleaseAccess( pReadAcc );
612*cdf0e10cSrcweir 
613*cdf0e10cSrcweir             if( bRet )
614*cdf0e10cSrcweir             {
615*cdf0e10cSrcweir                 const MapMode   aMap( maPrefMapMode );
616*cdf0e10cSrcweir                 const Size      aSize( maPrefSize );
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir                 *this = aNewBmp;
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir                 maPrefMapMode = aMap;
621*cdf0e10cSrcweir                 maPrefSize = aSize;
622*cdf0e10cSrcweir             }
623*cdf0e10cSrcweir         }
624*cdf0e10cSrcweir     }
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir     return bRet;
627*cdf0e10cSrcweir }
628*cdf0e10cSrcweir 
629*cdf0e10cSrcweir // -----------------------------------------------------------------------------
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir sal_Bool Bitmap::ImplSolarize( const BmpFilterParam* pFilterParam, const Link* /*pProgress*/ )
632*cdf0e10cSrcweir {
633*cdf0e10cSrcweir     sal_Bool                bRet = sal_False;
634*cdf0e10cSrcweir     BitmapWriteAccess*  pWriteAcc = AcquireWriteAccess();
635*cdf0e10cSrcweir 
636*cdf0e10cSrcweir     if( pWriteAcc )
637*cdf0e10cSrcweir     {
638*cdf0e10cSrcweir         const sal_uInt8 cThreshold = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_SOLARIZE ) ?
639*cdf0e10cSrcweir                                 pFilterParam->mcSolarGreyThreshold : 128;
640*cdf0e10cSrcweir 
641*cdf0e10cSrcweir         if( pWriteAcc->HasPalette() )
642*cdf0e10cSrcweir         {
643*cdf0e10cSrcweir             const BitmapPalette& rPal = pWriteAcc->GetPalette();
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir             for( sal_uInt16 i = 0, nCount = rPal.GetEntryCount(); i < nCount; i++ )
646*cdf0e10cSrcweir             {
647*cdf0e10cSrcweir                 if( rPal[ i ].GetLuminance() >= cThreshold )
648*cdf0e10cSrcweir                 {
649*cdf0e10cSrcweir                     BitmapColor aCol( rPal[ i ] );
650*cdf0e10cSrcweir                     pWriteAcc->SetPaletteColor( i, aCol.Invert() );
651*cdf0e10cSrcweir                 }
652*cdf0e10cSrcweir             }
653*cdf0e10cSrcweir         }
654*cdf0e10cSrcweir         else
655*cdf0e10cSrcweir         {
656*cdf0e10cSrcweir             BitmapColor aCol;
657*cdf0e10cSrcweir             const long  nWidth = pWriteAcc->Width();
658*cdf0e10cSrcweir             const long  nHeight = pWriteAcc->Height();
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir             for( long nY = 0; nY < nHeight ; nY++ )
661*cdf0e10cSrcweir             {
662*cdf0e10cSrcweir                 for( long nX = 0; nX < nWidth; nX++ )
663*cdf0e10cSrcweir                 {
664*cdf0e10cSrcweir                     aCol = pWriteAcc->GetPixel( nY, nX );
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir                     if( aCol.GetLuminance() >= cThreshold )
667*cdf0e10cSrcweir                         pWriteAcc->SetPixel( nY, nX, aCol.Invert() );
668*cdf0e10cSrcweir                 }
669*cdf0e10cSrcweir             }
670*cdf0e10cSrcweir         }
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir         ReleaseAccess( pWriteAcc );
673*cdf0e10cSrcweir         bRet = sal_True;
674*cdf0e10cSrcweir     }
675*cdf0e10cSrcweir 
676*cdf0e10cSrcweir     return bRet;
677*cdf0e10cSrcweir }
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir // -----------------------------------------------------------------------------
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir sal_Bool Bitmap::ImplSepia( const BmpFilterParam* pFilterParam, const Link* /*pProgress*/ )
682*cdf0e10cSrcweir {
683*cdf0e10cSrcweir     BitmapReadAccess*   pReadAcc = AcquireReadAccess();
684*cdf0e10cSrcweir     sal_Bool                bRet = sal_False;
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir     if( pReadAcc )
687*cdf0e10cSrcweir     {
688*cdf0e10cSrcweir         long            nSepiaPercent = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_SEPIA ) ?
689*cdf0e10cSrcweir                                         pFilterParam->mcSolarGreyThreshold : 10;
690*cdf0e10cSrcweir         const long      nSepia = 10000 - 100 * VOS_BOUND( nSepiaPercent, 0, 100 );
691*cdf0e10cSrcweir         BitmapPalette   aSepiaPal( 256 );
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir         DBG_ASSERT( nSepiaPercent <= 100, "Bitmap::ImplSepia(): sepia value out of range; defaulting to 100%" );
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir         for( sal_uInt16 i = 0; i < 256; i++ )
696*cdf0e10cSrcweir         {
697*cdf0e10cSrcweir             BitmapColor&    rCol = aSepiaPal[ i ];
698*cdf0e10cSrcweir             const sal_uInt8     cSepiaValue = (sal_uInt8) ( ( nSepia * i ) / 10000 );
699*cdf0e10cSrcweir 
700*cdf0e10cSrcweir             rCol.SetRed( (sal_uInt8) i );
701*cdf0e10cSrcweir             rCol.SetGreen( cSepiaValue );
702*cdf0e10cSrcweir             rCol.SetBlue( cSepiaValue );
703*cdf0e10cSrcweir         }
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir         Bitmap              aNewBmp( GetSizePixel(), 8, &aSepiaPal );
706*cdf0e10cSrcweir         BitmapWriteAccess*  pWriteAcc = aNewBmp.AcquireWriteAccess();
707*cdf0e10cSrcweir 
708*cdf0e10cSrcweir         if( pWriteAcc )
709*cdf0e10cSrcweir         {
710*cdf0e10cSrcweir             BitmapColor aCol( (sal_uInt8) 0 );
711*cdf0e10cSrcweir             const long  nWidth = pWriteAcc->Width();
712*cdf0e10cSrcweir             const long  nHeight = pWriteAcc->Height();
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir             if( pReadAcc->HasPalette() )
715*cdf0e10cSrcweir             {
716*cdf0e10cSrcweir                 for( long nY = 0; nY < nHeight ; nY++ )
717*cdf0e10cSrcweir                 {
718*cdf0e10cSrcweir                     const sal_uInt16    nPalCount = pReadAcc->GetPaletteEntryCount();
719*cdf0e10cSrcweir                     sal_uInt8*          pIndexMap = new sal_uInt8[ nPalCount ];
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir                     for( sal_uInt16 i = 0; i < nPalCount; i++ )
722*cdf0e10cSrcweir                         pIndexMap[ i ] = pReadAcc->GetPaletteColor( i ).GetLuminance();
723*cdf0e10cSrcweir 
724*cdf0e10cSrcweir                     for( long nX = 0; nX < nWidth; nX++ )
725*cdf0e10cSrcweir                     {
726*cdf0e10cSrcweir                         aCol.SetIndex( pIndexMap[ pReadAcc->GetPixel( nY, nX ).GetIndex() ] );
727*cdf0e10cSrcweir                         pWriteAcc->SetPixel( nY, nX, aCol );
728*cdf0e10cSrcweir                     }
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir                     delete[] pIndexMap;
731*cdf0e10cSrcweir                 }
732*cdf0e10cSrcweir             }
733*cdf0e10cSrcweir             else
734*cdf0e10cSrcweir             {
735*cdf0e10cSrcweir                 for( long nY = 0; nY < nHeight ; nY++ )
736*cdf0e10cSrcweir                 {
737*cdf0e10cSrcweir                     for( long nX = 0; nX < nWidth; nX++ )
738*cdf0e10cSrcweir                     {
739*cdf0e10cSrcweir                         aCol.SetIndex( pReadAcc->GetPixel( nY, nX ).GetLuminance() );
740*cdf0e10cSrcweir                         pWriteAcc->SetPixel( nY, nX, aCol );
741*cdf0e10cSrcweir                     }
742*cdf0e10cSrcweir                 }
743*cdf0e10cSrcweir             }
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir             aNewBmp.ReleaseAccess( pWriteAcc );
746*cdf0e10cSrcweir             bRet = sal_True;
747*cdf0e10cSrcweir         }
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir         ReleaseAccess( pReadAcc );
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir         if( bRet )
752*cdf0e10cSrcweir         {
753*cdf0e10cSrcweir             const MapMode   aMap( maPrefMapMode );
754*cdf0e10cSrcweir             const Size      aSize( maPrefSize );
755*cdf0e10cSrcweir 
756*cdf0e10cSrcweir             *this = aNewBmp;
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir             maPrefMapMode = aMap;
759*cdf0e10cSrcweir             maPrefSize = aSize;
760*cdf0e10cSrcweir         }
761*cdf0e10cSrcweir     }
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir     return bRet;
764*cdf0e10cSrcweir }
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir // -----------------------------------------------------------------------------
767*cdf0e10cSrcweir 
768*cdf0e10cSrcweir sal_Bool Bitmap::ImplMosaic( const BmpFilterParam* pFilterParam, const Link* /*pProgress*/ )
769*cdf0e10cSrcweir {
770*cdf0e10cSrcweir     sal_uLong               nTileWidth = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_MOSAIC ) ?
771*cdf0e10cSrcweir                                      pFilterParam->maMosaicTileSize.mnTileWidth : 4;
772*cdf0e10cSrcweir     sal_uLong               nTileHeight = ( pFilterParam && pFilterParam->meFilter == BMP_FILTER_MOSAIC ) ?
773*cdf0e10cSrcweir                                       pFilterParam->maMosaicTileSize.mnTileHeight : 4;
774*cdf0e10cSrcweir     sal_Bool                bRet = sal_False;
775*cdf0e10cSrcweir 
776*cdf0e10cSrcweir     if( !nTileWidth )
777*cdf0e10cSrcweir         nTileWidth = 1;
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir     if( !nTileHeight )
780*cdf0e10cSrcweir         nTileHeight = 1;
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir     if( nTileWidth > 1 || nTileHeight > 1 )
783*cdf0e10cSrcweir     {
784*cdf0e10cSrcweir         Bitmap*             pNewBmp;
785*cdf0e10cSrcweir         BitmapReadAccess*   pReadAcc;
786*cdf0e10cSrcweir         BitmapWriteAccess*  pWriteAcc;
787*cdf0e10cSrcweir 
788*cdf0e10cSrcweir         if( GetBitCount() > 8 )
789*cdf0e10cSrcweir         {
790*cdf0e10cSrcweir             pNewBmp = NULL;
791*cdf0e10cSrcweir             pReadAcc = pWriteAcc = AcquireWriteAccess();
792*cdf0e10cSrcweir         }
793*cdf0e10cSrcweir         else
794*cdf0e10cSrcweir         {
795*cdf0e10cSrcweir             pNewBmp = new Bitmap( GetSizePixel(), 24 );
796*cdf0e10cSrcweir             pReadAcc = AcquireReadAccess();
797*cdf0e10cSrcweir             pWriteAcc = pNewBmp->AcquireWriteAccess();
798*cdf0e10cSrcweir         }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir         if( pReadAcc && pWriteAcc )
801*cdf0e10cSrcweir         {
802*cdf0e10cSrcweir             BitmapColor aCol;
803*cdf0e10cSrcweir             long        nWidth = pReadAcc->Width();
804*cdf0e10cSrcweir             long        nHeight = pReadAcc->Height();
805*cdf0e10cSrcweir             long        nX, nY, nX1, nX2, nY1, nY2, nSumR, nSumG, nSumB;
806*cdf0e10cSrcweir             double      fArea_1;
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir             nY1 = 0; nY2 = nTileHeight - 1;
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir             if( nY2 >= nHeight )
811*cdf0e10cSrcweir                 nY2 = nHeight - 1;
812*cdf0e10cSrcweir 
813*cdf0e10cSrcweir             do
814*cdf0e10cSrcweir             {
815*cdf0e10cSrcweir                 nX1 = 0; nX2 = nTileWidth - 1;
816*cdf0e10cSrcweir 
817*cdf0e10cSrcweir                 if( nX2 >= nWidth )
818*cdf0e10cSrcweir                     nX2 = nWidth - 1;
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir                 fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir                 if( !pNewBmp )
823*cdf0e10cSrcweir                 {
824*cdf0e10cSrcweir                     do
825*cdf0e10cSrcweir                     {
826*cdf0e10cSrcweir                         for( nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++ )
827*cdf0e10cSrcweir                         {
828*cdf0e10cSrcweir                             for( nX = nX1; nX <= nX2; nX++ )
829*cdf0e10cSrcweir                             {
830*cdf0e10cSrcweir                                 aCol = pReadAcc->GetPixel( nY, nX );
831*cdf0e10cSrcweir                                 nSumR += aCol.GetRed();
832*cdf0e10cSrcweir                                 nSumG += aCol.GetGreen();
833*cdf0e10cSrcweir                                 nSumB += aCol.GetBlue();
834*cdf0e10cSrcweir                             }
835*cdf0e10cSrcweir                         }
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir                         aCol.SetRed( (sal_uInt8) ( nSumR * fArea_1 ) );
838*cdf0e10cSrcweir                         aCol.SetGreen( (sal_uInt8) ( nSumG * fArea_1 ) );
839*cdf0e10cSrcweir                         aCol.SetBlue( (sal_uInt8) ( nSumB * fArea_1 ) );
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir                         for( nY = nY1; nY <= nY2; nY++ )
842*cdf0e10cSrcweir                             for( nX = nX1; nX <= nX2; nX++ )
843*cdf0e10cSrcweir                                 pWriteAcc->SetPixel( nY, nX, aCol );
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir                         nX1 += nTileWidth; nX2 += nTileWidth;
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir                         if( nX2 >= nWidth )
848*cdf0e10cSrcweir                         {
849*cdf0e10cSrcweir                             nX2 = nWidth - 1;
850*cdf0e10cSrcweir                             fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
851*cdf0e10cSrcweir                         }
852*cdf0e10cSrcweir                     }
853*cdf0e10cSrcweir                     while( nX1 < nWidth );
854*cdf0e10cSrcweir                 }
855*cdf0e10cSrcweir                 else
856*cdf0e10cSrcweir                 {
857*cdf0e10cSrcweir                     do
858*cdf0e10cSrcweir                     {
859*cdf0e10cSrcweir                         for( nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++ )
860*cdf0e10cSrcweir                         {
861*cdf0e10cSrcweir                             for( nX = nX1; nX <= nX2; nX++ )
862*cdf0e10cSrcweir                             {
863*cdf0e10cSrcweir                                 const BitmapColor& rCol = pReadAcc->GetPaletteColor( (sal_uInt8) pReadAcc->GetPixel( nY, nX ) );
864*cdf0e10cSrcweir                                 nSumR += rCol.GetRed();
865*cdf0e10cSrcweir                                 nSumG += rCol.GetGreen();
866*cdf0e10cSrcweir                                 nSumB += rCol.GetBlue();
867*cdf0e10cSrcweir                             }
868*cdf0e10cSrcweir                         }
869*cdf0e10cSrcweir 
870*cdf0e10cSrcweir                         aCol.SetRed( (sal_uInt8) ( nSumR * fArea_1 ) );
871*cdf0e10cSrcweir                         aCol.SetGreen( (sal_uInt8) ( nSumG * fArea_1 ) );
872*cdf0e10cSrcweir                         aCol.SetBlue( (sal_uInt8) ( nSumB * fArea_1 ) );
873*cdf0e10cSrcweir 
874*cdf0e10cSrcweir                         for( nY = nY1; nY <= nY2; nY++ )
875*cdf0e10cSrcweir                             for( nX = nX1; nX <= nX2; nX++ )
876*cdf0e10cSrcweir                                 pWriteAcc->SetPixel( nY, nX, aCol );
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir                         nX1 += nTileWidth; nX2 += nTileWidth;
879*cdf0e10cSrcweir 
880*cdf0e10cSrcweir                         if( nX2 >= nWidth )
881*cdf0e10cSrcweir                         {
882*cdf0e10cSrcweir                             nX2 = nWidth - 1;
883*cdf0e10cSrcweir                             fArea_1 = 1.0 / ( ( nX2 - nX1 + 1 ) * ( nY2 - nY1 + 1 ) );
884*cdf0e10cSrcweir                         }
885*cdf0e10cSrcweir                     }
886*cdf0e10cSrcweir                     while( nX1 < nWidth );
887*cdf0e10cSrcweir                 }
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir                 nY1 += nTileHeight; nY2 += nTileHeight;
890*cdf0e10cSrcweir 
891*cdf0e10cSrcweir                 if( nY2 >= nHeight )
892*cdf0e10cSrcweir                     nY2 = nHeight - 1;
893*cdf0e10cSrcweir             }
894*cdf0e10cSrcweir             while( nY1 < nHeight );
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir             bRet = sal_True;
897*cdf0e10cSrcweir         }
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir         ReleaseAccess( pReadAcc );
900*cdf0e10cSrcweir 
901*cdf0e10cSrcweir         if( pNewBmp )
902*cdf0e10cSrcweir         {
903*cdf0e10cSrcweir             pNewBmp->ReleaseAccess( pWriteAcc );
904*cdf0e10cSrcweir 
905*cdf0e10cSrcweir             if( bRet )
906*cdf0e10cSrcweir             {
907*cdf0e10cSrcweir                 const MapMode   aMap( maPrefMapMode );
908*cdf0e10cSrcweir                 const Size      aSize( maPrefSize );
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir                 *this = *pNewBmp;
911*cdf0e10cSrcweir 
912*cdf0e10cSrcweir                 maPrefMapMode = aMap;
913*cdf0e10cSrcweir                 maPrefSize = aSize;
914*cdf0e10cSrcweir             }
915*cdf0e10cSrcweir 
916*cdf0e10cSrcweir             delete pNewBmp;
917*cdf0e10cSrcweir         }
918*cdf0e10cSrcweir     }
919*cdf0e10cSrcweir     else
920*cdf0e10cSrcweir         bRet = sal_True;
921*cdf0e10cSrcweir 
922*cdf0e10cSrcweir     return bRet;
923*cdf0e10cSrcweir }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir // -----------------------------------------------------------------------------
926*cdf0e10cSrcweir 
927*cdf0e10cSrcweir struct PopArtEntry
928*cdf0e10cSrcweir {
929*cdf0e10cSrcweir     sal_uInt32  mnIndex;
930*cdf0e10cSrcweir     sal_uInt32  mnCount;
931*cdf0e10cSrcweir };
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir // ------------------------------------------------------------------------
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir extern "C" int __LOADONCALLAPI ImplPopArtCmpFnc( const void* p1, const void* p2 )
936*cdf0e10cSrcweir {
937*cdf0e10cSrcweir     int nRet;
938*cdf0e10cSrcweir 
939*cdf0e10cSrcweir     if( ( (PopArtEntry*) p1 )->mnCount < ( (PopArtEntry*) p2 )->mnCount )
940*cdf0e10cSrcweir         nRet = 1;
941*cdf0e10cSrcweir     else if( ( (PopArtEntry*) p1 )->mnCount == ( (PopArtEntry*) p2 )->mnCount )
942*cdf0e10cSrcweir         nRet = 0;
943*cdf0e10cSrcweir     else
944*cdf0e10cSrcweir         nRet = -1;
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir     return nRet;
947*cdf0e10cSrcweir }
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir // ------------------------------------------------------------------------
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir sal_Bool Bitmap::ImplPopArt( const BmpFilterParam* /*pFilterParam*/, const Link* /*pProgress*/ )
952*cdf0e10cSrcweir {
953*cdf0e10cSrcweir     sal_Bool bRet = ( GetBitCount() > 8 ) ? Convert( BMP_CONVERSION_8BIT_COLORS ) : sal_True;
954*cdf0e10cSrcweir 
955*cdf0e10cSrcweir     if( bRet )
956*cdf0e10cSrcweir     {
957*cdf0e10cSrcweir         bRet = sal_False;
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir         BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
960*cdf0e10cSrcweir 
961*cdf0e10cSrcweir         if( pWriteAcc )
962*cdf0e10cSrcweir         {
963*cdf0e10cSrcweir             const long      nWidth = pWriteAcc->Width();
964*cdf0e10cSrcweir             const long      nHeight = pWriteAcc->Height();
965*cdf0e10cSrcweir             const sal_uLong     nEntryCount = 1 << pWriteAcc->GetBitCount();
966*cdf0e10cSrcweir             sal_uLong           n;
967*cdf0e10cSrcweir             PopArtEntry*    pPopArtTable = new PopArtEntry[ nEntryCount ];
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir             for( n = 0; n < nEntryCount; n++ )
970*cdf0e10cSrcweir             {
971*cdf0e10cSrcweir                 PopArtEntry& rEntry = pPopArtTable[ n ];
972*cdf0e10cSrcweir                 rEntry.mnIndex = (sal_uInt16) n;
973*cdf0e10cSrcweir                 rEntry.mnCount = 0;
974*cdf0e10cSrcweir             }
975*cdf0e10cSrcweir 
976*cdf0e10cSrcweir             // get pixel count for each palette entry
977*cdf0e10cSrcweir             for( long nY = 0; nY < nHeight ; nY++ )
978*cdf0e10cSrcweir                 for( long nX = 0; nX < nWidth; nX++ )
979*cdf0e10cSrcweir                     pPopArtTable[ pWriteAcc->GetPixel( nY, nX ).GetIndex() ].mnCount++;
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir             // sort table
982*cdf0e10cSrcweir             qsort( pPopArtTable, nEntryCount, sizeof( PopArtEntry ), ImplPopArtCmpFnc );
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir             // get last used entry
985*cdf0e10cSrcweir             sal_uLong nFirstEntry;
986*cdf0e10cSrcweir             sal_uLong nLastEntry = 0;
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir             for( n = 0; n < nEntryCount; n++ )
989*cdf0e10cSrcweir                 if( pPopArtTable[ n ].mnCount )
990*cdf0e10cSrcweir                     nLastEntry = n;
991*cdf0e10cSrcweir 
992*cdf0e10cSrcweir             // rotate palette (one entry)
993*cdf0e10cSrcweir             const BitmapColor aFirstCol( pWriteAcc->GetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ 0 ].mnIndex) ) );
994*cdf0e10cSrcweir             for( nFirstEntry = 0; nFirstEntry < nLastEntry; nFirstEntry++ )
995*cdf0e10cSrcweir             {
996*cdf0e10cSrcweir                 pWriteAcc->SetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nFirstEntry ].mnIndex),
997*cdf0e10cSrcweir                                             pWriteAcc->GetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nFirstEntry + 1 ].mnIndex) ) );
998*cdf0e10cSrcweir             }
999*cdf0e10cSrcweir             pWriteAcc->SetPaletteColor( sal::static_int_cast<sal_uInt16>(pPopArtTable[ nLastEntry ].mnIndex), aFirstCol );
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir             // cleanup
1002*cdf0e10cSrcweir             delete[] pPopArtTable;
1003*cdf0e10cSrcweir             ReleaseAccess( pWriteAcc );
1004*cdf0e10cSrcweir             bRet = sal_True;
1005*cdf0e10cSrcweir         }
1006*cdf0e10cSrcweir     }
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir     return bRet;
1009*cdf0e10cSrcweir }
1010