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