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 <rtl/crc.h>
28cdf0e10cSrcweir #include <tools/stream.hxx>
29cdf0e10cSrcweir #include <tools/poly.hxx>
30cdf0e10cSrcweir #include <tools/rc.h>
31cdf0e10cSrcweir
32cdf0e10cSrcweir #include <vcl/salbtype.hxx>
33cdf0e10cSrcweir #include <vcl/bmpacc.hxx>
34cdf0e10cSrcweir #include <vcl/outdev.hxx>
35cdf0e10cSrcweir #include <vcl/bitmap.hxx>
36cdf0e10cSrcweir #include <vcl/bitmapex.hxx>
37cdf0e10cSrcweir #include <vcl/svapp.hxx>
38cdf0e10cSrcweir #include <vcl/image.hxx>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include <impbmp.hxx>
41cdf0e10cSrcweir #include <salbmp.hxx>
42cdf0e10cSrcweir
43cdf0e10cSrcweir // ----------
44cdf0e10cSrcweir // - Bitmap -
45cdf0e10cSrcweir // ----------
46cdf0e10cSrcweir
Bitmap()47cdf0e10cSrcweir Bitmap::Bitmap() :
48cdf0e10cSrcweir mpImpBmp( NULL )
49cdf0e10cSrcweir {
50cdf0e10cSrcweir }
51cdf0e10cSrcweir
52cdf0e10cSrcweir // ------------------------------------------------------------------
53cdf0e10cSrcweir
Bitmap(const ResId & rResId)54cdf0e10cSrcweir Bitmap::Bitmap( const ResId& rResId ) :
55cdf0e10cSrcweir mpImpBmp( NULL )
56cdf0e10cSrcweir {
57cdf0e10cSrcweir const BitmapEx aBmpEx( rResId );
58cdf0e10cSrcweir
59cdf0e10cSrcweir if( !aBmpEx.IsEmpty() )
60cdf0e10cSrcweir *this = aBmpEx.GetBitmap();
61cdf0e10cSrcweir }
62cdf0e10cSrcweir
63cdf0e10cSrcweir // ------------------------------------------------------------------
64cdf0e10cSrcweir
Bitmap(const Bitmap & rBitmap)65cdf0e10cSrcweir Bitmap::Bitmap( const Bitmap& rBitmap ) :
66cdf0e10cSrcweir maPrefMapMode ( rBitmap.maPrefMapMode ),
67cdf0e10cSrcweir maPrefSize ( rBitmap.maPrefSize )
68cdf0e10cSrcweir {
69cdf0e10cSrcweir mpImpBmp = rBitmap.mpImpBmp;
70cdf0e10cSrcweir
71cdf0e10cSrcweir if ( mpImpBmp )
72cdf0e10cSrcweir mpImpBmp->ImplIncRefCount();
73cdf0e10cSrcweir }
74cdf0e10cSrcweir
75cdf0e10cSrcweir // ------------------------------------------------------------------
76cdf0e10cSrcweir
Bitmap(SalBitmap * pSalBitmap)77cdf0e10cSrcweir Bitmap::Bitmap( SalBitmap* pSalBitmap )
78cdf0e10cSrcweir {
79cdf0e10cSrcweir mpImpBmp = new ImpBitmap();
80cdf0e10cSrcweir mpImpBmp->ImplSetSalBitmap( pSalBitmap );
81cdf0e10cSrcweir maPrefMapMode = MapMode( MAP_PIXEL );
82cdf0e10cSrcweir maPrefSize = mpImpBmp->ImplGetSize();
83cdf0e10cSrcweir }
84cdf0e10cSrcweir
85cdf0e10cSrcweir // ------------------------------------------------------------------
86cdf0e10cSrcweir
Bitmap(const Size & rSizePixel,sal_uInt16 nBitCount,const BitmapPalette * pPal)87cdf0e10cSrcweir Bitmap::Bitmap( const Size& rSizePixel, sal_uInt16 nBitCount, const BitmapPalette* pPal )
88cdf0e10cSrcweir {
89cdf0e10cSrcweir if( rSizePixel.Width() && rSizePixel.Height() )
90cdf0e10cSrcweir {
91cdf0e10cSrcweir BitmapPalette aPal;
92cdf0e10cSrcweir BitmapPalette* pRealPal = NULL;
93cdf0e10cSrcweir
94cdf0e10cSrcweir if( nBitCount <= 8 )
95cdf0e10cSrcweir {
96cdf0e10cSrcweir if( !pPal )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir if( 1 == nBitCount )
99cdf0e10cSrcweir {
100cdf0e10cSrcweir aPal.SetEntryCount( 2 );
101cdf0e10cSrcweir aPal[ 0 ] = Color( COL_BLACK );
102cdf0e10cSrcweir aPal[ 1 ] = Color( COL_WHITE );
103cdf0e10cSrcweir }
104cdf0e10cSrcweir else if( ( 4 == nBitCount ) || ( 8 == nBitCount ) )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir aPal.SetEntryCount( 1 << nBitCount );
107cdf0e10cSrcweir aPal[ 0 ] = Color( COL_BLACK );
108cdf0e10cSrcweir aPal[ 1 ] = Color( COL_BLUE );
109cdf0e10cSrcweir aPal[ 2 ] = Color( COL_GREEN );
110cdf0e10cSrcweir aPal[ 3 ] = Color( COL_CYAN );
111cdf0e10cSrcweir aPal[ 4 ] = Color( COL_RED );
112cdf0e10cSrcweir aPal[ 5 ] = Color( COL_MAGENTA );
113cdf0e10cSrcweir aPal[ 6 ] = Color( COL_BROWN );
114cdf0e10cSrcweir aPal[ 7 ] = Color( COL_GRAY );
115cdf0e10cSrcweir aPal[ 8 ] = Color( COL_LIGHTGRAY );
116cdf0e10cSrcweir aPal[ 9 ] = Color( COL_LIGHTBLUE );
117cdf0e10cSrcweir aPal[ 10 ] = Color( COL_LIGHTGREEN );
118cdf0e10cSrcweir aPal[ 11 ] = Color( COL_LIGHTCYAN );
119cdf0e10cSrcweir aPal[ 12 ] = Color( COL_LIGHTRED );
120cdf0e10cSrcweir aPal[ 13 ] = Color( COL_LIGHTMAGENTA );
121cdf0e10cSrcweir aPal[ 14 ] = Color( COL_YELLOW );
122cdf0e10cSrcweir aPal[ 15 ] = Color( COL_WHITE );
123cdf0e10cSrcweir
124cdf0e10cSrcweir // Dither-Palette erzeugen
125cdf0e10cSrcweir if( 8 == nBitCount )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir sal_uInt16 nActCol = 16;
128cdf0e10cSrcweir
129cdf0e10cSrcweir for( sal_uInt16 nB = 0; nB < 256; nB += 51 )
130cdf0e10cSrcweir for( sal_uInt16 nG = 0; nG < 256; nG += 51 )
131cdf0e10cSrcweir for( sal_uInt16 nR = 0; nR < 256; nR += 51 )
132cdf0e10cSrcweir aPal[ nActCol++ ] = BitmapColor( (sal_uInt8) nR, (sal_uInt8) nG, (sal_uInt8) nB );
133cdf0e10cSrcweir
134cdf0e10cSrcweir // Standard-Office-Farbe setzen
135cdf0e10cSrcweir aPal[ nActCol++ ] = BitmapColor( 0, 184, 255 );
136cdf0e10cSrcweir }
137cdf0e10cSrcweir }
138cdf0e10cSrcweir }
139cdf0e10cSrcweir else
140cdf0e10cSrcweir pRealPal = (BitmapPalette*) pPal;
141cdf0e10cSrcweir }
142cdf0e10cSrcweir
143cdf0e10cSrcweir mpImpBmp = new ImpBitmap;
144cdf0e10cSrcweir mpImpBmp->ImplCreate( rSizePixel, nBitCount, pRealPal ? *pRealPal : aPal );
145cdf0e10cSrcweir }
146cdf0e10cSrcweir else
147cdf0e10cSrcweir mpImpBmp = NULL;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir
150cdf0e10cSrcweir // ------------------------------------------------------------------
151cdf0e10cSrcweir
~Bitmap()152cdf0e10cSrcweir Bitmap::~Bitmap()
153cdf0e10cSrcweir {
154cdf0e10cSrcweir ImplReleaseRef();
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
157cdf0e10cSrcweir // ------------------------------------------------------------------
158cdf0e10cSrcweir
GetGreyPalette(int nEntries)159cdf0e10cSrcweir const BitmapPalette& Bitmap::GetGreyPalette( int nEntries )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir static BitmapPalette aGreyPalette2;
162cdf0e10cSrcweir static BitmapPalette aGreyPalette4;
163cdf0e10cSrcweir static BitmapPalette aGreyPalette16;
164cdf0e10cSrcweir static BitmapPalette aGreyPalette256;
165cdf0e10cSrcweir
166cdf0e10cSrcweir // create greyscale palette with 2, 4, 16 or 256 entries
167cdf0e10cSrcweir if( 2 == nEntries || 4 == nEntries || 16 == nEntries || 256 == nEntries )
168cdf0e10cSrcweir {
169cdf0e10cSrcweir if( 2 == nEntries )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir if( !aGreyPalette2.GetEntryCount() )
172cdf0e10cSrcweir {
173cdf0e10cSrcweir aGreyPalette2.SetEntryCount( 2 );
174cdf0e10cSrcweir aGreyPalette2[ 0 ] = BitmapColor( 0, 0, 0 );
175cdf0e10cSrcweir aGreyPalette2[ 1 ] = BitmapColor( 255, 255, 255 );
176cdf0e10cSrcweir }
177cdf0e10cSrcweir
178cdf0e10cSrcweir return aGreyPalette2;
179cdf0e10cSrcweir }
180cdf0e10cSrcweir else if( 4 == nEntries )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir if( !aGreyPalette4.GetEntryCount() )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir aGreyPalette4.SetEntryCount( 4 );
185cdf0e10cSrcweir aGreyPalette4[ 0 ] = BitmapColor( 0, 0, 0 );
186cdf0e10cSrcweir aGreyPalette4[ 1 ] = BitmapColor( 85, 85, 85 );
187cdf0e10cSrcweir aGreyPalette4[ 2 ] = BitmapColor( 170, 170, 170 );
188cdf0e10cSrcweir aGreyPalette4[ 3 ] = BitmapColor( 255, 255, 255 );
189cdf0e10cSrcweir }
190cdf0e10cSrcweir
191cdf0e10cSrcweir return aGreyPalette4;
192cdf0e10cSrcweir }
193cdf0e10cSrcweir else if( 16 == nEntries )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir if( !aGreyPalette16.GetEntryCount() )
196cdf0e10cSrcweir {
197cdf0e10cSrcweir sal_uInt8 cGrey = 0, cGreyInc = 17;
198cdf0e10cSrcweir
199cdf0e10cSrcweir aGreyPalette16.SetEntryCount( 16 );
200cdf0e10cSrcweir
201cdf0e10cSrcweir for( sal_uInt16 i = 0; i < 16; i++, cGrey = sal::static_int_cast<sal_uInt8>(cGrey + cGreyInc) )
202cdf0e10cSrcweir aGreyPalette16[ i ] = BitmapColor( cGrey, cGrey, cGrey );
203cdf0e10cSrcweir }
204cdf0e10cSrcweir
205cdf0e10cSrcweir return aGreyPalette16;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir else
208cdf0e10cSrcweir {
209cdf0e10cSrcweir if( !aGreyPalette256.GetEntryCount() )
210cdf0e10cSrcweir {
211cdf0e10cSrcweir aGreyPalette256.SetEntryCount( 256 );
212cdf0e10cSrcweir
213cdf0e10cSrcweir for( sal_uInt16 i = 0; i < 256; i++ )
214cdf0e10cSrcweir aGreyPalette256[ i ] = BitmapColor( (sal_uInt8) i, (sal_uInt8) i, (sal_uInt8) i );
215cdf0e10cSrcweir }
216cdf0e10cSrcweir
217cdf0e10cSrcweir return aGreyPalette256;
218cdf0e10cSrcweir }
219cdf0e10cSrcweir }
220cdf0e10cSrcweir else
221cdf0e10cSrcweir {
222cdf0e10cSrcweir DBG_ERROR( "Bitmap::GetGreyPalette: invalid entry count (2/4/16/256 allowed)" );
223cdf0e10cSrcweir return aGreyPalette2;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir // ------------------------------------------------------------------
228cdf0e10cSrcweir
IsGreyPalette() const229cdf0e10cSrcweir bool BitmapPalette::IsGreyPalette() const
230cdf0e10cSrcweir {
231cdf0e10cSrcweir // TODO: add an IsGreyPalette flag to BitmapPalette
232cdf0e10cSrcweir // TODO: unless this causes problems binary compatibility
233cdf0e10cSrcweir const int nEntryCount = GetEntryCount();
234cdf0e10cSrcweir if( !nEntryCount ) // NOTE: an empty palette means 1:1 mapping
235cdf0e10cSrcweir return true;
236cdf0e10cSrcweir // see above: only certain entry values will result in a valid call to GetGreyPalette
237cdf0e10cSrcweir if( nEntryCount == 2 || nEntryCount == 4 || nEntryCount == 16 || nEntryCount == 256 )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir const BitmapPalette& rGreyPalette = Bitmap::GetGreyPalette( nEntryCount );
240cdf0e10cSrcweir if( rGreyPalette == *this )
241cdf0e10cSrcweir return true;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir // TODO: is it worth to compare the entries?
244cdf0e10cSrcweir return false;
245cdf0e10cSrcweir }
246cdf0e10cSrcweir
247cdf0e10cSrcweir // ------------------------------------------------------------------
248cdf0e10cSrcweir
operator =(const Bitmap & rBitmap)249cdf0e10cSrcweir Bitmap& Bitmap::operator=( const Bitmap& rBitmap )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir maPrefSize = rBitmap.maPrefSize;
252cdf0e10cSrcweir maPrefMapMode = rBitmap.maPrefMapMode;
253cdf0e10cSrcweir
254cdf0e10cSrcweir if ( rBitmap.mpImpBmp )
255cdf0e10cSrcweir rBitmap.mpImpBmp->ImplIncRefCount();
256cdf0e10cSrcweir
257cdf0e10cSrcweir ImplReleaseRef();
258cdf0e10cSrcweir mpImpBmp = rBitmap.mpImpBmp;
259cdf0e10cSrcweir
260cdf0e10cSrcweir return *this;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
263cdf0e10cSrcweir // ------------------------------------------------------------------
264cdf0e10cSrcweir
IsEqual(const Bitmap & rBmp) const265cdf0e10cSrcweir sal_Bool Bitmap::IsEqual( const Bitmap& rBmp ) const
266cdf0e10cSrcweir {
267cdf0e10cSrcweir return( IsSameInstance( rBmp ) ||
268cdf0e10cSrcweir ( rBmp.GetSizePixel() == GetSizePixel() &&
269cdf0e10cSrcweir rBmp.GetBitCount() == GetBitCount() &&
270cdf0e10cSrcweir rBmp.GetChecksum() == GetChecksum() ) );
271cdf0e10cSrcweir }
272cdf0e10cSrcweir
273cdf0e10cSrcweir // ------------------------------------------------------------------
274cdf0e10cSrcweir
SetEmpty()275cdf0e10cSrcweir void Bitmap::SetEmpty()
276cdf0e10cSrcweir {
277cdf0e10cSrcweir maPrefMapMode = MapMode();
278cdf0e10cSrcweir maPrefSize = Size();
279cdf0e10cSrcweir
280cdf0e10cSrcweir ImplReleaseRef();
281cdf0e10cSrcweir mpImpBmp = NULL;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir
284cdf0e10cSrcweir // ------------------------------------------------------------------
285cdf0e10cSrcweir
GetSizePixel() const286cdf0e10cSrcweir Size Bitmap::GetSizePixel() const
287cdf0e10cSrcweir {
288cdf0e10cSrcweir return( mpImpBmp ? mpImpBmp->ImplGetSize() : Size() );
289cdf0e10cSrcweir }
290cdf0e10cSrcweir // ------------------------------------------------------------------
291cdf0e10cSrcweir
SetSizePixel(const Size & rNewSize,sal_uInt32 nScaleFlag)292*54628ca4SArmin Le Grand void Bitmap::SetSizePixel( const Size& rNewSize, sal_uInt32 nScaleFlag )
293cdf0e10cSrcweir {
294*54628ca4SArmin Le Grand if(GetSizePixel() != rNewSize)
295*54628ca4SArmin Le Grand {
296*54628ca4SArmin Le Grand Scale( rNewSize, nScaleFlag );
297*54628ca4SArmin Le Grand }
298cdf0e10cSrcweir }
299cdf0e10cSrcweir
300cdf0e10cSrcweir // ------------------------------------------------------------------
301cdf0e10cSrcweir
GetSourceSizePixel() const302cdf0e10cSrcweir Size Bitmap::GetSourceSizePixel() const
303cdf0e10cSrcweir {
304cdf0e10cSrcweir return( mpImpBmp ? mpImpBmp->ImplGetSourceSize() : Size() );
305cdf0e10cSrcweir }
306cdf0e10cSrcweir
307cdf0e10cSrcweir // ------------------------------------------------------------------
308cdf0e10cSrcweir
SetSourceSizePixel(const Size & rSize)309cdf0e10cSrcweir void Bitmap::SetSourceSizePixel( const Size& rSize)
310cdf0e10cSrcweir {
311cdf0e10cSrcweir if( mpImpBmp )
312cdf0e10cSrcweir mpImpBmp->ImplSetSourceSize( rSize);
313cdf0e10cSrcweir }
314cdf0e10cSrcweir
315cdf0e10cSrcweir // ------------------------------------------------------------------
316cdf0e10cSrcweir
GetBitCount() const317cdf0e10cSrcweir sal_uInt16 Bitmap::GetBitCount() const
318cdf0e10cSrcweir {
319cdf0e10cSrcweir return( mpImpBmp ? mpImpBmp->ImplGetBitCount() : 0 );
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
322cdf0e10cSrcweir // ------------------------------------------------------------------
323cdf0e10cSrcweir
HasGreyPalette() const324cdf0e10cSrcweir sal_Bool Bitmap::HasGreyPalette() const
325cdf0e10cSrcweir {
326cdf0e10cSrcweir const sal_uInt16 nBitCount = GetBitCount();
327cdf0e10cSrcweir sal_Bool bRet = sal_False;
328cdf0e10cSrcweir
329cdf0e10cSrcweir if( 1 == nBitCount )
330cdf0e10cSrcweir {
331cdf0e10cSrcweir BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
332cdf0e10cSrcweir
333cdf0e10cSrcweir if( pRAcc )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir const BitmapColor& rCol0( pRAcc->GetPaletteColor( 0 ) );
336cdf0e10cSrcweir const BitmapColor& rCol1( pRAcc->GetPaletteColor( 1 ) );
337cdf0e10cSrcweir if( rCol0.GetRed() == rCol0.GetGreen() && rCol0.GetRed() == rCol0.GetBlue() &&
338cdf0e10cSrcweir rCol1.GetRed() == rCol1.GetGreen() && rCol1.GetRed() == rCol1.GetBlue() )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir bRet = sal_True;
341cdf0e10cSrcweir }
342cdf0e10cSrcweir ( (Bitmap*) this )->ReleaseAccess( pRAcc );
343cdf0e10cSrcweir }
344cdf0e10cSrcweir else
345cdf0e10cSrcweir bRet = sal_True;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir else if( 4 == nBitCount || 8 == nBitCount )
348cdf0e10cSrcweir {
349cdf0e10cSrcweir BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
350cdf0e10cSrcweir
351cdf0e10cSrcweir if( pRAcc )
352cdf0e10cSrcweir {
353cdf0e10cSrcweir if( pRAcc->HasPalette() && ( (BitmapPalette&) pRAcc->GetPalette() == GetGreyPalette( 1 << nBitCount ) ) )
354cdf0e10cSrcweir bRet = sal_True;
355cdf0e10cSrcweir
356cdf0e10cSrcweir ( (Bitmap*) this )->ReleaseAccess( pRAcc );
357cdf0e10cSrcweir }
358cdf0e10cSrcweir }
359cdf0e10cSrcweir
360cdf0e10cSrcweir return bRet;
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
363cdf0e10cSrcweir // ------------------------------------------------------------------
364cdf0e10cSrcweir
GetChecksum() const365cdf0e10cSrcweir sal_uLong Bitmap::GetChecksum() const
366cdf0e10cSrcweir {
367cdf0e10cSrcweir sal_uLong nRet = 0UL;
368cdf0e10cSrcweir
369cdf0e10cSrcweir if( mpImpBmp )
370cdf0e10cSrcweir {
371cdf0e10cSrcweir nRet = mpImpBmp->ImplGetChecksum();
372cdf0e10cSrcweir
373cdf0e10cSrcweir if( !nRet )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir BitmapReadAccess* pRAcc = ( (Bitmap*) this )->AcquireReadAccess();
376cdf0e10cSrcweir
377cdf0e10cSrcweir if( pRAcc && pRAcc->Width() && pRAcc->Height() )
378cdf0e10cSrcweir {
379cdf0e10cSrcweir sal_uInt32 nCrc = 0;
380cdf0e10cSrcweir SVBT32 aBT32;
381cdf0e10cSrcweir
382cdf0e10cSrcweir pRAcc->ImplZeroInitUnusedBits();
383cdf0e10cSrcweir
384cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->Width(), aBT32 );
385cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
386cdf0e10cSrcweir
387cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->Height(), aBT32 );
388cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
389cdf0e10cSrcweir
390cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->GetBitCount(), aBT32 );
391cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
392cdf0e10cSrcweir
393cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->GetColorMask().GetRedMask(), aBT32 );
394cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
395cdf0e10cSrcweir
396cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->GetColorMask().GetGreenMask(), aBT32 );
397cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
398cdf0e10cSrcweir
399cdf0e10cSrcweir UInt32ToSVBT32( pRAcc->GetColorMask().GetBlueMask(), aBT32 );
400cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 );
401cdf0e10cSrcweir
402cdf0e10cSrcweir if( pRAcc->HasPalette() )
403cdf0e10cSrcweir {
404cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, pRAcc->GetPalette().ImplGetColorBuffer(),
405cdf0e10cSrcweir pRAcc->GetPaletteEntryCount() * sizeof( BitmapColor ) );
406cdf0e10cSrcweir }
407cdf0e10cSrcweir
408cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, pRAcc->GetBuffer(), pRAcc->GetScanlineSize() * pRAcc->Height() );
409cdf0e10cSrcweir
410cdf0e10cSrcweir mpImpBmp->ImplSetChecksum( nRet = nCrc );
411cdf0e10cSrcweir }
412cdf0e10cSrcweir
413cdf0e10cSrcweir if (pRAcc) ( (Bitmap*) this )->ReleaseAccess( pRAcc );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir }
416cdf0e10cSrcweir
417cdf0e10cSrcweir return nRet;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir
420cdf0e10cSrcweir // ------------------------------------------------------------------
421cdf0e10cSrcweir
ImplReleaseRef()422cdf0e10cSrcweir void Bitmap::ImplReleaseRef()
423cdf0e10cSrcweir {
424cdf0e10cSrcweir if( mpImpBmp )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir if( mpImpBmp->ImplGetRefCount() > 1UL )
427cdf0e10cSrcweir mpImpBmp->ImplDecRefCount();
428cdf0e10cSrcweir else
429cdf0e10cSrcweir {
430cdf0e10cSrcweir delete mpImpBmp;
431cdf0e10cSrcweir mpImpBmp = NULL;
432cdf0e10cSrcweir }
433cdf0e10cSrcweir }
434cdf0e10cSrcweir }
435cdf0e10cSrcweir
436cdf0e10cSrcweir // ------------------------------------------------------------------
437cdf0e10cSrcweir
ImplMakeUnique()438cdf0e10cSrcweir void Bitmap::ImplMakeUnique()
439cdf0e10cSrcweir {
440cdf0e10cSrcweir if( mpImpBmp && mpImpBmp->ImplGetRefCount() > 1UL )
441cdf0e10cSrcweir {
442cdf0e10cSrcweir ImpBitmap* pOldImpBmp = mpImpBmp;
443cdf0e10cSrcweir
444cdf0e10cSrcweir pOldImpBmp->ImplDecRefCount();
445cdf0e10cSrcweir
446cdf0e10cSrcweir mpImpBmp = new ImpBitmap;
447cdf0e10cSrcweir mpImpBmp->ImplCreate( *pOldImpBmp );
448cdf0e10cSrcweir }
449cdf0e10cSrcweir }
450cdf0e10cSrcweir
451cdf0e10cSrcweir // ------------------------------------------------------------------
452cdf0e10cSrcweir
ImplAssignWithSize(const Bitmap & rBitmap)453cdf0e10cSrcweir void Bitmap::ImplAssignWithSize( const Bitmap& rBitmap )
454cdf0e10cSrcweir {
455cdf0e10cSrcweir const Size aOldSizePix( GetSizePixel() );
456cdf0e10cSrcweir const Size aNewSizePix( rBitmap.GetSizePixel() );
457cdf0e10cSrcweir const MapMode aOldMapMode( maPrefMapMode );
458cdf0e10cSrcweir Size aNewPrefSize;
459cdf0e10cSrcweir
460cdf0e10cSrcweir if( ( aOldSizePix != aNewSizePix ) && aOldSizePix.Width() && aOldSizePix.Height() )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir aNewPrefSize.Width() = FRound( maPrefSize.Width() * aNewSizePix.Width() / aOldSizePix.Width() );
463cdf0e10cSrcweir aNewPrefSize.Height() = FRound( maPrefSize.Height() * aNewSizePix.Height() / aOldSizePix.Height() );
464cdf0e10cSrcweir }
465cdf0e10cSrcweir else
466cdf0e10cSrcweir aNewPrefSize = maPrefSize;
467cdf0e10cSrcweir
468cdf0e10cSrcweir *this = rBitmap;
469cdf0e10cSrcweir
470cdf0e10cSrcweir maPrefSize = aNewPrefSize;
471cdf0e10cSrcweir maPrefMapMode = aOldMapMode;
472cdf0e10cSrcweir }
473cdf0e10cSrcweir
474cdf0e10cSrcweir // ------------------------------------------------------------------
475cdf0e10cSrcweir
ImplGetImpBitmap() const476cdf0e10cSrcweir ImpBitmap* Bitmap::ImplGetImpBitmap() const
477cdf0e10cSrcweir {
478cdf0e10cSrcweir return mpImpBmp;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir
481cdf0e10cSrcweir // ------------------------------------------------------------------
482cdf0e10cSrcweir
ImplSetImpBitmap(ImpBitmap * pImpBmp)483cdf0e10cSrcweir void Bitmap::ImplSetImpBitmap( ImpBitmap* pImpBmp )
484cdf0e10cSrcweir {
485cdf0e10cSrcweir if( pImpBmp != mpImpBmp )
486cdf0e10cSrcweir {
487cdf0e10cSrcweir ImplReleaseRef();
488cdf0e10cSrcweir mpImpBmp = pImpBmp;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir }
491cdf0e10cSrcweir
492cdf0e10cSrcweir // ------------------------------------------------------------------
493cdf0e10cSrcweir
AcquireReadAccess()494cdf0e10cSrcweir BitmapReadAccess* Bitmap::AcquireReadAccess()
495cdf0e10cSrcweir {
496cdf0e10cSrcweir BitmapReadAccess* pReadAccess = new BitmapReadAccess( *this );
497cdf0e10cSrcweir
498cdf0e10cSrcweir if( !*pReadAccess )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir delete pReadAccess;
501cdf0e10cSrcweir pReadAccess = NULL;
502cdf0e10cSrcweir }
503cdf0e10cSrcweir
504cdf0e10cSrcweir return pReadAccess;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir
507cdf0e10cSrcweir // ------------------------------------------------------------------
508cdf0e10cSrcweir
AcquireWriteAccess()509cdf0e10cSrcweir BitmapWriteAccess* Bitmap::AcquireWriteAccess()
510cdf0e10cSrcweir {
511cdf0e10cSrcweir BitmapWriteAccess* pWriteAccess = new BitmapWriteAccess( *this );
512cdf0e10cSrcweir
513cdf0e10cSrcweir if( !*pWriteAccess )
514cdf0e10cSrcweir {
515cdf0e10cSrcweir delete pWriteAccess;
516cdf0e10cSrcweir pWriteAccess = NULL;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir
519cdf0e10cSrcweir return pWriteAccess;
520cdf0e10cSrcweir }
521cdf0e10cSrcweir
522cdf0e10cSrcweir // ------------------------------------------------------------------
523cdf0e10cSrcweir
ReleaseAccess(BitmapReadAccess * pBitmapAccess)524cdf0e10cSrcweir void Bitmap::ReleaseAccess( BitmapReadAccess* pBitmapAccess )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir delete pBitmapAccess;
527cdf0e10cSrcweir }
528cdf0e10cSrcweir
529cdf0e10cSrcweir // ------------------------------------------------------------------
530cdf0e10cSrcweir
Erase(const Color & rFillColor)531cdf0e10cSrcweir sal_Bool Bitmap::Erase( const Color& rFillColor )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir if( !(*this) )
534cdf0e10cSrcweir return sal_True;
535cdf0e10cSrcweir
536cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
537cdf0e10cSrcweir sal_Bool bRet = sal_False;
538cdf0e10cSrcweir
539cdf0e10cSrcweir if( pWriteAcc )
540cdf0e10cSrcweir {
541cdf0e10cSrcweir const sal_uLong nFormat = pWriteAcc->GetScanlineFormat();
542cdf0e10cSrcweir sal_uInt8 cIndex = 0;
543cdf0e10cSrcweir sal_Bool bFast = sal_False;
544cdf0e10cSrcweir
545cdf0e10cSrcweir switch( nFormat )
546cdf0e10cSrcweir {
547cdf0e10cSrcweir case( BMP_FORMAT_1BIT_MSB_PAL ):
548cdf0e10cSrcweir case( BMP_FORMAT_1BIT_LSB_PAL ):
549cdf0e10cSrcweir {
550cdf0e10cSrcweir cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
551cdf0e10cSrcweir cIndex = ( cIndex ? 255 : 0 );
552cdf0e10cSrcweir bFast = sal_True;
553cdf0e10cSrcweir }
554cdf0e10cSrcweir break;
555cdf0e10cSrcweir
556cdf0e10cSrcweir case( BMP_FORMAT_4BIT_MSN_PAL ):
557cdf0e10cSrcweir case( BMP_FORMAT_4BIT_LSN_PAL ):
558cdf0e10cSrcweir {
559cdf0e10cSrcweir cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
560cdf0e10cSrcweir cIndex = cIndex | ( cIndex << 4 );
561cdf0e10cSrcweir bFast = sal_True;
562cdf0e10cSrcweir }
563cdf0e10cSrcweir break;
564cdf0e10cSrcweir
565cdf0e10cSrcweir case( BMP_FORMAT_8BIT_PAL ):
566cdf0e10cSrcweir {
567cdf0e10cSrcweir cIndex = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( rFillColor );
568cdf0e10cSrcweir bFast = sal_True;
569cdf0e10cSrcweir }
570cdf0e10cSrcweir break;
571cdf0e10cSrcweir
572cdf0e10cSrcweir case( BMP_FORMAT_24BIT_TC_BGR ):
573cdf0e10cSrcweir case( BMP_FORMAT_24BIT_TC_RGB ):
574cdf0e10cSrcweir {
575cdf0e10cSrcweir if( ( rFillColor.GetRed() == rFillColor.GetGreen() ) &&
576cdf0e10cSrcweir ( rFillColor.GetRed() == rFillColor.GetBlue() ) )
577cdf0e10cSrcweir {
578cdf0e10cSrcweir cIndex = rFillColor.GetRed();
579cdf0e10cSrcweir bFast = sal_True;
580cdf0e10cSrcweir }
581cdf0e10cSrcweir else
582cdf0e10cSrcweir bFast = sal_False;
583cdf0e10cSrcweir }
584cdf0e10cSrcweir break;
585cdf0e10cSrcweir
586cdf0e10cSrcweir default:
587cdf0e10cSrcweir bFast = sal_False;
588cdf0e10cSrcweir break;
589cdf0e10cSrcweir }
590cdf0e10cSrcweir
591cdf0e10cSrcweir if( bFast )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir const sal_uLong nBufSize = pWriteAcc->GetScanlineSize() * pWriteAcc->Height();
594cdf0e10cSrcweir memset( pWriteAcc->GetBuffer(), cIndex, nBufSize );
595cdf0e10cSrcweir }
596cdf0e10cSrcweir else
597cdf0e10cSrcweir {
598cdf0e10cSrcweir Point aTmpPoint;
599cdf0e10cSrcweir const Rectangle aRect( aTmpPoint, Size( pWriteAcc->Width(), pWriteAcc->Height() ) );
600cdf0e10cSrcweir pWriteAcc->SetFillColor( rFillColor );
601cdf0e10cSrcweir pWriteAcc->FillRect( aRect );
602cdf0e10cSrcweir }
603cdf0e10cSrcweir
604cdf0e10cSrcweir ReleaseAccess( pWriteAcc );
605cdf0e10cSrcweir bRet = sal_True;
606cdf0e10cSrcweir }
607cdf0e10cSrcweir
608cdf0e10cSrcweir return bRet;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir
611cdf0e10cSrcweir // ------------------------------------------------------------------
612cdf0e10cSrcweir
Invert()613cdf0e10cSrcweir sal_Bool Bitmap::Invert()
614cdf0e10cSrcweir {
615cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
616cdf0e10cSrcweir sal_Bool bRet = sal_False;
617cdf0e10cSrcweir
618cdf0e10cSrcweir if( pAcc )
619cdf0e10cSrcweir {
620cdf0e10cSrcweir if( pAcc->HasPalette() )
621cdf0e10cSrcweir {
622cdf0e10cSrcweir BitmapPalette aBmpPal( pAcc->GetPalette() );
623cdf0e10cSrcweir const sal_uInt16 nCount = aBmpPal.GetEntryCount();
624cdf0e10cSrcweir
625cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nCount; i++ )
626cdf0e10cSrcweir aBmpPal[ i ].Invert();
627cdf0e10cSrcweir
628cdf0e10cSrcweir pAcc->SetPalette( aBmpPal );
629cdf0e10cSrcweir }
630cdf0e10cSrcweir else
631cdf0e10cSrcweir {
632cdf0e10cSrcweir const long nWidth = pAcc->Width();
633cdf0e10cSrcweir const long nHeight = pAcc->Height();
634cdf0e10cSrcweir
635cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
636cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
637cdf0e10cSrcweir pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nX ).Invert() );
638cdf0e10cSrcweir }
639cdf0e10cSrcweir
640cdf0e10cSrcweir ReleaseAccess( pAcc );
641cdf0e10cSrcweir bRet = sal_True;
642cdf0e10cSrcweir }
643cdf0e10cSrcweir
644cdf0e10cSrcweir return bRet;
645cdf0e10cSrcweir }
646cdf0e10cSrcweir
647cdf0e10cSrcweir // ------------------------------------------------------------------
648cdf0e10cSrcweir
Mirror(sal_uLong nMirrorFlags)649cdf0e10cSrcweir sal_Bool Bitmap::Mirror( sal_uLong nMirrorFlags )
650cdf0e10cSrcweir {
651cdf0e10cSrcweir sal_Bool bHorz = ( ( nMirrorFlags & BMP_MIRROR_HORZ ) == BMP_MIRROR_HORZ );
652cdf0e10cSrcweir sal_Bool bVert = ( ( nMirrorFlags & BMP_MIRROR_VERT ) == BMP_MIRROR_VERT );
653cdf0e10cSrcweir sal_Bool bRet = sal_False;
654cdf0e10cSrcweir
655cdf0e10cSrcweir if( bHorz && !bVert )
656cdf0e10cSrcweir {
657cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
658cdf0e10cSrcweir
659cdf0e10cSrcweir if( pAcc )
660cdf0e10cSrcweir {
661cdf0e10cSrcweir const long nWidth = pAcc->Width();
662cdf0e10cSrcweir const long nHeight = pAcc->Height();
663cdf0e10cSrcweir const long nWidth1 = nWidth - 1L;
664cdf0e10cSrcweir const long nWidth_2 = nWidth >> 1L;
665cdf0e10cSrcweir
666cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
667cdf0e10cSrcweir {
668cdf0e10cSrcweir for( long nX = 0L, nOther = nWidth1; nX < nWidth_2; nX++, nOther-- )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
671cdf0e10cSrcweir
672cdf0e10cSrcweir pAcc->SetPixel( nY, nX, pAcc->GetPixel( nY, nOther ) );
673cdf0e10cSrcweir pAcc->SetPixel( nY, nOther, aTemp );
674cdf0e10cSrcweir }
675cdf0e10cSrcweir }
676cdf0e10cSrcweir
677cdf0e10cSrcweir ReleaseAccess( pAcc );
678cdf0e10cSrcweir bRet = sal_True;
679cdf0e10cSrcweir }
680cdf0e10cSrcweir }
681cdf0e10cSrcweir else if( bVert && !bHorz )
682cdf0e10cSrcweir {
683cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
684cdf0e10cSrcweir
685cdf0e10cSrcweir if( pAcc )
686cdf0e10cSrcweir {
687cdf0e10cSrcweir const long nScanSize = pAcc->GetScanlineSize();
688cdf0e10cSrcweir sal_uInt8* pBuffer = new sal_uInt8[ nScanSize ];
689cdf0e10cSrcweir const long nHeight = pAcc->Height();
690cdf0e10cSrcweir const long nHeight1 = nHeight - 1L;
691cdf0e10cSrcweir const long nHeight_2 = nHeight >> 1L;
692cdf0e10cSrcweir
693cdf0e10cSrcweir for( long nY = 0L, nOther = nHeight1; nY < nHeight_2; nY++, nOther-- )
694cdf0e10cSrcweir {
695cdf0e10cSrcweir memcpy( pBuffer, pAcc->GetScanline( nY ), nScanSize );
696cdf0e10cSrcweir memcpy( pAcc->GetScanline( nY ), pAcc->GetScanline( nOther ), nScanSize );
697cdf0e10cSrcweir memcpy( pAcc->GetScanline( nOther ), pBuffer, nScanSize );
698cdf0e10cSrcweir }
699cdf0e10cSrcweir
700cdf0e10cSrcweir delete[] pBuffer;
701cdf0e10cSrcweir ReleaseAccess( pAcc );
702cdf0e10cSrcweir bRet = sal_True;
703cdf0e10cSrcweir }
704cdf0e10cSrcweir }
705cdf0e10cSrcweir else if( bHorz && bVert )
706cdf0e10cSrcweir {
707cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
708cdf0e10cSrcweir
709cdf0e10cSrcweir if( pAcc )
710cdf0e10cSrcweir {
711cdf0e10cSrcweir const long nWidth = pAcc->Width();
712cdf0e10cSrcweir const long nWidth1 = nWidth - 1L;
713cdf0e10cSrcweir const long nHeight = pAcc->Height();
714cdf0e10cSrcweir long nHeight_2 = nHeight >> 1;
715cdf0e10cSrcweir
716cdf0e10cSrcweir for( long nY = 0L, nOtherY = nHeight - 1L; nY < nHeight_2; nY++, nOtherY-- )
717cdf0e10cSrcweir {
718cdf0e10cSrcweir for( long nX = 0L, nOtherX = nWidth1; nX < nWidth; nX++, nOtherX-- )
719cdf0e10cSrcweir {
720cdf0e10cSrcweir const BitmapColor aTemp( pAcc->GetPixel( nY, nX ) );
721cdf0e10cSrcweir
722cdf0e10cSrcweir pAcc->SetPixel( nY, nX, pAcc->GetPixel( nOtherY, nOtherX ) );
723cdf0e10cSrcweir pAcc->SetPixel( nOtherY, nOtherX, aTemp );
724cdf0e10cSrcweir }
725cdf0e10cSrcweir }
726cdf0e10cSrcweir
727cdf0e10cSrcweir // ggf. noch mittlere Zeile horizontal spiegeln
728cdf0e10cSrcweir if( nHeight & 1 )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir for( long nX = 0L, nOtherX = nWidth1, nWidth_2 = nWidth >> 1; nX < nWidth_2; nX++, nOtherX-- )
731cdf0e10cSrcweir {
732cdf0e10cSrcweir const BitmapColor aTemp( pAcc->GetPixel( nHeight_2, nX ) );
733cdf0e10cSrcweir pAcc->SetPixel( nHeight_2, nX, pAcc->GetPixel( nHeight_2, nOtherX ) );
734cdf0e10cSrcweir pAcc->SetPixel( nHeight_2, nOtherX, aTemp );
735cdf0e10cSrcweir }
736cdf0e10cSrcweir }
737cdf0e10cSrcweir
738cdf0e10cSrcweir ReleaseAccess( pAcc );
739cdf0e10cSrcweir bRet = sal_True;
740cdf0e10cSrcweir }
741cdf0e10cSrcweir }
742cdf0e10cSrcweir else
743cdf0e10cSrcweir bRet = sal_True;
744cdf0e10cSrcweir
745cdf0e10cSrcweir return bRet;
746cdf0e10cSrcweir }
747cdf0e10cSrcweir
748cdf0e10cSrcweir // ------------------------------------------------------------------
749cdf0e10cSrcweir
Rotate(long nAngle10,const Color & rFillColor)750cdf0e10cSrcweir sal_Bool Bitmap::Rotate( long nAngle10, const Color& rFillColor )
751cdf0e10cSrcweir {
752cdf0e10cSrcweir sal_Bool bRet = sal_False;
753cdf0e10cSrcweir
754cdf0e10cSrcweir nAngle10 %= 3600L;
755cdf0e10cSrcweir nAngle10 = ( nAngle10 < 0L ) ? ( 3599L + nAngle10 ) : nAngle10;
756cdf0e10cSrcweir
757cdf0e10cSrcweir if( !nAngle10 )
758cdf0e10cSrcweir bRet = sal_True;
759cdf0e10cSrcweir else if( 1800L == nAngle10 )
760cdf0e10cSrcweir bRet = Mirror( BMP_MIRROR_HORZ | BMP_MIRROR_VERT );
761cdf0e10cSrcweir else
762cdf0e10cSrcweir {
763cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess();
764cdf0e10cSrcweir Bitmap aRotatedBmp;
765cdf0e10cSrcweir
766cdf0e10cSrcweir if( pReadAcc )
767cdf0e10cSrcweir {
768cdf0e10cSrcweir const Size aSizePix( GetSizePixel() );
769cdf0e10cSrcweir
770cdf0e10cSrcweir if( ( 900L == nAngle10 ) || ( 2700L == nAngle10 ) )
771cdf0e10cSrcweir {
772cdf0e10cSrcweir const Size aNewSizePix( aSizePix.Height(), aSizePix.Width() );
773cdf0e10cSrcweir Bitmap aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
774cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
775cdf0e10cSrcweir
776cdf0e10cSrcweir if( pWriteAcc )
777cdf0e10cSrcweir {
778cdf0e10cSrcweir const long nWidth = aSizePix.Width();
779cdf0e10cSrcweir const long nWidth1 = nWidth - 1L;
780cdf0e10cSrcweir const long nHeight = aSizePix.Height();
781cdf0e10cSrcweir const long nHeight1 = nHeight - 1L;
782cdf0e10cSrcweir const long nNewWidth = aNewSizePix.Width();
783cdf0e10cSrcweir const long nNewHeight = aNewSizePix.Height();
784cdf0e10cSrcweir
785cdf0e10cSrcweir if( 900L == nAngle10 )
786cdf0e10cSrcweir {
787cdf0e10cSrcweir for( long nY = 0L, nOtherX = nWidth1; nY < nNewHeight; nY++, nOtherX-- )
788cdf0e10cSrcweir for( long nX = 0L, nOtherY = 0L; nX < nNewWidth; nX++ )
789cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY++, nOtherX ) );
790cdf0e10cSrcweir }
791cdf0e10cSrcweir else if( 2700L == nAngle10 )
792cdf0e10cSrcweir {
793cdf0e10cSrcweir for( long nY = 0L, nOtherX = 0L; nY < nNewHeight; nY++, nOtherX++ )
794cdf0e10cSrcweir for( long nX = 0L, nOtherY = nHeight1; nX < nNewWidth; nX++ )
795cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nOtherY--, nOtherX ) );
796cdf0e10cSrcweir }
797cdf0e10cSrcweir
798cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc );
799cdf0e10cSrcweir }
800cdf0e10cSrcweir
801cdf0e10cSrcweir aRotatedBmp = aNewBmp;
802cdf0e10cSrcweir }
803cdf0e10cSrcweir else
804cdf0e10cSrcweir {
805cdf0e10cSrcweir Point aTmpPoint;
806cdf0e10cSrcweir Rectangle aTmpRectangle( aTmpPoint, aSizePix );
807cdf0e10cSrcweir Polygon aPoly( aTmpRectangle );
808cdf0e10cSrcweir aPoly.Rotate( aTmpPoint, (sal_uInt16) nAngle10 );
809cdf0e10cSrcweir
810cdf0e10cSrcweir Rectangle aNewBound( aPoly.GetBoundRect() );
811cdf0e10cSrcweir const Size aNewSizePix( aNewBound.GetSize() );
812cdf0e10cSrcweir Bitmap aNewBmp( aNewSizePix, GetBitCount(), &pReadAcc->GetPalette() );
813cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
814cdf0e10cSrcweir
815cdf0e10cSrcweir if( pWriteAcc )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir const BitmapColor aFillColor( pWriteAcc->GetBestMatchingColor( rFillColor ) );
818cdf0e10cSrcweir const double fCosAngle = cos( nAngle10 * F_PI1800 );
819cdf0e10cSrcweir const double fSinAngle = sin( nAngle10 * F_PI1800 );
820cdf0e10cSrcweir const double fXMin = aNewBound.Left();
821cdf0e10cSrcweir const double fYMin = aNewBound.Top();
822cdf0e10cSrcweir const long nWidth = aSizePix.Width();
823cdf0e10cSrcweir const long nHeight = aSizePix.Height();
824cdf0e10cSrcweir const long nNewWidth = aNewSizePix.Width();
825cdf0e10cSrcweir const long nNewHeight = aNewSizePix.Height();
826cdf0e10cSrcweir long nX;
827cdf0e10cSrcweir long nY;
828cdf0e10cSrcweir long nRotX;
829cdf0e10cSrcweir long nRotY;
830cdf0e10cSrcweir long nSinY;
831cdf0e10cSrcweir long nCosY;
832cdf0e10cSrcweir long* pCosX = new long[ nNewWidth ];
833cdf0e10cSrcweir long* pSinX = new long[ nNewWidth ];
834cdf0e10cSrcweir long* pCosY = new long[ nNewHeight ];
835cdf0e10cSrcweir long* pSinY = new long[ nNewHeight ];
836cdf0e10cSrcweir
837cdf0e10cSrcweir for ( nX = 0; nX < nNewWidth; nX++ )
838cdf0e10cSrcweir {
839cdf0e10cSrcweir const double fTmp = ( fXMin + nX ) * 64.;
840cdf0e10cSrcweir
841cdf0e10cSrcweir pCosX[ nX ] = FRound( fCosAngle * fTmp );
842cdf0e10cSrcweir pSinX[ nX ] = FRound( fSinAngle * fTmp );
843cdf0e10cSrcweir }
844cdf0e10cSrcweir
845cdf0e10cSrcweir for ( nY = 0; nY < nNewHeight; nY++ )
846cdf0e10cSrcweir {
847cdf0e10cSrcweir const double fTmp = ( fYMin + nY ) * 64.;
848cdf0e10cSrcweir
849cdf0e10cSrcweir pCosY[ nY ] = FRound( fCosAngle * fTmp );
850cdf0e10cSrcweir pSinY[ nY ] = FRound( fSinAngle * fTmp );
851cdf0e10cSrcweir }
852cdf0e10cSrcweir
853cdf0e10cSrcweir for( nY = 0L; nY < nNewHeight; nY++ )
854cdf0e10cSrcweir {
855cdf0e10cSrcweir nSinY = pSinY[ nY ];
856cdf0e10cSrcweir nCosY = pCosY[ nY ];
857cdf0e10cSrcweir
858cdf0e10cSrcweir for( nX = 0L; nX < nNewWidth; nX++ )
859cdf0e10cSrcweir {
860cdf0e10cSrcweir nRotX = ( pCosX[ nX ] - nSinY ) >> 6;
861cdf0e10cSrcweir nRotY = ( pSinX[ nX ] + nCosY ) >> 6;
862cdf0e10cSrcweir
863cdf0e10cSrcweir if ( ( nRotX > -1L ) && ( nRotX < nWidth ) && ( nRotY > -1L ) && ( nRotY < nHeight ) )
864cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nRotY, nRotX ) );
865cdf0e10cSrcweir else
866cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aFillColor );
867cdf0e10cSrcweir }
868cdf0e10cSrcweir }
869cdf0e10cSrcweir
870cdf0e10cSrcweir delete[] pSinX;
871cdf0e10cSrcweir delete[] pCosX;
872cdf0e10cSrcweir delete[] pSinY;
873cdf0e10cSrcweir delete[] pCosY;
874cdf0e10cSrcweir
875cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc );
876cdf0e10cSrcweir }
877cdf0e10cSrcweir
878cdf0e10cSrcweir aRotatedBmp = aNewBmp;
879cdf0e10cSrcweir }
880cdf0e10cSrcweir
881cdf0e10cSrcweir ReleaseAccess( pReadAcc );
882cdf0e10cSrcweir }
883cdf0e10cSrcweir
884cdf0e10cSrcweir if( ( bRet = !!aRotatedBmp ) == sal_True )
885cdf0e10cSrcweir ImplAssignWithSize( aRotatedBmp );
886cdf0e10cSrcweir }
887cdf0e10cSrcweir
888cdf0e10cSrcweir return bRet;
889cdf0e10cSrcweir };
890cdf0e10cSrcweir
891cdf0e10cSrcweir // ------------------------------------------------------------------
892cdf0e10cSrcweir
Crop(const Rectangle & rRectPixel)893cdf0e10cSrcweir sal_Bool Bitmap::Crop( const Rectangle& rRectPixel )
894cdf0e10cSrcweir {
895cdf0e10cSrcweir const Size aSizePix( GetSizePixel() );
896cdf0e10cSrcweir Rectangle aRect( rRectPixel );
897cdf0e10cSrcweir sal_Bool bRet = sal_False;
898cdf0e10cSrcweir
899cdf0e10cSrcweir aRect.Intersection( Rectangle( Point(), aSizePix ) );
900cdf0e10cSrcweir
901cdf0e10cSrcweir if( !aRect.IsEmpty() )
902cdf0e10cSrcweir {
903cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess();
904cdf0e10cSrcweir
905cdf0e10cSrcweir if( pReadAcc )
906cdf0e10cSrcweir {
907cdf0e10cSrcweir Point aTmpPoint;
908cdf0e10cSrcweir const Rectangle aNewRect( aTmpPoint, aRect.GetSize() );
909cdf0e10cSrcweir Bitmap aNewBmp( aNewRect.GetSize(), GetBitCount(), &pReadAcc->GetPalette() );
910cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
911cdf0e10cSrcweir
912cdf0e10cSrcweir if( pWriteAcc )
913cdf0e10cSrcweir {
914cdf0e10cSrcweir const long nOldX = aRect.Left();
915cdf0e10cSrcweir const long nOldY = aRect.Top();
916cdf0e10cSrcweir const long nNewWidth = aNewRect.GetWidth();
917cdf0e10cSrcweir const long nNewHeight = aNewRect.GetHeight();
918cdf0e10cSrcweir
919cdf0e10cSrcweir for( long nY = 0, nY2 = nOldY; nY < nNewHeight; nY++, nY2++ )
920cdf0e10cSrcweir for( long nX = 0, nX2 = nOldX; nX < nNewWidth; nX++, nX2++ )
921cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, pReadAcc->GetPixel( nY2, nX2 ) );
922cdf0e10cSrcweir
923cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc );
924cdf0e10cSrcweir bRet = sal_True;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir
927cdf0e10cSrcweir ReleaseAccess( pReadAcc );
928cdf0e10cSrcweir
929cdf0e10cSrcweir if( bRet )
930cdf0e10cSrcweir ImplAssignWithSize( aNewBmp );
931cdf0e10cSrcweir }
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
934cdf0e10cSrcweir return bRet;
935cdf0e10cSrcweir };
936cdf0e10cSrcweir
937cdf0e10cSrcweir // ------------------------------------------------------------------
938cdf0e10cSrcweir
CopyPixel(const Rectangle & rRectDst,const Rectangle & rRectSrc,const Bitmap * pBmpSrc)939cdf0e10cSrcweir sal_Bool Bitmap::CopyPixel( const Rectangle& rRectDst,
940cdf0e10cSrcweir const Rectangle& rRectSrc, const Bitmap* pBmpSrc )
941cdf0e10cSrcweir {
942cdf0e10cSrcweir const Size aSizePix( GetSizePixel() );
943cdf0e10cSrcweir Rectangle aRectDst( rRectDst );
944cdf0e10cSrcweir sal_Bool bRet = sal_False;
945cdf0e10cSrcweir
946cdf0e10cSrcweir aRectDst.Intersection( Rectangle( Point(), aSizePix ) );
947cdf0e10cSrcweir
948cdf0e10cSrcweir if( !aRectDst.IsEmpty() )
949cdf0e10cSrcweir {
950cdf0e10cSrcweir if( pBmpSrc && ( *pBmpSrc != *this ) )
951cdf0e10cSrcweir {
952cdf0e10cSrcweir Bitmap* pSrc = (Bitmap*) pBmpSrc;
953cdf0e10cSrcweir const Size aCopySizePix( pSrc->GetSizePixel() );
954cdf0e10cSrcweir Rectangle aRectSrc( rRectSrc );
955cdf0e10cSrcweir const sal_uInt16 nSrcBitCount = pBmpSrc->GetBitCount();
956cdf0e10cSrcweir const sal_uInt16 nDstBitCount = GetBitCount();
957cdf0e10cSrcweir
958cdf0e10cSrcweir if( nSrcBitCount > nDstBitCount )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir long nNextIndex = 0L;
961cdf0e10cSrcweir
962cdf0e10cSrcweir if( ( nSrcBitCount == 24 ) && ( nDstBitCount < 24 ) )
963cdf0e10cSrcweir Convert( BMP_CONVERSION_24BIT );
964cdf0e10cSrcweir else if( ( nSrcBitCount == 8 ) && ( nDstBitCount < 8 ) )
965cdf0e10cSrcweir {
966cdf0e10cSrcweir Convert( BMP_CONVERSION_8BIT_COLORS );
967cdf0e10cSrcweir nNextIndex = 16;
968cdf0e10cSrcweir }
969cdf0e10cSrcweir else if( ( nSrcBitCount == 4 ) && ( nDstBitCount < 4 ) )
970cdf0e10cSrcweir {
971cdf0e10cSrcweir Convert( BMP_CONVERSION_4BIT_COLORS );
972cdf0e10cSrcweir nNextIndex = 2;
973cdf0e10cSrcweir }
974cdf0e10cSrcweir
975cdf0e10cSrcweir if( nNextIndex )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir BitmapReadAccess* pSrcAcc = pSrc->AcquireReadAccess();
978cdf0e10cSrcweir BitmapWriteAccess* pDstAcc = AcquireWriteAccess();
979cdf0e10cSrcweir
980cdf0e10cSrcweir if( pSrcAcc && pDstAcc )
981cdf0e10cSrcweir {
982cdf0e10cSrcweir const long nSrcCount = pDstAcc->GetPaletteEntryCount();
983cdf0e10cSrcweir const long nDstCount = 1 << nDstBitCount;
984cdf0e10cSrcweir sal_Bool bFound;
985cdf0e10cSrcweir
986cdf0e10cSrcweir for( long i = 0L; ( i < nSrcCount ) && ( nNextIndex < nSrcCount ); i++ )
987cdf0e10cSrcweir {
988cdf0e10cSrcweir const BitmapColor& rSrcCol = pSrcAcc->GetPaletteColor( (sal_uInt16) i );
989cdf0e10cSrcweir
990cdf0e10cSrcweir bFound = sal_False;
991cdf0e10cSrcweir
992cdf0e10cSrcweir for( long j = 0L; j < nDstCount; j++ )
993cdf0e10cSrcweir {
994cdf0e10cSrcweir if( rSrcCol == pDstAcc->GetPaletteColor( (sal_uInt16) j ) )
995cdf0e10cSrcweir {
996cdf0e10cSrcweir bFound = sal_True;
997cdf0e10cSrcweir break;
998cdf0e10cSrcweir }
999cdf0e10cSrcweir }
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir if( !bFound )
1002cdf0e10cSrcweir pDstAcc->SetPaletteColor( (sal_uInt16) nNextIndex++, rSrcCol );
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir }
1005cdf0e10cSrcweir
1006cdf0e10cSrcweir if( pSrcAcc )
1007cdf0e10cSrcweir pSrc->ReleaseAccess( pSrcAcc );
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir if( pDstAcc )
1010cdf0e10cSrcweir ReleaseAccess( pDstAcc );
1011cdf0e10cSrcweir }
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir
1014cdf0e10cSrcweir aRectSrc.Intersection( Rectangle( Point(), aCopySizePix ) );
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir if( !aRectSrc.IsEmpty() )
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir BitmapReadAccess* pReadAcc = pSrc->AcquireReadAccess();
1019cdf0e10cSrcweir
1020cdf0e10cSrcweir if( pReadAcc )
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
1023cdf0e10cSrcweir
1024cdf0e10cSrcweir if( pWriteAcc )
1025cdf0e10cSrcweir {
1026cdf0e10cSrcweir const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
1027cdf0e10cSrcweir const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
1028cdf0e10cSrcweir const long nSrcEndX = aRectSrc.Left() + nWidth;
1029cdf0e10cSrcweir const long nSrcEndY = aRectSrc.Top() + nHeight;
1030cdf0e10cSrcweir long nDstY = aRectDst.Top();
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir if( pReadAcc->HasPalette() && pWriteAcc->HasPalette() )
1033cdf0e10cSrcweir {
1034cdf0e10cSrcweir const sal_uInt16 nCount = pReadAcc->GetPaletteEntryCount();
1035cdf0e10cSrcweir sal_uInt8* pMap = new sal_uInt8[ nCount ];
1036cdf0e10cSrcweir
1037cdf0e10cSrcweir // Index-Map fuer Farbtabelle
1038cdf0e10cSrcweir // aufbauen, da das Bild ja (relativ) farbgenau
1039cdf0e10cSrcweir // kopiert werden soll
1040cdf0e10cSrcweir for( sal_uInt16 i = 0; i < nCount; i++ )
1041cdf0e10cSrcweir pMap[ i ] = (sal_uInt8) pWriteAcc->GetBestPaletteIndex( pReadAcc->GetPaletteColor( i ) );
1042cdf0e10cSrcweir
1043cdf0e10cSrcweir for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
1044cdf0e10cSrcweir for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
104587bc88d3SHerbert Dürr pWriteAcc->SetPixelIndex( nDstY, nDstX, pMap[ pReadAcc->GetPixelIndex( nSrcY, nSrcX ) ] );
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir delete[] pMap;
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir else if( pReadAcc->HasPalette() )
1050cdf0e10cSrcweir {
1051cdf0e10cSrcweir for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
1052cdf0e10cSrcweir for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
105387bc88d3SHerbert Dürr pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nSrcY, nSrcX ) ) );
1054cdf0e10cSrcweir }
1055cdf0e10cSrcweir else
1056cdf0e10cSrcweir for( long nSrcY = aRectSrc.Top(); nSrcY < nSrcEndY; nSrcY++, nDstY++ )
1057cdf0e10cSrcweir for( long nSrcX = aRectSrc.Left(), nDstX = aRectDst.Left(); nSrcX < nSrcEndX; nSrcX++, nDstX++ )
1058cdf0e10cSrcweir pWriteAcc->SetPixel( nDstY, nDstX, pReadAcc->GetPixel( nSrcY, nSrcX ) );
1059cdf0e10cSrcweir
1060cdf0e10cSrcweir ReleaseAccess( pWriteAcc );
1061cdf0e10cSrcweir bRet = ( nWidth > 0L ) && ( nHeight > 0L );
1062cdf0e10cSrcweir }
1063cdf0e10cSrcweir
1064cdf0e10cSrcweir pSrc->ReleaseAccess( pReadAcc );
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir }
1067cdf0e10cSrcweir }
1068cdf0e10cSrcweir else
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir Rectangle aRectSrc( rRectSrc );
1071cdf0e10cSrcweir
1072cdf0e10cSrcweir aRectSrc.Intersection( Rectangle( Point(), aSizePix ) );
1073cdf0e10cSrcweir
1074cdf0e10cSrcweir if( !aRectSrc.IsEmpty() && ( aRectSrc != aRectDst ) )
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = AcquireWriteAccess();
1077cdf0e10cSrcweir
1078cdf0e10cSrcweir if( pWriteAcc )
1079cdf0e10cSrcweir {
1080cdf0e10cSrcweir const long nWidth = Min( aRectSrc.GetWidth(), aRectDst.GetWidth() );
1081cdf0e10cSrcweir const long nHeight = Min( aRectSrc.GetHeight(), aRectDst.GetHeight() );
1082cdf0e10cSrcweir const long nSrcX = aRectSrc.Left();
1083cdf0e10cSrcweir const long nSrcY = aRectSrc.Top();
1084cdf0e10cSrcweir const long nSrcEndX1 = nSrcX + nWidth - 1L;
1085cdf0e10cSrcweir const long nSrcEndY1 = nSrcY + nHeight - 1L;
1086cdf0e10cSrcweir const long nDstX = aRectDst.Left();
1087cdf0e10cSrcweir const long nDstY = aRectDst.Top();
1088cdf0e10cSrcweir const long nDstEndX1 = nDstX + nWidth - 1L;
1089cdf0e10cSrcweir const long nDstEndY1 = nDstY + nHeight - 1L;
1090cdf0e10cSrcweir
1091cdf0e10cSrcweir if( ( nDstX <= nSrcX ) && ( nDstY <= nSrcY ) )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
1094cdf0e10cSrcweir for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
1095cdf0e10cSrcweir pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
1096cdf0e10cSrcweir }
1097cdf0e10cSrcweir else if( ( nDstX <= nSrcX ) && ( nDstY >= nSrcY ) )
1098cdf0e10cSrcweir {
1099cdf0e10cSrcweir for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
1100cdf0e10cSrcweir for( long nX = nSrcX, nXN = nDstX; nX <= nSrcEndX1; nX++, nXN++ )
1101cdf0e10cSrcweir pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
1102cdf0e10cSrcweir }
1103cdf0e10cSrcweir else if( ( nDstX >= nSrcX ) && ( nDstY <= nSrcY ) )
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir for( long nY = nSrcY, nYN = nDstY; nY <= nSrcEndY1; nY++, nYN++ )
1106cdf0e10cSrcweir for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
1107cdf0e10cSrcweir pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
1108cdf0e10cSrcweir }
1109cdf0e10cSrcweir else
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir for( long nY = nSrcEndY1, nYN = nDstEndY1; nY >= nSrcY; nY--, nYN-- )
1112cdf0e10cSrcweir for( long nX = nSrcEndX1, nXN = nDstEndX1; nX >= nSrcX; nX--, nXN-- )
1113cdf0e10cSrcweir pWriteAcc->SetPixel( nYN, nXN, pWriteAcc->GetPixel( nY, nX ) );
1114cdf0e10cSrcweir }
1115cdf0e10cSrcweir
1116cdf0e10cSrcweir ReleaseAccess( pWriteAcc );
1117cdf0e10cSrcweir bRet = sal_True;
1118cdf0e10cSrcweir }
1119cdf0e10cSrcweir }
1120cdf0e10cSrcweir }
1121cdf0e10cSrcweir }
1122cdf0e10cSrcweir
1123cdf0e10cSrcweir return bRet;
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir
1126cdf0e10cSrcweir // ------------------------------------------------------------------
1127cdf0e10cSrcweir
Expand(sal_uLong nDX,sal_uLong nDY,const Color * pInitColor)1128cdf0e10cSrcweir sal_Bool Bitmap::Expand( sal_uLong nDX, sal_uLong nDY, const Color* pInitColor )
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir sal_Bool bRet = sal_False;
1131cdf0e10cSrcweir
1132cdf0e10cSrcweir if( nDX || nDY )
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir const Size aSizePixel( GetSizePixel() );
1135cdf0e10cSrcweir const long nWidth = aSizePixel.Width();
1136cdf0e10cSrcweir const long nHeight = aSizePixel.Height();
1137cdf0e10cSrcweir const Size aNewSize( nWidth + nDX, nHeight + nDY );
1138cdf0e10cSrcweir BitmapReadAccess* pReadAcc = AcquireReadAccess();
1139cdf0e10cSrcweir
1140cdf0e10cSrcweir if( pReadAcc )
1141cdf0e10cSrcweir {
1142cdf0e10cSrcweir BitmapPalette aBmpPal( pReadAcc->GetPalette() );
1143cdf0e10cSrcweir Bitmap aNewBmp( aNewSize, GetBitCount(), &aBmpPal );
1144cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
1145cdf0e10cSrcweir
1146cdf0e10cSrcweir if( pWriteAcc )
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir BitmapColor aColor;
1149cdf0e10cSrcweir const long nNewX = nWidth;
1150cdf0e10cSrcweir const long nNewY = nHeight;
1151cdf0e10cSrcweir const long nNewWidth = pWriteAcc->Width();
1152cdf0e10cSrcweir const long nNewHeight = pWriteAcc->Height();
1153cdf0e10cSrcweir long nX;
1154cdf0e10cSrcweir long nY;
1155cdf0e10cSrcweir
1156cdf0e10cSrcweir if( pInitColor )
1157cdf0e10cSrcweir aColor = pWriteAcc->GetBestMatchingColor( *pInitColor );
1158cdf0e10cSrcweir
1159cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir pWriteAcc->CopyScanline( nY, *pReadAcc );
1162cdf0e10cSrcweir
1163cdf0e10cSrcweir if( pInitColor && nDX )
1164cdf0e10cSrcweir for( nX = nNewX; nX < nNewWidth; nX++ )
1165cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aColor );
1166cdf0e10cSrcweir }
1167cdf0e10cSrcweir
1168cdf0e10cSrcweir if( pInitColor && nDY )
1169cdf0e10cSrcweir for( nY = nNewY; nY < nNewHeight; nY++ )
1170cdf0e10cSrcweir for( nX = 0; nX < nNewWidth; nX++ )
1171cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aColor );
1172cdf0e10cSrcweir
1173cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc );
1174cdf0e10cSrcweir bRet = sal_True;
1175cdf0e10cSrcweir }
1176cdf0e10cSrcweir
1177cdf0e10cSrcweir ReleaseAccess( pReadAcc );
1178cdf0e10cSrcweir
1179cdf0e10cSrcweir if( bRet )
1180cdf0e10cSrcweir ImplAssignWithSize( aNewBmp );
1181cdf0e10cSrcweir }
1182cdf0e10cSrcweir }
1183cdf0e10cSrcweir
1184cdf0e10cSrcweir return bRet;
1185cdf0e10cSrcweir }
1186cdf0e10cSrcweir
1187cdf0e10cSrcweir // ------------------------------------------------------------------
1188cdf0e10cSrcweir
CreateMask(const Color & rTransColor,sal_uLong nTol) const1189cdf0e10cSrcweir Bitmap Bitmap::CreateMask( const Color& rTransColor, sal_uLong nTol ) const
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 1 );
1192cdf0e10cSrcweir BitmapWriteAccess* pWriteAcc = aNewBmp.AcquireWriteAccess();
1193cdf0e10cSrcweir sal_Bool bRet = sal_False;
1194cdf0e10cSrcweir
1195cdf0e10cSrcweir if( pWriteAcc )
1196cdf0e10cSrcweir {
1197cdf0e10cSrcweir BitmapReadAccess* pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
1198cdf0e10cSrcweir
1199cdf0e10cSrcweir if( pReadAcc )
1200cdf0e10cSrcweir {
1201cdf0e10cSrcweir const long nWidth = pReadAcc->Width();
1202cdf0e10cSrcweir const long nHeight = pReadAcc->Height();
1203cdf0e10cSrcweir const BitmapColor aBlack( pWriteAcc->GetBestMatchingColor( Color( COL_BLACK ) ) );
1204cdf0e10cSrcweir const BitmapColor aWhite( pWriteAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
1205cdf0e10cSrcweir
1206cdf0e10cSrcweir if( !nTol )
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir const BitmapColor aTest( pReadAcc->GetBestMatchingColor( rTransColor ) );
1209cdf0e10cSrcweir long nX, nY, nShift;
1210cdf0e10cSrcweir
1211cdf0e10cSrcweir if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ||
1212cdf0e10cSrcweir pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_LSN_PAL )
1213cdf0e10cSrcweir {
1214cdf0e10cSrcweir // optimized for 4Bit-MSN/LSN source palette
1215cdf0e10cSrcweir const sal_uInt8 cTest = aTest.GetIndex();
1216cdf0e10cSrcweir const long nShiftInit = ( ( pReadAcc->GetScanlineFormat() == BMP_FORMAT_4BIT_MSN_PAL ) ? 4 : 0 );
1217cdf0e10cSrcweir
1218cdf0e10cSrcweir if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
1219cdf0e10cSrcweir aWhite.GetIndex() == 1 )
1220cdf0e10cSrcweir {
1221cdf0e10cSrcweir // optimized for 1Bit-MSB destination palette
1222cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1223cdf0e10cSrcweir {
1224cdf0e10cSrcweir Scanline pSrc = pReadAcc->GetScanline( nY );
1225cdf0e10cSrcweir Scanline pDst = pWriteAcc->GetScanline( nY );
1226cdf0e10cSrcweir for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
1227cdf0e10cSrcweir {
1228cdf0e10cSrcweir if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
1229cdf0e10cSrcweir pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
1230cdf0e10cSrcweir else
1231cdf0e10cSrcweir pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir else
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir Scanline pSrc = pReadAcc->GetScanline( nY );
1240cdf0e10cSrcweir for( nX = 0L, nShift = nShiftInit; nX < nWidth; nX++, nShift ^= 4 )
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir if( cTest == ( ( pSrc[ nX >> 1 ] >> nShift ) & 0x0f ) )
1243cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite );
1244cdf0e10cSrcweir else
1245cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack );
1246cdf0e10cSrcweir }
1247cdf0e10cSrcweir }
1248cdf0e10cSrcweir }
1249cdf0e10cSrcweir }
1250cdf0e10cSrcweir else if( pReadAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL )
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir // optimized for 8Bit source palette
1253cdf0e10cSrcweir const sal_uInt8 cTest = aTest.GetIndex();
1254cdf0e10cSrcweir
1255cdf0e10cSrcweir if( pWriteAcc->GetScanlineFormat() == BMP_FORMAT_1BIT_MSB_PAL &&
1256cdf0e10cSrcweir aWhite.GetIndex() == 1 )
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir // optimized for 1Bit-MSB destination palette
1259cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1260cdf0e10cSrcweir {
1261cdf0e10cSrcweir Scanline pSrc = pReadAcc->GetScanline( nY );
1262cdf0e10cSrcweir Scanline pDst = pWriteAcc->GetScanline( nY );
1263cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ )
1264cdf0e10cSrcweir {
1265cdf0e10cSrcweir if( cTest == pSrc[ nX ] )
1266cdf0e10cSrcweir pDst[ nX >> 3 ] |= 1 << ( 7 - ( nX & 7 ) );
1267cdf0e10cSrcweir else
1268cdf0e10cSrcweir pDst[ nX >> 3 ] &= ~( 1 << ( 7 - ( nX & 7 ) ) );
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir }
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir else
1273cdf0e10cSrcweir {
1274cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1275cdf0e10cSrcweir {
1276cdf0e10cSrcweir Scanline pSrc = pReadAcc->GetScanline( nY );
1277cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ )
1278cdf0e10cSrcweir {
1279cdf0e10cSrcweir if( cTest == pSrc[ nX ] )
1280cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite );
1281cdf0e10cSrcweir else
1282cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack );
1283cdf0e10cSrcweir }
1284cdf0e10cSrcweir }
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir else
1288cdf0e10cSrcweir {
1289cdf0e10cSrcweir // not optimized
1290cdf0e10cSrcweir for( nY = 0L; nY < nHeight; nY++ )
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir for( nX = 0L; nX < nWidth; nX++ )
1293cdf0e10cSrcweir {
1294cdf0e10cSrcweir if( aTest == pReadAcc->GetPixel( nY, nX ) )
1295cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite );
1296cdf0e10cSrcweir else
1297cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack );
1298cdf0e10cSrcweir }
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir }
1301cdf0e10cSrcweir }
1302cdf0e10cSrcweir else
1303cdf0e10cSrcweir {
1304cdf0e10cSrcweir BitmapColor aCol;
1305cdf0e10cSrcweir long nR, nG, nB;
1306cdf0e10cSrcweir const long nMinR = MinMax( (long) rTransColor.GetRed() - nTol, 0, 255 );
1307cdf0e10cSrcweir const long nMaxR = MinMax( (long) rTransColor.GetRed() + nTol, 0, 255 );
1308cdf0e10cSrcweir const long nMinG = MinMax( (long) rTransColor.GetGreen() - nTol, 0, 255 );
1309cdf0e10cSrcweir const long nMaxG = MinMax( (long) rTransColor.GetGreen() + nTol, 0, 255 );
1310cdf0e10cSrcweir const long nMinB = MinMax( (long) rTransColor.GetBlue() - nTol, 0, 255 );
1311cdf0e10cSrcweir const long nMaxB = MinMax( (long) rTransColor.GetBlue() + nTol, 0, 255 );
1312cdf0e10cSrcweir
1313cdf0e10cSrcweir if( pReadAcc->HasPalette() )
1314cdf0e10cSrcweir {
1315cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
1316cdf0e10cSrcweir {
1317cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
1318cdf0e10cSrcweir {
131987bc88d3SHerbert Dürr aCol = pReadAcc->GetPaletteColor( pReadAcc->GetPixelIndex( nY, nX ) );
1320cdf0e10cSrcweir nR = aCol.GetRed();
1321cdf0e10cSrcweir nG = aCol.GetGreen();
1322cdf0e10cSrcweir nB = aCol.GetBlue();
1323cdf0e10cSrcweir
1324cdf0e10cSrcweir if( nMinR <= nR && nMaxR >= nR &&
1325cdf0e10cSrcweir nMinG <= nG && nMaxG >= nG &&
1326cdf0e10cSrcweir nMinB <= nB && nMaxB >= nB )
1327cdf0e10cSrcweir {
1328cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite );
1329cdf0e10cSrcweir }
1330cdf0e10cSrcweir else
1331cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack );
1332cdf0e10cSrcweir }
1333cdf0e10cSrcweir }
1334cdf0e10cSrcweir }
1335cdf0e10cSrcweir else
1336cdf0e10cSrcweir {
1337cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
1338cdf0e10cSrcweir {
1339cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
1340cdf0e10cSrcweir {
1341cdf0e10cSrcweir aCol = pReadAcc->GetPixel( nY, nX );
1342cdf0e10cSrcweir nR = aCol.GetRed();
1343cdf0e10cSrcweir nG = aCol.GetGreen();
1344cdf0e10cSrcweir nB = aCol.GetBlue();
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir if( nMinR <= nR && nMaxR >= nR &&
1347cdf0e10cSrcweir nMinG <= nG && nMaxG >= nG &&
1348cdf0e10cSrcweir nMinB <= nB && nMaxB >= nB )
1349cdf0e10cSrcweir {
1350cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aWhite );
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir else
1353cdf0e10cSrcweir pWriteAcc->SetPixel( nY, nX, aBlack );
1354cdf0e10cSrcweir }
1355cdf0e10cSrcweir }
1356cdf0e10cSrcweir }
1357cdf0e10cSrcweir }
1358cdf0e10cSrcweir
1359cdf0e10cSrcweir ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
1360cdf0e10cSrcweir bRet = sal_True;
1361cdf0e10cSrcweir }
1362cdf0e10cSrcweir
1363cdf0e10cSrcweir aNewBmp.ReleaseAccess( pWriteAcc );
1364cdf0e10cSrcweir }
1365cdf0e10cSrcweir
1366cdf0e10cSrcweir if( bRet )
1367cdf0e10cSrcweir {
1368cdf0e10cSrcweir aNewBmp.maPrefSize = maPrefSize;
1369cdf0e10cSrcweir aNewBmp.maPrefMapMode = maPrefMapMode;
1370cdf0e10cSrcweir }
1371cdf0e10cSrcweir else
1372cdf0e10cSrcweir aNewBmp = Bitmap();
1373cdf0e10cSrcweir
1374cdf0e10cSrcweir return aNewBmp;
1375cdf0e10cSrcweir }
1376cdf0e10cSrcweir
1377cdf0e10cSrcweir // ------------------------------------------------------------------
1378cdf0e10cSrcweir
CreateRegion(const Color & rColor,const Rectangle & rRect) const1379cdf0e10cSrcweir Region Bitmap::CreateRegion( const Color& rColor, const Rectangle& rRect ) const
1380cdf0e10cSrcweir {
1381cdf0e10cSrcweir Region aRegion;
1382cdf0e10cSrcweir Rectangle aRect( rRect );
1383cdf0e10cSrcweir BitmapReadAccess* pReadAcc = ( (Bitmap*) this )->AcquireReadAccess();
1384cdf0e10cSrcweir
1385cdf0e10cSrcweir aRect.Intersection( Rectangle( Point(), GetSizePixel() ) );
1386cdf0e10cSrcweir aRect.Justify();
1387cdf0e10cSrcweir
1388cdf0e10cSrcweir if( pReadAcc )
1389cdf0e10cSrcweir {
1390e6f63103SArmin Le Grand //Rectangle aSubRect;
1391cdf0e10cSrcweir const long nLeft = aRect.Left();
1392cdf0e10cSrcweir const long nTop = aRect.Top();
1393cdf0e10cSrcweir const long nRight = aRect.Right();
1394cdf0e10cSrcweir const long nBottom = aRect.Bottom();
1395cdf0e10cSrcweir const BitmapColor aMatch( pReadAcc->GetBestMatchingColor( rColor ) );
1396cdf0e10cSrcweir
1397e6f63103SArmin Le Grand //RectangleVector aRectangles;
1398e6f63103SArmin Le Grand //aRegion.ImplBeginAddRect();
1399e6f63103SArmin Le Grand std::vector< long > aLine;
1400e6f63103SArmin Le Grand long nYStart(nTop);
1401e6f63103SArmin Le Grand long nY(nTop);
1402cdf0e10cSrcweir
1403e6f63103SArmin Le Grand for( ; nY <= nBottom; nY++ )
1404cdf0e10cSrcweir {
1405e6f63103SArmin Le Grand //aSubRect.Top() = aSubRect.Bottom() = nY;
1406e6f63103SArmin Le Grand std::vector< long > aNewLine;
1407e6f63103SArmin Le Grand long nX(nLeft);
1408cdf0e10cSrcweir
1409e6f63103SArmin Le Grand for( ; nX <= nRight; )
1410cdf0e10cSrcweir {
1411cdf0e10cSrcweir while( ( nX <= nRight ) && ( aMatch != pReadAcc->GetPixel( nY, nX ) ) )
1412cdf0e10cSrcweir nX++;
1413cdf0e10cSrcweir
1414cdf0e10cSrcweir if( nX <= nRight )
1415cdf0e10cSrcweir {
1416e6f63103SArmin Le Grand aNewLine.push_back(nX);
1417e6f63103SArmin Le Grand //aSubRect.Left() = nX;
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir while( ( nX <= nRight ) && ( aMatch == pReadAcc->GetPixel( nY, nX ) ) )
1420cdf0e10cSrcweir nX++;
1421cdf0e10cSrcweir
1422e6f63103SArmin Le Grand //aSubRect.Right() = nX - 1L;
1423e6f63103SArmin Le Grand aNewLine.push_back(nX - 1);
1424e6f63103SArmin Le Grand
1425e6f63103SArmin Le Grand //aRegion.ImplAddRect( aSubRect );
1426e6f63103SArmin Le Grand //aRectangles.push_back(aSubRect);
1427e6f63103SArmin Le Grand //aRegion.Union(aSubRect);
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir
1431e6f63103SArmin Le Grand if(aNewLine != aLine)
1432e6f63103SArmin Le Grand {
1433e6f63103SArmin Le Grand // need to write aLine, it's different from the next line
1434e6f63103SArmin Le Grand if(aLine.size())
1435e6f63103SArmin Le Grand {
1436e6f63103SArmin Le Grand Rectangle aSubRect;
1437e6f63103SArmin Le Grand
1438e6f63103SArmin Le Grand // enter y values and proceed ystart
1439e6f63103SArmin Le Grand aSubRect.Top() = nYStart;
1440e6f63103SArmin Le Grand aSubRect.Bottom() = nY ? nY - 1 : 0;
1441e6f63103SArmin Le Grand
1442e6f63103SArmin Le Grand for(sal_uInt32 a(0); a < aLine.size();)
1443e6f63103SArmin Le Grand {
1444e6f63103SArmin Le Grand aSubRect.Left() = aLine[a++];
1445e6f63103SArmin Le Grand aSubRect.Right() = aLine[a++];
1446e6f63103SArmin Le Grand aRegion.Union(aSubRect);
1447e6f63103SArmin Le Grand }
1448e6f63103SArmin Le Grand }
1449e6f63103SArmin Le Grand
1450e6f63103SArmin Le Grand // copy line as new line
1451e6f63103SArmin Le Grand aLine = aNewLine;
1452e6f63103SArmin Le Grand nYStart = nY;
1453e6f63103SArmin Le Grand }
1454e6f63103SArmin Le Grand }
1455e6f63103SArmin Le Grand
1456e6f63103SArmin Le Grand // write last line if used
1457e6f63103SArmin Le Grand if(aLine.size())
1458e6f63103SArmin Le Grand {
1459e6f63103SArmin Le Grand Rectangle aSubRect;
1460e6f63103SArmin Le Grand
1461e6f63103SArmin Le Grand // enter y values
1462e6f63103SArmin Le Grand aSubRect.Top() = nYStart;
1463e6f63103SArmin Le Grand aSubRect.Bottom() = nY ? nY - 1 : 0;
1464e6f63103SArmin Le Grand
1465e6f63103SArmin Le Grand for(sal_uInt32 a(0); a < aLine.size();)
1466e6f63103SArmin Le Grand {
1467e6f63103SArmin Le Grand aSubRect.Left() = aLine[a++];
1468e6f63103SArmin Le Grand aSubRect.Right() = aLine[a++];
1469e6f63103SArmin Le Grand aRegion.Union(aSubRect);
1470e6f63103SArmin Le Grand }
1471e6f63103SArmin Le Grand }
1472e6f63103SArmin Le Grand
1473e6f63103SArmin Le Grand //aRegion.ImplEndAddRect();
1474e6f63103SArmin Le Grand //aRegion.SetRegionRectangles(aRectangles);
1475e6f63103SArmin Le Grand
1476cdf0e10cSrcweir ( (Bitmap*) this )->ReleaseAccess( pReadAcc );
1477cdf0e10cSrcweir }
1478cdf0e10cSrcweir else
1479cdf0e10cSrcweir aRegion = aRect;
1480cdf0e10cSrcweir
1481cdf0e10cSrcweir return aRegion;
1482cdf0e10cSrcweir }
1483cdf0e10cSrcweir
1484cdf0e10cSrcweir // ------------------------------------------------------------------
1485cdf0e10cSrcweir
Replace(const Bitmap & rMask,const Color & rReplaceColor)1486cdf0e10cSrcweir sal_Bool Bitmap::Replace( const Bitmap& rMask, const Color& rReplaceColor )
1487cdf0e10cSrcweir {
1488cdf0e10cSrcweir BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
1489cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
1490cdf0e10cSrcweir sal_Bool bRet = sal_False;
1491cdf0e10cSrcweir
1492cdf0e10cSrcweir if( pMaskAcc && pAcc )
1493cdf0e10cSrcweir {
1494cdf0e10cSrcweir const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
1495cdf0e10cSrcweir const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
1496cdf0e10cSrcweir const BitmapColor aMaskWhite( pMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
1497cdf0e10cSrcweir BitmapColor aReplace;
1498cdf0e10cSrcweir
1499cdf0e10cSrcweir if( pAcc->HasPalette() )
1500cdf0e10cSrcweir {
1501cdf0e10cSrcweir const sal_uInt16 nActColors = pAcc->GetPaletteEntryCount();
1502cdf0e10cSrcweir const sal_uInt16 nMaxColors = 1 << pAcc->GetBitCount();
1503cdf0e10cSrcweir
150487bc88d3SHerbert Dürr // default to the nearest color
1505cdf0e10cSrcweir aReplace = pAcc->GetBestMatchingColor( rReplaceColor );
1506cdf0e10cSrcweir
150787bc88d3SHerbert Dürr // for paletted images without a matching palette entry
150887bc88d3SHerbert Dürr // look for an unused palette entry (NOTE: expensive!)
150987bc88d3SHerbert Dürr if( pAcc->GetPaletteColor( aReplace.GetIndex() ) != BitmapColor( rReplaceColor ) )
1510cdf0e10cSrcweir {
151187bc88d3SHerbert Dürr // if the palette has empty entries use the last one
1512cdf0e10cSrcweir if( nActColors < nMaxColors )
1513cdf0e10cSrcweir {
1514cdf0e10cSrcweir pAcc->SetPaletteEntryCount( nActColors + 1 );
1515cdf0e10cSrcweir pAcc->SetPaletteColor( nActColors, rReplaceColor );
1516cdf0e10cSrcweir aReplace = BitmapColor( (sal_uInt8) nActColors );
1517cdf0e10cSrcweir }
1518cdf0e10cSrcweir else
1519cdf0e10cSrcweir {
1520cdf0e10cSrcweir sal_Bool* pFlags = new sal_Bool[ nMaxColors ];
1521cdf0e10cSrcweir
1522cdf0e10cSrcweir // alle Eintraege auf 0 setzen
1523cdf0e10cSrcweir memset( pFlags, 0, nMaxColors );
1524cdf0e10cSrcweir
1525cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
1526cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
152787bc88d3SHerbert Dürr pFlags[ pAcc->GetPixelIndex( nY, nX ) ] = sal_True;
1528cdf0e10cSrcweir
1529cdf0e10cSrcweir for( sal_uInt16 i = 0UL; i < nMaxColors; i++ )
1530cdf0e10cSrcweir {
1531cdf0e10cSrcweir // Hurra, wir haben einen unbenutzten Eintrag
1532cdf0e10cSrcweir if( !pFlags[ i ] )
1533cdf0e10cSrcweir {
1534cdf0e10cSrcweir pAcc->SetPaletteColor( (sal_uInt16) i, rReplaceColor );
1535cdf0e10cSrcweir aReplace = BitmapColor( (sal_uInt8) i );
1536cdf0e10cSrcweir }
1537cdf0e10cSrcweir }
1538cdf0e10cSrcweir
1539cdf0e10cSrcweir delete[] pFlags;
1540cdf0e10cSrcweir }
1541cdf0e10cSrcweir }
1542cdf0e10cSrcweir }
1543cdf0e10cSrcweir else
1544cdf0e10cSrcweir aReplace = rReplaceColor;
1545cdf0e10cSrcweir
1546cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
1547cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
1548cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) == aMaskWhite )
1549cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aReplace );
1550cdf0e10cSrcweir
1551cdf0e10cSrcweir bRet = sal_True;
1552cdf0e10cSrcweir }
1553cdf0e10cSrcweir
1554cdf0e10cSrcweir ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
1555cdf0e10cSrcweir ReleaseAccess( pAcc );
1556cdf0e10cSrcweir
1557cdf0e10cSrcweir return bRet;
1558cdf0e10cSrcweir }
1559cdf0e10cSrcweir
1560cdf0e10cSrcweir // ------------------------------------------------------------------
1561cdf0e10cSrcweir
Replace(const AlphaMask & rAlpha,const Color & rMergeColor)1562cdf0e10cSrcweir sal_Bool Bitmap::Replace( const AlphaMask& rAlpha, const Color& rMergeColor )
1563cdf0e10cSrcweir {
1564cdf0e10cSrcweir Bitmap aNewBmp( GetSizePixel(), 24 );
1565cdf0e10cSrcweir BitmapReadAccess* pAcc = AcquireReadAccess();
1566cdf0e10cSrcweir BitmapReadAccess* pAlphaAcc = ( (AlphaMask&) rAlpha ).AcquireReadAccess();
1567cdf0e10cSrcweir BitmapWriteAccess* pNewAcc = aNewBmp.AcquireWriteAccess();
1568cdf0e10cSrcweir sal_Bool bRet = sal_False;
1569cdf0e10cSrcweir
1570cdf0e10cSrcweir if( pAcc && pAlphaAcc && pNewAcc )
1571cdf0e10cSrcweir {
1572cdf0e10cSrcweir BitmapColor aCol;
1573cdf0e10cSrcweir const long nWidth = Min( pAlphaAcc->Width(), pAcc->Width() );
1574cdf0e10cSrcweir const long nHeight = Min( pAlphaAcc->Height(), pAcc->Height() );
1575cdf0e10cSrcweir
1576cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ )
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; nX++ )
1579cdf0e10cSrcweir {
1580cdf0e10cSrcweir aCol = pAcc->GetColor( nY, nX );
158187bc88d3SHerbert Dürr pNewAcc->SetPixel( nY, nX, aCol.Merge( rMergeColor, 255 - pAlphaAcc->GetPixelIndex( nY, nX ) ) );
1582cdf0e10cSrcweir }
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir
1585cdf0e10cSrcweir bRet = sal_True;
1586cdf0e10cSrcweir }
1587cdf0e10cSrcweir
1588cdf0e10cSrcweir ReleaseAccess( pAcc );
1589cdf0e10cSrcweir ( (AlphaMask&) rAlpha ).ReleaseAccess( pAlphaAcc );
1590cdf0e10cSrcweir aNewBmp.ReleaseAccess( pNewAcc );
1591cdf0e10cSrcweir
1592cdf0e10cSrcweir if( bRet )
1593cdf0e10cSrcweir {
1594cdf0e10cSrcweir const MapMode aMap( maPrefMapMode );
1595cdf0e10cSrcweir const Size aSize( maPrefSize );
1596cdf0e10cSrcweir
1597cdf0e10cSrcweir *this = aNewBmp;
1598cdf0e10cSrcweir
1599cdf0e10cSrcweir maPrefMapMode = aMap;
1600cdf0e10cSrcweir maPrefSize = aSize;
1601cdf0e10cSrcweir }
1602cdf0e10cSrcweir
1603cdf0e10cSrcweir return bRet;
1604cdf0e10cSrcweir }
1605cdf0e10cSrcweir
1606cdf0e10cSrcweir // ------------------------------------------------------------------
1607cdf0e10cSrcweir
Replace(const Color & rSearchColor,const Color & rReplaceColor,sal_uLong nTol)1608cdf0e10cSrcweir sal_Bool Bitmap::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
1609cdf0e10cSrcweir {
1610cdf0e10cSrcweir // Bitmaps with 1 bit color depth can cause problems
1611cdf0e10cSrcweir // if they have other entries than black/white in their palette
1612cdf0e10cSrcweir if( 1 == GetBitCount() )
1613cdf0e10cSrcweir Convert( BMP_CONVERSION_4BIT_COLORS );
1614cdf0e10cSrcweir
1615cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
1616cdf0e10cSrcweir sal_Bool bRet = sal_False;
1617cdf0e10cSrcweir
1618cdf0e10cSrcweir if( pAcc )
1619cdf0e10cSrcweir {
1620cdf0e10cSrcweir const long nMinR = MinMax( (long) rSearchColor.GetRed() - nTol, 0, 255 );
1621cdf0e10cSrcweir const long nMaxR = MinMax( (long) rSearchColor.GetRed() + nTol, 0, 255 );
1622cdf0e10cSrcweir const long nMinG = MinMax( (long) rSearchColor.GetGreen() - nTol, 0, 255 );
1623cdf0e10cSrcweir const long nMaxG = MinMax( (long) rSearchColor.GetGreen() + nTol, 0, 255 );
1624cdf0e10cSrcweir const long nMinB = MinMax( (long) rSearchColor.GetBlue() - nTol, 0, 255 );
1625cdf0e10cSrcweir const long nMaxB = MinMax( (long) rSearchColor.GetBlue() + nTol, 0, 255 );
1626cdf0e10cSrcweir
1627cdf0e10cSrcweir if( pAcc->HasPalette() )
1628cdf0e10cSrcweir {
1629cdf0e10cSrcweir for( sal_uInt16 i = 0, nPalCount = pAcc->GetPaletteEntryCount(); i < nPalCount; i++ )
1630cdf0e10cSrcweir {
1631cdf0e10cSrcweir const BitmapColor& rCol = pAcc->GetPaletteColor( i );
1632cdf0e10cSrcweir
1633cdf0e10cSrcweir if( nMinR <= rCol.GetRed() && nMaxR >= rCol.GetRed() &&
1634cdf0e10cSrcweir nMinG <= rCol.GetGreen() && nMaxG >= rCol.GetGreen() &&
1635cdf0e10cSrcweir nMinB <= rCol.GetBlue() && nMaxB >= rCol.GetBlue() )
1636cdf0e10cSrcweir {
1637cdf0e10cSrcweir pAcc->SetPaletteColor( i, rReplaceColor );
1638cdf0e10cSrcweir }
1639cdf0e10cSrcweir }
1640cdf0e10cSrcweir }
1641cdf0e10cSrcweir else
1642cdf0e10cSrcweir {
1643cdf0e10cSrcweir BitmapColor aCol;
1644cdf0e10cSrcweir const BitmapColor aReplace( pAcc->GetBestMatchingColor( rReplaceColor ) );
1645cdf0e10cSrcweir
1646cdf0e10cSrcweir for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
1647cdf0e10cSrcweir {
1648cdf0e10cSrcweir for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
1649cdf0e10cSrcweir {
1650cdf0e10cSrcweir aCol = pAcc->GetPixel( nY, nX );
1651cdf0e10cSrcweir
1652cdf0e10cSrcweir if( nMinR <= aCol.GetRed() && nMaxR >= aCol.GetRed() &&
1653cdf0e10cSrcweir nMinG <= aCol.GetGreen() && nMaxG >= aCol.GetGreen() &&
1654cdf0e10cSrcweir nMinB <= aCol.GetBlue() && nMaxB >= aCol.GetBlue() )
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aReplace );
1657cdf0e10cSrcweir }
1658cdf0e10cSrcweir }
1659cdf0e10cSrcweir }
1660cdf0e10cSrcweir }
1661cdf0e10cSrcweir
1662cdf0e10cSrcweir ReleaseAccess( pAcc );
1663cdf0e10cSrcweir bRet = sal_True;
1664cdf0e10cSrcweir }
1665cdf0e10cSrcweir
1666cdf0e10cSrcweir return bRet;
1667cdf0e10cSrcweir }
1668cdf0e10cSrcweir
1669cdf0e10cSrcweir // ------------------------------------------------------------------
1670cdf0e10cSrcweir
Replace(const Color * pSearchColors,const Color * pReplaceColors,sal_uLong nColorCount,sal_uLong * _pTols)1671cdf0e10cSrcweir sal_Bool Bitmap::Replace( const Color* pSearchColors, const Color* pReplaceColors,
1672cdf0e10cSrcweir sal_uLong nColorCount, sal_uLong* _pTols )
1673cdf0e10cSrcweir {
1674cdf0e10cSrcweir // Bitmaps with 1 bit color depth can cause problems
1675cdf0e10cSrcweir // if they have other entries than black/white in their palette
1676cdf0e10cSrcweir if( 1 == GetBitCount() )
1677cdf0e10cSrcweir Convert( BMP_CONVERSION_4BIT_COLORS );
1678cdf0e10cSrcweir
1679cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
1680cdf0e10cSrcweir sal_Bool bRet = sal_False;
1681cdf0e10cSrcweir
1682cdf0e10cSrcweir if( pAcc )
1683cdf0e10cSrcweir {
1684cdf0e10cSrcweir long* pMinR = new long[ nColorCount ];
1685cdf0e10cSrcweir long* pMaxR = new long[ nColorCount ];
1686cdf0e10cSrcweir long* pMinG = new long[ nColorCount ];
1687cdf0e10cSrcweir long* pMaxG = new long[ nColorCount ];
1688cdf0e10cSrcweir long* pMinB = new long[ nColorCount ];
1689cdf0e10cSrcweir long* pMaxB = new long[ nColorCount ];
1690cdf0e10cSrcweir long* pTols;
1691cdf0e10cSrcweir sal_uLong i;
1692cdf0e10cSrcweir
1693cdf0e10cSrcweir if( !_pTols )
1694cdf0e10cSrcweir {
1695cdf0e10cSrcweir pTols = new long[ nColorCount ];
1696cdf0e10cSrcweir memset( pTols, 0, nColorCount * sizeof( long ) );
1697cdf0e10cSrcweir }
1698cdf0e10cSrcweir else
1699cdf0e10cSrcweir pTols = (long*) _pTols;
1700cdf0e10cSrcweir
1701cdf0e10cSrcweir for( i = 0UL; i < nColorCount; i++ )
1702cdf0e10cSrcweir {
1703cdf0e10cSrcweir const Color& rCol = pSearchColors[ i ];
1704cdf0e10cSrcweir const long nTol = pTols[ i ];
1705cdf0e10cSrcweir
1706cdf0e10cSrcweir pMinR[ i ] = MinMax( (long) rCol.GetRed() - nTol, 0, 255 );
1707cdf0e10cSrcweir pMaxR[ i ] = MinMax( (long) rCol.GetRed() + nTol, 0, 255 );
1708cdf0e10cSrcweir pMinG[ i ] = MinMax( (long) rCol.GetGreen() - nTol, 0, 255 );
1709cdf0e10cSrcweir pMaxG[ i ] = MinMax( (long) rCol.GetGreen() + nTol, 0, 255 );
1710cdf0e10cSrcweir pMinB[ i ] = MinMax( (long) rCol.GetBlue() - nTol, 0, 255 );
1711cdf0e10cSrcweir pMaxB[ i ] = MinMax( (long) rCol.GetBlue() + nTol, 0, 255 );
1712cdf0e10cSrcweir }
1713cdf0e10cSrcweir
1714cdf0e10cSrcweir if( pAcc->HasPalette() )
1715cdf0e10cSrcweir {
1716cdf0e10cSrcweir for( sal_uInt16 nEntry = 0, nPalCount = pAcc->GetPaletteEntryCount(); nEntry < nPalCount; nEntry++ )
1717cdf0e10cSrcweir {
1718cdf0e10cSrcweir const BitmapColor& rCol = pAcc->GetPaletteColor( nEntry );
1719cdf0e10cSrcweir
1720cdf0e10cSrcweir for( i = 0UL; i < nColorCount; i++ )
1721cdf0e10cSrcweir {
1722cdf0e10cSrcweir if( pMinR[ i ] <= rCol.GetRed() && pMaxR[ i ] >= rCol.GetRed() &&
1723cdf0e10cSrcweir pMinG[ i ] <= rCol.GetGreen() && pMaxG[ i ] >= rCol.GetGreen() &&
1724cdf0e10cSrcweir pMinB[ i ] <= rCol.GetBlue() && pMaxB[ i ] >= rCol.GetBlue() )
1725cdf0e10cSrcweir {
1726cdf0e10cSrcweir pAcc->SetPaletteColor( (sal_uInt16)nEntry, pReplaceColors[ i ] );
1727cdf0e10cSrcweir break;
1728cdf0e10cSrcweir }
1729cdf0e10cSrcweir }
1730cdf0e10cSrcweir }
1731cdf0e10cSrcweir }
1732cdf0e10cSrcweir else
1733cdf0e10cSrcweir {
1734cdf0e10cSrcweir BitmapColor aCol;
1735cdf0e10cSrcweir BitmapColor* pReplaces = new BitmapColor[ nColorCount ];
1736cdf0e10cSrcweir
1737cdf0e10cSrcweir for( i = 0UL; i < nColorCount; i++ )
1738cdf0e10cSrcweir pReplaces[ i ] = pAcc->GetBestMatchingColor( pReplaceColors[ i ] );
1739cdf0e10cSrcweir
1740cdf0e10cSrcweir for( long nY = 0L, nHeight = pAcc->Height(); nY < nHeight; nY++ )
1741cdf0e10cSrcweir {
1742cdf0e10cSrcweir for( long nX = 0L, nWidth = pAcc->Width(); nX < nWidth; nX++ )
1743cdf0e10cSrcweir {
1744cdf0e10cSrcweir aCol = pAcc->GetPixel( nY, nX );
1745cdf0e10cSrcweir
1746cdf0e10cSrcweir for( i = 0UL; i < nColorCount; i++ )
1747cdf0e10cSrcweir {
1748cdf0e10cSrcweir if( pMinR[ i ] <= aCol.GetRed() && pMaxR[ i ] >= aCol.GetRed() &&
1749cdf0e10cSrcweir pMinG[ i ] <= aCol.GetGreen() && pMaxG[ i ] >= aCol.GetGreen() &&
1750cdf0e10cSrcweir pMinB[ i ] <= aCol.GetBlue() && pMaxB[ i ] >= aCol.GetBlue() )
1751cdf0e10cSrcweir {
1752cdf0e10cSrcweir pAcc->SetPixel( nY, nX, pReplaces[ i ] );
1753cdf0e10cSrcweir break;
1754cdf0e10cSrcweir }
1755cdf0e10cSrcweir }
1756cdf0e10cSrcweir }
1757cdf0e10cSrcweir }
1758cdf0e10cSrcweir
1759cdf0e10cSrcweir delete[] pReplaces;
1760cdf0e10cSrcweir }
1761cdf0e10cSrcweir
1762cdf0e10cSrcweir if( !_pTols )
1763cdf0e10cSrcweir delete[] pTols;
1764cdf0e10cSrcweir
1765cdf0e10cSrcweir delete[] pMinR;
1766cdf0e10cSrcweir delete[] pMaxR;
1767cdf0e10cSrcweir delete[] pMinG;
1768cdf0e10cSrcweir delete[] pMaxG;
1769cdf0e10cSrcweir delete[] pMinB;
1770cdf0e10cSrcweir delete[] pMaxB;
1771cdf0e10cSrcweir ReleaseAccess( pAcc );
1772cdf0e10cSrcweir bRet = sal_True;
1773cdf0e10cSrcweir }
1774cdf0e10cSrcweir
1775cdf0e10cSrcweir return bRet;
1776cdf0e10cSrcweir }
1777cdf0e10cSrcweir
1778cdf0e10cSrcweir // ------------------------------------------------------------------
1779cdf0e10cSrcweir
CreateDisplayBitmap(OutputDevice * pDisplay)1780cdf0e10cSrcweir Bitmap Bitmap::CreateDisplayBitmap( OutputDevice* pDisplay )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir Bitmap aDispBmp( *this );
1783cdf0e10cSrcweir
1784cdf0e10cSrcweir if( mpImpBmp && ( pDisplay->mpGraphics || pDisplay->ImplGetGraphics() ) )
1785cdf0e10cSrcweir {
1786cdf0e10cSrcweir ImpBitmap* pImpDispBmp = new ImpBitmap;
1787cdf0e10cSrcweir
1788cdf0e10cSrcweir if( pImpDispBmp->ImplCreate( *mpImpBmp, pDisplay->mpGraphics ) )
1789cdf0e10cSrcweir aDispBmp.ImplSetImpBitmap( pImpDispBmp );
1790cdf0e10cSrcweir else
1791cdf0e10cSrcweir delete pImpDispBmp;
1792cdf0e10cSrcweir }
1793cdf0e10cSrcweir
1794cdf0e10cSrcweir return aDispBmp;
1795cdf0e10cSrcweir }
1796cdf0e10cSrcweir
1797cdf0e10cSrcweir // ------------------------------------------------------------------
1798cdf0e10cSrcweir
GetColorTransformedBitmap(BmpColorMode eColorMode) const1799cdf0e10cSrcweir Bitmap Bitmap::GetColorTransformedBitmap( BmpColorMode eColorMode ) const
1800cdf0e10cSrcweir {
1801cdf0e10cSrcweir Bitmap aRet;
1802cdf0e10cSrcweir
1803cdf0e10cSrcweir if( BMP_COLOR_HIGHCONTRAST == eColorMode )
1804cdf0e10cSrcweir {
1805cdf0e10cSrcweir Color* pSrcColors = NULL;
1806cdf0e10cSrcweir Color* pDstColors = NULL;
1807cdf0e10cSrcweir sal_uLong nColorCount = 0;
1808cdf0e10cSrcweir
1809cdf0e10cSrcweir aRet = *this;
1810cdf0e10cSrcweir
1811cdf0e10cSrcweir Image::GetColorTransformArrays( (ImageColorTransform) eColorMode, pSrcColors, pDstColors, nColorCount );
1812cdf0e10cSrcweir
1813cdf0e10cSrcweir if( nColorCount && pSrcColors && pDstColors )
1814cdf0e10cSrcweir aRet.Replace( pSrcColors, pDstColors, nColorCount );
1815cdf0e10cSrcweir
1816cdf0e10cSrcweir delete[] pSrcColors;
1817cdf0e10cSrcweir delete[] pDstColors;
1818cdf0e10cSrcweir }
1819cdf0e10cSrcweir else if( BMP_COLOR_MONOCHROME_BLACK == eColorMode ||
1820cdf0e10cSrcweir BMP_COLOR_MONOCHROME_WHITE == eColorMode )
1821cdf0e10cSrcweir {
1822cdf0e10cSrcweir aRet = *this;
1823cdf0e10cSrcweir aRet.MakeMono( BMP_COLOR_MONOCHROME_THRESHOLD );
1824cdf0e10cSrcweir }
1825cdf0e10cSrcweir
1826cdf0e10cSrcweir return aRet;
1827cdf0e10cSrcweir }
1828cdf0e10cSrcweir
1829cdf0e10cSrcweir // ------------------------------------------------------------------
1830cdf0e10cSrcweir
CombineSimple(const Bitmap & rMask,BmpCombine eCombine)1831cdf0e10cSrcweir sal_Bool Bitmap::CombineSimple( const Bitmap& rMask, BmpCombine eCombine )
1832cdf0e10cSrcweir {
1833cdf0e10cSrcweir BitmapReadAccess* pMaskAcc = ( (Bitmap&) rMask ).AcquireReadAccess();
1834cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
1835cdf0e10cSrcweir sal_Bool bRet = sal_False;
1836cdf0e10cSrcweir
1837cdf0e10cSrcweir if( pMaskAcc && pAcc )
1838cdf0e10cSrcweir {
1839cdf0e10cSrcweir const long nWidth = Min( pMaskAcc->Width(), pAcc->Width() );
1840cdf0e10cSrcweir const long nHeight = Min( pMaskAcc->Height(), pAcc->Height() );
1841cdf0e10cSrcweir const Color aColBlack( COL_BLACK );
1842cdf0e10cSrcweir BitmapColor aPixel;
1843cdf0e10cSrcweir BitmapColor aMaskPixel;
1844cdf0e10cSrcweir const BitmapColor aWhite( pAcc->GetBestMatchingColor( Color( COL_WHITE ) ) );
1845cdf0e10cSrcweir const BitmapColor aBlack( pAcc->GetBestMatchingColor( aColBlack ) );
1846cdf0e10cSrcweir const BitmapColor aMaskBlack( pMaskAcc->GetBestMatchingColor( aColBlack ) );
1847cdf0e10cSrcweir
1848cdf0e10cSrcweir switch( eCombine )
1849cdf0e10cSrcweir {
1850cdf0e10cSrcweir case( BMP_COMBINE_COPY ):
1851cdf0e10cSrcweir {
1852cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1853cdf0e10cSrcweir {
1854cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) == aMaskBlack )
1855cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1856cdf0e10cSrcweir else
1857cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1858cdf0e10cSrcweir }
1859cdf0e10cSrcweir }
1860cdf0e10cSrcweir break;
1861cdf0e10cSrcweir
1862cdf0e10cSrcweir case( BMP_COMBINE_INVERT ):
1863cdf0e10cSrcweir {
1864cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir if( pAcc->GetPixel( nY, nX ) == aBlack )
1867cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1868cdf0e10cSrcweir else
1869cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1870cdf0e10cSrcweir }
1871cdf0e10cSrcweir }
1872cdf0e10cSrcweir break;
1873cdf0e10cSrcweir
1874cdf0e10cSrcweir case( BMP_COMBINE_AND ):
1875cdf0e10cSrcweir {
1876cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1877cdf0e10cSrcweir {
1878cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
1879cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1880cdf0e10cSrcweir else
1881cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1882cdf0e10cSrcweir }
1883cdf0e10cSrcweir }
1884cdf0e10cSrcweir break;
1885cdf0e10cSrcweir
1886cdf0e10cSrcweir case( BMP_COMBINE_NAND ):
1887cdf0e10cSrcweir {
1888cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1889cdf0e10cSrcweir {
1890cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack && pAcc->GetPixel( nY, nX ) != aBlack )
1891cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1892cdf0e10cSrcweir else
1893cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1894cdf0e10cSrcweir }
1895cdf0e10cSrcweir }
1896cdf0e10cSrcweir break;
1897cdf0e10cSrcweir
1898cdf0e10cSrcweir case( BMP_COMBINE_OR ):
1899cdf0e10cSrcweir {
1900cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1901cdf0e10cSrcweir {
1902cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
1903cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1904cdf0e10cSrcweir else
1905cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1906cdf0e10cSrcweir }
1907cdf0e10cSrcweir }
1908cdf0e10cSrcweir break;
1909cdf0e10cSrcweir
1910cdf0e10cSrcweir case( BMP_COMBINE_NOR ):
1911cdf0e10cSrcweir {
1912cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1913cdf0e10cSrcweir {
1914cdf0e10cSrcweir if( pMaskAcc->GetPixel( nY, nX ) != aMaskBlack || pAcc->GetPixel( nY, nX ) != aBlack )
1915cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1916cdf0e10cSrcweir else
1917cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1918cdf0e10cSrcweir }
1919cdf0e10cSrcweir }
1920cdf0e10cSrcweir break;
1921cdf0e10cSrcweir
1922cdf0e10cSrcweir case( BMP_COMBINE_XOR ):
1923cdf0e10cSrcweir {
1924cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1925cdf0e10cSrcweir {
1926cdf0e10cSrcweir aPixel = pAcc->GetPixel( nY, nX );
1927cdf0e10cSrcweir aMaskPixel = pMaskAcc->GetPixel( nY, nX );
1928cdf0e10cSrcweir
1929cdf0e10cSrcweir if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
1930cdf0e10cSrcweir ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
1931cdf0e10cSrcweir {
1932cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1933cdf0e10cSrcweir }
1934cdf0e10cSrcweir else
1935cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1936cdf0e10cSrcweir }
1937cdf0e10cSrcweir }
1938cdf0e10cSrcweir break;
1939cdf0e10cSrcweir
1940cdf0e10cSrcweir case( BMP_COMBINE_NXOR ):
1941cdf0e10cSrcweir {
1942cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; nY++ ) for( long nX = 0L; nX < nWidth; nX++ )
1943cdf0e10cSrcweir {
1944cdf0e10cSrcweir aPixel = pAcc->GetPixel( nY, nX );
1945cdf0e10cSrcweir aMaskPixel = pMaskAcc->GetPixel( nY, nX );
1946cdf0e10cSrcweir
1947cdf0e10cSrcweir if( ( aMaskPixel != aMaskBlack && aPixel == aBlack ) ||
1948cdf0e10cSrcweir ( aMaskPixel == aMaskBlack && aPixel != aBlack ) )
1949cdf0e10cSrcweir {
1950cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aBlack );
1951cdf0e10cSrcweir }
1952cdf0e10cSrcweir else
1953cdf0e10cSrcweir pAcc->SetPixel( nY, nX, aWhite );
1954cdf0e10cSrcweir }
1955cdf0e10cSrcweir }
1956cdf0e10cSrcweir break;
1957cdf0e10cSrcweir }
1958cdf0e10cSrcweir
1959cdf0e10cSrcweir bRet = sal_True;
1960cdf0e10cSrcweir }
1961cdf0e10cSrcweir
1962cdf0e10cSrcweir ( (Bitmap&) rMask ).ReleaseAccess( pMaskAcc );
1963cdf0e10cSrcweir ReleaseAccess( pAcc );
1964cdf0e10cSrcweir
1965cdf0e10cSrcweir return bRet;
1966cdf0e10cSrcweir }
1967cdf0e10cSrcweir
1968cdf0e10cSrcweir // ------------------------------------------------------------------
1969cdf0e10cSrcweir
Blend(const AlphaMask & rAlpha,const Color & rBackgroundColor)1970cdf0e10cSrcweir sal_Bool Bitmap::Blend( const AlphaMask& rAlpha, const Color& rBackgroundColor )
1971cdf0e10cSrcweir {
1972cdf0e10cSrcweir // TODO: Have a look at OutputDevice::ImplDrawAlpha() for some
1973cdf0e10cSrcweir // optimizations. Might even consolidate the code here and there.
1974cdf0e10cSrcweir
1975cdf0e10cSrcweir // convert to a truecolor bitmap, if we're a paletted one. There's
1976cdf0e10cSrcweir // room for tradeoff decision here, maybe later for an overload (or a flag)
1977cdf0e10cSrcweir if( GetBitCount() <= 8 )
1978cdf0e10cSrcweir Convert( BMP_CONVERSION_24BIT );
1979cdf0e10cSrcweir
1980cdf0e10cSrcweir BitmapReadAccess* pAlphaAcc = const_cast<AlphaMask&>(rAlpha).AcquireReadAccess();
1981cdf0e10cSrcweir BitmapWriteAccess* pAcc = AcquireWriteAccess();
1982cdf0e10cSrcweir sal_Bool bRet = sal_False;
1983cdf0e10cSrcweir
1984cdf0e10cSrcweir if( pAlphaAcc && pAcc )
1985cdf0e10cSrcweir {
1986cdf0e10cSrcweir const long nWidth = Min( pAlphaAcc->Width(), pAcc->Width() );
1987cdf0e10cSrcweir const long nHeight = Min( pAlphaAcc->Height(), pAcc->Height() );
1988cdf0e10cSrcweir
1989cdf0e10cSrcweir for( long nY = 0L; nY < nHeight; ++nY )
1990cdf0e10cSrcweir for( long nX = 0L; nX < nWidth; ++nX )
1991cdf0e10cSrcweir pAcc->SetPixel( nY, nX,
1992cdf0e10cSrcweir pAcc->GetPixel( nY, nX ).Merge( rBackgroundColor,
199387bc88d3SHerbert Dürr 255 - pAlphaAcc->GetPixelIndex( nY, nX ) ) );
1994cdf0e10cSrcweir
1995cdf0e10cSrcweir bRet = sal_True;
1996cdf0e10cSrcweir }
1997cdf0e10cSrcweir
1998cdf0e10cSrcweir const_cast<AlphaMask&>(rAlpha).ReleaseAccess( pAlphaAcc );
1999cdf0e10cSrcweir ReleaseAccess( pAcc );
2000cdf0e10cSrcweir
2001cdf0e10cSrcweir return bRet;
2002cdf0e10cSrcweir }
2003cdf0e10cSrcweir
2004cdf0e10cSrcweir // ------------------------------------------------------------------
2005cdf0e10cSrcweir
MakeMono(sal_uInt8 cThreshold)2006cdf0e10cSrcweir sal_Bool Bitmap::MakeMono( sal_uInt8 cThreshold )
2007cdf0e10cSrcweir {
2008cdf0e10cSrcweir return ImplMakeMono( cThreshold );
2009cdf0e10cSrcweir }
2010cdf0e10cSrcweir
2011cdf0e10cSrcweir // ------------------------------------------------------------------
2012cdf0e10cSrcweir
GetSystemData(BitmapSystemData & rData) const2013cdf0e10cSrcweir bool Bitmap::GetSystemData( BitmapSystemData& rData ) const
2014cdf0e10cSrcweir {
2015cdf0e10cSrcweir bool bRet = false;
2016cdf0e10cSrcweir if( mpImpBmp )
2017cdf0e10cSrcweir {
2018cdf0e10cSrcweir SalBitmap* pSalBitmap = mpImpBmp->ImplGetSalBitmap();
2019cdf0e10cSrcweir if( pSalBitmap )
2020cdf0e10cSrcweir bRet = pSalBitmap->GetSystemData( rData );
2021cdf0e10cSrcweir }
2022cdf0e10cSrcweir
2023cdf0e10cSrcweir return bRet;
2024cdf0e10cSrcweir }
2025